29

My /usr folder needs to get moved to a new partition. How can I do this without erasing the contents?

Can this be done while Ubuntu is running, or do I need to use the LiveCD for this?

jrg
  • 60,611
Nathan Osman
  • 32,155

5 Answers5

34

It would be safest to use a Live CD, but you could do:

  • copy all the files to a new partition, making sure that the contents of /usr do not change while you are doing this.
  • edit /etc/fstab so that /usr will be mounted on the next reboot
  • reboot
  • delete the old files

See below for details on each step.

Note that you can't mount the new partition on /usr while running as there will be lots of files in /usr that will be open.

Copying the files

I would use cp -a. -a is the archive option. From the man page:

-a, --archive
          same as -dR --preserve=all
...
-d     same as --no-dereference --preserve=links
...
-P, --no-dereference
          never follow symbolic links in SOURCE
...
--preserve[=ATTR_LIST]
          preserve      the      specified      attributes       (default:
          mode,ownership,timestamps),  if  possible additional attributes:
          context, links, xattr, all
...
-R, -r, --recursive
          copy directories recursively

Editing /etc/fstab

You need to know the UUID of your new partition. You can see the mapping by doing:

$ ls -l /dev/disk/by-uuid/

or

$ sudo blkid

And then add this line to /etc/fstab:

UUID=634c31a5-e27c-4e33-ac67-2e22491a30c2 /usr           ext4    defaults        0       2

Change the UUID to your UUID, and change ext4 to be the file system type you are using - you should know this if you have set up the partition.

Delete the old files

After the reboot, the old files in /usr on the root partition will be hidden by the new partition mounted on /usr. But we can use some mount bind trickery to get to the old files and then delete them.

