GuestbookSign our guestbook ContactGet in touch with the authors ArchiveAll unixwerk articles since 2003
August 5, 2008

Slackware 12.1 on LVM - Installation and Migration

Slackware 12.1 is the first Slackware release that can be installed on LVM, i.e. the Slackware Installer now supports Logical Volumes as Installation targets. Part I of this article describes how to install Slackware 12.1 on LVM while part II shows how to migrate an existing installation to LVM.

There are older articles available on unixwerk about Slackware and LVM. But in those articles we still had the root (/) directory outside LVM. This avoided the use of an initial ramdisk. In this article, however, we learn how to install Slackware on LVM including the root (/) directory. This is the standard setup for all other main distributions.

Contents

Part I: Installation

  1. Boot from Installation CD/DVD
  2. Partition your Harddrive
  3. Prepare LVM
  4. Start Installation
  5. Create an initrd Image

Part II: Migration

  1. Boot from Rescue CD
  2. Backup
  3. Repartition your Harddrive
  4. Prepare LVM
  5. Restore
  6. Create an initrd Image
  7. Change /etc/fstab

What bugs me

 

Part I: Installation

In the first part of this small course we install Slackware from scratch on LVM.  

1. Boot from Installation CD/DVD

We insert the Slackware Installation CD or DVD in our optical drive and boot up...  

2. Partition your Harddrive

Once we see the login prompt we login as root and prepare one or more partitons for usage with LVM. This is how it looks on my harddrive:

    Device Boot      Start         End      Blocks   Id  System
 /dev/sda1   *           1        1034     8305573+  a5  FreeBSD
 /dev/sda2            1035        1302     2152710   82  Linux swap
 /dev/sda3            1303        1337      281137+  83  Linux
 /dev/sda4            1338       19457   145548900    5  Extended
 /dev/sda5            1338        2554     9775521   8e  Linux LVM
 /dev/sda6            2555       19457   135773284   8e  Linux LVM

Two partitions are needed for this scenario: a small partition of type 83 (Linux) for /boot and a big one of type 8e for LVM. The rest in the above picture is optional. You might or might not put the swap partition on its own partition - you could also prepare an LV for it, you might or might not create two partitions for LVM (one for the system, one for data); and a partiton for FreeBSD is obviously not needed ;-)  

3. Prepare LVM

As always, all partitions have to be created before starting Slackware's installation routine setup. In order to install on LVM we need to prepare all LVs in forehand. To create two Volume Groups we first need two Physical Volumes:

 # pvcreate /dev/sda5
   Physical volume "/dev/sda5" successfully created
 # pvcreate /dev/sda6
   Physical volume "/dev/sda6" successfully created
 # vgcreate sysvg /dev/sda5
   Volume group "sysvg" successfully created
 # vgcreate datavg /dev/sda6
   Volume group "datavg" successfully created

Btw: You are totally free with the names of the VGs! They have no meaning for Linux or any system tool.

Now we can continue creating Logical Volumes. We create 6 LVs in the sysvg. This is an example, you might prefer a different setup, e.g. an extra LV for /tmp, /home in the datavg and no extra LV for the Linux kernel sources. That's all fine, the below example is just what I did. For the moment we concentrate on the sysvg and leave the datavg empty.

 # lvcreate -L 400M -n root sysvg
   Logical volume "root" created
 # lvcreate -L 100M -n var sysvg
   Logical volume "var" created
 # lvcreate -L 4500M -n usr sysvg
   Logical volume "usr" created
 # lvcreate -L 900M -n src sysvg
   Logical volume "src" created
 # lvcreate -L 150M -n home sysvg
   Logical volume "home" created
 # lvcreate -L 1000M -n opt sysvg
   Logical volume "opt" created
 

4. Start Installation

Now we are ready to start the installation procedure:

 # setup

We just walk through the menus as usual, selecting /dev/sysvg/root for the root directory /. Further we select

