Tag Archives: mount

Mount/Access physical disks and USB devices into WSL2

With Windows 11 and WSL2, you can do much more than before. For example, you can run application from the WSL2 with graphical interface as well.

I used to have a virtual machine with Linux used mainly to perform tasks like partitioning, Linux filesystem checks etc, mainly with SD cards used on Raspberry Pis or even for external big disks where I keep backups – and the filesystem is EXT4, for example.

Well, with some little “tuning”, you can now have your WSL2 vms (yes, they are virtual machines too) able to access the physical disks/usb devices as you would do in a VMWare vm or if your pc was actually a Linux box.

To do so, at today, May 2025, you can natively access physical disks but not USB pen/SD cards using USB dongle. In fact, if you run zcat /proc/config.gz | grep ^CONFIG_USB_STORAGE within your WSL VM, you will probably see some output like “not set” or something that’s telling you… nothing here, sorry.

But here… how we can achieve it.

How to access a Physical disk

Source: https://learn.microsoft.com/en-us/windows/wsl/wsl2-mount-disk

You need to open Powershell, and run the following command to identify what is the disk that you want to mount/access from the WSL2 vm.

GET-CimInstance -query "SELECT * from Win32_DiskDrive"

Let’s say that you see that you want to access the secondary disk \\.\PHYSICALDRIVE2
REMEMBER: this procedure is for a physical disk, not USB one.

To safely mount the disk to WSL, it’s recommended to put the disk offline. To do so, use diskpart command.

diskpart /s /select disk 2
diskpart /s /offline disk

Then, still in Powershell (Admin), you can run the following command to expose the full disk to the WSL2. I have multiple WSL2 vms, so I wanted to connect to a specific one called “Workspace” and not to the default Ubuntu one.

wsl -d Workspace --mount \\.\PHYSICALDRIVE2 --bare 

At this point, in your Linux WSL2 machine, you should be able to see the new disk. You can use fdisk -l or any other commands as you would do on a disk physically attached to a Linux box.

Once done, you can unmount (and have the device back in Windows) with:

wsl --unmount \\.\PHYSICALDRIVE2
diskpart /s /select disk 2
diskpart /s /online disk

How to access an USB Mass Storage device

Sources: https://learn.microsoft.com/en-us/windows/wsl/connect-usb and https://www.tomshardware.com/how-to/access-linux-ext4-partitions-in-windows

Here things gets a bit more complicated.

We need to:

  • recompile the WSL2 kernel
  • configure WSL2 to use the new kernel
  • install USBIPD-WIN and use it to connect the USB device to the vm

Recompile the kernel

Source: https://www.tomshardware.com/how-to/access-linux-ext4-partitions-in-windows

I used a second WSL2 vm for this, just to avoid to install loads of packages. But you can safely do in your own.

NOTE: all the WSL vms that you’re running are using the same kernel, unless you specify differently. You can find how to setup Advanced settings configuration in WSL in this link.

Now, you need to be sure to find the right version of the kernel that you’re running. At this stage I’m running version 5.15.167.4

uname -r | awk -F- '{print $1}'

I used this command. Or a simple uname -a will show all the information and you can pick it manually.

You can elevate yourself as root user, and run the following:

# Update and install required packages
apt update && apt upgrade
apt install -y build-essential flex bison libgtk2.0-dev libelf-dev libncurses-dev autoconf libudev-dev libtool zip unzip v4l-utils libssl-dev python3-pip cmake git iputils-ping net-tools dwarves usbutils bc git

# Set the version of your kernel and download the right version
VER=$(uname -r | awk -F- '{print $1}')
git clone -b linux-msft-wsl-${VER} https://github.com/microsoft/WSL2-Linux-Kernel.git ${VER}-microsoft-standard && cd ${VER}-microsoft-standard

# Set the config and start menuconfig
cp /proc/config.gz config.gz && sudo gunzip config.gz && sudo mv config .config

At this stage you should see a GUI menu:

  • Navigate to Device Drivers > USB support
  • Select USB Mass Storage Support and hit Y to put an * next to it, to include this module within the main kernel, instead of adding it as a module.
  • Select Exit on the bottom of the screen (using the Tab key) multiple times until you get asked to save
  • Make sure to select YES when it asks to save your configuration.

