Mike Slinn
Mike Slinn

WSL / WSL 2 Backup and Restore

Published 2022-01-10.
Time to read: 6 minutes.

This site is categorized under WSL.

I needed to back up my WSL2 installation before reinstalling Windows 10, as one must do every 6 months if you work your machine like a developer. It had been years since I had last refreshed this machine, and it was now bluescreening several times a day. Reboots took forever.

😁

This story detail the various approaches I attempted; all failed until I was able to duplicate the original Ubuntu instance using LxRunOffline.

I wanted to retain my WSL2 instance. When refreshing Windows you must reinstall all your programs, and you lose all the WSL/WSL2 instances. The refresh decommissions them, then moves them into a hidden directory tree, along with the rest of the stuff stored in your old Windows 10 profile directory tree.

I also wanted to be able to replicate my WSL2 instance reliably and easily. It was very important to me to be able to administer WSL instances separately from my Windows 10 profile.

Only recently has it become possible to work with WSL/WSL2 images on non-system drives. Most online documentation is now out of date in this regard. Running Windows off a different drive than the drive that a WSL/WSL2 client OS runs from can provide a dramatic performance boost for some applications.

I use Dell laptops, because I love their onsite warranty price and features. However, sometimes it feels like Dell's solution to every problem is to replace the motherboard. That means Windows 10 feels a bit uncomfortable, and it wonders if it has been pirated. Refreshing Windows solves that problem, and blows away the standard WSL/WSL2 image. Again. And again. And again! Dell replaced the motherboard 4 times in 2 years for one of my laptops.

Having the WSL/WSL2 image elsewhere in the filesystem means that reinstalling Windows is not as traumatic.

Backing up WSL/WSL2 can be problematic. Restoring it is even more delicate. Knowing this, I decided to backup and test the restoration process before refreshing Windows and potentially losing my working system.

I have tried several times before to make this work. As I said, it had been years since I allowed the OS in my main workstation to be refreshed. The reason I resisted doing proper maintenance was because I wanted to preserve my WSL2 Ubuntu image. Until today, I met with frustrating failures every time I attempted to use the standard tools. Today I succeeded, via new software, hence the publication of my notes. Who wants to read stories about all the things that do not work?

Following is my experience. I began by following the directions in How to back up a Windows Subsystem for Linux (WSL) distribution, published 18 Feb 2021 by Windows Central. It is a nice story, but I've tried this stuff on a variety of computers, and this is not Microsoft's most robust code base as yet. Read on and I will tell you of reality as I found it.

WSL Command-Line Options

First let's look at the command-line options for the wsl command.

cmd.exe
Microsoft Windows [Version 10.0.19044.1415]
(c) Microsoft Corporation. All rights reserved. 

C:\Users\Mike Slinn> wsl -?
Invalid command line option: -?
Copyright (c) Microsoft Corporation. All rights reserved.

Usage: wsl.exe [Argument] [Options...] [CommandLine]

Arguments for running Linux binaries:

    If no command line is provided, wsl.exe launches the default shell.

    --exec, -e <CommandLine>
        Execute the specified command without using the default Linux shell.

    --
        Pass the remaining command line as is.

Options:
    --cd <Directory>
        Sets the specified directory as the current working directory.
        If ~ is used the Linux user’s home path will be used. If the path begins
        with a / character, it will be interpreted as an absolute Linux path.
        Otherwise, the value must be an absolute Windows path.

    --distribution, -d <Distro>
        Run the specified distribution.

    --user, -u <UserName>
        Run as the specified user.

Arguments for managing Windows Subsystem for Linux:

    --help
        Display usage information.

    --install [Options]
        Install additional Windows Subsystem for Linux distributions.
        For a list of valid distributions, use "wsl --list --online".

        Options:
            --distribution, -d [Argument]
                Downloads and installs a distribution by name.

                Arguments:
                    A valid distribution name (not case sensitive).

                Examples:
                    wsl --install -d Ubuntu
                    wsl --install --distribution Debian

    --set-default-version <Version>
        Changes the default install version for new distributions.

    --shutdown
        Immediately terminates all running distributions and the WSL 2
        lightweight utility virtual machine.

    --status
        Show the status of Windows Subsystem for Linux.

    --update [Options]
        If no options are specified, the WSL 2 kernel will be updated
        to the latest version.

        Options:
            --rollback
                Revert to the previous version of the WSL 2 kernel.

