billw2 / rpi-clone

A shell script to clone a booted disk.
BSD 3-Clause "New" or "Revised" License
2.49k stars 327 forks source link

Feature request: Preserve filesystem labels #100

Open matthijskooijman opened 3 years ago

matthijskooijman commented 3 years ago

It is possible to change the filesystem label of the root partition (or maybe all ext partitions, that's what the docs suggest), but otherwise all partition are created without a filesystem label.

Wouldn't it make more sense to copy the existing filesystem labels? Given the goal is to create a clone?

gromain commented 3 years ago

Seconded. Just had an issue with Manjaro ARM where if the labels are not propagated the copy will not boot. Not a big issue, but nonetheless annoying!

mvdklip commented 3 years ago

I had the same issue with a copy of Ubuntu Server on a raspberry pi 3 not booting from the cloned disk. Fixed this by manually setting the filesystem labels on the destination card.

This however does introduce a new problem: with both the source and the destination card sharing the same labels the system would boot from either, which is not what I want. I want the system to always boot from the main (source) card sitting in the internal slot and not from the backup (destination) card sitting in a USB card reader. So copying the labels accross is not as good as an idea as it seems.

I ended up converting my fstab and cmdline.txt to 'good old' device names, which is certainly not a great idea but at least guarantees that the system boots from whatever card is sitting in the internal card reader. I might try using the --convert-fstab-to-partuuid option next to convert to PARTUUID instead but will first thoroughly check I have a working backup scenario now.

IMO it would be really nice if rpi-clone would:

  1. Detect fstab using labels or uuids and issue a warning about rpi-clone only supporting device names and partuuids.
  2. Add support for converting labels or uuids to partuuids using the convert-fstab-to-partuuid option.
sineverba commented 2 years ago

+1 for this

ioogithub commented 2 years ago

I ended up converting my fstab and cmdline.txt to 'good old' device names, which is certainly not a great idea but at least guarantees that the system boots from whatever card is sitting in the internal card reader. I might try using the --convert-fstab-to-partuuid option next to convert to PARTUUID instead but will first thoroughly check I have a working backup scenario now.

Could you explain this a bit further, what do you mean by 'good old' device names and what specifically did you have to rename in fstab and cmdline.txt? Does the pi use these labels exclusively to determine which partition to boot from? Were you able to test the --convert-fstab-to-partuuid command? I have the exact same problem as you. I used @matthijskooijman code to successfully clone my Ubuntu server however now my pi always seems to pick /dev/sdb to boot from as opposed to /dev/mmcblk01 which is not what I want.

The end goal is to have an sd card attached to usb which is an incrementally updated clone of the original so when the original dies (again) I can simply swap the cards. In this scenario I always need to boot from the original card attached directly to the pi.

sineverba commented 2 years ago

In reality, the missing part is only rename the partitions.

I.e., when I had the PI, I "solved" with another PC with LInux.

sudo lsblk -o name,mountpoint,fstype,label,size,uuid

Print all info about your disks / sd.

sudo fatlabel /dev/sda1 system-boot && sudo e2label /dev/sda2 writable

With last command, you rename the partitions name. Simply, change (if need) dev/sdX

matthijskooijman commented 2 years ago

I had the same issue with a copy of Ubuntu Server on a raspberry pi 3 not booting from the cloned disk. Fixed this by manually setting the filesystem labels on the destination card.

This however does introduce a new problem: with both the source and the destination card sharing the same labels the system would boot from either, which is not what I want. I want the system to always boot from the main (source) card sitting in the internal slot and not from the backup (destination) card sitting in a USB card reader. So copying the labels accross is not as good as an idea as it seems.

Hm, this seems a bit weird: I would expect that the labels are irrelevant for selecting the boot device, but the (PART)UUID would be used. However, reading what you wrote, you really do seem to mean labels. Does Ubuntu maybe use labels instead of UUIDs, then?

@ioogithub, could you maybe paste the /etc/fstab from your original Ubuntu installation here?

mvdklip commented 2 years ago

@matthijskooijman I think you're quoting my comments but asking @ioogithub for input. Is that what you meant to do?

To explain what I did I think you have to understand that to some this is counterproductive. In the 'good old' days your fstab would always be pointing to devices (/dev/sdaX, etc). A lot of work has gone over the years into supporting persistent block device naming which has a different goal than what I was trying to achieve: to mount a unique piece of hardware in a given place. If you don't want this (and I didn't want that) you can always revert to an old style fstab. The result is getting the old (sometimes quirky) behaviour as well.

