BTRFS Support

Cockpit btrfs support, initial read only support has landed with create/delete subvolume support on the way. Some missing features in general are:

  • UDisks improvements
  • Further tests
  • Resize/Grow support
  • Multi device support
    • Adding a new device to a filesystem
    • Remove a device from a filesystem
  • Volume creation support
    • RAID1/RAID5 etc.
  • Snapshots support
  • Quota support
  • Robistifcation of libblockdev

UDisks Improvements

  • use udisks for listing subvolumes (GetSubvolumes) currently does not work well for us due to MountPoints notes
  • use udisks CreateSubvolume, issue (does not work as it always selects the first mountpoint)
  • use udisks CreateSnapshot, issue (does not work as it always selects the first mountpoint)
  • use udisks DeleteSubvolume issue (does not work as it always selects the first mountpoint and no recursive removal support)
  • reproduce the issue below and create a good bug report

Bugs

Repeatedly adding/removing a device to a volume either loses an udev event or udisks does not pick up a udev event.

btrfs device add /dev/mapper/vgroup0-lvol1 /mnt/data; date
btrfs device remove /dev/mapper/vgroup0-lvol1 /mnt/data; date

This generates a udev event, it's udisks which no longer knows!

Further tests

Test setting a different default subvolume in btrfs and see how Cockpit handles this.

Resize / Grow support

Should be exposed by UDisks, see dbus docs.

Multi device support

CreateVolume exists in UDisks and should be implemented like LVM in Cockpit. It works a bit different then LVM in that metadata and data can have different raid profiles.

Finding out what multi device profile was selected can only be done via:

btrfs --format json filesystem df $mountpoint

For options see mkfs.btrfs --help

A device can be added or removed with AddDevice and RemoveDevice but currently we can't detect when a drive is missing or obtain health stats from the "array".

UDisks does not know about missing devices see, btrfs filesystem show does but it is hard to parse:

echo >/sys/block/sdx/device/delete

Label: 'fedora-test'  uuid: cece4dd8-6168-4c88-a4a8-f7c51ed4f82b
Total devices 3 FS bytes used 2.08GiB
devid    1 size 11.92GiB used 3.56GiB path /dev/vda5
devid    2 size 0 used 0 path /dev/sda MISSING
devid    3 size 512.00MiB used 0.00B path /dev/sdc

In LVM in UDisks this is shows as VolumeGroup => MissingPhysicalVolumes readable as

  • Teach libblockdev to expose the data and metadata profile
    • Expand libblockdev with filesystem information using btrfs --format json filesystem $mountpoint
  • Teach udisks to expose missing disks
    • Expand libblockdev BDBtrfsDeviceInfo with missing bool field
    • Teach libblockdev bd_btrfs_list_devices to detect missing devices
  • Read up if btrfs exposes any health stats about the array and if it was synced
  • Research if an array needs to be balanced when a device is added as this does not happen automatically
    • Implement btrfs balance in libblockdev
    • Expose balance start/end in UDisks, requires a job API

libbtrfsutil

C test program

gcc -O0 -ggdb -I /home/jelle/projects/btrfs-progs -L /home/jelle/projects/btrfs-progs -lbtrfsutil test.c
LD_LIBRARY_PATH=/home/jelle/projects/btrfs-progs ./a.out

Running build Python module:

LD_LIBRARY_PATH=/home/jelle/projects/btrfs-progs  PYTHONPATH=libbtrfsutil/python valgrind --leak-check=full  python3 test.py

Snapshots support

We currently list all subvolumes, so also snapshots. Cockpit should display snapshots and regular subvolumes different and also check if they are readonly or not.

  • Listing snapshots different, how do we identify if it is a snapshot can we only differentiate between btrfs subvolume list -s and without?
  • Snapshot creation
    • Extend the create subvolume or create a new menu entry for Create snapshot
    • Add option to create a readonly snapshot
    • can't use UDisks for this as it suffers from the same issue as CreateSubvolume (getting the first mount point)
  • Snapshot deletion - should be the same as a normal subvolume removal, just needs tests

Quota support

  • Learn about quotas
  • Expose quotas via libblockdev
    • Create quota group support
    • Create subvolume allow setting quotas

Robistifcation of libblockdev

Use libbtrfsutil where possible instead of shelling out btrfs.

  • Port create/delete subvolume to libbtrfsutil
    • Use btrfs_util_delete_subvolume
    • Extend delete with a new flag for BTRFS_UTIL_DELETE_SUBVOLUME_RECURSIVE
    • Use btrfs_util_create_subvolume
  • Port create_snapshot to libbtrfsutil
  • Port listing subvolumes to libbtrfsutil
  • libbtrfsutil extending
    • extend libbtrfsutil with per device or volume information like btrfs filesystem show and/or data/metadata
    • add addDevice/removeDevice support if allowed
    • add createVolume support if allowed
    • setLabel support

Old notes

Subvolumes

Just directories under a subvolume

default subvolume id [5] is the ultimate root of every btrfs filesystem

Usually mounted as:

UUID=a280b604-6023-4ba5-bb9e-80d612f84b0d /home btrfs subvol=home,compress=zstd:1 0 0

A proper subvolume has always inode number 256. If a subvolume is nested and then a snapshot is taken, then the cloned directory entry representing the subvolume becomes empty and the inode has number 2.

Udisks

Snapshots

  • How to create them? btrfs subvolume snapshot $subvolume $target

  • How to mount them?

  • How to identify them? Snapshots are basically subvolumes but with initial contents

  • Different types of snapshots? btrfs has read only and read/write snapshots

    Then be set on creation with -r or with a property btrfs property set /root/@snapshots/6oct-1 ro true

  • How do we identify a rw/readonly snapshot btrfs property get /root/@snapshots/6oct-1 ro

multiple disks

  • Should cockpit balance for you? (udisks does not)
  • What modes should we offer? raid0/raid1/raid01?