Tag: RaspberryPi

  • Changing hostname on RaspberryPi

    There seem to be lots of posts about changing your hostname on a RaspberryPi. The issue is that “something” keeps overriding the changes for you. This thing seems to be cloud-init, which appears to be installed by default now.

    Digging about I found people turning off and removing cloud-init. I also found people trying to lean into cloud-init – which also attempted but it always reverted my change.

    What I eventually found is that the user-data file in /boot/firmware doesn’t seem to be read correctly on boot. The system appears to read a cached version which is stored in /var/lib/cloud/instances.

    My solution? I told cloud-init to purge its cache:

    cloud-init -c

    And then I rebooted the device. The change I was attempting to make appeared straight after the reboot. I have no idea if there is a better way of having the instance file refresh – not gone that far down the cloud-init rabbithole. But I wanted to get my method out there, as it might be a bit simpler.

    FWIW, what I was attempting was to get the fully qualified domain name correctly reflected in the system. I did this by adding the following to the user-data file:

    fqdn: <full name of the device>

    Now when I run hostname -f, I get the correct response.

    There you go – a different approach to changing a RaspberryPi hostname.

  • Convert root filesystem to btrfs on RaspberryPi

    This collates the lessons I have learned when I attempted to convert the root filesystem to btrfs on my RaspberryPi.

    First things first – it is NOT just run the btrfs-convert and change a couple of bits of config. I initially thought it was, and this bit me quite spectacularly. I’ve now spent a few hours getting this working, so learn from my experience.

    I should note that my work comes from digging about on the internet. These posts helped point the way:

    Steps:

    1. You will need to be able to work with two operating systems which may mean you need use a USB -> SD Card converter.
    2. Check whether btrfs is being loaded on boot.
      If it isn’t it will need adding FIRST. Do not go any further until the module is included in the initramfs.
      • Check in boot log
        • Run this command:
          dmesg | grep -i btrfs
        • You are looking for this in the output:
          [ 2.651955] Btrfs loaded, zoned=no, fsverity=no
      • Check in kernel
        • Can see the module here:
          lsmod | grep -i btrfs
        • Output should be similar to:
          btrfs 1630208 1
          xor 12288 1 btrfs
          raid6_pq 106496 1 btrfs
      • Check whether btrfs is in the initramfs
        • Run this:
          lsinitramfs /boot/initrd.img-$(uname -r) | grep btrfs
        • You are looking specifically for these lines:
          usr/lib/modules/6.12.75+rpt-rpi-v8/kernel/fs/btrfs
          usr/lib/modules/6.12.75+rpt-rpi-v8/kernel/fs/btrfs/btrfs.ko.xz
    3. If these lines are NOT appearing then you MUST do the following:
      • Add BTRFS into the initramfs modules:
        echo 'btrfs' | sudo tee -a /etc/initramfs-tools/modules
      • Update Initramfs
        sudo update-initramfs -c -k $(uname -r)
    4. You can check the the initramfs is now correct using the lsinitramfs command above.
    5. Reboot your system
    6. Check for the module in the boot log AND the kernel as before.
    7. Now you can install btrfs:
      sudo apt install btrfs-progs
    8. The system is now prepared – shut it down and BACKUP the SD Card.

    Everything from here on could lead to a broken system so it is at your own risk. If you can’t risk having a broken system, and starting everything again from scratch, do not go any further.

    1. Boot from another SD Card. This system will need btrfs installed on it obviously.
    2. Check the root volume for errors:
      sudo fsck -f /dev/sdb2
    3. Convert the root volume:
      sudo btrfs-convert /dev/sdb2
    4. Obviously, this will take a while
    5. It will finish, with output similar to:
      btrfs-convert from btrfs-progs v6.14
      Source filesystem:
      Type: ext2
      Label: rootfs
      Blocksize: 4096
      UUID: ed6c7f1b-238b-41a1-b4b6-7bcdef3270fe
      Target filesystem:
      Label:
      Blocksize: 4096
      Nodesize: 16384
      UUID: cd4d1c9c-8fe9-4fac-a8e5-1e828ef54432
      Checksum: crc32c
      Features: extref, skinny-metadata, no-holes, free-space-tree (default)
      Data csum: yes
      Inline data: yes
      Copy xattr: yes
      Reported stats:
      Total space: 63319310336
      Free space: 50360090624 (79.53%)
      Inode count: 3813760
      Free inodes: 3590302
      Block count: 15458816
      Create initial btrfs filesystem
      Create ext2 image file
      Create btrfs metadata
      Copy inodes [o] [ 223370/ 223458]
      Free space cache cleared
      Conversion complete
    6. At this point, conversion is complete.
    7. Perform a sanity mount of this converted filesystem:
      sudo mount /dev/sdb2 /mnt
    8. Assuming it mounts fine we want to fix fstab:
      vi /mnt/etc/fstab
    9. It will look something like this:
      proc /proc proc defaults 0 0
      PARTUUID=3ae81c03-01 /boot/firmware vfat defaults 0 2
      PARTUUID=3ae81c03-02 / ext4 defaults,noatime 0 1
    10. Convert the line for / to use btrfs.
      NB The PARTUUIDs did not change for me.
    11. Will now look like this:
      proc /proc proc defaults 0 0
      PARTUUID=3ae81c03-01 /boot/firmware vfat defaults 0 2
      PARTUUID=3ae81c03-02 / btrfs defaults,noatime 0 1
    12. Unmount converted root.
      sudo umount /mnt
    13. Mount the boot filesystem
      sudo mount /dev/sdb1 /mnt
    14. Update boot options:
      sudo vi /mnt/cmdline.txt
    15. Should look like this:
      console=serial0,115200 console=tty1 root=PARTUUID=3ae81c03-02 rootfstype=ext4 fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles ds=nocloud;i=rpi-imager-1777239363059 cfg80211.ieee80211_regdom=GB
    16. Change rootfstype to btrfs.
    17. Will now look like this:
      console=serial0,115200 console=tty1 root=PARTUUID=3ae81c03-02 rootfstype=btrfs fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles ds=nocloud;i=rpi-imager-1777239363059 cfg80211.ieee80211_regdom=GB
    18. Everything should now be ready. Shut everything down put you SD Card in and cross your fingers. It should boot.

    One the system boots you should see further entries related to btrfs in the boot log if you look using dmesg | grep -i btrfs

    [    0.000000] Kernel command line: coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0 cgroup_disable=memory numa_policy=interleave nvme.max_host_mem_size_mb=0 snd_bcm2835.enable_headphones=1 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_hdmi=0  numa=fake=2 system_heap.max_order=0 iommu_dma_numa_policy=interleave smsc95xx.macaddr=E4:5F:01:05:57:6B vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000  console=ttyS0,115200 console=tty1 root=PARTUUID=3ae81c03-02 rootfstype=btrfs fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles ds=nocloud;i=rpi-imager-1777239363059 cfg80211.ieee80211_regdom=GB
    [    2.689648] Btrfs loaded, zoned=no, fsverity=no
    [    2.994418] BTRFS: device label rootfs devid 1 transid 209 /dev/mmcblk0p2 (179:2) scanned by mount (212)
    [    2.995544] BTRFS info (device mmcblk0p2): first mount of filesystem cd4d1c9c-8fe9-4fac-a8e5-1e828ef54432
    [    2.995568] BTRFS info (device mmcblk0p2): using crc32c (crc32c-generic) checksum algorithm
    [    3.040169] BTRFS info (device mmcblk0p2): enabling ssd optimizations
    [    3.040186] BTRFS info (device mmcblk0p2): turning on async discard
    [    3.040191] BTRFS info (device mmcblk0p2): enabling free space tree

    Once you are happy everything is alright, you can delete the failback subvolume:

    sudo btrfs subvolume delete /ext2_saved

    Should see similar to:

    Delete subvolume 256 (no-commit): '//ext2_saved'

    And that should be it root is converted – enjoy your btrfs based RaspberryPi system.

    Things I discovered.

    • If you are an idiot like me, you can copy an initramfs of the same kernel (with the module) to the boot volume.
      The one that was important to me was the one called initramfs8 in that directory.
    • If you’ve stuffed up the cmdline.txt file you can also copy that.
    • Remember that you do have to correct the PARTUUID when you do this (I didn’t).