microsoft / WSL

Issues found on WSL
https://docs.microsoft.com/windows/wsl
MIT License
17.42k stars 824 forks source link

WSL 2 should automatically release disk space back to the host OS #4699

Open dsmaher opened 4 years ago

dsmaher commented 4 years ago

Is your feature request related to a problem? Please describe. I occasionally have workloads that consume large amounts of disk space for temporary use in /tmp. For example, transcoding large video files or processing large datasets exported from a database. Since WSL2 stores its filesystem on a .vhdx, that file grows when the dataset is processed and never releases that space. Also, it doesn't appear to re-use released disk space in the .vhdx when files are deleted... it seems to prefer to grow the file rather than re-use existing empty space. (I haven't explicitly tested that theory, but my workload deletes temporary files as they are used and I never had enough of them existing simultaneously to reach 250GB, but the size of the .vhdx eventually expanded to that size.

When I'm done with that workload, I have to:

wsl --shutdown
optimize-vhd -Path .\ext4.vhdx -Mode full

This is annoying since it basically means that my system backups include a huge .vhdx file that is mostly empty. Also, until about 2 weeks ago, it was consuming the entire remainder of my system disk. I had only 50GB free, which was enough to handle the workload, but since it continued to grow even after files were removed, that didn't matter. (I figured it was time to upgrade the disk size anyway)

Describe the solution you'd like Automatic compaction of the .vhdx, or a way to do so while WSL2 is still running so that I can schedule it for frequent cleanups.

Describe alternatives you've considered

okibcn commented 1 year ago

@theAkito This is the function I use. I have it in my PS profile file and I use it normally. It works with any distro I have tested.

I have never seen a BasePath not starting with \\?\ when using the wsl.exe app to add or manage. But since other methods of installing images can generate BasePaths in other than standard UNC paths, I have modified the wslcompact function above to be compatible with your system. Could you please share how did you get that image? somehow it is not a standard way to store paths in WSL.

theAkito commented 1 year ago

Could you please share how did you get that image? somehow it is not a standard way to store paths in WSL.

I do not remember, because I had to re-install WSL so many times since I started using it. It could've been a manual installation by installing an archive, but since it was in the very default location for Microsoft Apps, this iteration of the installation should be the official Microsoft Store one, since I wouldn't have manually installed into that location.

theAkito commented 1 year ago

@okibcn

I created a manual backup by copying the VHD before moving the compacted one, while WSL was still shut down.

When restoring the backup, WSL goes into installation mode each time it is opened. Is there some additional metadata that needs to be restored or how do I make the previous state work again?


Got it to work through the way portrayed in the following comment.

https://github.com/microsoft/WSL/issues/4762#issuecomment-578545574

okibcn commented 1 year ago

@theAkito I am not sure what are you referring to when saying

When restoring the backup, WSL goes into installation mode each time it is opened.

If you refer to the default user, I advise you to set the default user in /etc/wsl.conf. Just edit it in superuser mode and ensure you have the user properly set. Otherwise, just add these lines:

[user]
default=YOUR_DEFAULT_USERNAME

Configurations of your distro should be self-contained in that file. See all the settings here. Forget about the registry settings, I never needed to backup those as long as you keep your settings self-contained in the image.

This way, you can create a zipped backup directly by doing:

cmd /c "wsl  --export DISTRO_NAME - | 7z a -si  ""Z:\External\path\dump.tar.7z"" "

(I use 7z, but you can use any other supporting stdin and stdout binary pipelines.)

This way you end up using a small portion of disk space, as your distro dump will end up compressed without temporal files in the drive and you can move it around to another computer if you like.

You can now remove the distro from your WSL

wsl --unregister DISTRO_NAME

You can import the dump again by doing:

cmd /c "7z x -so -bsp2 ""Z:\External\path\dump.tar.7z""  | wsl  --import DISTRO_NAME ""C:\path\to\distro"" -"

And it will be exactly as you left it. In any case, the wslcompact function doesn't remove any of your settings, even if they are done by using the Ubuntu/debian/Arch/... executable app instead of using the more standard official WSL commands.

theAkito commented 1 year ago

I am not sure what are you referring to when saying

When restoring the backup, WSL goes into installation mode each time it is opened.

I meant, that the distribution acts as if it were just installed for the first time. Then, it automatically wipes all data.

This way, you can create a zipped backup directly by doing:

I guess, everything is easier, if a proper export is done. If one has only a copied vhdx, it seems like it has to be manually restored, as mentioned in my previous comment.

