Mike Slinn

WSL / WSL 2 Backup and Restore

Published 2022-01-10. Last modified 2023-04-02.
Time to read: 6 minutes.

This page is part of the posts collection, 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 article presents the best WSL backup approaches I found

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.

Location, Location, Location

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.

Reinstalling Windows is less traumatic if the WSL/WSL2 image elsewhere in the filesystem

Dell’s Ignorance Causes Pain

I use Dell laptops, because I love their onsite warranty price and product features. However, sometimes it feels like Dell’s solution to every problem is to replace the motherboard.

When Windows 10 encounters a new motherboard, it takes anti-piracy measures, and refuses to do much of anything useful.

Refreshing Windows solves that problem, but doing that 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. They simply do not understand how replacing the motherboard creates long-term issues.

Test Your Backup

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. 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 --help Copyright (c) Microsoft Corporation. All rights reserved. For privacy information about this product please visit https://aka.ms/privacy.
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.
--shell-type <Type> Execute the specified command with the provided shell type.
Types: standard Execute the specified command using the default Linux shell.
login Execute the specified command using the default Linux shell as a log-in shell.
none 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.
--system Launches a shell for the system distribution.
Arguments for managing Windows Subsystem for Linux:
--help Display usage information.
--debug-shell Open a WSL2 debug shell for diagnostics purposes.
--install [Distro] [Options...] Install a Windows Subsystem for Linux distribution. For a list of valid distributions, use 'wsl.exe --list --online'.
Options: --no-launch, -n Do not launch the distribution after install.
--web-download Download the distribution from the internet instead of the Microsoft Store.
--mount <Disk> Attaches and mounts a physical or virtual disk in all WSL 2 distributions.
Options: --vhd Specifies that <Disk> refers to a virtual hard disk.
--bare Attach the disk to WSL2, but don't mount it.
--name <Name> Mount the disk using a customised name for the mount-point.
--type <Type> Filesystem to use when mounting a disk, if not specified defaults to ext4.
--options <Options> Additional mount options.
--partition <Index> Index of the partition to mount, if not specified defaults to the whole disk.
--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.
--unmount [Disk] Unmounts and detaches a disk from all WSL2 distributions. Unmounts and detaches all disks if called without argument.
--update Update the Windows Subsystem for Linux package.
Options: --web-download Download the update from the internet instead of the Microsoft Store.
--pre-release Download a pre-release version if available. Implies --web-download.
--version, -v Display version information.
Arguments for managing distributions in Windows Subsystem for Linux:
--export <Distro> <FileName> [Options] Exports the distribution to a tar file. The filename can be - for standard output.
Options: --vhd Specifies that the distribution should be exported as a .vhdx file.
--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.
--vhd Specifies that the provided file is a .vhdx file, not a tar file. This operation makes a copy of the .vhdx file at the specified install location.
--import-in-place <Distro> <FileName> Imports the specified .vhdx file as a new distribution. This virtual hard disk must be formatted with the ext4 filesystem type.
--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.exe --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. I found a few potential solutions, detailed below; I show the most desirable solution first.

Solution 1: Importing the VDHX File

Importing the original vhdx file directly instead of creating and importing the tar file has been reported to work by several people. This is a more desirable solution because it requires less work and is faster. Note that the ^ character is a DOS command-line continuation character, much like the Bash \ character.

cmd.exe
C:\Users\Mike Slinn> wsl --import Ubuntu-20.04-d^
  D:\WSL\Ubuntu-22.04\^
  %HOMEDRIVE%%HOMEPATH%\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu20.04onWindows_79rhkp1fndgsc\LocalState\ext4.vhdx^
  --vhd

Solution 2: Updating Linux Kernel

The following was written by ken-cdit:

Had the same issue. I exported two WSL 2 distros and then did a clean install of my Windows OS. "Unspecified error" came up when I tried to import them.

I fixed it by downloading the Linux kernel update package referred to at https://docs.microsoft.com/en-us/windows/wsl/install-win10 and then running the command wsl --set-default-version 2.

After this, my two distros imported without error.

I had the whole thing still in the console so here is a screencap...

Solution 3: LxRunOffline

Installing LxRunOffline

Google brought me to a potential solution, LxRunOffline, which provided me limited success.

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:

cmd.exe
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:

cmd.exe
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.

cmd.exe
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 
😁

LxRunOffline Update 2023-04-25

Arman Mazloumzadeh posted the following:

I finally resolved this amiss during the following steps (Windows 10.0.19045 Build 19045):

Running wsl.exe --import Ubuntu A:\wsl\Ubuntu A:\wsl\Ubuntu.tar = > Unspecified error

Running LxRunOffline.exe install -n Ubuntu -d A:\wsl\Ubuntu -f A:\wsl\Ubuntu.tar => [ERROR] Couldn't get the value "DistributionName" of the registry key "Software\Microsoft\Windows\CurrentVersion\Lxss\AppxInstallerCache"

Removing the Software\Microsoft\Windows\CurrentVersion\Lxss\AppxInstallerCache registry key
Running LxRunOffline.exe install -n Ubuntu -d A:\wsl\Ubuntu -f A:\wsl\Ubuntu.tar => [ERROR] Couldn't get the value "DistributionName" of the registry key "Software\Microsoft\Windows\CurrentVersion\Lxss\TryStoreWSL"

Removing the Software\Microsoft\Windows\CurrentVersion\Lxss\TryStoreWSL registry key
Running LxRunOffline.exe install -n Ubuntu -d A:\wsl\Ubuntu -f A:\wsl\Ubuntu.tar => ✔

Running ubuntu.exe config --default-user arman => ✔

done 🎉

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 article I found the web page for reporting a WSL issue, so that Microsoft can look at it.



* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.