diff options
| author | Johannes Erdfelt <johannes.erdfelt@rackspace.com> | 2012-01-06 12:57:37 -0800 |
|---|---|---|
| committer | Johannes Erdfelt <johannes.erdfelt@rackspace.com> | 2012-01-24 16:54:23 +0000 |
| commit | a4223f1d89ea7033cbae35790a0411ec439cdb6d (patch) | |
| tree | bf3768b78a9ab8633b525b17579bc8326bbcab63 /nova/virt | |
| parent | 91bc67d81a9711fbf5a0f0c46bbf1d87232391f8 (diff) | |
KVM and XEN Disk Management Parity
Implements blueprint disk-configuration-parity
This change splits local_gb into root_gb and ephemeral_gb. libvirt
interpreted local_gb as what ephemeral_gb is now, whereas XenAPI
interpreted local_gb as what root_gb is now.
Change-Id: I496600991bac1e990326d4ded1607fee08209d68
Diffstat (limited to 'nova/virt')
| -rw-r--r-- | nova/virt/disk/api.py | 2 | ||||
| -rw-r--r-- | nova/virt/libvirt.xml.template | 4 | ||||
| -rw-r--r-- | nova/virt/libvirt/connection.py | 45 | ||||
| -rw-r--r-- | nova/virt/xenapi/vm_utils.py | 65 | ||||
| -rw-r--r-- | nova/virt/xenapi/vmops.py | 19 |
5 files changed, 80 insertions, 55 deletions
diff --git a/nova/virt/disk/api.py b/nova/virt/disk/api.py index 9a457a318..1cd697347 100644 --- a/nova/virt/disk/api.py +++ b/nova/virt/disk/api.py @@ -39,8 +39,6 @@ from nova.virt.disk import nbd LOG = logging.getLogger('nova.compute.disk') FLAGS = flags.FLAGS -flags.DEFINE_integer('minimum_root_size', 1024 * 1024 * 1024 * 10, - 'minimum size in bytes of root partition') flags.DEFINE_string('injected_network_template', utils.abspath('virt/interfaces.template'), 'Template file for injected network') diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index 2dda60edb..5b464a2d8 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -79,11 +79,11 @@ <target dev='${root_device}' bus='${root_disk_bus}'/> </disk> #end if - #if $getVar('local_device', False) + #if $getVar('ephemeral_device', False) <disk type='file'> <driver type='${driver_type}'/> <source file='${basepath}/disk.local'/> - <target dev='${local_device}' bus='${ephemeral_disk_bus}'/> + <target dev='${ephemeral_device}' bus='${ephemeral_disk_bus}'/> </disk> #end if #for $eph in $ephemerals diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index bf46c7728..8ebaa276f 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -131,10 +131,6 @@ flags.DEFINE_list('libvirt_volume_drivers', 'rbd=nova.virt.libvirt.volume.LibvirtNetVolumeDriver', 'sheepdog=nova.virt.libvirt.volume.LibvirtNetVolumeDriver'], 'Libvirt handlers for remote volumes.') -flags.DEFINE_string('default_local_format', - None, - 'The default format a local_volume will be formatted with ' - 'on creation.') flags.DEFINE_bool('libvirt_use_virtio_for_bridges', False, 'Use virtio for bridge interfaces') @@ -195,7 +191,7 @@ class LibvirtConnection(driver.ComputeDriver): else: self._disk_prefix = disk_prefix_map.get(FLAGS.libvirt_type, 'vd') self.default_root_device = self._disk_prefix + 'a' - self.default_local_device = self._disk_prefix + 'b' + self.default_ephemeral_device = self._disk_prefix + 'b' self.default_swap_device = self._disk_prefix + 'c' @property @@ -834,15 +830,15 @@ class LibvirtConnection(driver.ComputeDriver): """Create a blank image of specified size""" if not fs_format: - fs_format = FLAGS.default_local_format + fs_format = FLAGS.default_ephemeral_format libvirt_utils.create_image('raw', target, '%d%c' % (local_size, unit)) if fs_format: libvirt_utils.mkfs(fs_format, target) - def _create_ephemeral(self, target, local_size, fs_label, os_type): - self._create_local(target, local_size) + def _create_ephemeral(self, target, ephemeral_size, fs_label, os_type): + self._create_local(target, ephemeral_size) disk.mkfs(os_type, fs_label, target) @staticmethod @@ -901,13 +897,15 @@ class LibvirtConnection(driver.ComputeDriver): project_id=inst['project_id']) root_fname = hashlib.sha1(str(disk_images['image_id'])).hexdigest() - size = FLAGS.minimum_root_size + size = inst['root_gb'] * 1024 * 1024 * 1024 inst_type_id = inst['instance_type_id'] inst_type = instance_types.get_instance_type(inst_type_id) if inst_type['name'] == 'm1.tiny' or suffix == '.rescue': size = None root_fname += "_sm" + else: + root_fname += "_%d" % inst['root_gb'] if not self._volume_in_mapping(self.default_root_device, block_device_info): @@ -921,18 +919,18 @@ class LibvirtConnection(driver.ComputeDriver): project_id=inst['project_id'], size=size) - local_gb = inst['local_gb'] - if local_gb and not self._volume_in_mapping( - self.default_local_device, block_device_info): + ephemeral_gb = inst['ephemeral_gb'] + if ephemeral_gb and not self._volume_in_mapping( + self.default_ephemeral_device, block_device_info): fn = functools.partial(self._create_ephemeral, fs_label='ephemeral0', os_type=inst.os_type) self._cache_image(fn=fn, target=basepath('disk.local'), fname="ephemeral_%s_%s_%s" % - ("0", local_gb, inst.os_type), + ("0", ephemeral_gb, inst.os_type), cow=FLAGS.use_cow_images, - local_size=local_gb) + ephemeral_size=ephemeral_gb) for eph in driver.block_device_info_get_ephemerals(block_device_info): fn = functools.partial(self._create_ephemeral, @@ -943,7 +941,7 @@ class LibvirtConnection(driver.ComputeDriver): fname="ephemeral_%s_%s_%s" % (eph['num'], eph['size'], inst.os_type), cow=FLAGS.use_cow_images, - local_size=eph['size']) + ephemeral_size=eph['size']) swap_mb = 0 @@ -1119,14 +1117,14 @@ class LibvirtConnection(driver.ComputeDriver): ebs_root = self._volume_in_mapping(self.default_root_device, block_device_info) - local_device = False - if not (self._volume_in_mapping(self.default_local_device, + ephemeral_device = False + if not (self._volume_in_mapping(self.default_ephemeral_device, block_device_info) or 0 in [eph['num'] for eph in driver.block_device_info_get_ephemerals( block_device_info)]): - if instance['local_gb'] > 0: - local_device = self.default_local_device + if instance['ephemeral_gb'] > 0: + ephemeral_device = self.default_ephemeral_device ephemerals = [] for eph in driver.block_device_info_get_ephemerals(block_device_info): @@ -1147,7 +1145,7 @@ class LibvirtConnection(driver.ComputeDriver): 'vif_type': FLAGS.libvirt_vif_type, 'nics': nics, 'ebs_root': ebs_root, - 'local_device': local_device, + 'ephemeral_device': ephemeral_device, 'volumes': volumes, 'use_virtio_for_bridges': FLAGS.libvirt_use_virtio_for_bridges, @@ -1165,10 +1163,11 @@ class LibvirtConnection(driver.ComputeDriver): nova_context.get_admin_context(), instance['id'], {'root_device_name': '/dev/' + self.default_root_device}) - if local_device: + if ephemeral_device: db.instance_update( nova_context.get_admin_context(), instance['id'], - {'default_local_device': '/dev/' + self.default_local_device}) + {'default_ephemeral_device': + '/dev/' + self.default_ephemeral_device}) swap = driver.block_device_info_get_swap(block_device_info) if driver.swap_is_usable(swap): @@ -1790,7 +1789,7 @@ class LibvirtConnection(driver.ComputeDriver): image_id=instance_ref['image_ref'], user_id=instance_ref['user_id'], project_id=instance_ref['project_id'], - size=instance_ref['local_gb']) + size=instance_ref['ephemeral_gb']) libvirt_utils.create_cow_image(backing_file, instance_disk) diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 3c03d2a59..75ff011b3 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -393,7 +393,7 @@ class VMHelper(HelperBase): # Resize partition and filesystem down cls.auto_configure_disk(session=session, vdi_ref=copy_ref, - new_gb=instance_type['local_gb']) + new_gb=instance_type['root_gb']) # Create new VDI new_ref = cls.fetch_blank_disk(session, @@ -401,7 +401,7 @@ class VMHelper(HelperBase): new_uuid = session.call_xenapi('VDI.get_uuid', new_ref) # Manually copy contents over - virtual_size = instance_type['local_gb'] * 1024 * 1024 * 1024 + virtual_size = instance_type['root_gb'] * 1024 * 1024 * 1024 _copy_partition(session, copy_ref, new_ref, 1, virtual_size) return new_ref, new_uuid @@ -411,7 +411,7 @@ class VMHelper(HelperBase): @classmethod def auto_configure_disk(cls, session, vdi_ref, new_gb): """Partition and resize FS to match the size specified by - instance_types.local_gb. + instance_types.root_gb. This is a fail-safe to prevent accidentally destroying data on a disk erroneously marked as auto_disk_config=True. @@ -437,48 +437,52 @@ class VMHelper(HelperBase): _resize_part_and_fs(dev, start, old_sectors, new_sectors) @classmethod - def generate_swap(cls, session, instance, vm_ref, userdevice, swap_mb): + def _generate_disk(cls, session, instance, vm_ref, userdevice, name, + size_mb, fs_type): """ - Steps to programmatically generate swap: + Steps to programmatically generate a disk: - 1. Create VDI of desired swap size + 1. Create VDI of desired size 2. Attach VDI to compute worker - 3. Create swap partition + 3. Create partition - 4. Create VBD between instance VM and swap VDI + 4. Create VBD between instance VM and VDI """ # 1. Create VDI sr_ref = cls.safe_find_sr(session) - name_label = instance.name + "-swap" + name_label = '%s-%s' % (instance.name, name) ONE_MEG = 1024 * 1024 - virtual_size = swap_mb * ONE_MEG + virtual_size = size_mb * ONE_MEG vdi_ref = cls.create_vdi( session, sr_ref, name_label, virtual_size, read_only=False) try: # 2. Attach VDI to compute worker (VBD hotplug) with vdi_attached_here(session, vdi_ref, read_only=False) as dev: - # 3. Create swap partition - - # NOTE(jk0): We use a FAT32 filesystem for the Windows swap - # partition because that is what parted supports. - is_windows = instance.os_type == "windows" - fs_type = "fat32" if is_windows else "linux-swap" - + # 3. Create partition dev_path = utils.make_dev_path(dev) utils.execute('parted', '--script', dev_path, 'mklabel', 'msdos', run_as_root=True) partition_start = 0 - partition_end = swap_mb - utils.execute('parted', '--script', dev_path, 'mkpartfs', - 'primary', fs_type, + partition_end = size_mb + utils.execute('parted', '--script', dev_path, + 'mkpart', 'primary', str(partition_start), str(partition_end), run_as_root=True) + partition_path = utils.make_dev_path(dev, partition=1) + + if fs_type == 'linux-swap': + utils.execute('mkswap', partition_path, + run_as_root=True) + elif fs_type is not None: + utils.execute('mkfs', '-t', fs_type, partition_path, + run_as_root=True) + # 4. Create VBD between instance VM and swap VDI volume_utils.VolumeHelper.create_vbd( session, vm_ref, vdi_ref, userdevice, bootable=False) @@ -487,11 +491,28 @@ class VMHelper(HelperBase): cls.destroy_vdi(session, vdi_ref) @classmethod + def generate_swap(cls, session, instance, vm_ref, userdevice, swap_mb): + # NOTE(jk0): We use a FAT32 filesystem for the Windows swap + # partition because that is what parted supports. + is_windows = instance.os_type == "windows" + fs_type = "fat32" if is_windows else "linux-swap" + + cls._generate_disk(session, instance, vm_ref, userdevice, + 'swap', swap_mb, fs_type) + + @classmethod + def generate_ephemeral(cls, session, instance, vm_ref, userdevice, + size_gb): + cls._generate_disk(session, instance, vm_ref, userdevice, + 'ephemeral', size_gb * 1024, + FLAGS.default_ephemeral_format) + + @classmethod def fetch_blank_disk(cls, session, instance_type_id): # Size the blank harddrive to suit the machine type: one_gig = 1024 * 1024 * 1024 req_type = instance_types.get_instance_type(instance_type_id) - req_size = req_type['local_gb'] + req_size = req_type['root_gb'] LOG.debug("Creating blank HD of size %(req_size)d gigs" % locals()) @@ -595,7 +616,7 @@ class VMHelper(HelperBase): # refactor this to a common area instance_type_id = instance['instance_type_id'] instance_type = instance_types.get_instance_type(instance_type_id) - allowed_size_gb = instance_type['local_gb'] + allowed_size_gb = instance_type['root_gb'] allowed_size_bytes = allowed_size_gb * 1024 * 1024 * 1024 LOG.debug(_("image_size_bytes=%(size_bytes)d, allowed_size_bytes=" diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 606da3bcc..1309879b5 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -371,7 +371,7 @@ class VMOps(object): instance.instance_type_id) VMHelper.auto_configure_disk(session=self._session, vdi_ref=first_vdi_ref, - new_gb=instance_type['local_gb']) + new_gb=instance_type['root_gb']) VolumeHelper.create_vbd(session=self._session, vm_ref=vm_ref, vdi_ref=first_vdi_ref, @@ -390,6 +390,13 @@ class VMOps(object): swap_mb=swap_mb) userdevice += 1 + ephemeral_gb = instance_type['ephemeral_gb'] + if ephemeral_gb: + VMHelper.generate_ephemeral(self._session, instance, + vm_ref, userdevice, + ephemeral_gb) + userdevice += 1 + # Attach any other disks for vdi in vdis[1:]: if generate_swap and vdi['vdi_type'] == 'swap': @@ -703,10 +710,10 @@ class VMOps(object): sr_path = VMHelper.get_sr_path(self._session) if instance['auto_disk_config'] and \ - instance['local_gb'] > instance_type['local_gb']: + instance['root_gb'] > instance_type['root_gb']: # Resizing disk storage down - old_gb = instance['local_gb'] - new_gb = instance_type['local_gb'] + old_gb = instance['root_gb'] + new_gb = instance_type['root_gb'] LOG.debug(_("Resizing down VDI %(cow_uuid)s from " "%(old_gb)dGB to %(new_gb)dGB") % locals()) @@ -816,7 +823,7 @@ class VMOps(object): """Resize a running instance by changing its disk size.""" #TODO(mdietz): this will need to be adjusted for swap later - new_disk_size = instance.local_gb * 1024 * 1024 * 1024 + new_disk_size = instance.root_gb * 1024 * 1024 * 1024 if not new_disk_size: return @@ -828,7 +835,7 @@ class VMOps(object): instance_name = instance.name old_gb = virtual_size / (1024 * 1024 * 1024) - new_gb = instance.local_gb + new_gb = instance.root_gb if virtual_size < new_disk_size: # Resize up. Simple VDI resize will do the trick |