You can now remove the distro from your WSL

Sidenote: I was really confused to see, that there is an unregister option, but no register option...

And it will be exactly as you left it. In any case, the wslcompact function doesn't remove any of your settings, even if they are done by using the Ubuntu/debian/Arch/... executable app instead of using the more standard official WSL commands.

The registry entry was not there. It was gone. Not sure if the compacting did it or the installation mode, when I tried to boot the distribution, again.

okibcn commented 1 year ago

I meant, that the distribution acts as if it were just installed for the first time. Then, it automatically wipes all data.

No, it doesn't wipe the data at all. If you have the default user set in /etc/wsl.conf and exported and imported as instructed above, everything remains the same. I just tested with Ubuntu, Kali, and Arch. No issues whatsoever.

I guess, everything is easier, if a proper export is done. If one has only a copied vhdx, it seems like it has to be manually restored, as mentioned in my previous comment.

A proper export is done using the wsl --export, and that is what I did above. The restore is done using wsl --import, as done above. There is no problem at all. If you have more than one wsl distro, you have to use wsl -d DISTRO_NAME. launching wsl without any option will start your default distro. You can see your default distro by typing wsl -l.

Sidenote: I was really confused to see, that there is an unregister option, but no register option...

Actually, wsl --unregister is actually the way to uninstall a distro, as it also deletes the image file. So, the hypothetical register option is done with the wsl --install, wlsl --import or wsl --import-in-place commands depending on how you get and install the images.

theAkito commented 1 year ago

No, it doesn't wipe the data at all.

I guess, shrinking the ext4.vhdx from several tens of GBs into 30MB within two seconds is just a matter of compression? 😄

If you have the default user set in /etc/wsl.conf and exported and imported as instructed above, everything remains the same.

When is the user set in a safe & user-friendly way? Like, when does it get set, when you do not know/think about this file, at all? Or do you have to just know about it & remember it whenever you deal with WSL?

A proper export is done using the wsl --export, and that is what I did above. The restore is done using wsl --import, as done above. There is no problem at all.

The problem is, that wsl --export requires wsl, whereas copying the folder or simply the ext4.vhdx does not require anything, but cp or whatever equivalent there is. The latter is available on every distribution on the world, while wsl only works on Windows and if it's broken, you may not be able to use it. Example: If you back up a database, you should use dumps. But that requires the database server to be contacted. If the database was shut down gracefully, you can just copy the database folder and open it later. No import/export needed, at all. This is the method with the least friction, overall.

Actually, wsl --unregister is actually the way to uninstall a distro, as it also deletes the image file. So, the hypothetical register option is done with the wsl --install, wlsl --import or wsl ---import-in-place commands depending on how you get and install the images.

I see. A bit inconsistent wording.


When reading the part about export again, I received an idea. Is the mehotd of exporting essentially fairly straightforward or is it fundamentally Windows based? If it is essentially fairly generic, it would be nice to have a tool, that can export the image "properly" without using wsl. 💡

okibcn commented 1 year ago

@theAkito

I guess, shrinking the ext4.vhdx from several tens of GBs into 30MB within two seconds is just a matter of compression? 😄

That men's you have some corruption in your image file, or you are using an old WSL version. Ensure you are in WSL v1.0.0. YOu can update easily using the wsl --update function.

The problem is, that wsl --export requires wsl, whereas copying the folder or simply the ext4.vhdx does not require anything, but cp or whatever equivalent there is. The latter is available on every distribution on the world, while wsl only works on Windows and if it's broken, you may not be able to use it. Example: If you back up a database, you should use dumps. But that requires the database server to be contacted. If the database was shut down gracefully, you can just copy the database folder and open it later. No import/export needed, at all. This is the method with the least friction, overall.

WSL is a VM environment with specific images. The proper way to export and import images is by using the import and export functions. you can alternatively backup the ext4.vhdx image file using a simple cp and later import it using wsl--import or wsl --import-in-place. But, for better portability, the TAR format is the recommended way, and can be compressed more than vhdx for portability.

When reading the part about export again, I received an idea. Is the mehotd of exporting essentially fairly straightforward or is it fundamentally Windows based? If it is essentially fairly generic, it would be nice to have a tool, that can export the image "properly" without using wsl. 💡

No, the current way is the right way, the wsl.exe app is the best way to handle all the WSL management tasks in a single executable. If you want a GUI wrapper for WSL, there are a few of them out there to do those tasks in a GUI environment. I think that's what you are looking for.