Now, it’s time to compile! (it reminds me the old times…). Well, back to now 🙂

Use the following and fingers crossed:

make -j$(nproc) && make modules_install -j$(nproc) &&  make install -j$(nproc) && echo "ALL DONE"

Once you see ALL DONE, it means that you can proceed with the following steps. If you see errors… well… time to troubleshooting yourself 😉

Configure WSL2 to use the new kernel

Hoping all went fine, here the following steps. I assume your Windows username is pippo.

USER="pippo"
cp -rf vmlinux /mnt/c/Users/$USER/
cd /mnt/c/Users/$USER/
echo -e "[wsl2]\nkernel=C:\\\\\\Users\\\\\\$USER\\\\\\\vmlinux" > .wslconfig

You should have now copied the new kernel into pippo’s home directory on the Windows machine, and have a hidden file called .wslconfig (file that applies to ALL your WSL2 vms – see above the advanced settings) with a content like this:
[wsl2]
kernel=C:\Users\pippo\vmlinux

Now, back to Powershell (Admin), and restart WSL to pick up the new changes.

wsl --shutdown

Restart your WSL2 virtual machine. If all went well, you should have your new kernel with the new USB module built in. You can verify it using the same grep that we used before, and you should see a line with a nice “Y”:

$ zcat /proc/config.gz | grep ^CONFIG_USB_STORAGE
CONFIG_USB_STORAGE=y

Install and use USBIPD-WIN

Now that the harder bit has been done, we need the last step to make actually the magic happen. We need to install USBIPD-WIN and actually connect the USB device to the WSL2 virtual machine.

Quicker way – command line, just open again Powershell (Admin) and run:

winget install --interactive --exact dorssel.usbipd-win

Using usbipd list you can see which are the devices attached and pick the one you want to expose to the WSL2 vm. You need to look for the BUSID.

In this example, I can see that the USB drive is actually ID 1-16

> usbipd list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-10   8087:0026  Intel(R) Wireless Bluetooth(R)                                Not shared
1-16   05e3:0749  USB Mass Storage Device                                       Not shared
4-1    046d:0893  Logitech StreamCam, Logitech StreamCam WinUSB, USB Input ...  Not shared
6-3    046d:c31c  USB Input Device                                              Not shared
6-4    045e:0039  Microsoft USB IntelliMouse Optical                            Not shared

Cool, so we can finally attach (expose) the drive to our WSL2 vm.

As mentioned before, I have multiple WSL2 vms, so I wanted to connect to “Workspace” and not to the default Ubuntu one.

usbipd bind --busid 1-16
usbipd attach --busid 1-16 --wsl Workspace

With this command I have connected the USB Mass Storage Device with BUSID 1-16 to the WSL2 VM called Workspace. Without the name Workspace in the command, it will connect to the default WSL2 vm (you can check with wsl --list command).

At this stage, if you go again into your WSL2 vm, you should see the device available simply using lsblk command. And if you have installed gparted, for example, with a sudo gparted (needs to run with the main user but with privileged grants) you should access your SD card or USB drive, and perform all the checks etc you’d like to do.

Same, you can mount etc, exactly as you would do with your Linux machine.

Last but not least, once you’ve finished, you need to detach and unbind the device. Simply run in Powershell (Admin) the following:

usbipd detach -a
usbipd unbind -a

And that’s it! 🙂

I might work on a comprehensive script to do so – I have already my repository here – but for the time being, feel free to use these instructions.

Happy WSL2’ing 🙂

Mount Windows Network drives in WSL

In Windows WSL, you can access the local disk navigating the path /mnt/c/ for the C: drive, for example.

Sometimes, network drives mounted on boot aren’t automatically mounted within your WSL Linux shell. You can do it manually using the following commands:

# For a drive already mapped in Windows (e.g. Z: drive)
$ sudo mkdir /mnt/z
$ sudo mount -t drvfs Z: /mnt/z