This is straight forward and does not differ from the normal procedure. setup will format these partitions as ext3, xfs, or whatever we prefer.

One small note: If you put swap on an LV rather than on its own harddrive partition, setup will not find it. You have to add it manually to /etc/fstab lateron.  

5. Create an initrd Image

In order to create the initrd image we chroot to our Slackware installation, run mkinitrd...

 # chroot /mnt
 # mkinitrd -c -m ext3 -f ext3 -k 2.6.24.5-smp -r /dev/sysvg/root -L -o /boot/initrd-2.6.24.5-smp.gz

.. check the image section of our lilo.conf:

 # Linux bootable partition config begins
 image = /boot/vmlinuz-generic-smp-2.6.24.5-smp
   initrd=/boot/initrd-2.6.24.5-smp.gz
   #root = /dev/sda5
   label = Linux
   read-only  # Partitions should be mounted read-only for checking
 # Linux bootable partition config ends

and run lilo.

 # lilo
 Added Linux *

Note: We might just use the provided image /boot/initrd.gz instead of creating our own. However, I haven't tested the default image.


 

Part II: Migration

Now that we know how to deal with Linux and LVM it might be interesting to migrate an existing installation to LVM. The following section provides a path for migration. This is much more work than just fresh installing on LVM!

This procedure might also be used with other Linux distributions (possibly with small changes).  

1. Boot from Rescue CD

We insert the first Slackware CD (or another Rescue CD) in our optical drive and boot up. We login as root.  

2. Backup

Assuming we have one big filesystem for / (this is what Patrick recommends), we have to free it up in order to migrate to LVM. The easiest way is to connnect a USB drive to our computer and copy all data over. Therefore we mount the external disk under /backup and our Linux partiton to /mnt (we can also cascade if we have more than one partition for Slackware), e.g.:

 # mkdir /backup
 # mount /dev/sda1 /backup   # our USB disk
 # mount /dev/hda6 /mnt      # our root
 # mount /dev/hda7 /mnt/usr  # if we have an extra partition for /usr

 # cd /mnt
 # /mnt/bin/tar cpBf - . | ( cd /backup && /mnt/bin/tar xvpBf - )

We could also backup to a tape or to a file, e.g.

 # cd /mnt
 # /mnt/bin/tar cvpzf /backup/linux.tar.gz .
 

3. Repartition your Harddrive

Once our data are saved, we can remove our old Linux partition(s) and create one or more partitons for usage with LVM:

 # fdisk /dev/hda

This is how it could look:

    Device Boot      Start         End      Blocks   Id  System
 /dev/hda1               1        1459    11719386    7  HPFS/NTFS
 /dev/hda2   *        1460        1829     2972025   a5  FreeBSD
 /dev/hda4            1830        9729    63456750    5  Extended
 /dev/hda5            1830        2764     7510356    b  W95 FAT32
 /dev/hda6            2765        2811      377496   82  Linux Swap
 /dev/hda7            2812        2858      377496   83  Linux
 /dev/hda8            2859        5629    22249836   8e  Linux LVM
 /dev/hda9            5630        9729    32941251   8e  Linux LVM

In the above example we have one logical partiton for swap, one for /boot, and two for LVM.  

4. Prepare LVM

We will create two Volume Groups, sysvg for the system, and datavg for data:

 # pvcreate /dev/hda8
   Physical volume "/dev/hda8" successfully created
 # pvcreate /dev/hda9
   Physical volume "/dev/hda9" successfully created
 # vgcreate sysvg /dev/hda8
   Volume group "sysvg" successfully created
 # vgcreate datavg /dev/hda9
   Volume group "datavg" successfully created

In the sysvg we create the same 6 Logical Volumes as seen in part I:

 # lvcreate -L 400M -n root sysvg
   Logical volume "root" created
 # lvcreate -L 100M -n var sysvg
   Logical volume "var" created
 # lvcreate -L 4500M -n usr sysvg
   Logical volume "usr" created
 # lvcreate -L 900M -n src sysvg
   Logical volume "src" created
 # lvcreate -L 150M -n home sysvg
   Logical volume "home" created
 # lvcreate -L 1000M -n opt sysvg
   Logical volume "opt" created

