Enable Project Quota for the DIR storage backend on a live root EXT4 filesystem without live-cd

Thanks to @stgraber telling me that running tune2fs -O project -Q prjquota /dev/sdaX is absolutely essential to enable Project Quota on a device, I searched for a solution that does not require switching off or using a live-cd as this requires too much time and does not always work well in my experience with my VPS provider. And I also hoped that I can turn the steps into a script, which did not work out so far, but is still a possibility.

Thanks to a StackExchange question I was able to put together a solution that worked for me on Ubuntu 18.04. You do need ca. 4GB of RAM to do this (and of course a kernel after version 4.4).

Sources:

1. Make a RAMdisk filesystem

mkdir /tmp/tmproot
mount none /tmp/tmproot -t tmpfs -o rw
mkdir /tmp/tmproot/{proc,oldroot,sys}
cp -a /dev /tmp/tmproot/dev
cp -ax /{bin,etc,opt,run,usr,home,mnt,sbin,lib,lib64,var,root,srv} /tmp/tmproot/

2. Switch root to the new RAMdisk filesystem

cd /tmp/tmproot
unshare -m
pivot_root /tmp/tmproot/ /tmp/tmproot/oldroot
mount none /proc -t proc
mount none /sys -t sysfs
mount none /dev/pts -t devpts

3. Restart SSH on another port than 22 and reconnect with another session

nano /etc/ssh/sshd_config
  • Change the port to 2211
  • Restart SSH with /usr/sbin/sshd -D &
  • Connect again from 2211

4. Kill processes using /oldroot or /dev/sdaX

fuser -km /oldroot
fuser -km /dev/sdaX

5. Unmount /dev/sdaX and apply the project quota feature

umount -l /dev/sdaX
tune2fs -O project -Q prjquota /dev/sdaX

6. Mount with Project Quota

mount /dev/sda2 -o prjquota /oldroot

7. Putting things back

pivot_root /oldroot /oldroot/tmp/tmproot
umount /tmp/tmproot/proc
mount none /proc -t proc
cp -ax /tmp/tmproot/dev/* /dev/
mount /dev/sda1 /boot  ### This might be different for you
reboot -f

8. Turn quota on after reboot

apt install quota -y
quotaon -Pv -F vfsv1 /

9. Check if quota is on on root

repquota -Ps /

10. Make it persistent

  • Put prjquota into the options of root in /etc/fstab

11. Put limits on DIR backend Linux Containers

Either to a profile.

incus profile device add profilename root disk pool=default path=/ size=40GiB

Or to a container.

incus config device add containername root disk pool=default path=/ size=40GiB

Enjoy!