# For a network drive accessible via \\myserver\dir1 in Explorer
$ sudo mkdir /mnt/dir1
$ sudo mount -t drvfs '\\myserver\dir1' /mnt/dir1

LVM – How to

Intro

LVM is a very powerful technology, and can really help the Sysadmin’s life.
However, this is something that we generally setup at the beginning (most of the time now it’s automatically setup during the installation process), and it’s well know… when we stop using something, we tend to forget how to use it.

This is why I’m writing this how to, mostly to keep track of the major features and commands, in case I will need them again in the future 😉

Before proceeding, please digest the following journey of this poor physical device that gets abstracted up to usable pieces.

                                                          VG                        VG
                                                   +---------------+         +---------------+
                                                   |      PV       |  +--->  |               |
                                   PV              | +-----------+ |         |  LV           |
                              +-----------+        | |  8E LVM   | |         |               |
              8E LVM          |  8E LVM   |        | | +-------+ | |         +---------------+
             +-------+        | +-------+ |        | | | +---+ | | |  +--->  +---------------+
+---+        | +---+ |        | | +---+ | |        | | | |DEV| | | |         |               |
|DEV| +----> | |DEV| | +----> | | |DEV| | | +----> | | | +---+ | | |         |  LV           |
+---+        | +---+ |        | | +---+ | |        | | +-------+ | |         |               |
  1.         +-------+        | +-------+ |        | +-----------+ |  +--->  |               |
                2.            +-----------+        |               |         +---------------+
                                   3.              |      PV       |         +---------------+
                                                   | +-----------+ |         |               |
 1. Original Device:                               | |  8E LVM   | |  +--->  |  LV           |
    (physical/virtual disk/partition/raid)         | | +-------+ | |         |               |
 2. fdisk'd to label 8E for LVM                    | | | +---+ | | |         |               |
 3. initialised as LVM Physical Volume             | | | |DEV| | | |         |               |
 4. Added in a LVM Volume Group                    | | | +---+ | | |  +--->  |               |
 5. "partitioned" in single/multiple               | | +-------+ | |         |               |
    LVM Logical Groups                          4. | +-----------+ |      5. |               |
                                                   +---------------+         +---------------+

 

 

Prepare partions

First of all, we need to find which device(s) we want to setup for LVM

fdisk -l

[root@n1 ~]# fdisk -l

Disk /dev/xvda: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000b7f16

    Device Boot      Start         End      Blocks   Id  System
/dev/xvda1   *        2048    41943039    20970496   83  Linux

Disk /dev/md1: 4996 MB, 4996726784 bytes, 9759232 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/md2: 4996 MB, 4996726784 bytes, 9759232 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/md3: 4996 MB, 4996726784 bytes, 9759232 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

We can see 3 md devices, probably RAID devices. These are the ones that we are going to use for our LVM exercise.

Now, let’s create an LVM partition.

fdisk <device> => n , p , 1 , (enter) , (enter) , t , 8e , w

[root@n1 ~]# fdisk /dev/md1
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0x50b03cd2.

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-9759231, default 2048): 
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-9759231, default 9759231): 
Using default value 9759231
Partition 1 of type Linux and of size 4.7 GiB is set

Command (m for help): t
Selected partition 1
Hex code (type L to list all codes): 8e
Changed type of partition 'Linux' to 'Linux LVM'

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Do the same for all the devices that you want to use for LVM. In my example, I’ve done this for /dev/md1, /dev/md2 and /dev/md3.

Shortcut (risky but quicker) 🙂

echo -e "o\nn\np\n1\n\n\nt\n8e\nw" | fdisk /dev/mdx

All seems now good to go: we have Linux LVM partitions!

Disk /dev/md1: 4996 MB, 4996726784 bytes, 9759232 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x50b03cd2

    Device Boot      Start         End      Blocks   Id  System
/dev/md1p1            2048     9759231     4878592   8e  Linux LVM

Disk /dev/md2: 4996 MB, 4996726784 bytes, 9759232 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x4b68e9a3

    Device Boot      Start         End      Blocks   Id  System
/dev/md2p1            2048     9759231     4878592   8e  Linux LVM