Arguments for managing distributions in Windows Subsystem for Linux:

    --export <Distro> <FileName>
        Exports the distribution to a tar file.
        The filename can be - for standard output.

    --import <Distro> <InstallLocation> <FileName> [Options]
        Imports the specified tar file as a new distribution.
        The filename can be - for standard input.

        Options:
            --version <Version>
                Specifies the version to use for the new distribution.

    --list, -l [Options]
        Lists distributions.

        Options:
            --all
                List all distributions, including distributions that are
                currently being installed or uninstalled.

            --running
                List only distributions that are currently running.

            --quiet, -q
                Only show distribution names.

            --verbose, -v
                Show detailed information about all distributions.

            --online, -o
                Displays a list of available distributions for install with 'wsl --install'.

    --set-default, -s <Distro>
        Sets the distribution as the default.

    --set-version <Distro> <Version>
        Changes the version of the specified distribution.

    --terminate, -t <Distro>
        Terminates the specified distribution.

    --unregister <Distro>
        Unregisters the distribution and deletes the root filesystem. 

Backing Up With WSL

Now let's use the wsl command to back up the Ubuntu VM in WSL2.

cmd.exe
C:\Users\Mike Slinn> wsl --export Ubuntu ubuntuBear_2021-01-10.tar

Well, well, it backed up without any problem in about an hour! Color me surprisedhappy. File size was about 50 GB.

Alright, let's try importing the image now. We'll locate the new image at f:\ubuntuBear. It used to be that WSL did not support moving or installing a distro to non-system drives. No longer!

cmd.exe
C:\Users\Mike Slinn> wsl --import Ubuntu f:\ubuntuBear ubuntuBear_2021-01-10.tar
A distribution with the supplied name already exists. 

The error message “A distribution with the supplied name already exists” makes sense because I backed up a WSL2 instance called Ubuntu and instance names must be unique. Let's import under the name UbuntuBear:

cmd.exe
C:\Users\Mike Slinn> wsl --import UbuntuBear f:\ubuntuBear ubuntuBear_2021-01-10.tar
Unspecified error 

Ahh, the dreaded Unspecified error that wsl import is infamous for. Google brought me to a potential solution, LxRunOffline.

Installing LxRunOffline

I downloaded the binaries in LxRunOffline-v3.5.0-msvc.zip directly from GitHub into C:\Program Files\LxRunOffline.

Now add C:\Program Files\LxRunOffline to the Windows PATH:

cmd.exe
C:\Users\Mike Slinn> setx PATH "%PATH%;C:\Program Files\LxRunOffline"

SUCCESS: Specified value was saved. %}

I then ran the following in an administrative shell to register the DLL:

cmd.exe
C:\Users\Mike Slinn> regsvr32 "C:\Program Files\LxRunOffline\LxRunOfflineShellExt.dll"

LxRunOffline Help Info

Let's progressively discover how this command-line program can be used. First I'll just type the command name, which causes the program to list its top-level actions.

cmd.exe
C:\Users\Mike Slinn> LxRunOffline
[ERROR] No action is specified.

