Linux: Resizing the /boot Partition

Resizing the /boot partition often becomes necessary when upgrading older Linux systems.  A good example of this would be when upgrading from RHEL 5 to RHEL 6 or CentOS 5 to CentOS 6.  In the earlier versions, RHEL 5 and CentOS 5, the default partition size is about 100MB.  With the bulkier mkinitramfs files (roughly 20 to 30MB each) coming in at 6 to 7 times the size of the old mkinitrd files (roughly 3 to 4MB each), install 2 to 3 kernels and you could find yourself running out of space very quickly.  You will almost certainly want to double or triple your existing /boot partition.

There are a few assumptions made in the process outlined below:
  • Your /boot partition is located at /dev/sda1.
  • Your /boot partition is using the ext2 or ext3 filesystems.
  • Your SWAP partition is located at /dev/sda2.
  • Your /dev/sda2 partition is at least 512MB.
  • You have a far understanding of the ext filesystem.
  • You have a far understanding of resizing and partitioning.
  • You are not performing this on a system currently in production.
  • You are responsible for any and all damages that may occur from this process.

Resizing the /boot partition

1. List the partition table contents.

[root@linux ~]# fdisk -l

Disk /dev/sda: 750.2 GB, 750156374016 bytes
255 heads, 63 sectors/track, 91201 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0001a00e

  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14        1057     8385930   82  Linux swap / Solaris
/dev/sda3            1058       91201   724081680   83  Linux

2. Ensure that /dev/sda1 is the boot partition and /dev/sda2 is the swap partition, note swap partition label.

[root@linux ~]# blkid /dev/sda1 /dev/sda2

/dev/sda1: LABEL="/boot" UUID="9d056123-abcc-4522-aaaa-126dc8b27890" SEC_TYPE="ext2" TYPE="ext3" /dev/sda2: TYPE="swap" LABEL="SWAP-sda2"

3. Disable swap space.

[root@linux ~]# swapoff -a

4. Unmount the /boot partition.

[root@linux ~]# umount /boot

5. Remove journal from /dev/sda1.

[root@linux ~]# tune2fs -O ^has_journal /dev/sda1

6. Open partition table.

[root@linux ~]# fdisk /dev/sda

7. Delete swap partition.

Command (m for help): d
Partition number (1-4): 2

8. Create new swap partition whose starting cylinder is 2-3 times greater than the original.

Command (m for help): n
Command action
  e   extended
  p   primary partition (1-4)
Partition number (1-4): 2
First cylinder (14-91201, default 14): 42
Last cylinder, +cylinders or +size{K,M,G} (42-1057, default 1057):
Using default value 1057

9. Change disk type on /dev/sda2 to 82 - Linux swap / Solaris.
Command (m for help): t
Partition number (1-4): 2
Hex code (type L to list codes): 82
Changed system type of partition 2 to 82 (Linux swap / Solaris)

10. Delete /dev/sda1 partition.
Command (m for help): d
Partition number (1-4): 1

11. Add new /dev/sda1 partition using default sizes.
Command (m for help): n
Command action
  e   extended
  p   primary partition (1-4)
Partition number (1-4): 1
First cylinder (1-91201, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-41, default 41):
Using default value 41

12. Verify new partition table.
Command (m for help): p

Disk /dev/sda: 750.2 GB, 750156374016 bytes
255 heads, 63 sectors/track, 91201 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0001a00e

  Device Boot      Start         End      Blocks   Id  System
/dev/sda1               1          41      329301   83  Linux
/dev/sda2              42        1057     8161020   82  Linux swap / Solaris
/dev/sda3            1058       91201   724081680   83  Linux

13. If partition table is correct, write to disk with w.  If not, quit with q.
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.

14. Check /dev/sda1 for errors to make sure we didn’t corrupt anything in /boot.
[root@linux ~]# e2fsck -f /dev/sda1

e2fsck 1.41.12 (17-May-2010)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/boot1: 90/26104 files (7.8% non-contiguous), 72369/104388 blocks

15. Reboot system.
[root@linux ~]# reboot

16. Disable swap.
[root@linux ~]# swapoff -a

17. Recreate swap, using swap partition label from step 2.
[root@linux ~]# mkswap -L SWAP-sda2 /dev/sda2

18. Enable swap.
[root@linux ~]# swapon -a

19. Unmount /boot.
[root@linux ~]# umount /boot

20. Resize /dev/sda1 partition.
[root@linux ~]# resize2fs /dev/sda1

