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 __reparent_children(opq, db, cb, journal_entries): for child in journal_entries: child_path = cb.volumeGetPath(opq, str(child.id)) # Find all leaves having child as an ancestor leaves = [] find_leaves(db.get_vhd_by_id(child.id), db, leaves) # reparent child to grandparent log.debug("Reparenting {} to {}".format(child.id, child.new_parent_id)) with db.write_context(): db.update_vhd_parent(child.id, child.new_parent_id) new_parent_path = cb.volumeGetPath(opq, str(child.new_parent_id)) VHDUtil.set_parent(GC, child_path, new_parent_path) db.remove_journal_entry(child.id) # Add leaves to database leaves_to_refresh = db.add_refresh_entries(child.id, leaves) # Refresh all leaves having child as an ancestor log.debug( ("Children {}: refreshing all " "leaves: {}").format(child.id, leaves_to_refresh)) __refresh_leaf_vdis(opq, db, cb, leaves_to_refresh)