Disk /dev/md3: 4996 MB, 4996726784 bytes, 9759232 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x8dcf9ba0

    Device Boot      Start         End      Blocks   Id  System
/dev/md3p1            2048     9759231     4878592   8e  Linux LVM

Time to start to configure LVM

Configure LVM

First of all, we need to make these Linux LVM partition able to be part of a group (vg). I always find tricky to remember the logic behind. Let’s imagine that the device itself now is just labelled “Linux LVM” but we need to initiate it in somehow.

pvcreate <dev>

[root@n1 ~]# pvcreate /dev/md1p1
  Physical volume "/dev/md1p1" successfully created.
[root@n1 ~]# pvcreate /dev/md2p1
  Physical volume "/dev/md2p1" successfully created.
[root@n1 ~]# pvcreate /dev/md3p1
  Physical volume "/dev/md3p1" successfully created.

Now these guys are ready to be part of a group. In this case a Virtual Group (vg).
Let’s check that it’s actually true:
pvs

[root@n1 ~]# pvs
  PV         VG Fmt  Attr PSize PFree
  /dev/md1p1    lvm2 ---  4.65g 4.65g
  /dev/md2p1    lvm2 ---  4.65g 4.65g
  /dev/md3p1    lvm2 ---  4.65g 4.65g

Time to create a group with these devices (this could be done also with just a single device):

vgcreate <lvmgroupname> <dev> <dev> …

[root@n1 ~]# vgcreate mylvmvg /dev/md1p1 /dev/md2p1 /dev/md3p1
  Volume group "mylvmvg" successfully created

Now, let’s check again with pvs and vgs

[root@n1 ~]# pvs
  PV         VG      Fmt  Attr PSize PFree
  /dev/md1p1 mylvmvg lvm2 a--  4.65g 4.65g
  /dev/md2p1 mylvmvg lvm2 a--  4.65g 4.65g
  /dev/md3p1 mylvmvg lvm2 a--  4.65g 4.65g
[root@n1 ~]# vgs
  VG      #PV #LV #SN Attr   VSize  VFree 
  mylvmvg   3   0   0 wz--n- 13.95g 13.95g

Now pvs shows the VG group no longer empty but with mylvmvg. And vgs tells us that the VG is about 14GB in size, fully free with no LV in it.

Good! Now, let’s make some LVs (logical volumes). These will be the new “partitions/disks” that we will be actually able to format, mount and use! 🙂

lvcreate -n <name> -L xGB <vg_group_name>

[root@n1 ~]# lvcreate -n part1 -L 2GB mylvmvg
  Logical volume "part1" created.

Some checks to verify:

[root@n1 ~]# vgs
  VG      #PV #LV #SN Attr   VSize  VFree 
  mylvmvg   3   1   0 wz--n- 13.95g 11.95g
[root@n1 ~]# lvs
  LV    VG      Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  part1 mylvmvg -wi-a----- 2.00g

A new LV appears in vgs and lvs shows the 2GB volume that we have created.

Let’s create another one, but this time, using the full remaining space (using -l 100%VG option instead of -L xGB)

[root@n1 ~]# lvcreate -n part2 -l 100%VG mylvmvg
  Logical volume "part2" created.
[root@n1 ~]# vgs
  VG      #PV #LV #SN Attr   VSize  VFree
  mylvmvg   3   2   0 wz--n- 13.95g    0 
[root@n1 ~]# lvs
  LV    VG      Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  part1 mylvmvg -wi-a-----  2.00g                                                    
  part2 mylvmvg -wi-a----- 11.95g                                                    
[root@n1 ~]# 

Magic!

Now, we have two devices, both ‘a’ -> active and ready to be formatted:
mkfs.ext4 <device>

[root@n1 ~]# mkfs.ext4 /dev/mylvmvg/part1 
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
131072 inodes, 524288 blocks
26214 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=536870912
16 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done 

I’ve done this for /dev/mylvmvg/part1 and /dev/mylvmvg/part2.

Let’s create the mount points and mount them:

[root@n1 ~]# mkdir -p /mountpoint1 /mountpoint2