We also create some LVs in the datavg, e.g.

 # lvcreate -L 3500M -n myhome datavg
   Logical volume "myhome" created
 # lvcreate -L 8000M -n data datavg
   Logical volume "data" created
 # lvcreate -L 2000M -n scratch datavg
   Logical volume "scratch" created

Now we need to format all LVs. Let's use ext3 for the system and xfs for data. That's how I would do it:

 # mke2fs /dev/sysvg/root
 # mke2fs /dev/sysvg/var
 # mke2fs /dev/sysvg/usr
 # mke2fs -i 8192 /dev/sysvg/src
 # mke2fs /dev/sysvg/home
 # mke2fs /dev/sysvg/opt

Since on the Rescue CD we don't find a program called mkfs.ext3 we add the ext3-journal with tune2fs, along with some other settings:

 # tune2fs -j -m 1 -c 200 -i 365d /dev/sysvg/root
 # tune2fs -j -m 1 -c 200 -i 365d /dev/sysvg/var
 # tune2fs -j -m 0 -c 200 -i 365d /dev/sysvg/usr
 # tune2fs -j -m 0 -c 200 -i 365d /dev/sysvg/src
 # tune2fs -j -m 0 -c 200 -i 365d /dev/sysvg/home
 # tune2fs -j -m 0 -c 200 -i 365d /dev/sysvg/opt

And the datavg

 # mkfs.xfs /dev/datavg/myhome
 # mkfs.xfs /dev/datavg/data
 # mkfs.xfs /dev/datavg/scratch

Our LVs are prepared, we can populate it with our backup'd data:  

5. Restore

Before we can proceed we need to mount our filesystem cascade:

 # mkdir /new_root
 # mount /dev/sysvg/root /new_root
 # cd /new_root
 # mkdir boot var usr home opt data scratch
 # mount /dev/sysvg/var /new_root/var
 # mount /dev/sysvg/usr /new_root/usr
 # mkdir /new_root/usr/src
 # mount /dev/sysvg/src /new_root/usr/src
 # mount /dev/sysvg/opt /new_root/opt
 # mount /dev/sysvg/home /new_root/home
 # mkdir /new_root/home/myhome
 # mount /dev/datavg/myhome /new_root/home/myhome
 # mount /dev/datavg/scratch /new_root/scratch
 # mount /dev/datavg/data /new_root/data
 

Now we are ready to restore our backup'd data to the newly created LVs. Assuming that our data on another disk partition (e.g. an external USB disk) are still mounted under /backup this can be done as shown below:

 # cd /backup
 # /backup/bin/tar cpBf - . | ( cd /new_root && /backup/bin/tar xvpBf - )

Please note, we use the tar executable on our Slackware installation rather than the one provided by the rescue disk. There is probably nothing wrong with the tar provided by busybox on the rescue CD, but I trust GNU's tar more regarding preservation of owner settings and permissions. And you have to use the CD's tar anyway in case you used a file or a tape for backup (see above). Use then a line like this: cd /new_root && tar xvzf /backup/linux.tar.gz  

6. Create an initrd Image

In order to create the initrd image we chroot to our Slackware installation, run mkinitrd....

 # chroot /new_root
 # mkinitrd -c -f ext3 -k 2.6.26-smp -r /dev/sysvg/root -L -o /boot/initrd-2.6.26-smp.gz

.. change the image section of our lilo.conf:

 # Linux bootable partition config begins
 image = /boot/vmlinuz-2.6.26-smp
   initrd=/boot/initrd-2.6.26-smp.gz
   #root = /dev/sda5
   label = Linux
   read-only  # Partitions should be mounted read-only for checking
 # Linux bootable partition config ends