Supported actions are:
    l, list            List all installed distributions.
    gd, get-default    Get the default distribution, which is used by bash.exe.
    sd, set-default    Set the default distribution, which is used by bash.exe.
    i, install         Install a new distribution.
    ui, uninstall      Uninstall a distribution.
    rg, register       Register an existing installation directory.
    ur, unregister     Unregister a distribution but not delete the installation directory.
    m, move            Move a distribution to a new directory.
    d, duplicate       Duplicate an existing distribution in a new directory.
    e, export          Export a distribution"s filesystem to a .tar.gz file, which can be imported by the "install" command.
    r, run             Run a command in a distribution.
    di, get-dir        Get the installation directory of a distribution.
    gv, get-version    Get the filesystem version of a distribution.
    ge, get-env        Get the default environment variables of a distribution.
    se, set-env        Set the default environment variables of a distribution.
    ae, add-env        Add to the default environment variables of a distribution.
    re, remove-env     Remove from the default environment variables of a distribution.
    gu, get-uid        Get the UID of the default user of a distribution.
    su, set-uid        Set the UID of the default user of a distribution.
    gk, get-kernelcmd  Get the default kernel command line of a distribution.
    sk, set-kernelcmd  Set the default kernel command line of a distribution.
    gf, get-flags      Get some flags of a distribution. See https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/wslapi/ne-wslapi-wsl_distribution_flags for details.
    sf, set-flags      Set some flags of a distribution. See https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/wslapi/ne-wslapi-wsl_distribution_flags for details.
    s, shortcut        Create a shortcut to launch a distribution.
    ec, export-config  Export configuration of a distribution to an XML file.
    ic, import-config  Import configuration of a distribution from an XML file.
    sm, summary        Get general information of a distribution.
    version            Get version information about this LxRunOffline.exe. 

Alright, let's get information about the i (install) option.

cmd.exe
C:\Users\Mike Slinn> LxRunOffline i
[ERROR] the option '-d' is required but missing

Options:
  -n arg                Name of the distribution
  -d arg                The directory to install the distribution into.
  -f arg                The tar file containing the root filesystem of the
                        distribution to be installed. If a file of the same
                        name with a .xml extension exists and "-c" isn"t
                        specified, that file will be imported as a config file.
  -r arg                The directory in the tar file to extract. This argument
                        is optional.
  -c arg                The config file to use. This argument is optional.
  -v arg (=2)           The version of filesystem to use, latest available one
                        if not specified.
  -s                    Create a shortcut for this distribution on Desktop. 

I'll use the -d option to specify the directory to install into, as well as the -f and -n options.

LxRunOffline Import

I feel brave, let's try importing for real now:

cmd.exe
C:\Users\Mike Slinn> LxRunOffline i -d f:/ubuntuBear -n UbuntuBear -f ubuntuBear_2021-01-10.tar
[ERROR] The distro "UbuntuBear" already exists. 

Some debris remains from the failed import (remember the Unspecified error a moment ago?). I will delete the b0rked UbuntuBear instance in a moment. Let's call this newly cloned linux instance UbuntuBear2.

cmd.exe
C:\Users\Mike Slinn> LxRunOffline i -d f:/ubuntuBear -n UbuntuBear2 -f ubuntuBear_2021-01-10.tar
[WARNING] Ignoring an unsupported file "var/lib/docker/volumes/backingFsBlockDev" of type 0060000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-17041-8893592-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-10716-846285-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-1899-75308257-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-10151-8749190-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-18789-129803847-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-811-127664322-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-12447-115564106-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-24480-65839207-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-23230-107496852-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-23230-107496852-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-24480-65839207-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-14211-5836039-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-19778-110293600-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-1969-34761241-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-17041-8893592-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-1899-75308257-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-7642-17996-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-10151-8749190-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-19082-8772885-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-12857-5829248-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-26692-70009588-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-12447-115564106-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-22582-1181861-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-14211-5836039-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-1969-34761241-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-7642-17996-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-10716-846285-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-11424-57667328-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-28497-49814437-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-18789-129803847-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-2234-80045-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-19082-8772885-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-12857-5829248-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-22582-1181861-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-26692-70009588-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-10990-5814132-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-811-127664322-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-10990-5814132-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-11424-57667328-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-2234-80045-out" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-19778-110293600-in" of type 0010000.
[WARNING] Ignoring an unsupported file "tmp/clr-debug-pipe-28497-49814437-in" of type 0010000.
[WARNING] Ignoring an unsupported file "dev/random" of type 0020000.
[WARNING] Ignoring an unsupported file "dev/tty" of type 0020000.
[WARNING] Ignoring an unsupported file "dev/full" of type 0020000.
[WARNING] Ignoring an unsupported file "dev/urandom" of type 0020000.
[WARNING] Ignoring an unsupported file "dev/ptmx" of type 0020000.
[WARNING] Ignoring an unsupported file "dev/zero" of type 0020000.
[WARNING] Ignoring an unsupported file "dev/console" of type 0020000.
[WARNING] Ignoring an unsupported file "dev/null" of type 0020000.
[WARNING] Ignoring an unsupported file "dev/mapper/control" of type 0020000.
[ERROR] Couldn"t create the file "\\?\f:\ubuntuBear\rootfs\home\mslinn\.atom\packages\markdown-preview-plus\spec\fixtures\subdir\�cc�nt�d.md".
Reason: The file exists. 

