Resizing

A single disk system usually has two or more partitions on its only disk (at the very least, a swap partition and a system partition). Expanding the storage capacity of the video storage partition (or the system partition, if the videos are stored along with the system files on the system partition) is basically like expanding a single partition volume except that there are a couple of extra steps before you get started, and you must do the appropriate type of copy for each partition, not just a single partition.

The extra steps are necessitated by the fact that the single disk system must have a bootable disk and the system also needs some swap space on the disk.

To illustrate the complete steps necessary to expand a single disk system, let's take the example of a system that has three partitions, one for /boot, one for swap space, and one for root. Furthermore, let's assume that the /boot partition is formatted using ext3 and the root partition is formatted using XFS (as is the case with many of the latest Linux installs).

As we note in the previous section, the duration of the copy operation that is used to expand a volume depends on the amount of data on it (duh) so you may wish to clean up all of the old stuff that you were thinking of deleting, before you proceed. On the other hand, if you could do that, you probably wouldn't need a bigger disk in the first place....

Again, we begin by getting ourselves a copy of Knoppix (the CD works just swell but later versions will only fit on a DVD):

     http://knopper.net/knoppix/index-en.html

And burning the ISO image onto a CD (or DVD, if you took that route).

Next, configure the single disk machine who's disk is to be expanded with the old disk and new disk attached and a CD/DVD drive added, if necessary. In this example, we're presuming the original drive is on SATA0 and the new drive is on SATA1, which should map to /dev/sda and /dev/sdb respectively, when Knoppix is booted.

Put the Knoppix CD/DVD into the CD/DVD drive and boot it. Once Knoppix comes up (you're booting from a CD/DVD, remember, so be patient), open up a console window and become super user. To do this, simply type the "su" command. There's no password (how refreshing).

Before proceeding, you should check that the original and new drives are installed where you expect them to be. You can do this by typing:

     /sbin/fdisk -lu /dev/sda
     /sbin/fdisk -lu /dev/sdb

The first drive should show a valid partition table that looks something like this:

     Disk /dev/sda: 640.1 GB, 640135028736 bytes
     255 heads, 63 sectors/track, 77825 cylinders, total 1250263728 sectors
     Units = sectors of 1 * 512 = 512 bytes
     Disk identifier: 0x63c6c105
     Device Boot      Start         End      Blocks   Id  System
  /dev/sda1   *          63      996029      497983+  83  Linux
  /dev/sda2          996030     4996214     2000092+  82  Linux swap / Solaris
  /dev/sda3         4996215  1250263728   622633756   83  Linux

Be sure that the original drive's size and partition information is correct to ensure that it is mounted where you think it is. Also verify that the new drive has nothing on it (or has the expected layout, if you're reusing it). Since, we're going to be wiping out all data on the new drive in a minute, it pays to make sure you've got the right target in your sights.

You can also check the various partitions to see what type of file systems are on each of them. In our example, we'd do:

     df -T /dev/sda1
     df -T /dev/sda3

We're expecting to see an ext3 file system on /dev/sda1 and an XFS file system on /dev/sda3.

If everything looks good, you can avoid all the trouble of setting up the boot sector with the boot loader by just copying the first few tracks of the source disk directly with dd:

     dd bs=512 count=63 if=/dev/hdc of=/dev/hdb

This will also copy the partition table which probably won't be correct. However, since we are expanding the disk size, usually the only required change to the copied partition table is that the last partition be expanded to fit the new disk. This can be done by deleting the last partition and adding a new partition that uses all of the available space:

     su
     /sbin/fdisk /dev/sdb
       d                         (Delete a partition)
       3                         (Partition 3)
       n                         (To create a new partition)
       p                         (As a primary partition)
       3                         (Partition 3)
       <cr>                      (Accept previous end cylinder + 1 as the start)
       <cr>                      (To accept the last cylinder as the end)
       w                         (Write the partition table to the disk)

Be sure that the appropriate partition is marked as the boot partition, if it hasn't already been marked that way.

Alternately, if you want or need to create the partition table from scratch, you should do so using fdisk like this:

     su
     /sbin/fdisk /dev/sdb
       n                         (To create a new partition)
       p                         (As a primary partition)
       1                         (Partition 1)
       <cr>                      (To accept the first cylinder as the start)
       62                        (To set cylinder 62 as the end)
       n                         (To create a new partition)
       p                         (As a primary partition)
       2                         (Partition 2)
       <cr>                      (Accept previous end cylinder + 1 as the start)
       311                       (To set cylinder 311 as the end)
       n                         (To create a new partition)
       p                         (As a primary partition)
       3                         (Partition 3)
       <cr>                      (Accept previous end cylinder + 1 as the start)
       <cr>                      (To accept the last cylinder as the end)
       t                         (To set the partition type)
       2                         (Partition 2)
       82                        (Partition type 82, swap space)
       w                         (Write the partition table to the disk)

On most older disks (i.e. less than or equal to 1TB), this creates a new partition layout that has approximately 500MB for the boot partition, 2GB for swap space, and the remaining disk space for the root partition. This layout has proven to work well during years of constant use.