and run lilo.

 # lilo
 Added Linux *

Warning: Check the kernel version of your installation, it very likely differs from the one used by the rescue CD! The kernel version is used by mkinitrd (-k <kernel-version>) to find the matching modules under /lib/modules/<kernel-version>  

7. Change /etc/fstab

It is important to adapt /etc/fstab now to the new situation, otherwise things go haywire after reboot. These are the important lines, based on our example setup:

 /dev/hda6            swap            swap    defaults                 0  0
 /dev/sysvg/root      /               ext3    defaults                 1  1
 /dev/tmp             /tmp            tmpfs   size=256M,nr_inodes=32k  0  0
 /dev/sysvg/var       /var            ext3    defaults                 1  1
 /dev/sysvg/usr       /usr            ext3    defaults                 1  1
 /dev/sysvg/src       /usr/src        ext3    defaults                 1  1
 /dev/sysvg/opt       /opt            ext3    defaults                 1  1
 /dev/sysvg/home      /home           ext3    defaults                 1  2
 /dev/datavg/myhome   /home/myhome    xfs     defaults                 1  2
 /dev/datavg/scratch  /scratch        xfs     defaults                 1  2
 /dev/datavg/data     /data           xfs     defaults                 1  2
 /dev/hda7            /boot           ext3    defaults                 1  1
 devpts               /dev/pts        devpts  gid=5,mode=620           0  0
 proc                 /proc           proc    defaults                 0  0
 tmpfs                /dev/shm        tmpfs   defaults                 0  0

Now we leave the chroot environment, unmount all filesystems and reboot from harddrive.  

What bugs me

After reboot one of the first commands to issue of course is df. And the output was a small surprise for me:

 root@slack# df -m
 Filesystem           1M-blocks      Used Available Use% Mounted on
 /dev/mapper/sysvg-root
                            388       177       207  47% /
 /dev/tmp                   256         1       255   1% /tmp
 /dev/mapper/sysvg-var
                             97        43        54  45% /var
 /dev/mapper/sysvg-usr
                           4430      4071       359  92% /usr
 /dev/mapper/sysvg-src
                            886       654       233  74% /usr/src
 /dev/mapper/sysvg-opt
                            985       267       718  28% /opt
 /dev/mapper/sysvg-home
                            148         8       140   5% /home
 /dev/mapper/datavg-myhome
                          24988      3522     21467  15% /home/myhome
 /dev/mapper/datavg-scratch
                           2538        24      2515   1% /scratch
 /dev/mapper/datavg-data
                          11254      9417      1838  84% /data
 /dev/hda7                  266        29       238  11% /boot
 tmpfs                      512         0       384   0% /dev/shm

With LVM 2 the device files /dev/<VolumeGroup>/<LogivalVolume> are symlinks to the devices under /dev/mapper, resulting in very long device names that are exceeding the field length in df, the result can be seen above, what I find hard to read and hard to handle in scripting.

I wrote a small wrapper script around df to get the old (LVM1) situation back: *dfwrapper.

If you put something like

 alias df=/usr/local/bin/dfwrapper

to your local profile, the output will be like this:

 root@slack# df -m
 Filesystem           1M-blocks      Used Available Use% Mounted on
 /dev/sysvg/root            387       176       206  47% /
 /dev/tmp                   256         0       255   1% /tmp
 /dev/sysvg/var              96        42        53  45% /var
 /dev/sysvg/usr            4429      4070       358  92% /usr
 /dev/sysvg/src             885       653       232  74% /usr/src
 /dev/sysvg/opt             984       266       717  28% /opt
 /dev/sysvg/home            147         7       139   5% /home
 /dev/datavg/myhome       24987      3521     21466  15% /home/myhome
 /dev/datavg/scratch       2538        23      2514   1% /scratch
 /dev/datavg/data         11254      9416      1837  84% /data
 /dev/sda3                  265        28       237  11% /boot
 tmpfs                      512         0       512   0% /dev/shm