def non_leaf_coalesce(node, parent, uri, cb): node_vhd = node.vhd parent_vhd = parent.vhd log.debug("non_leaf_coalesce key={}, parent={}".format(node_vhd.id, parent_vhd.id)) opq = cb.volumeStartOperations(uri, 'w') meta_path = cb.volumeMetadataGetPath(opq) node_path = cb.volumeGetPath(opq, str(node_vhd.id)) log.debug("Running vhd-coalesce on {}".format(node_vhd.id)) VHDUtil.coalesce(GC, node_path) db = VHDMetabase(meta_path) with Lock(opq, 'gl', cb): # reparent all of the children to this node's parent children = db.get_children(node_vhd.id) with db.write_context(): journal_entries = db.add_journal_entries(node_vhd.id, parent_vhd.id, children) __reparent_children(opq, db, cb, journal_entries) # remove key log.debug("Destroy {}".format(node_vhd.id)) cb.volumeDestroy(opq, str(node_vhd.id)) with db.write_context(): db.delete_vhd(node_vhd.id) cb.volumeUnlock(opq, node.lock) cb.volumeUnlock(opq, parent.lock) db.close() cb.volumeStopOperations(opq)
def recover_journal(uri, cb): opq = cb.volumeStartOperations(uri, 'w') meta_path = cb.volumeMetadataGetPath(opq) db = VHDMetabase(meta_path) # Take the global SR lock, the coaleasce reparenting happens within this # lock, so if we can get it and if there are any pending operations then # a different process crashed or was aborted and we need to complete # the outstanding operations with Lock(opq, 'gl', cb): # First get any leaf VDIs that need a tap refresh refresh_entries = db.get_refresh_entries() __refresh_leaf_vdis(opq, db, cb, refresh_entries) # Now get the journalled reparent operations journal_entries = db.get_journal_entries() __reparent_children(opq, db, cb, journal_entries)
def find_best_non_leaf_coalesceable_2(uri, cb): opq = cb.volumeStartOperations(uri, 'w') meta_path = cb.volumeMetadataGetPath(opq) db = VHDMetabase(meta_path) ret = (None, None) with Lock(opq, 'gl', cb): nodes = find_non_leaf_coalesceable(db) for node in nodes: parent_lock = cb.volumeTryLock(opq, __create_vhd_lock_name(node.parent_id)) if parent_lock: node_lock = cb.volumeTryLock(opq, __create_vhd_lock_name(node.id)) if node_lock: parent = db.get_vhd_by_id(node.parent_id) ret = (VhdLock(node, node_lock), VhdLock(parent, parent_lock)) break else: cb.volumeUnlock(opq, parent_lock) db.close() cb.volumeStopOperations(opq) return ret
def remove_garbage_vhds(uri, cb): opq = cb.volumeStartOperations(uri, 'w') meta_path = cb.volumeMetadataGetPath(opq) db = VHDMetabase(meta_path) garbage = db.get_garbage_vhds() if len(garbage) > 0: for vhd in garbage: cb.volumeDestroy(opq, str(vhd.id)) with db.write_context(): db.delete_vhd(vhd.id) db.close() cb.volumeStopOperations(opq)