okibcn commented 1 year ago

Going back to the wslcompact function presented above, I have 3 distros: Kali, Arch and Ubuntu. These are the settings in the registry:

$ ls HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss

    Hive: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss

Name                           Property
----                           --------
{051bf3f0-b759-412f-af85-a39c7 State             : 1
184bd26}                       DistributionName  : kali-linux
                               Version           : 2
                               BasePath          :
                               C:\Users\Oki\AppData\Local\Packages\KaliLinux.54290C8133FEE_ey8k8hqnwqnmg\LocalState
                               Flags             : 15
                               DefaultUid        : 1000
                               PackageFamilyName : KaliLinux.54290C8133FEE_ey8k8hqnwqnmg
{427e9287-259f-4709-81f3-05a22 State            : 1
9a2e590}                       DistributionName : Arch
                               Version          : 2
                               BasePath         : \\?\C:\Users\Oki\scoop\persist\archwsl\data
                               Flags            : 15
                               DefaultUid       : 1000
{d67e9a09-d7b3-44c9-948c-8a5b6 State            : 1
30e3ed7}                       DistributionName : Ubuntu
                               Version          : 2
                               BasePath         : \\?\C:\Users\Oki\ubuntu
                               Flags            : 15
                               DefaultUid       : 0

Calling the wslcompact function presented above returns:

$ wslcompact
Creating optimized kali-linux image.
Import in progress, this may take a few minutes.
The operation completed successfully.
kali-linux image file: C:\Users\Oki\AppData\Local\Packages\KaliLinux.54290C8133FEE_ey8k8hqnwqnmg\LocalState\ext4.vhdx
Compacted from 1388 MB to 788 MB
Creating optimized Arch image.
Import in progress, this may take a few minutes.
The operation completed successfully.
Arch image file: C:\Users\Oki\scoop\persist\archwsl\data\ext4.vhdx
Compacted from 1421 MB to 920 MB
Creating optimized Ubuntu image.
Import in progress, this may take a few minutes.
The operation completed successfully.
Ubuntu image file: C:\Users\Oki\ubuntu\ext4.vhdx
Compacted from 3381 MB to 1285 MB
theAkito commented 1 year ago

WSL is a VM environment with specific images. The proper way to export and import images is by using the import and export functions. you can alternatively backup the ext4.vhdx image file using a simple cp and later import it using wsl--import or wsl --import-in-place. But, for better portability, the TAR format is the recommended way, and can be compressed more than vhdx for portability.

My research from earlier suggested, that there is no way whatsoever to "import" an ext4.vhdx. Hence the workaround, as described earlier.

No, the current way is the right way, the wsl.exe app is the best way to handle all the WSL management tasks in a single executable. If you want a GUI wrapper for WSL, there are a few of them out there to do those tasks in a GUI environment. I think that's what you are looking for.

No, I was referring to to the sole functionality of exporting and essentially extracting a proper tar file from the image. If the process of doing this export is fairly simple, one could make a generic tool, which can be used anywhere, on any system, without having to rely on wsl.exe for Windows 10 and up. There are plenty of open source tools, which partially or entirely replace, extend or enhance the behaviour of official software counter-parts.

Just wrapping wsl.exe would miss the entire point, because it would still depend on wsl.exe. The point of my idea is to remove the wsl.exe dependency, just for the export functionality.

Going back to the wslcompact function presented above, I have 3 distros: Kali, Arch and Ubuntu. These are the settings in the registry:

Okay, but if we ignore the data loss issue, there was an issue before that, already. The move did not work, because "the file was in use" or something, even though wsl was shut down and not running. So, the compacting supposedly succeeded, but not the final move, which would've finished the process.

okibcn commented 1 year ago

@theAkito

My research from earlier suggested, that there is no way whatsoever to "import" an ext4.vhdx. Hence the workaround, as described earlier.

Not true, you have two ways to import an ext4.vhdx file:

This operation makes a copy of the .vhdx file at the specified install location.

wsl   --import <Distro> <InstallLocation> <vhdxFileName> --vhd

or this method that imports the specified .vhdx file as a new distribution.

wsl   --import-in-place <Distro> <vhdxFileName>

Okay, but if we ignore the data loss issue, there was an issue before that, already. The move did not work, because "the file was in use" or something, even though wsl was shut down and not running. So, the compacting supposedly succeeded, but not the final move, which would've finished the process.

