There may be times when you find you need to adjust the allocations of resources to your child sessions. In most cases, a client might need more disk space or RAM for their session. Theis is done by shutting down the session, making the necessary adjustment, and starting it back up again.
For a child session (i.e. a session which is not the xen0 session for the machine) this is simple- just shut down the child session, make the changes within the xen0 session, and start the child back up.
However, if you need to change the xen0 session, you will end up needing to reboot the entire machine- and if you're changing the size of the "/" filesystem of the xen0 session, you will need to reboot the machine into an environment which has the necessary tools. Personally, I use a Fedora 8 KDE Live CD for this, because the tools are there and because it's very similar to a CentOS 5.0 environment.
It is necessary to shut down a session before you can adjust its RAM, CPU, or disk allocations.
The best way to do this is to go into the client as root (assuming you have this access, either by knowing the password or having an SSH key which allows you in) and type "shutdown -h now". This ensures that the system will shut down in an orderly fashion, and if you're using "xm console" instead of SSH, you'll be able to watch all of the services as they shut down, and make sure it goes smoothly.
Another option, if you don't have root access to the child, or if you don't want to do it that way, is this: from the xen0 session, you can order the child to do an orderly shutdown using the command "xm shutdown name" (which is the same as typing "telinit 0" as root within the session.)
If a client session is having problems and won't shut down properly, and you need to "hard kill" the session, you can use the "xm destroy name" command, which is like pulling the power cord on a physical machine- it's not something you should ever need to do... and if a client session is messed up enough to need to be shut down this way, you should seriously think about messing with the disks... at the very least, make sure you FIX any filesystem problems first.
Changing the RAM allocation for a child (i.e. non-xen0) session is as simple as changing the "memory" line in the client's config file. This change can even be made while the session is running, however you do need to stop and restart it in order for the new settings to take effect.
Changing the RAM allocation for the xen0 session involves editing the /boot/grub/grub.conf file, which controls how the machine boots when it first starts up (i.e. how the hardware boots, before the hypervisor is running.)
This file is made up of several sections. The first section normally controls the boot process itself- a background image for the menu, which item should be the default, a timeout for somebody to make a choice, a boot password, and so forth.
Each additional section ends up being a choice on the menu. Each section starts with a "title" line, and has a few other lines which tell how to boot that particular session. For a normal Linux system, there will be a "kernel" line which tells what kernel to load. For a Xen system, this "kernel" line is used to load the Xen hypervisor instead.
You can specify parameters on the kernel line which modify how the Xen hypervisor loads. The "dom0_mem" parameter controls how much RAM is given to the xen0 session when hypervisor starts. If you don't specify this, the hypervisor will give all of the available RAM on the system to the xen0 session, and then dynamically subtract from that allocation in order to assign memory to child sessions.
Remember that Xen sessions cannot "share" RAM allocations, other than the xen0 session's "balloon" allocation if no specific limit is set. If the machine only has 2GB of RAM, you should make sure not to assign more than this to your sessions- otherwise it will either steal memory from the xen0 session, or be unable to start new clients. Also remember that the Xen hypervisor itself needs a certain amount of RAM- as a rule of thumb, I plan on leaving 64MB for the hypervisor to run.
This section assumes that you are using LVM to manage the disks, as detailed earlier on this site.
This section also assumes that you are using ext2 or ext3 filesystems within the containers. If you are using some other filesystem, this section can give you an overview of how the process should work, but cannot give you specific commands to resize the filesystems, IF the filesystems are even resizeable to start with.
Before we begin, it is important to understand the basic steps involved. We are going to be resizing two things- the LVM container, and the filesystem within that container. The sequence of steps is different based on whether we are changing the size upwards or downwards, based on one simple rule: the filesystem must never be bigger than the LVM container.
If we are making the disk larger, we will first expand the LVM container and then expand the filesystem. If we are making the disk smaller, we will first shrink the filesystem and then shrink the LVM container.
The directions below are done as root, in the xen0 session. The examples will use "/dev/Disks/xyz_root" as the name of the LVM container.
The first step is to make sure there are no logical errors on the filesystem. (The "-f" option makes it do a full check, even if the filesystem was unmounted cleanly.)
# e2fsck -f /dev/Disks/xyz_root
If it finds any errors, you must fix them before continuing. DO NOT go any further if the filesystem has errors.
Resize the container. This example adds 5GB to the current size.
# lvresize -L +5G /dev/Disks/xyz_root
If the filesystem is an ext3 filesystem, we need to convert it to ext2 by removing the journal. This is because the "resize2fs" program knows how to resize an ext2 filesystem, but can't resize an ext3 filesystem, especially if the journal has uncommitted blocks.
# tune2fs -O ^has_journal /dev/Disks/xyz_root
You may wish to run e2fsck on the filesystem again, just to be sure there are still no logical errors.
Next we resize the filesystem itself. This is easy when we're making the filessytem bigger, since we don't need to figure out the new size. The resize2fs program automatically makes the filesystem fill the "physical device" (i.e. the LVM container) on which it resides, if no new size is specified.
# resize2fs /dev/Disks/xyz_root
You may wish to run e2fsck on the filesystem again, just to be sure there are still no logical errors.
If this was an ext3 filesystem, the final system is to convert it back to ext3 by adding a journal.
# tune2fs -O has_journal /dev/Disks/xyz_root
You should definitely run e2fsck on the filesystem again, just to be sure there are still no logical errors.
I'll be honest, I know that it IS possible to shrink a filesystem and then shrink the LVM container to match it... however it involves calculating the new size of the filesystem by hand, which is something I have never really felt comfortable with- at least not comfortable enough to write out directions on a web page about it.
What I DO know how to do is to create a new, smaller LVM container, copy the files from the old container to the new one, delete the old one, and rename the new one to have the old one's name. That process looks something like this:
# lvcreate -n work -L 3G Disks
...
# mke2fs -j /dev/disks/work
...
# mkdir /mnt/a /mnt/b
# mount /dev/Disks/xyz_root /mnt/a
# mount /dev/Disks/work /mnt/b
# ( cd /mnt/a ; tar cf - . ) | ( cd /mnt/b ; tar xvpf - )
...
# umount /dev/b
# umount /dev/a
# lvremove /dev/Disks/xyz_root
Do you really want to remove active logical volume "xyz_root"? [y/n]:
y
Logical volume "xyz_root" successfully removed
# lvrename Disks work xyz_root
Restarting a session is exactly like starting it the first time after you created it- use the "xm create" command, with or without the "-c" option.