Most of the warnings do not seem to be important. I do not care about Docker anyway. Also, now I know that temporary files and dev nodes should all be deleted before running this program. Even better, the program that created the tar should be modified to not attempt to replicate any temporary files.

I don't understand the problem with the atom package, but I'll try to delete all of the atom settings from the tar, along with the other problematic directories, and then retry.

Cleaning Up WSL

First let's see the VMs registered with WSL:

Shell
C:\Users\Mike Slinn> wsl -l
Windows Subsystem for Linux Distributions:
Ubuntu (Default)
UbuntuBear
UbuntuBear2 

Let's delete the debris remaining from the failed UbuntuBear and UbuntuBear2 imports:

Shell
C:\Users\Mike Slinn> wsl --unregister UbuntuBear
Unregistering... 

C:\Users\Mike Slinn> wsl --unregister UbuntuBear2
Unregistering... 

Attempting to delete the directory created by LxRunOffline hit a corrupted directory.

Shell
C:\Users\Mike Slinn> del /s /q f:\ubuntuBear
Deleted file - f:\ubuntuBear\rootfs\init
Deleted file - f:\ubuntuBear\rootfs\lib
Deleted file - f:\ubuntuBear\rootfs\lib32
Deleted file - f:\ubuntuBear\rootfs\lib64
Deleted file - f:\ubuntuBear\rootfs\libx32
Deleted file - f:\ubuntuBear\rootfs\sbin
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\.wget-hsts
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\.Xauthority
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\.zcompdump
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\.zcompdump-Bear-5.8
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\.zcompdump-localhost-5.8
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\.zshenv
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\.zshrc
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\.zshrc.pre-oh-my-zsh
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\.zsh_history
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\ancient_warmth_workspace.code-workspace
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\bear2.zip
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\bear3.zip
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\bearDirs.tar
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\dead.letter
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\django_bash_completion
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\jekyll_workspace.code-workspace
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\msp.txt
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\nodesource_setup.sh
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\package-lock.json
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\package.json
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\worldPeaceMusicCollective.png
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\worldPeaceMusicCollectiveBordered.png
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\.vscode-server\extensions\wix.vscode-import-cost-2.15.0\package.json
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\.vscode-server\extensions\wix.vscode-import-cost-2.15.0\pom.xml
Deleted file - f:\ubuntuBear\rootfs\home\mslinn\.vscode-server\extensions\wix.vscode-import-cost-2.15.0\README.md
The file or directory is corrupted and unreadable. 

“The file or directory is corrupted and unreadable.” That needs to be dealt with right away! I fixed the directory errors in drive F like this:

cmd.exe
C:\Program Files> chkdsk /F F:
The type of the file system is NTFS.

Chkdsk cannot run because the volume is in use by another
process.  Chkdsk may run if this volume is dismounted first.
ALL OPENED HANDLES TO THIS VOLUME WOULD THEN BE INVALID. y

Chkdsk cannot dismount the volume because it is a system drive or
there is an active paging file on it.  Would you like to schedule
this volume to be checked the next time the system restarts? (Y/N) y

This volume will be checked the next time the system restarts. 