[root@n1 ~]# mount -t ext4 /dev/mylvmvg/part1 /mountpoint1

[root@n1 ~]# mount -t ext4 /dev/mylvmvg/part2 /mountpoint2

[root@n1 ~]# mount | grep mylvmvg
/dev/mapper/mylvmvg-part1 on /mountpoint1 type ext4 (rw,relatime,data=ordered)
/dev/mapper/mylvmvg-part2 on /mountpoint2 type ext4 (rw,relatime,data=ordered)

[root@n1 ~]# df -Th | grep mapper
/dev/mapper/mylvmvg-part1 ext4      2.0G  6.0M  1.8G   1% /mountpoint1
/dev/mapper/mylvmvg-part2 ext4       12G   41M   11G   1% /mountpoint2

As you can see, the devices are appearing now as /dev/mapper/mylvmvg-partX. You can use either /dev/mylvmvg/partX or /dev/mapper/mylvmvg-partX. Theoretically, the mapper one is recommended (my bad!).

Now the 2 devices are ready to be used as a typical disk/partition formatted with ext4 filesystem.


Resize Logical Volume

Now, imagine that part1 is too small, and you need more space. And luckily, your part2 volume has plenty. Is there any way to “steal” some space from part2 and give it to part1?
Ooohh yesss! 🙂

How?

  1. shrink part2 logical volume AND its filesystem
  2. expand part1 logical volume AND its filesystem

Here the comments inline:

# Important the -r (this RESIZE the filesystem during the process)
[root@n1 ~]# lvreduce -L -5GB -r /dev/mylvmvg/part2 
Do you want to unmount "/mountpoint2"? [Y|n] y
fsck from util-linux 2.23.2
/dev/mapper/mylvmvg-part2: 12/783360 files (0.0% non-contiguous), 92221/3131392 blocks
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/mapper/mylvmvg-part2 to 1820672 (4k) blocks.
The filesystem on /dev/mapper/mylvmvg-part2 is now 1820672 blocks long.

  Size of logical volume mylvmvg/part2 changed from 11.95 GiB (3058 extents) to 6.95 GiB (1778 extents).
  Logical volume mylvmvg/part2 successfully resized.

# Here we can see that part2 is now smaller than before
[root@n1 ~]# lvs
  LV    VG      Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  part1 mylvmvg -wi-ao---- 2.00g                                                    
  part2 mylvmvg -wi-ao---- 6.95g                                                    

# And here we can see 5GB available in the vg
[root@n1 ~]# vgs
  VG      #PV #LV #SN Attr   VSize  VFree
  mylvmvg   3   2   0 wz--n- 13.95g 5.00g

# We assign the 5GB available to part1
[root@n1 ~]# lvextend -L +5GB -r /dev/mylvmvg/part1
  Size of logical volume mylvmvg/part1 changed from 2.00 GiB (512 extents) to 7.00 GiB (1792 extents).
  Logical volume mylvmvg/part1 successfully resized.
resize2fs 1.42.9 (28-Dec-2013)
Filesystem at /dev/mapper/mylvmvg-part1 is mounted on /mountpoint1; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/mapper/mylvmvg-part1 is now 1835008 blocks long.

# No more Free space
[root@n1 ~]# vgs
  VG      #PV #LV #SN Attr   VSize  VFree
  mylvmvg   3   2   0 wz--n- 13.95g    0 

# part1 is now 7GB (prev 2GB)
[root@n1 ~]# lvs
  LV    VG      Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  part1 mylvmvg -wi-ao---- 7.00g                                                    
  part2 mylvmvg -wi-ao---- 6.95g                                                    

# df shows as well the new size
[root@n1 ~]# df -Th | grep mapper
/dev/mapper/mylvmvg-part1 ext4      6.9G  9.1M  6.6G   1% /mountpoint1
/dev/mapper/mylvmvg-part2 ext4      6.8G   37M  6.4G   1% /mountpoint2

 

Move logical volume onto a new RAID array

Now, let’s imagine that one of the 3 initial md devices are having problems, or simply we want to move on a faster/bigger raid array.
The magic of LVM is that we can actually do this with NO DOWNTIME!

How?