After you've created the new partitions, you can check your work with:

     /sbin/fdisk -lu /dev/sdb

You should see something like this:

     Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes
     255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sectors
     Units = sectors of 1 * 512 = 512 bytes
     Disk identifier: 0x0002c738
     Device Boot      Start         End      Blocks   Id  System
  /dev/sdb1   *          63      996029      497983+  83  Linux
  /dev/sdb2          996030     4996214     2000092+  82  Linux swap / Solaris
  /dev/sdb3         4996215  1953520064   974261925   83  Linux

Unfortunately, for the advanced format hard drives (e.g. 1.5, 2 TB, or higher drives), one can no longer continue in the same old manner, as described above. If the partitions on the drive are not laid out properly and/or the file systems not constructed carefully, you will suffer from huge performance problems. This all but mandates that you lay the partitions out by hand, set the boot loader up manually, set the file systems up ahead of time, and copy all of the files manually. No use of dd or another direct partition copy program to speed up the process.

Note that, with the later versions of Knoppix that we have used (i.e. 7.2), fdisk knows about advanced format hard drives and handles alignment of the partitions on the proper boundaries, if you let it. It should start the first partition on sector 2048 and, if you use end sector numbers like +512M or +4G, calculate the proper end sectors so that the next partition will always begin on the proper boundary. Of course, once the disk is set up for advanced format use, the next time you do an upgrade (e.g. from the 2TB to 4TB disk), you can revert to the good old techniques but, in the meantime, begin by creating the partition table as follows:

     su
     /sbin/fdisk /dev/sdb
       u                         (All sizes are given in sectors, not
                                   cylinders)
       n                         (To create a new partition)
       p                         (As a primary partition)
       1                         (Partition 1)
       2048                      (Start the partition on a 4K boundary [i.e.
                                   0 mod 8])
       +512M                     (To define a 512 MB partition)
       n                         (To create a new partition)
       p                         (As a primary partition)
       2                         (Partition 2)
       <cr>                      (To accept the next block as the start)
       +2G                       (To define a 2 GB partition [or use +4G])
       t                         (To set the partition type)
       2                         (Partition 2)
       82                        (Partition type 82, swap space)
       n                         (To create a new partition)
       p                         (As a primary partition)
       3                         (Partition 3)
       <cr>                      (To accept the next block as the start)
       <cr>                      (To accept the last cylinder as the end)
       w                         (Write the partition table to the disk)

This creates a new partition layout that has approximately 500MB for the boot partition, 2GB for swap space, and the remaining disk space for the root partition. Just by way of example, if you were interested in upping the swap space to 4GB from 2GB, you might use +4G instead of +2G for the second partition.

After you've created the new partitions, you can check your work with:

     /sbin/fdisk -lu /dev/sdb

You should see something like this (in this example, we used +4G for the swap space):

     Disk /dev/sdb: 2000.0 GB, 1999988850688 bytes
     255 heads, 63 sectors/track, 243151 cylinders, total 3906228224 sectors
     Units = sectors of 1 * 512 = 512 bytes
     Sector size (logical/physical): 512 bytes / 4096 bytes
     I/O size (minimum/optimal): 512 bytes / 4096 bytes
     Disk identifier: 0x0000144d
     Device Boot      Start         End      Blocks   Id  System
  /dev/sdb1   *        2048     1050623      524288   83  Linux
  /dev/sdb2         1050624     9439231     4194304   82  Linux swap / Solaris
  /dev/sdb3         9439232  3906228223  1948394496   83  Linux

If you laid out the partition table using sector numbers instead of cylinders, you'll probably see some whining from fdisk about the partitions not starting on a cylinder boundary. Since all of the cylinder/sector numbers have been fake for many years, and since all sector addressing is done using LBAs, it doesn't much matter where the partitions start/end, as long as they all start on a sector whose address is 0 mod 8. You can safely ignore the warnings from fdisk about cylinder alignment.

