diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-02-22 11:31:39 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-02-22 11:31:39 +0000 |
| commit | 55fb5df69d475ffdb6f2d953cedf899afaace13e (patch) | |
| tree | 66eaf37632891f92085ace55991c57bd95df6d3e /nova/virt | |
| parent | d7fb579cf9e192dbbace1b11f2a2bc84555d4c71 (diff) | |
| parent | c867e089b1a945bd4181cbe651ad12649b345674 (diff) | |
| download | nova-55fb5df69d475ffdb6f2d953cedf899afaace13e.tar.gz nova-55fb5df69d475ffdb6f2d953cedf899afaace13e.tar.xz nova-55fb5df69d475ffdb6f2d953cedf899afaace13e.zip | |
Merge "Rework base file checksums."
Diffstat (limited to 'nova/virt')
| -rw-r--r-- | nova/virt/libvirt/connection.py | 5 | ||||
| -rw-r--r-- | nova/virt/libvirt/imagecache.py | 53 |
2 files changed, 45 insertions, 13 deletions
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index e8fdcd792..634acdeca 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -921,6 +921,11 @@ class LibvirtConnection(driver.ComputeDriver): If size is specified, we attempt to resize up to that size. """ + # NOTE(mikal): Checksums aren't created here, even if the image cache + # manager is enabled, as that would slow down VM startup. If both + # cache management and checksumming are enabled, then the checksum + # will be created on the first pass of the image cache manager. + generating = 'image_id' not in kwargs if not os.path.exists(target): base_dir = os.path.join(FLAGS.instances_path, '_base') diff --git a/nova/virt/libvirt/imagecache.py b/nova/virt/libvirt/imagecache.py index bd714ea7f..6226e8d4e 100644 --- a/nova/virt/libvirt/imagecache.py +++ b/nova/virt/libvirt/imagecache.py @@ -55,6 +55,9 @@ imagecache_opts = [ default=(24 * 3600), help='Unused unresized base images younger than this will not ' 'be removed'), + cfg.BoolOpt('checksum_base_images', + default=False, + help='Write a checksum for files in _base to disk'), ] flags.DECLARE('instances_path', 'nova.compute.manager') @@ -77,6 +80,23 @@ def read_stored_checksum(base_file): return stored_checksum +def write_stored_checksum(target): + """Write a checksum to disk for a file in _base.""" + + checksum_filename = '%s.sha1' % target + if os.path.exists(target) and not os.path.exists(checksum_filename): + # NOTE(mikal): Create the checksum file first to exclude possible + # overlap in checksum operations. An empty checksum file is ignored if + # encountered during verification. + sum_file = open(checksum_filename, 'w') + img_file = open(target, 'r') + checksum = utils.hash_file(img_file) + img_file.close() + + sum_file.write(checksum) + sum_file.close() + + class ImageCacheManager(object): def __init__(self): self.unexplained_images = [] @@ -200,13 +220,13 @@ class ImageCacheManager(object): action occurs. This is something sysadmins should monitor for and handle manually when it occurs. """ - f = open(base_file, 'r') - current_checksum = utils.hash_file(f) - f.close() stored_checksum = read_stored_checksum(base_file) - if stored_checksum: + f = open(base_file, 'r') + current_checksum = utils.hash_file(f) + f.close() + if current_checksum != stored_checksum: LOG.error(_('%(container_format)s-%(id)s ' '(%(base_file)s): ' @@ -225,6 +245,13 @@ class ImageCacheManager(object): {'container_format': img['container_format'], 'id': img['id'], 'base_file': base_file}) + + # NOTE(mikal): If the checksum file is missing, then we should + # create one. We don't create checksums when we download images + # from glance because that would delay VM startup. + if FLAGS.checksum_base_images: + write_stored_checksum(base_file) + return None def _remove_base_file(self, base_file): @@ -335,15 +362,15 @@ class ImageCacheManager(object): # TODO(mikal): Write a unit test for this method # TODO(mikal): Handle "generated" images - # The new scheme for base images is as follows -- an image is streamed - # from the image service to _base (filename is the sha1 hash of the - # image id). If CoW is enabled, that file is then resized to be the - # correct size for the instance (filename is the same as the original, - # but with an underscore and the resized size in bytes). This second - # file is then CoW'd to the instance disk. If CoW is disabled, the - # resize occurs as part of the copy from the cache to the instance - # directory. Files ending in _sm are no longer created, but may remain - # from previous versions. + # NOTE(mikal): The new scheme for base images is as follows -- an + # image is streamed from the image service to _base (filename is the + # sha1 hash of the image id). If CoW is enabled, that file is then + # resized to be the correct size for the instance (filename is the + # same as the original, but with an underscore and the resized size + # in bytes). This second file is then CoW'd to the instance disk. If + # CoW is disabled, the resize occurs as part of the copy from the + # cache to the instance directory. Files ending in _sm are no longer + # created, but may remain from previous versions. self.unexplained_images = [] self.active_base_files = [] |