You have to locate the reason why your vhdx file is still in use even after a wsl --shutdown instruction. That is not the right behavior. Be sure you don't have any other app accessing the vhdx file such as antivirus software, or any other kind of software. There are many ways of identifying the offending app.

theAkito commented 1 year ago

Not true, you have two ways to import an ext4.vhdx file

Must be some new method, then. I researched again after your comment, and every resource online says, there must be a tar file to be imported. No vhdx possible, according to the information spread everywhere.

You have to locate the reason why your vhdx file is still in use even after a wsl --shutdown instruction. That is not the right behavior. Be sure you don't have any other app accessing the vhdx file such as antivirus software, or any other kind of software. There are many ways of identifying the offending app.

Yes, not sure, either.

Is there a quick way of filling up a new distribution for testing purposes with data, that can be compacted? Then I would test the function again. I do not want to try again on my primary distribution, because I need it to work.

okibcn commented 1 year ago

Must be some new method, then. I researched again after your comment, and every resource online says, there must be a tar file to be imported. No vhdx possible, according to the information spread everywhere.

Not new, it has been there for a while now. You just need to read the wsl --help output. wsl.exe is quite straightforward and simple to use.

Is there a quick way of filling up a new distribution for testing purposes with data, that can be compacted? Then I would test the function again. I do not want to try again on my primary distribution, because I need it to work.

You can list the official distros in the online store with wsl --list --online. You can install any of them with wsl --install <distro>. You can login with wsl -d <distro>, play around for a while, install, uninstall software in it, or do whatever you want. Then you can test the wslcompact function with wslcompact [distro], you can test the backup and restore procedures, etc. For uninstalling it just do a wsl --unregister <distro>.

theAkito commented 1 year ago

Not new, it has been there for a while now. You just need to read the wsl --help output. wsl.exe I quite straightforward and simple to use.

Obviously, isn't that simple, when all online resources do not know about it. The --help output is quite long and confusing. Was reading it, when I was looking for a register option and I did not notice the commands you mentioned, except import and export.

Just looked at the --help text right now again and there is no --import-in-place. The WSL version is according to the --status text only a couple of months old. Same for --vhd. There is no option like that, available.

So much for reading the "straightforward" --help text...

You can list the official distros in the online store with wsl --list --online. You can install any of them with wsl --install <distro>. You can login with wsl -d <distro>, play around for a while, install, uninstall software in it, or do whatever you want.

I know that. But I don't want to play around for a while. I would like to just reproducibly fill up the space, so it can be compacted. There should be an automated way of achieving this, with reproducible results.

Then you can test the wslcompact function with wslcompact [distro], you can test the backup and restore procedures, etc. For uninstalling it just do a wsl --unregister <distro>.

Well, since the first attempt basically nuked my primary distribution, I won't repeat the same mistake twice and be cautious about it, even if you insinuate a user error. I might just repeat the user error accidentally, for example.

I'm also not a 100% sure yet, if only "free" space is compacted, which was once used but isn't used anymore, within WSL, or if it does more than that.

There have also been previous accounts of data being wiped, when applying certain methods of compaction.

okibcn commented 1 year ago

Just looked at the --help text right now again and there is no --import-in-place. The WSL version is according to the --status text only a couple of months old. Same for --vhd. There is no option like that, available.

@theAkito clearly youdidn't follow my instructions here and you are not in the latest wsl v1.0.0. Run wsl --update, then, when running wsl --version you should see this output:

$ wsl --version
WSL version: 1.0.0.0
Kernel version: 5.15.74.2
WSLg version: 1.0.47
MSRDC version: 1.2.3575
Direct3D version: 1.606.4
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.25247.1000

Probably you are still using the beta version. When reporting errors, you first have to ensure you are using the latest version, otherwise it is very confusing.

theAkito commented 1 year ago

clearly youdidn't follow my instructions here and you are not in the latest wsl v1.0.0. Run wsl --update, then, when running wsl --version you should see this output:

Yes, of course not; I need to know first, what exactly changed in-between versions, since downgrading in Windows is usually forbidden or barely possible. I also don't know of any way of how to export all WSL data, except the vhdx images.

Additionally, you said, the functionalities are "there for a while", so it shouldn't have hurt, when there is a slightly older version installed.

I just checked again and you did not say that WSL needs to be the newest version, when you posted the initial function. You said it more than 10 comments later, because I was providing feedback regarding the function you posted.