resize2fs 1.41.12 (17-May-2010)
Resizing the filesystem on /dev/sda1 to 329300 (1k) blocks.
The filesystem on /dev/sda1 is now 329300 blocks long.

21. Add journal to /dev/sda1.
[root@linux ~]# tune2fs -j /dev/sda1

tune2fs 1.41.12 (17-May-2010)
Creating journal inode: done
This filesystem will be automatically checked every -1 mounts or
0 days, whichever comes first.  Use tune2fs -c or -i to override.

22. Mount /boot.
[root@linux ~]# mount /boot


At this point, you should be able to use the system with the newly resized /boot partition.  I often reboot one more time for good measure, but it should not be necessary.


My Hobby

Rewriting songs from the point-of-view of a zombie.

To the tune of “People are Strange” by The Doors:

People are tasty, when you’re a zombie.
Chewy and crunchy, when you eat them.
Women seem wicked, when they run screaming.
Streets are uneven, nope, just my legs.

You eat brains,
Your face rotts off in the rain.
You eat brains,
No one remembers your name.

You eat brains.
You eat brains.
You eat brains.

To the tune of "If I Only Had a Brain."

And if your head was open,
I'd slurp it like its nothin',
I'd treat it like a bowl.

I'd grab it then I'd eat it,
I wouldn't even heat it.

If I only had a brain.


Brighthouse IPv6 - IPv4 Exhausted and Still Years Away?!?

Ok, rant time.

The final open IPv4 block of addresses was released from IANA which caused the final "triggered" release of the last 5 reserve IPv4 blocks. I think that most IT professionals new that this would happen, and most conservative estimates thought that it would occur in December of 2010. However, we wormed a few more months out of it and made it to February 2011.

Well, I have a static IP and run a business from it... So, I thought it was time to get my IPv6 address from Brighthouse / RoadRunner and start my transition. I called Brighthouse and asked for my shiny new 128-bit address.  The tier1 rep didn't know what an "IPv" was, but he recognized the word "business" so he passed me up the chain.

After advancing in queue to the next tier of support, I explained that IPv4 was nearly depleted and I wanted to remain in contact with potential customers, so I thought it was time that I get an IPv6 address.  The response I got was not that they were not prepared...it was that people are too dumb for such a long address and Brighthouse couldn't possibly support such a mass of stupid people.  He explained that since 128-bits is greater than 32-bits, that customers wouldn't be able to understand the address.  My experience here is that most non-IT persons do not understand IPv4 address space to begin with, so this argument is corporate fodder and ultimately makes no sense.

Well, anyway, I am not your average idiot [sic], so I pressed a bit further.

The rep further explained that "Brighthouse has plenty of IPv4 addresses remaining" and not to worry.  I'm not quite sure Brighthouse has done a proper job of educating their employees.  My concern is not that I will no longer be able to access Brighthouse services, but that as the rest of the world starts allocating IPv6 over the next few months, there will be no way for me to get to those networks and for those networks to get to me.  Again their argument is corporate fodder meant to assure the uneducated.

After explaining the whole "there are other networks in the world" argument to the Brighthouse rep, he said that he was not aware of any immediate plan for IPv6 and it would probably still be a couple of years out.  A couple of years?!?  Depletion of the remaining 5 subnet block will occur in less than 6 months!  This means IPv6 addresses will be allocated in their stead and that content will be inaccessible to IPv4 only users.  I will have to turn customers away because Brighthouse failed to meet a known address exhaustion deadline!

Comcast started Dual-Stack deployment at the end of January.  Don't get me wrong, I wouldn't touch Comcast with your router, but really, Comcast?  Brighthouse, TimeWarner, and RoadRunner, are you really going to let Comcast show you up?

Unallocated IPv4 Exhaustion: http://www.potaroo.net/tools/ipv4/

Test your IPv6 status: http://test-ipv6.com/


Asterisk - Defining the "sounds" directory.

I created a patch for Asterisk that allows for one to set the location of the "sounds" directory in /etc/asterisk/asterisk.conf just as one would set the location of the agi-bin (astagidir) directory or spool directory (astspooldir). The patch also checks for the existence of "/mnt/ramdisk/sounds" and uses that for the location if it does.

Just patch Asterisk and add "astsounddir => /path/to/sounds" to your asterisk.conf.

