Sunday, 17 April 2011

Set UUID on reiserfs partitions (fun with bash)

spanish version - all english posts

I've just realized that the reiserfs partitions of an old PC are not associated with their corresponding UUID in /etc/fstab. I usually use UUIDs in fstab to avoid problems when adding/removing disks.

This particular PC has several partitions with reiserfs filesystem. Many years ago I preferentially used reiserfs instead of ext2 for obvious reasons. With the advent of ext3 I stopped using the reiser filesystem on new installations. But my old PCs remained with reiserfs. That happened (and remained) over the time with non-system partitions (home, chroot, etc...)

Out of curiosity I've tried to find out how old these partitions are, but I have not been able (perhaps a seasoned forensic guru can help me ... debugreiserfs does not show this information). The oldest files I can see have access dates of 2004 but I'm sure the partitions are much older .... enough rambling!

Turning back to the UUID issue. The reiser partitions are not associated with a corresponding UUID:

root@oldandbeloveddesktop:~# debugreiserfs /dev/sda7 | grep UUID
debugreiserfs 3.6.21 (2009 www.namesys.com)

UUID: 00000000-0000-0000-0000-000000000000
root@oldandbeloveddesktop:~# blkid /dev/sda7
/dev/sda7: TYPE="reiserfs"

So we'll have to generate the UUIDs and assign them to their corresponding reiserfs partitions.

The fun part: We will do it in a single command:

root@oldandbeloveddesktop:~# mount -t reiserfs | while read part; do umount ${part%% *}; reiserfstune --uuid $(uuidgen -r) ${part%% *}; mount ${part%% *} ; done

That's it, we have assigned an UUID to each reiserfs partition. We can verify it using blkid:

root@oldandbeloveddesktop:~# blkid | grep reiserfs
/dev/sda7: TYPE="reiserfs" UUID="3cfa0f14-c35b-49fc-82a8-ff3e6e225af8"
/dev/sda10: TYPE="reiserfs" UUID="76255e20-92b1-4352-a604-6b371eb5ace0"
/dev/sda11: TYPE="reiserfs" UUID="06c74789-d403-408a-898f-b8e8880d3d3a"

We can now edit their corresponding fstab entries. It's the turn for sed and some more fun. Just run:

root@oldandbeloveddesktop:/etc# for part in $(mount -t reiserfs); do sed -i "/^\/dev.*reiser/ s@^${part%% }@#original ${part%% }\n$(blkid ${part%% }|awk '{print $NF}') @" /etc/fstab; done
root@oldandbeloveddesktop:/etc# mount -a -o remount

And that's all folks!

As this post is getting very short, lets fill it with a step by step explanation of the process.

The first command that helped us to assign a UUID to each partition reiserfs is summarized in the following steps.

  1. using "mount -t reiserfs" we get the list of the reiserfs partitions in use.

  2. the output will be passed to "bash's while" which will iterate each line of output assinging each outputed line to the "part" variable.

  3. Using bash parameter expansion we take only the partition device, which graphically can be reperesented as:

    root@oldandbeloveddesktop:~# part="/dev/sda7 /home reiserfs defaults 0 2"
    root@oldandbeloveddesktop:~# echo ${part%% *}
  4. for each partition:

    4.1) unmount the partition with "umount"

    4.2) generate a random uuid with uuidgen:

    uuidgen -r

    4.3) and assign it to the partition using reiserfstune command.

    4.4) remount the partition.

The second command, which edits "/etc/fstab" entries replacing each /dev/sdXY string with its corresponding UUID, is detailed in the following steps:

  1. as the first command we use "mount -t reiserfs" to get the list of reiserfs partitions (mounted) in the system.

  2. as before, we pass each line from the output to ''$part'' using bash's "while". Remember that ''${part%% *}'' will correspond to each of the partitions in the format '/dev/sdXY'.

  3. For each reiserfs partition we execute sed infile editin the /etc/fstab file. The sed command can be divided into:

    3.1) a first part where you select only the lines of the reiserfs partitions. Those with the format:


    3.2) on the previous selection sed will just edit the field "/dev/sdXY". 3.3) and sed will replace it with two lines: a comment header (just to remember which was the original partition's name), and the corresponding fstab's entry with the UUID.

    3.3.1) I get the UUID value with "blkid" keeping just the UUID value, which corresponds to the last field in the output if we divide it into spaces (awk NF). For example if you originally had lines with the format:

        /dev/sda10 /chroot reiserfs defaults 0 2
    they will be replaced with::
        #original /dev/sda10
        UUID="76255e20-92b1-4352-a604-6b371eb5ace0"  /chroot reiserfs defaults 0 2

Well, that's all. The objective has been achieved: We have assigned a UUID for each of the reiserfs partitions, and we have had some fun time playing with the shell.