I rebooted the system, and it fixed the errors on drive F:.

Pruning the tar

First lets back up the tar that we want to prune.

Shell
$ pushd '/mnt/c/Users/Mike Slinn/'

$ ls -alF *.tar
-rwxr--r-- 1 mslinn mslinn   524482560 Jan 10 18:45 'bear_ubuntu_2021-01-10.tar'*
-rwxr--r-- 1 mslinn mslinn 51464028160 Jan 10 21:11 'ubuntuBear_2021-01-10.tar'* 

$ cp ubuntuBear_2021-01-10.tar ubuntuBearPruned_2021-01-10.tar

Now lets try to prune out all the problematic, and unnecessary, files.

Shell
$ tar -f ubuntuBearPruned_2021-01-10.tar \
  --delete dev/* \
  --delete tmp/* \
  --delete home/mslinn/.atom/* \
  --delete var/lib/docker/* \
  --delete var/sitesUbuntu/* \
  --delete var/work/* \
  --delete var/tmp/*
tar: Ignoring unknown extended header keyword 'LIBARCHIVE.xattr.security.capability'
tar: Ignoring unknown extended header keyword 'LIBARCHIVE.xattr.security.capability'
tar: Ignoring unknown extended header keyword 'LIBARCHIVE.xattr.security.capability'
tar: Ignoring unknown extended header keyword 'LIBARCHIVE.xattr.security.capability'
tar: Ignoring unknown extended header keyword 'LIBARCHIVE.xattr.security.capability'
tar: Ignoring unknown extended header keyword 'LIBARCHIVE.xattr.user.fuseoverlayfs.opaque'
tar: Ignoring unknown extended header keyword 'LIBARCHIVE.xattr.user.fuseoverlayfs.opaque'
tar: Pattern matching characters used in file names
tar: Use --wildcards to enable pattern matching, or --no-wildcards to suppress this warning
tar: dev/*: Not found in archive
tar: Pattern matching characters used in file names
tar: Use --wildcards to enable pattern matching, or --no-wildcards to suppress this warning
tar: tmp/*: Not found in archive
tar: Pattern matching characters used in file names
tar: Use --wildcards to enable pattern matching, or --no-wildcards to suppress this warning
tar: home/mslinn/.atom/*: Not found in archive
tar: Pattern matching characters used in file names
tar: Use --wildcards to enable pattern matching, or --no-wildcards to suppress this warning
tar: var/lib/docker/*: Not found in archive
tar: Pattern matching characters used in file names
tar: Use --wildcards to enable pattern matching, or --no-wildcards to suppress this warning
tar: var/sitesUbuntu/*: Not found in archive
tar: Pattern matching characters used in file names
tar: Use --wildcards to enable pattern matching, or --no-wildcards to suppress this warning
tar: var/work/*: Not found in archive
tar: Pattern matching characters used in file names
tar: Use --wildcards to enable pattern matching, or --no-wildcards to suppress this warning
tar: var/tmp/*: Not found in archive
tar: Exiting with failure status due to previous errors 

I think the error messages just indicate that the tar was made by BSD-TAR, while Ubuntu uses GNU-TAR. I installed bsdtar like this:

Shell
$ yes | sudo apt-get install libarchive-tools
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
  libarchive-tools
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 57.1 kB of archives.
After this operation, 207 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu hirsute/universe amd64 libarchive-tools amd64 3.4.3-2 [57.1 kB]
Fetched 57.1 kB in 0s (167 kB/s)
Selecting previously unselected package libarchive-tools.
(Reading database ... 244498 files and directories currently installed.)
Preparing to unpack .../libarchive-tools_3.4.3-2_amd64.deb ...
Unpacking libarchive-tools (3.4.3-2) ...
Setting up libarchive-tools (3.4.3-2) ...
Processing triggers for man-db (2.9.4-2) ... 

I tried again using bsdtar, which does not support GNU tar's --delete option. Unfortunately, I only got a 1KB file out, no matter what I did.

Shell
$ bsdtar -cvf ubuntuBearPruned2_2021-01-10.tar \
  --exclude 'dev/*' \
  --exclude 'tmp/*' \
  --exclude 'home/mslinn/.atom/*' \
  --exclude 'var/lib/docker/*' \
  --exclude 'var/sitesUbuntu/*' \
  --exclude 'var/work/*' \
  --exclude 'var/tmp/*' \
  @ubuntuBear_2021-01-10.tar

Maybe there is a bug. Maybe there is bad documentation. I do not think I made an error. Life is short. Bugs are rampant. Illegitimi non carborundum!

I give up on this direction. Let's try to win some other way!

Success Duplicating the Ubuntu Instance

Let’s try duplicating the Ubuntu instance with LxRunOffline. First the Ubuntu VM must be terminated.

cmd.exe
C:\Users\Mike Slinn> wsl -t Ubuntu

C:\Users\Mike Slinn> LxRunOffline duplicate -n Ubuntu -N UbuntuWsl2 -d f:\UbuntuWsl2

The above ran for a couple of hours and concluded without error. LxRunOffline duplicate automatically registers the new instance.

The F:\UbuntuWsl2directory was 239 GB. That's a fair-sized VM. The directory only contains one file, called ext4.vhdx.

Let's see the Ubuntu instances that are currently set:

cmd.exe
C:\Users\Mike Slinn> wsl --list
Windows Subsystem for Linux Distributions:
Ubuntu (Default)
UbuntuWsl2 
😁

That is what I wanted to see! I started the new UbuntuWsl2 Ubuntu instance like this:

cmd.exe
C:\Users\Mike Slinn> wsl -d UbuntuWsl2

To set the default Ubuntu instance I typed:

cmd.exe
C:\Users\Mike Slinn> wsl --setdefault UbuntuWsl2

Let's verify that worked:

cmd.exe
C:\Users\Mike Slinn> wsl --list
Windows Subsystem for Linux Distributions:
UbuntuWsl2 (Default)
Ubuntu 

I then deleted the huge tar files that I had created in earlier steps. I never needed them because I used LxRunOffline duplicate.

Ubuntu on 500GB USB3 SSD

I have a Sandisk Extreme 500GB USB3 SSD drive. This tiny, light, and very portable storage device should be perfect for holding my Ubuntu development system. How cool it would be to be able to drop it into a small pocket!

Better yet, the performance of portable USB3 SSD drives blows away traditional hard drives.

For example, assume that your SSD drive appears as drive X. Also assume that LxRunOffline.exe and LxRunOffline.dll have been copied to the root directory of the SSD drive. To register your portable Ubuntu you would simply type:

cmd.exe
C:\> X:LxRunOffline register X:\MyUbuntu -n UbuntuMSlinn
You can walk up to any recently updated Windows 10 machine, plug your tiny USB3 SSD drive into a USB3 or USB3.1 port, run the registration command, and boom! you are productive with great storage performance.
😁

Duplicating to SSD

Again, the Ubuntu VM must be terminated.

cmd.exe
C:\Users\Mike Slinn> wsl -t Ubuntu

C:\Users\Mike Slinn> LxRunOffline duplicate -n Ubuntu -N UbuntuWsl2Extreme -d I:\UbuntuWsl2Extreme

The above ran for a couple of hours and concluded without error. LxRunOffline duplicate automatically registers the new instance.

Let's see the Ubuntu instances that are currently set:

cmd.exe
C:\Users\Mike Slinn> wsl --list
Windows Subsystem for Linux Distributions:
Ubuntu (Default)
UbuntuWsl2
UbuntuWsl2Extreme 
😁

Starting and Stopping Portable VMs

You can start the WSL VM called UbuntuMSlinn by using wsl -d:

cmd.exe
C:\> wsl -d UbuntuMSlinn

You can stop it by using wsl -t:

cmd.exe
C:\> wsl -t UbuntuMSlinn

Microsoft WSL Issue Reporting

In the course of writing this blog post I found the web page for reporting a WSL issue, so that Microsoft can look at it.