Probably you are still using the beta version. When reporting errors, you first have to ensure you are using the latest version, otherwise it is very confusing.

It says nothing about Beta or anything like that. That said, when there is an old version of Powershell installed, there is a big banner saying, that there is a new version available. Doesn't happen for WSL.

okibcn commented 1 year ago

Additionally, you said, the functionalities are "there for a while", so it shouldn't have hurt, when there is a slightly older version installed.

@theAkito the --vhd and --import-in-place options were introduced in WSL v0.58.0 back in April 7. Your WSL is VERY old and has a lot of bugs, it has probably a very old kernel too. There have been 18 releases after that v0.58.0. I advise you to install the Windows Subsystem for Linux from the MS Store to ensure your WSL system is up to date and gets updated automatically. Your distros will work a lot better. Otherwise please stop asking about issues at github.

Yes, of course not; I need to know first, what exactly changed in-between versions, since downgrading in Windows is usually forbidden or barely possible.

By the way, all the changelog is available on the releases page of this repo.

tusharsnx commented 1 year ago

@okibcn @theAkito

I am curious to know how much difference do you see when using DISKPART/export-import

okibcn commented 1 year ago

@tusharsnn the mileage may vary. But in some cases I've seen an image that diskpart could reduce to 2300 MB was reduced further to 1100 MB by the wslcompact function. In any case, wslcompact function will always achieve the minimum possible size, a little bit over the used size reported by the command df / inside the wsl distro. I did all those tests long ago. See my comments about them here.

vbrozik commented 1 year ago

@okibcn

the --vhd and --import-in-place options were introduced in WSL v0.58.0 back in April 7. Your WSL is VERY old and has a lot of bugs, it has probably a very old kernel too.

Only WSL from MS store has version numbers like this. It is available for Windows 11 only and it looks like Microsoft is not going to make it available for Windows 10.