However, if you care (which you probably don't), you can carefully chose all of the partitions to end on a sector boundary that is a multiple of the magic number 128520, minus 1. This number of sectors gives a chunk that is 64MB in size, which is the lowest number that is 0 mod 8 and also 0 mod 16065 (16065 is the result of multiplying 255 x 63, which are the values used for the number of heads and sectors on all LBA-addressed disks). Using a multiple of 128520, and then subtracting one, for all of your partition calculations, will ensure that they all end on a virtual cylinder boundary and fdisk will be happy. Mind you, you will have to calculate actual sector numbers instead of using offsets like "+2G", which tedious in the extreme. Best to just forget about this "feature" and move on with your life.

Once all of the partitions have been created, you must install the boot loader (most versions of Linux use GRUB or GRUB2) on the disk. As above, you can avoid the trouble of setting up the boot sector with the boot loader by just copying the first few tracks of the source disk directly with dd. However, since we've already set up the partition table, we must do the copy very carefully to avoid wiping it out:

     dd bs=446 count=1 if=/dev/sda of=/dev/sdb
     dd bs=2 skip=255 seek=255 count=1 if=/dev/sda of=/dev/sdb
     dd bs=512 skip=1 seek=1 count=62 if=/dev/sda of=/dev/sdb

This copies the first 446 bytes of the first sector (a.k.a. the MBR), which contains the boot loader code. It skips over the next 64 bytes, which contain the partition table. Then, it copies the two-byte magic cookie that defines it as the MBR. Finally, it copies the next 62 sectors (a.k.a. the DOS Compat Space), which contain the GRUB Stage 1.5 code. Once that is done, you should have a bootable disk that is partitioned the way you want it.

You might want to test that the system can boot the disk (admittedly, it won't get far but you should at least see GRUB Stage 1.5 running), before you proceed any further, because now is the time to redo the partition table and go with Plan B, if it didn't work, before you copy any data to the new disk.

Plan B is used if you are using GNU Partition Table (i.e. you set the disk up with parted), dd wiped out the partition table, or GRUB wouldn't boot into Stage 1.5. Plan B consists of installing GRUB from scratch, which is best done using the original OS installation disk, in rescue mode. To use Plan B, you must first copy the files to the /boot partition, as outlined below.

#>>>>>>
All of the ext2/ext3 file systems, that must appear in each of the partitions, should be made with mkfs. Similarly, swap space must be initialized with mkswap. However, the XFS file systems need not be created ahead of time as the copy operation will take care of that for us. Here's an example of how we'd set up one ext2 or ext3 file system and one swap space, first, using mkfs.ext2:

     mkfs.ext2 -L /boot -T news /dev/sdb1
     mkswap -v1 /dev/sdb2

or mkfs.ext3:

     mkfs.ext3 -j -L /boot -T news /dev/sdb1
     mkswap -v1 /dev/sdb2

Once you've done this, copy any files needed for the OS boot sequence to the boot partition. Knoppix thoughtfully provides predefined mount points in the "/media" directory for each of the attached devices that it finds (and even adds mount points for any new partitions created using fdisk) so you can do:

     mount -r /dev/sda1 /media/sda1
     mount /dev/sdb1 /media/sdb1
     cp -R --preserve=all /media/sda1/* /media/sdb1
     umount /media/sda1
     umount /media/sdb1

Now is the time, if you are going with GRUB Plan B, to set up the boot loader (as noted above, if you set up the boot sector using one of the dd methods, you can omit this step). There are so many ways of doing this that it is beyond the scope of these notes. Hopefully, you won't have to do it this way but, if you do, there are plenty of notes on the Internet that give the details. Find them and read them first. Just to make sure that you do it correctly, the basic steps should look something like this:

  1. Boot with your system's Installation CD and get into rescue mode.
  2. If you are asked if you want to look for an existing Linux installation, you can skip this step. This will get you to the console prompt a lot quicker.
  3. Once the console prompt appears, type "grub".
  4. Set GRUB's root device to the partition containing the boot directory by typing "root (hd1,0)". In our case, this would be /dev/sdb1. But, you may not want to live dangerously and trust that GRUB (which uses a truly strange numbering scheme for boot devices) will pick the right device to whack. In that case, you could uncable your original disk and leave only the new disk cabled. Then, you'd set GRUB's root device using "root (hd0,0)".
  5. Write GRUB to the hard drive with "setup (hd1)" or "setup (hd0)".
  6. Bail out by typing "quit".

Note that you may be able to do all of this with Knoppix and skip the rescue disk, depending on how compatible your system is with the Knoppix version of GRUB.

The data on the original XFS partition should now be copied to the new drive. This is done with:

     xfs_copy -d /dev/sda3 /dev/sdb3

The copy will take quite a while, depending on the size of the original partition and how full it is (if you were smart and deleted all of the junk shows off the original partition, it will be faster). Once the copy completes, the new disk will contain an exact copy of the original disk and the new XFS file system will be same size as the original (bummer).

The next step requires that you mount the new file system, using the mount points that Knoppix provides in the "/media" directory:

     mount /dev/sdb3 /media/sdb3

You can check that the mounted file system looks like the original with:

     ls -l /media/sdb3

If you're happy with the new file system, you can increase its size to fill the entire partition (nice) with:

     xfs_growfs /media/sdb3

Once that's done, unmount the new file system:

     umount /media/sdb3

Shut down Knoppix and recable the new disk to replace the original. Boot the machine with the new disk installed and see how it works.

#$$$$$$
After a direct copy ... to resize ext3 partitions: (full example at: https://www.howtoforge.com/linux_resizing_ext3_partitions_p2)

     <boot Knoppix>
     (here we assume that the partition to be resized is /dev/sda3)
     su
     (if partition is mounted, unmount it)  umount /media/sda3
     fsck -n /dev/sda3
     tune2fs -O ^has_journal /dev/sda3
     fdisk -u /dev/sda  (yes, we mean /dev/sda)
       p  (note start address of existing partition 3)
       d
       3
       n
       p
       3
       (choose original start address, if it isn't the default)
       (choose the full disk, or your new partition size)
       w
     partprobe
     e2fsck -f /dev/sda3
     resize2fs /dev/sda3
     tune2fs -j /dev/sda3
     tune2fs -c 0 -i 0 /dev/sda3

#<<<<<<