(c) 2026 Trevor E. Cordes for MUUG CC-BY-SA use at your own risk. no warranty. VERY DANGEROUS if you don't do things correctly. ssh -p 22222 root@localhost our demo will be on muug in a vm, for ease of demoing and testing umount -a unmounts everything it can; will say lots of fs's are "target is busy", that's ok df will confirm the only on-disk fs that remains is root; no other: sd* or vd* mkdir /z setup a temporary mountpoint we'll use for our new root fs mount -t tmpfs none /z make a ram fs on it mkdir /z/{proc,sys,dev,run,usr,var,tmp,oldroot} /z/usr/share cp -ax /{bin,etc,mnt,sbin,lib,lib64} /z cp -ax /usr/{bin,sbin,lib,lib64,libexec} /z/usr/ cp -ax /var/{empty,lib,local,lock,nis,opt,preserve,run,spool,tmp,yp} /z/var/ cp -ax /usr/share/terminfo /z/usr/share cp -ax /usr/share/crypto-policies /z/usr/share cp -ax /usr/share/empty.sshd /z/usr/share makes copies of critical files and programs you'll need to do the work you want once in the minimal env; the extra /usr/share stuff is to make systemctl and sshd happy, could just copy all of share if you have the ram mount --make-rprivate / pivot_root /z /z/oldroot bash for i in dev proc sys run; do mount --move /oldroot/$i /$i; done you're now running in the temporary root all of your previous root files are in /oldroot systemctl restart sshd need to make sure this critical daemon is fully running off the tmp root from the box you use to access the pivot-root box, start another ssh to make sure you can still get in: ssh -p 22222 root@localhost is what I use to get into the demo vm fuser -vm /oldroot you need to get rid of every entry shown systemctl | grep running |column -t|colrm 90 start with the systemd-controlled things killall -e auditd fuser -vm /oldroot systemctl won't allow it to be killed killall -r systemd-userwork killall -r systemd-resolve killall -r systemd-homed killall -r systemd-userdbd killall -r sd-pam killall agetty fuser -vm /oldroot systemctl stop chronyd systemctl stop systemd-oomd systemctl stop NetworkManager systemctl stop dbus-broker fuser -vm /oldroot systemctl restart systemd-udevd systemctl restart systemd-journald systemctl restart systemd-logind.service fuser -vm /oldroot systemctl daemon-reexec fuser -vm /oldroot needed to get rid of the systemd entry from the box you use to access the pivot-root box: ssh -p 22222 root@localhost and logout the other ssh session fuser -vm /oldroot kill ... fuser -vm /oldroot manually run kill on the remaining systemd entry (a user session ps) umount /oldroot we're done! right?? but it's lying to you! Modern linux has "namespaces" where you can have different views of the same system; so your current view says the disk/partitions are unused, but they are still held by ps's in other namespaces; resize2fs /dev/vda3 4G errors; device is busy! grep -R "vda3" /proc/*/mountinfo /proc/1204/mountinfo:56 55 253:3 / /oldroot ro,relatime shared:10 - ext4 /de... ... bash for x in `grep -R vda3 /proc/*/mountinfo | cut -d/ -f 3,3`; do echo -n "$x " readlink /proc/$x/ns/mnt done 994 mnt:[4026532426] ... will tell you all of the namespaces the device is still used in; you can enter each ns and run the umount there manually: nsenter -t 994 -m -- umount /oldroot nsenter -t 1204 -m -- umount /oldroot or automate... bash for x in `grep -R "vda3" /proc/*/mountinfo | cut -d/ -f 3,3`; do echo -n "$x " nsenter -t $x -m -- umount /oldroot done any ones done more than once can just be ignored manipulations::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: shrinking root::::::::::::::::::::::::::::::::::::: e2fsck -f /dev/vda3 resize2fs will make you do this anyhow resize2fs /dev/vda3 4G shrinks the fs record the final "(4k) blocks long" count from resize2fs (1048576) sfdisk --dump /dev/vda |colrm 90 record these numbers in case you need to revert echo 'size=4GiB' | sfdisk -N 3 /dev/vda shrinks the partition to 4G sfdisk --dump /dev/vda |colrm 90 take sfdisk's size= and calc sfdisksizex512/4096 and check it matches the number from resize2fs! if not, use the recorded info to reset the partition back to original size and debug expr 8388608 \* 512 / 4096; echo =; echo 1048576 moving root and making /boot bigger::::::::::::::::: echo '+1GiB,' | sfdisk --move-data /dev/vda -N 3 moves root 1GiB ahead echo 'size=+' | sfdisk -N 2 /dev/vda grows the /boot partition to max size to fill up the new space between partitions e2fsck -f /dev/vda2 resize2fs /dev/vda2 grows the fs add an lvm partition you can make a vg out of to make an xfs quota home dir:::::::::::: echo 'size=+, type=linux-lvm' | sfdisk --append /dev/vda now you have a big lvm block device you can creat a vg/lv's on; do it after you check things and reboot as you don't need this minimal environment any more checking things out::::::::::::::::::::::::::::::: mkdir /r; mount /dev/vda3 /r mkdir /b; mount /dev/vda2 /b ll /r ll /b df -h |grep vda /r root should be around 4G (from 6) /b should be around 2G (from 1) fdisk -l /dev/vda get things back to normal::::::::::::::::::::::::: umount /r umount /b sync; sync; sync; sleep 1; reboot -f safe in this case because no on-disk fs's are mounted; and don't want to risk normal systemd reboot which just loves to hang indefinitely uptime df -h