In Windows 10 you will probably never have the options to import VHDX. :(

okibcn commented 1 year ago

Only WSL from MS store has version numbers like this. It is available for Windows 11 only and it looks like Microsoft is not going to make it available for Windows 10. In Windows 10 you will probably never have the options to import VHDX. :(

@vbrozik that is not true and very misleading to others:

image

WSL v1.0.1 is available in the MS Store for any Windows 10 version 19041.0 or higher. There are many ways to install it in Windows 10. MS Store is the easiest. Have you tried to install the versions available in the releases section of this GitHub repo? Just download and install Microsoft.WSL_1.0.1.0_x64_ARM64.msixbundle or any newer release.

The VHDX import function is also available for Windows 10 users since it appeared back on April 7.

rraihansaputra commented 1 year ago

I would like to report that the WSL v1.0.1 or later from the Microsoft Store or the linked release above does not work on my machine with windows 10 build 19044.2251. I don't know what's going on and probably have lost my vhdx in trying to move my vhdx off my C:\ partition. My store page shows the same checkmark as above so this is very frustrating.

image

okibcn commented 1 year ago

I would like to report that the WSL v1.0.1 or later from the Microsoft Store or the linked release above does not work on my machine with windows 10 build 19044.2251. I don't know what's going on and probably have lost my vhdx in trying to move my vhdx off my C:\ partition. My store page shows the same checkmark as above so this is very frustrating.

@rraihansaputra , this is a new issue not related to this one. You should create a new issue, adding all the info required.

BryanDollery commented 1 year ago

3-years after this issue was raised and it's still a problem. My ubuntu 22 vhdx is now over 140gb and growing daily. It's so big that I don't have enough hd space left to export, compact, and reimport it. I find myself constantly struggling to find things to erase on my local storage. This should have been fixed a long time ago.

okibcn commented 1 year ago

3-years after this issue was raised and it's still a problem. My ubuntu 22 vhdx is now over 140gb and growing daily. It's so big that I don't have enough hd space left to export, compact, and re-import it. I find myself constantly struggling to find things to erase on my local storage. This should have been fixed a long time ago.

@BryanDollery, you are right, the problem is still there, but probably it is not related to the WSL but to the virtual drive system used by windows. The size reduction of VHDX images is something that only works fine for NTFS partitions, optimizing other filesystems is a pending issue of windows OS, not the WSL implementation. Probably creating an issue in the feedback hub (🪟+F) could do more than what the WSL team could do about the issue.

If you use the wslcompact function described above, then you only need a little bit more free temporal space than the actual size of the data contained in the ext4 partition, something you can see with the command df / inside your Linux distro. It is also relatively fast as it compresses about 15 s/GB (4 GB/min) in my system. There are ways to use a compressed temporal file if you don't have enough spare space, more info is in this comment.

You say your image is over 140 GB, but what is the actual size of the data reported by df / inside linux?

mathieures commented 1 year ago

For Windows 10 Home (alternative Optimize-VHD cmdlet):

wsl --shutdown
diskpart
# open window Diskpart
select vdisk file="C:\WSL-Distros\…\ext4.vhdx"
attach vdisk readonly
compact vdisk
detach vdisk
exit

Thanks to @davidwin for the tip #4699 (comment).

Thought I would share the batch script I made based on this reply. I don't actually know if all installs of Ubuntu have the same path in %LOCALAPPDATA%\Packages, but if they have, you can use the script as is if you have Ubuntu, or provide the quoted path of the ext4.vhdx file you want to compact as an argument.

@echo off

set temp_file=%TMP%\%RANDOM%%RANDOM%%RANDOM%.tmp

if not [%*] == [] (
    set target_file=%*
) else (
    set target_file="%LOCALAPPDATA%\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx"
)

echo Target file: %target_file%

echo Stopping WSL
wsl --shutdown

echo Creating temporary file %temp_file%
 >%temp_file% echo select vdisk file=%target_file%
>>%temp_file% echo attach vdisk readonly
>>%temp_file% echo compact vdisk
>>%temp_file% echo detach vdisk

echo Executing %temp_file%
rem The /s parameter executes a diskpart script
diskpart /s %temp_file%

echo Deleting %temp_file%
del %temp_file%
okibcn commented 1 year ago

Thought I would share the batch script I made based on this reply. I don't actually know if all installs of Ubuntu have the same path in %LOCALAPPDATA%\Packages, but if they have, you can use the script as is if you have Ubuntu, or provide the quoted path of the ext4.vhdx file you want to compact as an argument.

@mathieures I see the same problems with your approach, very similar to the other proposed here. I see several problems:

  1. Using the diskpart method is ineffective in too many cases. And, even in some cases, it ends up generating even larger images when used after running zerofree or fstrim / inside the WSL distro of choice.
  2. It requires elevated privileges, and some users use WSL as a user in machines without administrator rights.
  3. You need to know the name and location of the ext4.vhdx file, so it works for only one distro at a time.

If you want to know the minimum size achievable, you can do a df / inside your distro to know the actual size of the data inside the image. The WSLCOMPACT function is so far the only way I've found to reduce the size of the image file to its minimum, which is the data size reported by df / plus the small ext4 filesystem overhead. The function doesn't require elevated privileges, you can optimize all the WSL distros installed or a single one, and it detects automatically the path of the image files.

mathieures commented 1 year ago

I thought it was weird nobody had made a script already… I just didn't see it. Thank you for your reply! I'll use WSLCOMPACT from now on.

CleanHit commented 1 year ago

@okibcn, thanks for your script. However, I got a parsing error here when starting PowerShell:

$wsl_path=$wsl_.BasePath.StartsWith('\\') ? $wsl_.BasePath.Substring(4) : $wsl_.BasePath

in my PowerShell (v5.1.22621.963) on Windows 11 regarding the ternary operator ?. I had to replace this line with:

$wsl_path=if ($wsl_.BasePath.StartsWith('\\')) {$wsl_.BasePath.Substring(4)} else {$wsl_.BasePath}
okibcn commented 1 year ago

@CleanHit thanks for the heads up. I have updated the WSLCOMPACT script with your fix to make it backward compatible with the older versions of PowerShell that comes with the OS. I was (incorrectly) assuming everyone using WSL was also using a recent PowerShell, we are now at PowerShell 7.3.2. But it is true, sometimes you just don't need it and the default one should work too.

CleanHit commented 1 year ago

@okibcn well, I haven't been following newer versions of PowerShell since I rarely use it for heavy work. I've installed and switched to the newer version as default. Thanks for function the change. When writing my comment, I didn't realize that it's a version compatibility issue.

onomatopellan commented 1 year ago

@okibcn Thanks for the script! It works well for me but when it iterates the registry it shows an error that BasePath doesn't exist. I think it's because of this AppxInstallerCache registry key I have that it lacks BasePath.

image

So just assuring BasePath exists fixes the problem.

if ($wsl_.BasePath){
    $wsl_path=if ($wsl_.BasePath.StartsWith('\\')) {$wsl_.BasePath.Substring(4)} else {$wsl_.BasePath}
...
}
okibcn commented 1 year ago

@onomatopellan, I have implemented a different fix for that problem that should work. The fix was implemented in the same comment about WSLCOMPACT.

vbrozik commented 1 year ago

@okibcn the script is very useful. Thank you! Would it be possible to make it into a GitHub repo or Gist and make it installable using winget?

okibcn commented 1 year ago

@okibcn the script is very useful. Thank you! Would it be possible to make it into a GitHub repo or Gist and make it installable using winget?

Did you read my mind? just yesterday I made a full script with additional functionality such as test mode displaying the estimated target size without compacting. You find it at: https://github.com/okibcn/wslcompact . I need GitHub stars ⭐⭐⭐⭐... in that repo for Scoop organization to accept it in its repository of apps.

It is a tool too small to be installable through winget, but Scoop is the perfect lightweight package manager for these utils. Maybe in a future I will make a winget installable package.

CleanHit commented 1 year ago

@okibcn this is very good to have. Maybe the script should be incorporated into Microsoft's wsl package as e.g. a wsl --resize-vhdx option 🤔.

roslov commented 1 year ago

https://github.com/okibcn/wslcompact/issues/2

okibcn commented 1 year ago

Thanks, It will help me to debug the problem and make it better.

okibcn commented 1 year ago

There is a new version of WSLCompact. The usage information is:

    Usage: wslcompact [OPTIONS] [DISTROS]

   wslcompact compacts the images of WSL distros by removing unsused space.
   If no option is provided, it will default to info mode, without modifying any image.
   If no distro is provided it will process all the installed images.
   NOTE: WSL will be shutdown for compacting the images.

   Options:
       -c   Compacting mode: process the selected distros compacting the images.
       -d   Enable the processing of data images. Default is disabled.
       -y   Perform actions without asking for confirmation.
       -h   Prints this help

   Examples:
       wslcompact
       wslcompact -c -d
       wslcompact -c -y Ubuntu Kali

running it without parameters now runs in info mode:

PS> wslcompact
 WSL compact, v3.2023.01.30
 (C) 2023 Oscar Lopez
 wslcompact -h for help. For more information visit: https://github.com/okibcn/wslcompact

 Distro's name:  Ubuntu
 Image file:     C:\Users\Oki\WSL\Ubuntu\ext4.vhdx
 Current size:   12864 MB
 Estimated size: 7700 ± 188 MB
 The estimated process time using an SSD is about 2 minutes.

 Distro's name:  Kali
 Image file:     C:\Users\Oki\WSL\Kali\ext4.vhdx
 Current size:   1579 MB
 Estimated size: 723 ± 18 MB
 The estimated process time using an SSD is about 1 minutes.

 Distro's name:  Arch
 Image file:     C:\Users\Oki\WSL\Arch\ext4.vhdx
 Current size:   1075 MB
 Estimated size: 860 ± 21 MB
 The estimated process time using an SSD is about 1 minutes.

There is a compact mode with -c option that actually performs the compact action:

PS> wslcompact -c -y Ubuntu

 WSL compact, v3.2023.01.30
 (C) 2023 Oscar Lopez
 wslcompact -h for help. For more information visit: https://github.com/okibcn/wslcompact

 Distro's name:  Ubuntu
 Image file:     C:\Users\Oki\WSL\Ubuntu\ext4.vhdx
 Current size:   12864 MB
 Estimated size: 7700 ± 188 MB
 The estimated process time using an SSD is about 2 minutes.
 Import in progress, this may take a few minutes.
The operation completed successfully.
 Compacted from 12864 MB to 7728 MB

There will be a test mode tomorrow to perform the action but without modifying the current images.

andrescevp commented 1 year ago

If you have not an aux hard drive I would recommend go with https://github.com/microsoft/WSL/issues/4699#issuecomment-635673427

okibcn commented 1 year ago

@andrescevp that option requires administrative rights and installing the virtual disk management package. In addition to that it requires administrative rights every time you use it. Not a big deal, but maybe if the HD is full and you don't have enough space the DISKPART method would avoid the installation of more junk.

In any case, my experience with those methods was not positive. The size reduction was marginal and, in some cases, with sparse files, it was even larger. Just use it with caution. Those were the main reasons for me to go down the wslcompact option.

okibcn commented 1 year ago

There is a new version of WSLCompact. WSLCompact v4 now performs the compact process in a 'safe' mode. So, the user can cancel safely the, sometimes long, process without side effects. The user can decide if the new image is replaced after the result, so the final decision is on the user. Most errors should be tracked now, but do not panic, should you receive an error message, it won't modify any image without the user's approval (unless you use the -y option).

This is an example of a session:

PS> wslcompact -c Ubuntu
 WSL compact, v4.2023.01.31
 (C) 2023 Oscar Lopez
 wslcompact -h for help. For more information visit: https://github.com/okibcn/wslcompact

 Distro's name:  Ubuntu
 Image file:     C:\Users\Oki\WSL\Ubuntu\ext4.vhdx
 Current size:   12864 MB
 Estimated size: 7700 ± 188 MB
 The estimated process time using an SSD is about 2 minutes.
 NOTE: You can safely cancel at any time by pressing Ctrl-C
 Import in progress, this may take a few minutes.
The operation completed successfully.
 New Image compacted from 12864 MB to 7728 MB
 Do you want to apply changes and use the new image (y/N): y
 Image replaced for distro: Ubuntu
tusharsnx commented 1 year ago

I request everyone to keep this thread for an official way to shrink WSL vhdx and continue the discussion on WSLCompact on its repository.

caner-cetin commented 1 year ago

image any update on this? I am going slowly insane after all these high memory usage and storage issues.

berlincount commented 1 year ago

image any update on this? I am going slowly insane after all these high memory usage and storage issues.

Once you have gone entirely insane you will find peace. Or something like it.

caner-cetin commented 1 year ago

image any update on this? I am going slowly insane after all these high memory usage and storage issues.

Once you have gone entirely insane you will find peace. Or something like it.

Lol. If and only if I rolled with Linux in the first place...

sarim commented 1 year ago

SSD are cheap nowadays, Few months ago I installed a 970 EVO Plus 1TB and stopped worrying about disk space.

Here'e my wsl's disk usage:

↪ ~ ➤ df -h | grep /dev/s
/dev/sdb       1007G   72G  885G   8% /
↪ ~ ➤ ls -sh /mnt/h/UbuntuMain/ubuntu-ext4.vhdx
82G /mnt/h/UbuntuMain/ubuntu-ext4.vhdx

Without any babysitting. 72/82 = 87% efficient disk space utilization. I'm happy with it.

okibcn commented 1 year ago

I request everyone to keep this thread for an official way to shrink WSL vhdx and continue the discussion on WSLCompact on its repository.

Sadly there isn't any "official way" to shink WSL vhdx. Like in many other areas, there are small tools to fill those gaps. I don't want to maintain a discussion about wslcompact in this thread. However, people coming here ranting about how bad WSL is at keeping its footprint need to know that there is a solution outside Microsoft.

The tool actually came to life from this discussion, so, somehow, it is the product of all the tests and failures described by many people here. It started as a solution in a comment in this thread several months ago.

It actually uses WSL as a way to solve one of its problems. So any failure is actually related to WSL.

I want to keep the discussion about WSLCOMPACT in its repository since now it is no longer a post in this thread, and sorry if offering a solution has been a problem.

To know the actual space inside your vhdx drive, just type inside WSL:

df /

wslcompact procedure (the function shared in this thread, or the standalone utility) leaves an image about 2% larger than that number. So, yes Microsoft, it is possible to shrink the image.

caner-cetin commented 1 year ago

SSD are cheap nowadays, Few months ago I installed a 970 EVO Plus 1TB and stopped worrying about disk space.

Here'e my wsl's disk usage:

↪ ~ ➤ df -h | grep /dev/s
/dev/sdb       1007G   72G  885G   8% /
↪ ~ ➤ ls -sh /mnt/h/UbuntuMain/ubuntu-ext4.vhdx
82G /mnt/h/UbuntuMain/ubuntu-ext4.vhdx

Without any babysitting. 72/82 = 87% efficient disk space utilization. I'm happy with it.

guys I am rich, it is not a problem wewehwoewoeooooooooo

profanity censored

anyways, WSLCompact is not a solution if you are still poor.

image

you shouldn't use Docker with WSL at this stage, just go with another route. Docker Desktop is way too slow and way too bloated, and CLI Docker without Docker Desktop is eating your space until there is nothing left.

jerivas commented 1 year ago

Can someone at Microsoft please lock this issue until an official response is ready to be shared? The conversation has been completely derailed 😞