In this example we assume that a new /dev/md10 device is attached to our server and we want to remove /dev/md2 device.

  1. We need to take the new device and go through all the previous steps:
    1. fdisk
    2. pvcreate
  2. After that, we need to add this initialised device in the existing volume group (vg)
  3. Move whatever is stored on the physical device
  4. Shrink the volume group
  5. Remove the device
[root@n1 ~]# echo -e "o\nn\np\n1\n\n\nt\n8e\nw" | fdisk /dev/md10
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0x465fad01.

Command (m for help): Building a new DOS disklabel with disk identifier 0x5aa41f03.

Command (m for help): Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): Partition number (1-4, default 1): First sector (2048-104791935, default 2048): Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-104791935, default 104791935): Using default value 104791935
Partition 1 of type Linux and of size 50 GiB is set

Command (m for help): Selected partition 1
Hex code (type L to list all codes): Changed type of partition 'Linux' to 'Linux LVM'

Command (m for help): The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

[root@n1 ~]# fdisk -l | grep md10
Disk /dev/md10: 53.7 GB, 53653471232 bytes, 104791936 sectors
/dev/md10p1            2048   104791935    52394944   8e  Linux LVM

[root@n1 ~]# pvcreate /dev/md10p1
  Physical volume "/dev/md10p1" successfully created.

[root@n1 ~]# pvs
  PV          VG      Fmt  Attr PSize  PFree 
  /dev/md10p1         lvm2 ---  49.97g 49.97g
  /dev/md1p1  mylvmvg lvm2 a--   4.65g     0 
  /dev/md2p1  mylvmvg lvm2 a--   4.65g     0 
  /dev/md3p1  mylvmvg lvm2 a--   4.65g     0 

[root@n1 ~]# vgextend mylvmvg /dev/md10p1
  Volume group "mylvmvg" successfully extended

[root@n1 ~]# pvs
  PV          VG      Fmt  Attr PSize  PFree 
  /dev/md10p1 mylvmvg lvm2 a--  49.96g 49.96g
  /dev/md1p1  mylvmvg lvm2 a--   4.65g     0 
  /dev/md2p1  mylvmvg lvm2 a--   4.65g     0 
  /dev/md3p1  mylvmvg lvm2 a--   4.65g     0 

[root@n1 ~]# vgs
  VG      #PV #LV #SN Attr   VSize  VFree 
  mylvmvg   4   2   0 wz--n- 63.91g 49.96g

Now where the new bits are starting:
pvmove, vgreduce, pvremove

[root@n1 ~]# pvmove /dev/md2p1
  /dev/md2p1: Moved: 0.00%
  /dev/md2p1: Moved: 5.63%
  /dev/md2p1: Moved: 11.51%
  ...
  /dev/md2p1: Moved: 92.61%
  /dev/md2p1: Moved: 98.07%
  /dev/md2p1: Moved: 100.00%

# Here we can see 4 phisical volumes, and a size of ~64GB
[root@n1 ~]# vgs
  VG      #PV #LV #SN Attr   VSize  VFree 
  mylvmvg   4   2   0 wz--n- 63.91g 49.96g

# We can see also that /dev/md2p1 is now fully FREE
[root@n1 ~]# pvs
  PV          VG      Fmt  Attr PSize  PFree 
  /dev/md10p1 mylvmvg lvm2 a--  49.96g 45.32g
  /dev/md1p1  mylvmvg lvm2 a--   4.65g     0 
  /dev/md2p1  mylvmvg lvm2 a--   4.65g  4.65g
  /dev/md3p1  mylvmvg lvm2 a--   4.65g     0 

# we can safely remove this device from the vg
[root@n1 ~]# vgreduce mylvmvg /dev/md2p1
  Removed "/dev/md2p1" from volume group "mylvmvg"

[root@n1 ~]# vgs
  VG      #PV #LV #SN Attr   VSize  VFree 
  mylvmvg   3   2   0 wz--n- 59.26g 45.32g