$ sudo mount --bind / /mnt
$ sudo rm -rf /mnt/usr/*
$ sudo umount /mnt

But some slight mistyping (say, hitting Enter when you'd only typed sudo rm -rf /mnt ) could cause disaster, so I would only use this method if you were very confident in what you were doing, really couldn't deal with any downtime, or had no physical access to the machine and hence were unable to boot off a live CD or live USB stick.

Hamish Downer
  • 19,181
  • 6
    rsync is so much better suited for this than cp – Marco Ceppi Aug 02 '10 at 20:17
  • Could I use this guide to do the opposite. I mean move the /usr folder to root partition? – Nano May 01 '14 at 12:12
  • 1
    @MarcoCeppi Could you expand on that? Maybe give a variant answer that uses rsync instead? – Kazark Dec 31 '14 at 20:33
  • 7
    Replace cp command with rsync -avz. Rsync allows you to restart copies and should generally be used when moving between partitions, block devices, or machines. – Marco Ceppi Dec 31 '14 at 21:17
  • Also I left off the -f when I did sudo rm -r /mnt/usr as an extra safeguard against bad things. – Kazark Dec 31 '14 at 23:39
  • 4
    Do NOT use cp. It doesn't preserve HARD LINKS. This will break package upgrades in future. For example /usr/bin/s2p and /usr/bin/psed is the same file. Moving with cp will create 2 independent versions of that file. Do rsync -aH instead. – oᴉɹǝɥɔ Jun 04 '15 at 20:55
  • CAN SOMEONE POST A REAL EXAMPLE OF THIS? So many commands posted, but nobody isn't going into detail on how to do it, for example, how should a real case command look like? I've used rsync -avz, and it created "usr" folder on my new partition. Is that okay, or should contents of the folder be directly there, without the "usr" folder on the actual partition? – Aleksandar Stefanović Apr 03 '16 at 09:40
  • 1
    First of all, skip the -z flag - it enables compression, which given you're not sending the files over a network is useless overhead (except that rsync is usually smart enough to ignore it, but still, might as well drop it). @AleksandarStefanović you definitely want the contents there, not the folder, and the reason it's happened that way is due to some rsync quirks: it treats rsync -avH a/ b differently from rsync -avH a b, copying the contents of folder a (that is, a/*) in the first case and the folder itself in the second. Make sure you use the slash here. – Darael Apr 07 '16 at 09:09
  • I did exactly as you told above, but after I reboot I just can't get something right. My SD card are mounted on /usr thats all right. But I don't have wifi and powermanager and so on. I don't think it is because /etc/fstab since I exchange the / mounted and /usr mounted there is still the problem. Even when I don't mount just a ln -s, it also won't work. All I can do is to preserve the former /usr and mount sd to /usr manually after startup and that is annoying. Can you solve this? Thanks – a25bedc5-3d09-41b8-82fb-ea6c353d75ae Sep 10 '16 at 02:04
  • Is the '2' in the line added to /etc/fstab the partition #? I am wanting to move /home as well. I am wondering if it is '3' – Ron Piggott Jan 01 '17 at 07:08
  • @RonPiggott if you read the fstab man page you'll learn that : This field is used by fsck(8) to determine the order in which filesystem checks are done at boot time. The root filesystem should be specified with a fs_passno of 1. Other filesystems should have a fs_passno of 2. So stick with 2 for your home partition – Manumie Feb 27 '17 at 17:39
  • I can't delete original /usr folder, I deleted everything in it but rm -rf /mnt/usr gives me rm: cannot remove '/mnt/usr/': Device or resource busy, even after reboot :/ – Marecky Sep 01 '17 at 23:54
  • Any advice on how to do this using a live CD / USB stick? It might be obvious, but not to me. – Yair Daon Jun 19 '18 at 21:29
  • About the advice on not using cp - it appears that using cp -a does preserve hard links. I tend to use cp -ax just to be sure I'm limiting myself to the actual filesystem... – RoyM Dec 13 '19 at 15:15
  • It's better to use find follow by cpio, such as find . -depth -print0 | cpio --null -pvdm /usr_new/ because some partitions have block devices, binds, mounts, other kinda files. So with find you can manage what kinda files u will need to copy. Finally, do not forget to validate that previous to copy the files non of them are being used, this can be checked with lsof /usr/. – Manuel Lazo Jun 07 '23 at 05:29
8

Since most libraries that are used are in /usr, I would not recommend to move this directory while running Ubuntu. In fact, you probably get error messages when you try to do this. Hence, the best is to use the LiveCD.

You can use several possibilities to move/copy the files cp, rsync etc. you want to make sure that any symlinks are created and not just copied. cp and rsync both have options for this.

After moving the files to the other partition you need to add another mount in /etc/fstab to mount the new partition to /usr.

txwikinger
  • 28,462
2

This is how I've done it (following the Hamish's answer and the comments):

  1. Copy all the files the newly created partition (replace with the location of your partition, it should look similar to mine):

     rsync -avz /usr/* /media/aleksandar/750b84e2-e65f-4309-ade5-5af0033a937c 
    
  2. Edit /etc/fstab (same as in Hamish's answer, of course, replace xxxxxx with your UUID)

     UUID=xxxxxx/usr           ext4    defaults        0       2
    
  3. Reboot the system

  4. After rebooting, open System Monitor or similar application to see whether your new /usr partition is mounted, and to safety-check whether everything went as planned.

  5. After checking that everything is alright, you can delete your old /usr partition. I will keep mine just in case something goes wrong.

Cadoiz
  • 278
  • 4
    @cmks because I felt like other answers were incomplete - I didn't get complete solution from one answer, and none of the answers didn't have enough detail to them. I felt like users who would come to this question would need help. It doesn't matter if it's five years old if someone still needs the information from this question. – Aleksandar Stefanović Apr 08 '16 at 13:19
  • 1
    Why is everybody rebooting their system? Shouldn't a sudo mount -a allow it to keep on running? – Hagen von Eitzen Aug 06 '16 at 09:01
  • @Hagen I guess it's just for good measure – Aleksandar Stefanović Aug 06 '16 at 09:04
  • How can I to make step 7, if step 4 was skipped? mount --bind is the answer. – vp_arth Jul 10 '20 at 13:12
  • @vp_arth what he means is that he renamed it to /usrBACKUP while the system was still running, and then it crashed. So don't do that. Instead, just reboot the system normally. Don't worry about having two /usr folders, Linux will happily hide the old one and mount the new one in its place. (You can delete the hidden folder, but I'm not explaining that here.) – intrepidis Aug 22 '20 at 09:59
  • I end with moving /usr/local only. /usr binding is dangerous, because of /usr/sbin/init process location – vp_arth Aug 24 '20 at 05:57
  • It is needed to reboot vs. simply mounting in real time because there are files open in the usr directory. As per @Hamish said, If you do an fstab, then also mount without rebooting, the pointers to those files may be pointing to the wrong place. – Cool Javelin May 10 '21 at 17:28
0

I performed a migration of the /usr partition but I had some issues which I will be detailing in the following lines:

  • issues on /etc/fstab at the moment to mount by UUID (specially when u restart the OS), getting the error UUID specified does not exist.

Installation

Linux Distribution: Ubuntu 18 (x86_64)

The steps I performed were the following (/dev/vda will be my new disk):

  • Start the system in Recovery Mode or single user.
  • Validate that non of the files of /usr are being used:
lsof /usr
  • Create the new directory:
mkdir -p /usr_new
  • Create a pvs, vgs and lvs partitions:
pvcreate /dev/vda
vgcreate data_vg /dev/vda
lvcreate -l 100%FREE -n usr data_vg
  • Make a filesystem of the lv partition ( to identify the full path of the lv, execute lvdisplay) and mount the partition to the new directory /usr_new:
mkfs.ext4 /dev/data_vg/usr
mount -t ext4 /dev/data_vg/usr /usr_new
  • Move the content of the usr partition to the new one:
cd /usr
find . -depth -print0 | cpio --null -pvdm /usr_new/
  • Rename the old one and mount to the new one:
mv -v /usr /usr_old
umount /usr_new
mkdir /usr
mount -t ext4 /dev/data_vg/usr /usr
  • Make permanent changes on /etc/fstab file ( add the following line to the end of the file):
/dev/mapper/data_vg-usr /usr    ext4    defaults    0   0
  • Confirm that mounts are working as expected:
mount -a
  • Reboot the system:
init 6

Troubleshooting

In case you face incidents during the boot for mount incidents, take into consideration the following steps to fix / debug the issue:

  • From the grub options, type e and add the following text after the vmlinuz arguments:

enter image description here

  • Press control + x, and boot from the edited option (the first one most probably)

  • If you are addressed to the initramfs terminal, type the following:

initramfs > chroot /root
  • You will be moved on to your root system partition, from there try to check the content of the /etc/fstab and made the required changes, or return the system like it was before.
$ exit
initramfs > reboot
0

I needed to move /usr folder from the root partition to a new one, because the disk was full. It was a sort of "temporary" system, so it was ok for me to use an available 16 gig stick, the only thing I could spare at the moment. I recall here the steps I followed, if they are of any help for anyone.

make a new GPT, new ext4 (g, n & w options) on the stick. For me it was on sdd, please be carefull, find which is yours

sudo fdisk -l /dev/sdd

make filesystem

sudo mkfs.ext4 /dev/sdd1

mount somewhere the stick

sudo mkdir /mnt/16G
sudo mount /dev/sdd1 /mnt/16G

copy everything to the stick (-a=keep permissions, -h=human readable) (instead of "cp -r /usr /mnt/16G" use rsync)

rsync -ah --progress /usr /mnt/16G

find the UUID of the stick

sudo blkid

put it in fstab

sudo nano /etc/fstab
    UUID=40xxxx3f-exx8-4xx3-9xxx-xx055xx34xx5 /usr          ext4    defaults        0       2

poweroff

sudo poweroff

boot with a LiveUsb ubuntu and rename original /usr to something else, like /usr1

create a new empty folder on the root partition and name it "usr", for the stick to be mounted on, as stated in fstab. Otherwise you will get a nice initramfs on next boot (sorry, I haven't tested Hamish Downer's advise for [$ sudo mount --bind / /mnt] [$ sudo rm -rf /mnt/usr/*] [$ sudo umount /mnt])

reboot to the normal installation

Hope I didn't forget or messed up anything!

Edit: You can now remove /mnt/16G and IF everything is nice 'n' smooth, delete the /usr1 to regain the space!

jimmyz
  • 31