[Download Patch]
Author: Lott Caskey License: GPLv3 The patch adds the 'astsounddir' option to /etc/asterisk/asterisk.conf. This allows you to override Asterisk's sound directory without needing to make symlinks. If /mnt/ramdisk/sounds is present it will default the sounds location from /var/lib/asterisk/sounds to /mnt/ramdisk/sounds. diff -Naur asterisk- asterisk- --- asterisk- 2010-11-24 12:03:16.000000000 -0500 +++ asterisk- 2010-12-21 01:08:43.000000000 -0500 @@ -1456,7 +1456,7 @@ call is actually dialed */ /* make sure the priv-callerintros dir actually exists */ - snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR); + snprintf(pa->privintro, sizeof(pa->privintro), "%s/priv-callerintros", ast_config_AST_SOUND_DIR); if ((res = ast_mkdir(pa->privintro, 0755))) { ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res)); return -1; diff -Naur asterisk- asterisk- --- asterisk- 2008-01-24 17:58:10.000000000 -0500 +++ asterisk- 2010-12-21 01:08:43.000000000 -0500 @@ -21,6 +21,7 @@ #define DEFAULT_DATA_DIR "${INSTALL_PATH}${ASTDATADIR}" #define DEFAULT_KEY_DIR "${INSTALL_PATH}${ASTDATADIR}/keys" +#define DEFAULT_SOUND_DIR "${INSTALL_PATH}${ASTDATADIR}/sounds" #define DEFAULT_SPOOL_DIR "${INSTALL_PATH}${ASTSPOOLDIR}" #define DEFAULT_TMP_DIR "${INSTALL_PATH}${ASTSPOOLDIR}/tmp" diff -Naur asterisk- asterisk- --- asterisk- 2007-12-20 04:55:05.000000000 -0500 +++ asterisk- 2010-12-21 01:08:43.000000000 -0500 @@ -35,5 +35,6 @@ extern const char *ast_config_AST_RUN_GROUP; extern const char *ast_config_AST_RUN_USER; extern const char *ast_config_AST_SYSTEM_NAME; +extern const char *ast_config_AST_SOUND_DIR; #endif /* _ASTERISK_PATHS_H */ diff -Naur asterisk- asterisk- --- asterisk- 2010-05-17 14:44:53.000000000 -0400 +++ asterisk- 2010-12-21 01:08:43.000000000 -0500 @@ -481,7 +481,7 @@ if (filename[0] == '/') { ast_copy_string(tmpf, filename, sizeof(tmpf)); } else { - snprintf(tmpf, sizeof(tmpf), "%s/%s/%s", ast_config_AST_DATA_DIR, "sounds", filename); + snprintf(tmpf, sizeof(tmpf), "%s/%s", ast_config_AST_SOUND_DIR, filename); } if ((fd = open(tmpf, O_RDONLY)) < 0) { ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", tmpf, strerror(errno)); diff -Naur asterisk- asterisk- --- asterisk- 2010-11-29 02:27:09.000000000 -0500 +++ asterisk- 2010-12-21 02:41:41.000000000 -0500 @@ -233,6 +233,7 @@ char agi_dir[PATH_MAX]; char run_dir[PATH_MAX]; char key_dir[PATH_MAX]; + char sound_dir[PATH_MAX]; char config_file[PATH_MAX]; char db_path[PATH_MAX]; @@ -256,6 +257,7 @@ const char *ast_config_AST_AGI_DIR = cfg_paths.agi_dir; const char *ast_config_AST_KEY_DIR = cfg_paths.key_dir; const char *ast_config_AST_RUN_DIR = cfg_paths.run_dir; +const char *ast_config_AST_SOUND_DIR = cfg_paths.sound_dir; const char *ast_config_AST_DB = cfg_paths.db_path; const char *ast_config_AST_PID = cfg_paths.pid_path; @@ -485,7 +487,14 @@ ast_cli(a->fd, " Configuration directory: %s\n", ast_config_AST_CONFIG_DIR); ast_cli(a->fd, " Module directory: %s\n", ast_config_AST_MODULE_DIR); ast_cli(a->fd, " Spool directory: %s\n", ast_config_AST_SPOOL_DIR); + ast_cli(a->fd, " Var directory: %s\n", ast_config_AST_VAR_DIR); + ast_cli(a->fd, " Monitor directory: %s\n", ast_config_AST_MONITOR_DIR); + ast_cli(a->fd, " Data directory: %s\n", ast_config_AST_DATA_DIR); ast_cli(a->fd, " Log directory: %s\n", ast_config_AST_LOG_DIR); + ast_cli(a->fd, " AGI directory: %s\n", ast_config_AST_AGI_DIR); + ast_cli(a->fd, " Key directory: %s\n", ast_config_AST_KEY_DIR); + ast_cli(a->fd, " Run directory: %s\n", ast_config_AST_RUN_DIR); + ast_cli(a->fd, " Sounds directory: %s\n", ast_config_AST_SOUND_DIR); ast_cli(a->fd, "\n\n"); return CLI_SUCCESS; } @@ -2833,6 +2842,7 @@ struct ast_variable *v; char *config = DEFAULT_CONFIG_FILE; char hostname[MAXHOSTNAMELEN] = ""; + struct stat st; struct ast_flags config_flags = { 0 }; struct { unsigned int dbdir:1; @@ -2861,6 +2871,12 @@ ast_copy_string(cfg_paths.socket_path, DEFAULT_SOCKET, sizeof(cfg_paths.socket_path)); ast_copy_string(cfg_paths.run_dir, DEFAULT_RUN_DIR, sizeof(cfg_paths.run_dir)); + if (stat("/mnt/ramdisk/sounds", &st)==0) { + snprintf(cfg_paths.sound_dir, sizeof(cfg_paths.sound_dir), "/mnt/ramdisk/sounds"); + } else { + snprintf(cfg_paths.sound_dir, sizeof(cfg_paths.sound_dir), "%s", DEFAULT_SOUND_DIR); + } + ast_set_default_eid(&ast_eid_default); /* no asterisk.conf? no problem, use buildtime config! */ @@ -2909,6 +2925,8 @@ ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir)); } else if (!strcasecmp(v->name, "astmoddir")) { ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir)); + } else if (!strcasecmp(v->name, "astsounddir")) { + ast_copy_string(cfg_paths.sound_dir, v->value, sizeof(cfg_paths.sound_dir)); } } diff -Naur asterisk- asterisk- --- asterisk- 2010-10-06 09:48:27.000000000 -0400 +++ asterisk- 2010-12-21 01:08:43.000000000 -0500 @@ -245,7 +245,7 @@ /*! * \brief construct a filename. Absolute pathnames are preserved, - * relative names are prefixed by the sounds/ directory. + * relative names are prefixed by the ast_config_AST_SOUND_DIR directory. * The wav49 suffix is replaced by 'WAV'. * Returns a malloc'ed string to be freed by the caller. */ @@ -262,8 +262,8 @@ fn = NULL; } } else { - if (asprintf(&fn, "%s/sounds/%s.%s", - ast_config_AST_DATA_DIR, filename, ext) < 0) { + if (asprintf(&fn, "%s/%s.%s", + ast_config_AST_SOUND_DIR, filename, ext) < 0) { ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); fn = NULL; }


Upgrading Fedora 12 to Fedora 13

Personally, I have used the live method of upgrading my Fedora system for the last 5 releases. I would recommend that you understand what an RPM package is, how the dependency resolution process works, and finally, how to resolve conflicts manually. That being said, if you brick your system, you are the only one to blame.

  1. Download the fedora-release RPM package.
  2. (I usually like to download the release RPM before installing.)
    • wget http://mirrors.kernel.org/fedora/releases/13/Everything/i386/os/Packages/fedora-release-13-1.noarch.rpm
  3. Install the fedora-release RPM package.
    • rpm -Uvh fedora-release-13-1.noarch.rpm
  4. Update the yum package.
    • yum update yum
  5. Update the rpm package.
  6. (This step should generally be taken prior to performing an inline upgrade. I was not able to do so without RPM conflicts, and opted to skip this step.)
    • yum update rpm
  7. Update system.
    • yum update
  8. Reboot.


Fugitol RPMs

The primary purpose of Fugitol is the distribution of custom RPMs for CentOS5/RHEL5.  These include several packages that are hard to find, not built to my standard, or otherwise unavailable for these platforms.  These also include packages pertaining to OSDial, which are otherwise funded through Call Center Service Group.  All RPMs are compiled and maintained by Lott Caskey.  They RPM repository is located at http://rpm.fugitol.com.

CentOS / RedHat Enterprise Linux
  1. Install the RPMforge repository.
  2. 32bit:
    • rpm -ivh http://dag.wieers.com/rpm/packages/rpmforge-release/rpmforge-release-0.3.6-1.el5.rf.i386.rpm
    • rpm -ivh http://dag.wieers.com/rpm/packages/rpmforge-release/rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm
  3. Install the Fugitol repository.
    • rpm -ivh http://rpm.fugitol.com/el/5/noarch/fugitol-release-6-2.2.el5_fio.noarch.rpm