#/dev/md2p1 doesn't belong to any VG anymore
[root@n1 ~]# pvs
  PV          VG      Fmt  Attr PSize  PFree 
  /dev/md10p1 mylvmvg lvm2 a--  49.96g 45.32g
  /dev/md1p1  mylvmvg lvm2 a--   4.65g     0 
  /dev/md2p1          lvm2 ---   4.65g  4.65g
  /dev/md3p1  mylvmvg lvm2 a--   4.65g     0 

# Removing and confirm: no more /dev/md2p1
[root@n1 ~]# pvremove /dev/md2p1
  Labels on physical volume "/dev/md2p1" successfully wiped.

[root@n1 ~]# pvs
  PV          VG      Fmt  Attr PSize  PFree 
  /dev/md10p1 mylvmvg lvm2 a--  49.96g 45.32g
  /dev/md1p1  mylvmvg lvm2 a--   4.65g     0 
  /dev/md3p1  mylvmvg lvm2 a--   4.65g     0 

 

In this example we have left LVM to decide where to put the data that was stored on /dev/md2 device.
Just for reference, we could have specified the destination physical device (e.g. if we were thinking to remove more devices and make sure that the data was ending up on the new RAID and not sprat across the other disks):

pvmove /dev/md2p1 /dev/md10p1

Or, in case we just wanted to move a specific logical volume, let’s say part1

pvmove -n part1 /dev/md2p1 /dev/md10p1

 

…happy LVM’ing! 😉

Mac /Users partition on RAID1

This is what I’ve created:

  • Fresh new installation of Mac OS X Lion on a new 128SSD hard drive (this should work with Mavericks too);
  • Create a RAID1 with the 2 TB disks, and mounted in /Users;
  • Restored apps/confs/data from Time Machine using Migration Assistant.

Create RAID1

This is quite handy to have the user’s data safe.
I’ve simply created a RAID1 using Disk Utility and set this new device to auto mount in /Users folder 😉
Call the new device “Users“. I will use this name as reference in this guide.
Simply drop the hard drives in the Raid section and select Mirrored Raid Set – Mac OS Extended (journaled)
Once created, CMD+I on the new device and take note of Universal Unique Identifier the famous UUID

It might be interesting to follow this guide to create an encrypted logical volume on the RAID partition to save your data 😉

How to mount this new drive in /Users?

First of all you need to enable “root” user

Very easy… open Terminal, got superuser privilegies (sudo su - command) and once the prompt shows “#“, type passwd command.
Set a new password (it will ask to insert it twice).
Now, go to Users and Group and in Login Options select Show Input menu in login window (this can be rolled back once finished).
Logout (better if you do a full reboot).
Once the OS is up again you will have an “old fashion” login window, where you need to enter username and password.
Fantastic!
Insert root as username and the password is the one you’ve just set via Terminal: you will login as super user.

Second, copy the current data

Now… back to the Terminal!
Open it (and you will be already root user! ), have handy the UUID you’ve saved before and digit the following commands:

cd /
cp -a /Users/* /Volumes/Users/
cp -a /Users /Users.orig
rm -rf /Users/*
vifs

Now you need to press SHIFT+g
Then press o
Then insert the following, of course replacing the XXX with your UUID

UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /Users hfs auto

Once finished, to save press these in sequence esc : wq

For more info check any vim editor guide.

What we’ve done is coping the full content of /Users in our new RAID device (called “Users” during the RAID setup).
Created a copy on the local drive as well (just to stay from the safe side 😛 )
Removed all the content of /Users and make it ready to get the new RAID1 device mounted inside (sounds a bit xxx but it’s not 😀 )
Edited /etc/fstab to auto mount the RAID1 device automatically at the boot.

Third… reboot and login

Now it’s all ready for the reboot and login with your normal user!
Once confirmed that all works, you can safely remove Users.orig folder and restore the original login window.

Forth (optional): restore from Time Machine

Now you can finally restore your data manually using Time Machine.
Migration Assistant will probably fail if the amount of data is bigger than the size of your main OS disks. The reason is that It’s not able to understand that there are extra 2TB of space under Users.
What I’ve done is restoring ALL my OS except the users, using Migration Assistant, and then, I’ve used Time machine and copied manually all the folders inside /Users … and all worked! 😉