Procedure for shrinking the last slice on a disk so that another slice can be created after it. This is necessary when you reach the limit of 7 disklabel partitions within a slice, but there is still more space in the slice that you wish to utilise. This is for -STABLE; the existence of devfs and geom in -CURRENT may change the procedure significantly. The example here uses a SCSI disk `da1' and splits the first slice `da1s1' into two slices `da1s1' and `da1s2'. Adjust the device and slice numbers to match the disk and slice you are working on. Shrink the existing slice ========================= First the fdisk slice needs to be reduced to just the size of the filesystems it contains. Calculate the new size ---------------------- Use disklabel to figure out the correct size: # disklabel da1s1 ... sectors/track: 63 tracks/cylinder: 255 sectors/cylinder: 16065 ... 8 partitions: # size offset fstype [fsize bsize bps/cpg] c: 71119692 0 unused 0 0 # (Cyl. 0 - 4426*) d: 4194304 0 4.2BSD 2048 16384 102 # (Cyl. 0 - 261*) e: 6291456 4194304 4.2BSD 2048 16384 102 # (Cyl. 261*- 652*) f: 4194304 10485760 4.2BSD 2048 16384 94 # (Cyl. 652*- 913*) g: 6291456 14680064 4.2BSD 2048 16384 102 # (Cyl. 913*- 1305*) h: 20971520 20971520 4.2BSD 2048 16384 102 # (Cyl. 1305*- 2610*) Look for the largest used cylinder number, keeping in mind that it may not be on the last partition. In the above example, partition `h' is the last used partition, and it ends in cylinder 2610. We need to start the new slice on the next cylinder, i.e. 2611. Next look at the fdisk table: # fdisk da1 ... The data for partition 1 is: sysid 165,(FreeBSD/NetBSD/386BSD) start 63, size 71119692 (34726 Meg), flag 80 (active) beg: cyl 0/ head 1/ sector 1; end: cyl 330/ head 254/ sector 63 The data for partition 2 is: The data for partition 3 is: The data for partition 4 is: The important numbers are the `start' and `size' fields: start 63, size 71119692 (34726 Meg) Note: The `cyl' numbers can be completely ignored, as they wrap around at 1024 so can rarely encode the correct value. About the only time that these cylinder numbers are used is when booting without `packet mode' enabled. See boot0cfg(8). We wish to reduce the size of slice 1 to 2611 cylinders. Since there are 16065 sectors per cylinder (from disklabel output) and it starts at sector 63, that means that the new size is: 2611 * 16065 - 63 = 41945652 => Updated size for slice 1 is 41945652 sectors Important!: note down the original size of the partition (71119692) as it will be needed later. Use fdisk(8) to shrink the slice -------------------------------- Now we make these changes to the fdisk slice table: # fdisk -u da1 ... Figures below won't work with BIOS for partitions not in cyl 1 parameters to be used for BIOS calculations are: cylinders=4427 heads=255 sectors/track=63 (16065 blks/cyl) Do you want to change our idea of what BIOS thinks ? [n] Media sector size is 512 Warning: BIOS sector numbering starts with sector 1 Information from DOS bootblock is: The data for partition 1 is: sysid 165,(FreeBSD/NetBSD/386BSD) start 63, size 71119692 (34726 Meg), flag 80 (active) beg: cyl 0/ head 1/ sector 1; end: cyl 330/ head 254/ sector 63 Do you want to change it? [n] **y** Supply a decimal value for "sysid (165=FreeBSD)" [165] Supply a decimal value for "start" [63] Supply a decimal value for "size" [71119692] **41945652** Explicitly specify beg/end address ? [n] sysid 165,(FreeBSD/NetBSD/386BSD) start 63, size 41945652 (20481 Meg), flag 80 (active) beg: cyl 0/ head 1/ sector 1; end: cyl 562/ head 254/ sector 63 Are we happy with this entry? [n] **y** The data for partition 2 is: Do you want to change it? [n] ... Should we write new partition table? [n] **y** Synchronise the kernel with the changed size -------------------------------------------- There are two options here to synchronise the kernel's idea of the fdisk table. The first option is to reboot. Alternatively, run this magic command to get the kernel to re-read the slice table: # perl -e '$_="\x01\0\0\0";ioctl(STDIN,0x80046470,$_)||die"$!"' < /dev/da1 This should result in messages such as the following appearing on the console and in the output of dmesg: da1: raw partition size != slice size da1: start 63, end 41945714, size 41945652 da1c: start 63, end 71119754, size 71119692 da1: truncating raw partition Update the disklabel of the shrunk slice ---------------------------------------- The disklabel for the slice that has shrunk needs to be updated to the smaller size to avoid the above `truncating raw partition' diagnostic appearing every time you reboot. Simply edit the disklabel: # disklabel -e da1s1 Do not modify anything, but force the editor to write the file (`:w' in vi). Then quit the editor, and the disklabel will be updated. Check with `disklabel -r da1s1' that the size of the `c' partition is now correct in the on-disk copy. Add the new slice ================= Calculate the offset and size of the new slice ---------------------------------------------- The space left for the new slice is the difference between the old and new sizes: 71119692 - 41945652 = 29174040 sectors => Size of new slice will be 29174040 sectors The new slice will start at the point where the shrunk slice ends: 41945652 + 63 = 41945715 => Offset of new slice will be 41945715 sectors Create the slice with fdisk(8) ------------------------------ # fdisk -u da1 ... The data for partition 1 is: sysid 165,(FreeBSD/NetBSD/386BSD) start 63, size 41945652 (20481 Meg), flag 80 (active) beg: cyl 0/ head 1/ sector 1; end: cyl 562/ head 254/ sector 63 Do you want to change it? [n] The data for partition 2 is: Do you want to change it? [n] **y** Supply a decimal value for "sysid (165=FreeBSD)" [0] **165** Supply a decimal value for "start" [0] **41945715** Supply a decimal value for "size" [0] **29174040** Explicitly specify beg/end address ? [n] sysid 165,(FreeBSD/NetBSD/386BSD) start 41945715, size 29174040 (14245 Meg), flag 0 beg: cyl 563/ head 0/ sector 1; end: cyl 330/ head 254/ sector 63 Are we happy with this entry? [n] **y** ... Should we write new partition table? [n] **y** Get the kernel to re-read the fdisk slice table ----------------------------------------------- The kernel needs to be told to recheck the slice table as before. Either reboot, or else run the command: # perl -e '$_="\x01\0\0\0";ioctl(STDIN,0x80046470,$_)||die"$!"' < /dev/da1 This will cause some kernel log messages to appear as there is no label on the slice: da1s2: cannot find label (no disk label) Make the new device nodes in /dev --------------------------------- The device nodes for the new slice might not exist, so they need to be created now. The MAKEDEV script will create all of the nodes required when it is told to create the `a' partition node for the slice, so just this one command is required: # (cd /dev; sh MAKEDEV da1s2a) Create a disklabel on the new slice ----------------------------------- The new slice needs to be labeled before it can be used. # disklabel -r -w da1s2 auto ============ That's it! You can now use disklabel to add partitions to the new slice and newfs and mount them as usual.