def _get_snapshot_by_backing_file(self, volume, backing_file): all_snapshots = objects.SnapshotList.get_all_for_volume( context.get_admin_context(), volume.id) for snapshot in all_snapshots: snap_backing_file = snapshot.metadata.get('backing_file') if utils.paths_normcase_equal(snap_backing_file or '', backing_file): return snapshot
def _delete_snapshot(self, snapshot): # NOTE(lpetrut): We're slightly diverging from the super class # workflow. The reason is that we cannot query in-use vhd/x images, # nor can we add or remove images from a vhd/x chain in this case. volume_status = snapshot.volume.status if volume_status != 'in-use': return super(WindowsSmbfsDriver, self)._delete_snapshot(snapshot) info_path = self._local_path_volume_info(snapshot.volume) snap_info = self._read_info_file(info_path, empty_if_missing=True) if snapshot.id not in snap_info: LOG.info( 'Snapshot record for %s is not present, allowing ' 'snapshot_delete to proceed.', snapshot.id) return file_to_merge = snap_info[snapshot.id] delete_info = { 'file_to_merge': file_to_merge, 'volume_id': snapshot.volume.id } self._nova_assisted_vol_snap_delete(snapshot._context, snapshot, delete_info) # At this point, the image file should no longer be in use, so we # may safely query it so that we can update the 'active' image # reference, if needed. merged_img_path = os.path.join(self._local_volume_dir(snapshot.volume), file_to_merge) if utils.paths_normcase_equal(snap_info['active'], file_to_merge): new_active_file_path = self._vhdutils.get_vhd_parent_path( merged_img_path).lower() snap_info['active'] = os.path.basename(new_active_file_path) self._delete(merged_img_path) # TODO(lpetrut): drop snapshot info file usage. del (snap_info[snapshot.id]) self._write_info_file(info_path, snap_info)
def _delete_snapshot(self, snapshot): # NOTE(lpetrut): We're slightly diverging from the super class # workflow. The reason is that we cannot query in-use vhd/x images, # nor can we add or remove images from a vhd/x chain in this case. volume_status = snapshot.volume.status if volume_status != 'in-use': return super(WindowsSmbfsDriver, self)._delete_snapshot(snapshot) info_path = self._local_path_volume_info(snapshot.volume) snap_info = self._read_info_file(info_path, empty_if_missing=True) if snapshot.id not in snap_info: LOG.info('Snapshot record for %s is not present, allowing ' 'snapshot_delete to proceed.', snapshot.id) return file_to_merge = snap_info[snapshot.id] delete_info = {'file_to_merge': file_to_merge, 'volume_id': snapshot.volume.id} self._nova_assisted_vol_snap_delete( snapshot._context, snapshot, delete_info) # At this point, the image file should no longer be in use, so we # may safely query it so that we can update the 'active' image # reference, if needed. merged_img_path = os.path.join( self._local_volume_dir(snapshot.volume), file_to_merge) if utils.paths_normcase_equal(snap_info['active'], file_to_merge): new_active_file_path = self._vhdutils.get_vhd_parent_path( merged_img_path).lower() snap_info['active'] = os.path.basename(new_active_file_path) self._delete(merged_img_path) # TODO(lpetrut): drop snapshot info file usage. del(snap_info[snapshot.id]) self._write_info_file(info_path, snap_info)
def _delete_snapshot(self, snapshot): # NOTE(lpetrut): We're slightly diverging from the super class # workflow. The reason is that we cannot query in-use vhd/x images, # nor can we add or remove images from a vhd/x chain in this case. info_path = self._local_path_volume_info(snapshot.volume) snap_info = self._read_info_file(info_path, empty_if_missing=True) if snapshot.id not in snap_info: LOG.info('Snapshot record for %s is not present, allowing ' 'snapshot_delete to proceed.', snapshot.id) return file_to_merge = snap_info[snapshot.id] deleting_latest_snap = utils.paths_normcase_equal(snap_info['active'], file_to_merge) if not self._is_volume_attached(snapshot.volume): super(WindowsSmbfsDriver, self)._delete_snapshot(snapshot) else: delete_info = {'file_to_merge': file_to_merge, 'volume_id': snapshot.volume.id} self._nova_assisted_vol_snap_delete( snapshot._context, snapshot, delete_info) # At this point, the image file should no longer be in use, so we # may safely query it so that we can update the 'active' image # reference, if needed. merged_img_path = os.path.join( self._local_volume_dir(snapshot.volume), file_to_merge) if deleting_latest_snap: new_active_file_path = self._vhdutils.get_vhd_parent_path( merged_img_path).lower() snap_info['active'] = os.path.basename(new_active_file_path) self._delete(merged_img_path) # TODO(lpetrut): drop snapshot info file usage. del(snap_info[snapshot.id]) self._write_info_file(info_path, snap_info) if not isinstance(snapshot, objects.Snapshot): LOG.debug("Received a '%s' object, skipping setting the backing " "file in the DB.", type(snapshot)) elif not deleting_latest_snap: backing_file = snapshot['metadata'].get('backing_file') higher_snapshot = self._get_snapshot_by_backing_file( snapshot.volume, file_to_merge) # The snapshot objects should have a backing file set, unless # created before an upgrade. If the snapshot we're deleting # does not have a backing file set yet there is a newer one that # does, we're clearing it out so that it won't provide wrong info. if higher_snapshot: LOG.debug("Updating backing file reference (%(backing_file)s) " "for higher snapshot: %(higher_snapshot_id)s.", dict(backing_file=snapshot.metadata['backing_file'], higher_snapshot_id=higher_snapshot.id)) higher_snapshot.metadata['backing_file'] = ( snapshot.metadata['backing_file']) higher_snapshot.save() if not (higher_snapshot and backing_file): LOG.info( "The deleted snapshot is not latest one, yet we could not " "find snapshot backing file information in the DB. This " "may happen after an upgrade. Certain operations against " "this volume may be unavailable while it's in-use.")
def _delete_snapshot(self, snapshot): # NOTE(lpetrut): We're slightly diverging from the super class # workflow. The reason is that we cannot query in-use vhd/x images, # nor can we add or remove images from a vhd/x chain in this case. info_path = self._local_path_volume_info(snapshot.volume) snap_info = self._read_info_file(info_path, empty_if_missing=True) if snapshot.id not in snap_info: LOG.info( 'Snapshot record for %s is not present, allowing ' 'snapshot_delete to proceed.', snapshot.id) return file_to_merge = snap_info[snapshot.id] deleting_latest_snap = utils.paths_normcase_equal( snap_info['active'], file_to_merge) if not self._is_volume_attached(snapshot.volume): super(WindowsSmbfsDriver, self)._delete_snapshot(snapshot) else: delete_info = { 'file_to_merge': file_to_merge, 'volume_id': snapshot.volume.id } self._nova_assisted_vol_snap_delete(snapshot._context, snapshot, delete_info) # At this point, the image file should no longer be in use, so we # may safely query it so that we can update the 'active' image # reference, if needed. merged_img_path = os.path.join( self._local_volume_dir(snapshot.volume), file_to_merge) if deleting_latest_snap: new_active_file_path = self._vhdutils.get_vhd_parent_path( merged_img_path).lower() snap_info['active'] = os.path.basename(new_active_file_path) self._delete(merged_img_path) # TODO(lpetrut): drop snapshot info file usage. del (snap_info[snapshot.id]) self._write_info_file(info_path, snap_info) if not isinstance(snapshot, objects.Snapshot): LOG.debug( "Received a '%s' object, skipping setting the backing " "file in the DB.", type(snapshot)) elif not deleting_latest_snap: backing_file = snapshot['metadata'].get('backing_file') higher_snapshot = self._get_snapshot_by_backing_file( snapshot.volume, file_to_merge) # The snapshot objects should have a backing file set, unless # created before an upgrade. If the snapshot we're deleting # does not have a backing file set yet there is a newer one that # does, we're clearing it out so that it won't provide wrong info. if higher_snapshot: LOG.debug( "Updating backing file reference (%(backing_file)s) " "for higher snapshot: %(higher_snapshot_id)s.", dict(backing_file=snapshot.metadata['backing_file'], higher_snapshot_id=higher_snapshot.id)) higher_snapshot.metadata['backing_file'] = ( snapshot.metadata['backing_file']) higher_snapshot.save() if not (higher_snapshot and backing_file): LOG.info( "The deleted snapshot is not latest one, yet we could not " "find snapshot backing file information in the DB. This " "may happen after an upgrade. Certain operations against " "this volume may be unavailable while it's in-use.")