So why did I want this 'old' behaviour? Because I am mounting a backup memory card in a USB reader which should be identical to the main memory card and I should be able to swap them around at any time. I don't actually want the system to uniquely track one or the other card. Instead I want it to identify in which place (onboard or USB card reader) the card is and the easiest way to do that is by looking at the device name.

Original contents of my fstab:

LABEL=writable /    ext4   defaults    0 0
LABEL=system-boot       /boot/firmware  vfat    defaults        0       1

New contents:

/dev/mmcblk0p2  /       ext4    defaults    0 0
/dev/mmcblk0p1  /boot/firmware  vfat    defaults    0 1

The main card sits in /dev/mmcblk0, the backup card in /dev/sda. Similarly I needed to change cmdline.txt to indicate the correct root device (instead of label) to use.

@matthijskooijman So yes my experience is that Ubuntu uses labels.

matthijskooijman commented 2 years ago

@matthijskooijman I think you're quoting my comments but asking @ioogithub for input. Is that what you meant to do?

Yeah, because you changed your fstab I had assumed you no longer had the original contents, but well, assumptions are...

But interesting that they use labels, that seems quite fragile. What I would suggest to fix this, rather than using fixed device names, is to use PARTUUID (or UUID if you apply #140) and just rely on the rpi-clone code to ensure the PARTUUID is changed during the clone, and fstab and cmdline.txt is updated, since that's how this is designed to work (this probably also applies to @ioogithub's case).

I guess rpi-clone could be made to detect that labels are used for mounting and then ensure that labels are unique and updated in fstab/cmdline.txt, but I'm not sure if that's worth the extra complexity, really (I won't be implementing it in any case).

ioogithub commented 2 years ago

@ioogithub, could you maybe paste the /etc/fstab from your original Ubuntu installation here?

I can confirm that my original fstab matches what @mvdklip posted above. This is using the latest official Ubuntu image (arm64) for a Raspberry Pi 4.

@mvdklip, thank you for that description. This clarifies a lot. I have been experimenting with this over the past day and it appears that as long as /boot/firmware/cmdline.txt 'root=' matches the label for '/' is /etc/fstab my Pi will boot. This is probably obvious to everyone but I am just learning it now. So I have decided to take @matthijskooijman advice and use PARTUUID= for these two values but this is only a partial solution.

The rpi-clone switch --convert-fstab-to-partuuid does not work for me, either with the default value or any modified UUID values, I always get the error message:

Converting /etc/fstab from device names to PARTUUID
Could not find any mmcblk0 partition names in /etc/fstab, nothing changed.

So I manually changed my fstab to use PARTUUID like this:

PARTUUID=abcd1ab-02    /        ext4   discard,errors=remount-ro       0 1
PARTUUID=abcd1ab-01    /boot/firmware  vfat    defaults        0       1

and /boot/firmware/cmdline.txt:

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=abcd1ab-02 rootfstype=ext4 elevator=deadline rootwait fixrtc quiet splash

The problem I have now is that I do not have a way to use rpi-clone to keep this scheme. When I do an rpi-clone, the script will successfully update the fstab file with the new PARTUUID labels however it does not update cmdline.txt with PARTUUID of the / partition. As such it will not boot unless I manually update cmdline.txt manually after every clone. Interestingly, the original script will successfully copy the new PARTUUID to the cloned fstab as will #140 but neither will update cmdline.txt

@mvdklip, do you have an automated way to automatically update cmdline.txt after a clone because I suspect that for ubuntu since it was moved from /boot/cmdline.txt to /boot/firmware/cmdline.txt, rpi-clone just thinks it is a regular file and clones it as it is thus wiping out the change every time an incremental update happens and rendering the clone unbootable.

But interesting that they use labels, that seems quite fragile. What I would suggest to fix this, rather than using fixed device names, is to use PARTUUID (or UUID if you apply #140) and just rely on the rpi-clone code to ensure the PARTUUID is changed during the clone, and fstab and cmdline.txt is updated, since that's how this is designed to work (this probably also applies to @ioogithub's case).

From my reading of #140, this pull request will not fix my issue either because my cmdline.txt is in /boot/firmware/cmdline.txt while your PR updated /boot/armbianEnv.txt. Is this correct? Would it be possible to update #140 so that you update /boot/firmeware/cmdline.txt for Ubuntu as well? I would guess that you can probably use the same or similar code, isn't the file the same as the original but in a different location?

ioogithub commented 2 years ago

@matthijskooijman I don't think you need to change your PR. I was easily able to fix the problem by changing line 1733

from: cmdline_txt=${clone}/boot/cmdline.txt to cmdline_txt=${clone}/boot/firmware/cmdline.txt

The result is that rpi-clone successfully makes the change. Here is the end of operation status report:

Editing /mnt/clone/boot/firmware/cmdline.txt PARTUUID to use abcdef12
Editing /mnt/clone/etc/fstab PARTUUID to use abcdef12
===============================
Done with clone to /dev/sdb

I have tested several times and the clone boots when inserted into the primary slot, does not boot when attached to the pi as a USB device and is able to update incrementally without any further intervention.

I suspect this will work for Debian and Ubuntu users.

Thank you @mvdklip and @matthijskooijman for taking the time to explain your earlier posts.

matthijskooijman commented 2 years ago

The rpi-clone switch --convert-fstab-to-partuuid does not work for me, either with the default value or any modified UUID values, I always get the error message:

I assume this is because rpi-clone does not know about labels, so it only supports converting hardcoded device names to partuuid, not labels.

@matthijskooijman I don't think you need to change your PR. I was easily able to fix the problem by changing line 1733

Right, that seems to be completely unrelated to this PR, though. It might be better done in #140, because even though it is not entirely related to that PR either, it is similar to supporting armbian using a different filename (and the refactoring in there makes it easier). I'll push a commit to there in a minute, would be great if you could test it.

Edit: I complete misread "don't" in there, I thought you suggested to change this PR. Oh well, seems good to change the code to support this out of the box in any case, though I'm doubtful these PRs will ever be merged

mvdklip commented 2 years ago

I think this still leaves my original comments:

  1. Detect fstab using labels or uuids and issue a warning about rpi-clone only supporting device names and partuuids.
  2. Add support for converting labels or uuids to partuuids using the convert-fstab-to-partuuid option.

It's not obvious that rpi-clone doesn't support labels nor uuids and it would help if it would point that out by issuing a warning (point 1 above) and/or offer support for labels and/or uuids in the conversion script. But I guess I will have to make that myself if I'd really want that...

matthijskooijman commented 2 years ago

It's not obvious that rpi-clone doesn't support labels nor uuids and it would help if it would point that out by issuing a warning (point 1 above) and/or offer support for labels and/or uuids in the conversion script. But I guess I will have to make that myself if I'd really want that...

Yup. Maybe it's good to create a separate issue for that, at least?

ioogithub commented 2 years ago

Right, that seems to be completely unrelated to this PR, though. It might be better done in #140, because even though it is not entirely related to that PR either, it is similar to supporting armbian using a different filename (and the refactoring in there makes it easier). I'll push a commit to there in a minute, would be great if you could test it.

Edit: I complete misread "don't" in there, I thought you suggested to change this PR. Oh well, seems good to change the code to support this out of the box in any case, though I'm doubtful these PRs will ever be merged

Well I said don't because I was able to completely fix my issue by simple adding a few characters "/firmware/" to the code. I do not know (yet) how to share my fix with others who may benefit from it via PR other than discussing it here. I see that you added the change to #140. I will test it and let you know the results.

I agree that the changes may not get merged right away however the idea of having a warm swappable sd card clone ready is really interesting. SD Cards die often, even the high quality ones and perhaps even more so in a mini computer application which is constantly writing logs such as a pi or Orange Pi. rpi-clone is a really worthy project and elegant solution. If someone actively takes it over then the work we did will be worthwhile.