def create(dbg, qemudisk, uri, img_qemu_uri): log.debug("%s: xcpng.qemudisk.create: uri: %s " % (dbg, uri)) vdi_uuid = utils.get_vdi_uuid_by_uri(dbg, uri) sr_uuid = utils.get_sr_uuid_by_uri(dbg, uri) vdi_type = utils.get_vdi_type_by_uri(dbg, uri) if vdi_type not in IMAGE_TYPES: raise Exception('Incorrect VDI type') utils.mkdir_p(QEMU_DP_SOCKET_DIR, 0o0700) nbd_sock = QEMU_DP_SOCKET_DIR + "/qemu-nbd.{}".format(vdi_uuid) qmp_sock = QEMU_DP_SOCKET_DIR + "/qmp_sock.{}".format(vdi_uuid) qmp_log = QEMU_DP_SOCKET_DIR + "/qmp_log.{}".format(vdi_uuid) log.debug("%s: xcpng.qemudisk.create: Spawning qemu process for VDI %s with qmp socket at %s" % (dbg, vdi_uuid, qmp_sock)) cmd = [QEMU_DP, qmp_sock] try: log_fd = open(qmp_log, 'w+') p = subprocess.Popen(cmd, stdout=log_fd, stderr=log_fd) except Exception as e: log.error("%s: xcpng.qemudisk.create: Failed to create qemu_dp instance: uri %s" % (dbg, uri)) try: log_fd.close() except: pass raise Exception(e) log.debug("%s: xcpng.qemudisk.create: New qemu process has pid %d" % (dbg, p.pid)) return qemudisk(dbg, sr_uuid, vdi_uuid, vdi_type, img_qemu_uri, p.pid, qmp_sock, nbd_sock, qmp_log)
def get_vdi_meta(self, dbg, uri): log.debug("%s: xcpng.meta.MetadataHandler.get_vdi_meta: uri: %s " % (dbg, uri)) if self.__loaded is False: self.__load(dbg, uri) vdi_uuid = get_vdi_uuid_by_uri(dbg, uri) if vdi_uuid == '': raise('Incorrect VDI uri') return self.__get_meta(dbg, vdi_uuid, 'vdis')
def update_vdi_meta(self, dbg, uri, meta): log.debug("%s: xcpng.meta.MetadataHandler.update_vdi_meta: uri: %s " % (dbg, uri)) if self.__loaded is False: self.__load(dbg, uri) vdi_uuid = get_vdi_uuid_by_uri(dbg, uri) if vdi_uuid == '': raise('Incorrect VDI uri') self.__update(dbg, vdi_uuid, 'vdis', meta)
def find_vdi_children(self, dbg, uri): log.debug("%s: xcpng.meta.MetadataHandler.find_vdi_children: uri: %s" % (dbg, uri)) if self.__loaded is False: self.__load(dbg, uri) try: table = self.db.table('vdis') return table.search(where(PARENT_URI_TAG) == get_vdi_uuid_by_uri(dbg, uri)) except Exception as e: log.error("%s: xcpng.meta.MetadataHandler.find_vdi_children: Failed to find " "children for uri: %s " % (dbg, uri)) raise Exception(e)
def remove_vdi_meta(self, dbg, uri): log.debug("%s: xcpng.meta.MetadataHandler.remove_vdi_meta: uri: %s " % (dbg, uri)) if self.__loaded is False: self.__load(dbg, uri) vdi_uuid = get_vdi_uuid_by_uri(dbg, uri) if vdi_uuid == '': raise ('Incorrect VDI uri') self.db._storage.set_db_name(get_sr_uuid_by_uri(dbg, uri)) self.__remove(dbg, vdi_uuid, 'vdis')
def unlock(self, dbg, uri): log.debug("%s: xcpng.cluster-stack.locks.unlock: uri: %s" % (dbg, uri)) sr_uuid = get_sr_uuid_by_uri(dbg, uri) vdi_uuid = get_vdi_uuid_by_uri(dbg, uri) if vdi_uuid is not None: lock_uuid = vdi_uuid else: lock_uuid = sr_uuid if lock_uuid in self.__lhs: session_id = self.__lhs[lock_uuid] self.__consul.session.destroy(session_id) del self.__lhs[lock_uuid]
def lock(self, dbg, uri, timeout=10): log.debug( "%s: xcpng.cluster-stack.consul.locks.lock: uri: %s timeout %s" % (dbg, uri, timeout)) sr_uuid = get_sr_uuid_by_uri(dbg, uri) vdi_uuid = get_vdi_uuid_by_uri(dbg, uri) if vdi_uuid is not None: lock_uuid = vdi_uuid else: lock_uuid = sr_uuid start_time = time() lh = [None, None, None] if self.__consul.kv.get( key="%s%s" % (CONSUL_KV_LOCKS_PREFIX, sr_uuid))[1] is not None: # SR is locked raise Exception('SR is locked') try: while True: try: if lock_uuid in self.__lhs: raise Exception('Already locked') session_id = self.__consul.session.create() if not self.__consul.kv.put( key="%s%s" % (CONSUL_KV_LOCKS_PREFIX, lock_uuid), acquire=session_id): raise Exception('Already locked') self.__lhs[lock_uuid] = session_id break except Exception as e: if time() - start_time >= timeout: log.error( "%s: xcpng.cluster-stack.consul.locks.lock: Failed to lock: uri: %s" % (dbg, uri)) raise Exception(e) sleep(1) pass except Exception as e: log.error( "%s: xcpng.cluster-stack.consul.locks.lock: Failed to lock: uri: %s" % (dbg, uri)) raise Exception(e)
def lock(self, dbg, uri, timeout=10): log.debug("%s: xcpng.librbd.meta.MetaDBOpeations.lock: uri: %s timeout: %s" % (dbg, uri, timeout)) sr_uuid = get_sr_uuid_by_uri(dbg, uri) vdi_uuid = get_vdi_uuid_by_uri(dbg, uri) pool_name = get_sr_name_by_uri(dbg, uri) if vdi_uuid is not None: lock_uuid = vdi_uuid image_name = get_vdi_name_by_uri(dbg, uri) else: lock_uuid = sr_uuid image_name = '__lock__' start_time = time() lh = [None, None, None] lh[0] = ceph_cluster(dbg, get_cluster_name_by_uri(dbg, uri)) if is_locked(dbg, lh[0], pool_name, '__lock__'): # SR is locked raise ImageBusy try: while True: try: if lock_uuid in self.__lhs: raise ImageExists lh[0].connect() lh[1], lh[2] = rbd_lock(dbg, lh[0], pool_name, image_name) self.__lhs[lock_uuid] = lh break except Exception as e: if time() - start_time >= timeout: log.error("%s: xcpng.librbd.meta.MetaDBOpeations.lock: Failed to lock: uri: %s" % (dbg, uri)) raise Exception(e) sleep(1) pass except Exception as e: log.error("%s: xcpng.librbd.meta.MetaDBOpeations.lock: Failed to lock: uri: %s" % (dbg, uri)) log.error(traceback.format_exc()) lh[0].shutdown() raise Exception(e)
def unlock(self, dbg, uri): log.debug("%s: xcpng.librbd.meta.MetaDBOpeations.unlock: uri: %s" % (dbg, uri)) sr_uuid = get_sr_uuid_by_uri(dbg, uri) vdi_uuid = get_vdi_uuid_by_uri(dbg, uri) if vdi_uuid is not None: lock_uuid = vdi_uuid else: lock_uuid = sr_uuid if lock_uuid in self.__lhs: lh = self.__lhs[lock_uuid] rbd_unlock(dbg, lh) lh[0].shutdown() del self.__lhs[lock_uuid]
def _clone(self, dbg, sr, key, mode, base_meta): log.debug("%s: xcpng.volume.QCOW2Volume._clone: SR: %s Key: %s Mode: %s" % (dbg, sr, key, mode)) swapped = False clone_uri_for_exception = None new_base_uri_for_exception = None datapath = get_vdi_datapath_by_uri(dbg, sr) try: if base_meta[KEY_TAG] == key: # create clone clone_meta = self.create(dbg, sr, base_meta[NAME_TAG], base_meta[DESCRIPTION_TAG], base_meta[VIRTUAL_SIZE_TAG], base_meta[SHARABLE_TAG]) clone_uri_for_exception = clone_meta[URI_TAG][0] # create new base new_base_meta = self.create(dbg, sr, base_meta[NAME_TAG], base_meta[DESCRIPTION_TAG], base_meta[VIRTUAL_SIZE_TAG], base_meta[SHARABLE_TAG]) new_base_uri_for_exception = new_base_meta[URI_TAG][0] self.Datapathes[datapath].DatapathOpsHandler.map_vol(dbg, clone_meta[URI_TAG][0], chained=None) self.Datapathes[datapath].DatapathOpsHandler.map_vol(dbg, new_base_meta[URI_TAG][0], chained=None) call(dbg, ["/usr/lib64/qemu-dp/bin/qemu-img", "rebase", "-u", "-f", base_meta[TYPE_TAG], "-b", self.Datapathes[datapath].DatapathOpsHandler.gen_vol_uri(dbg, base_meta[URI_TAG][0]), self.Datapathes[datapath].DatapathOpsHandler.gen_vol_uri(dbg, new_base_meta[URI_TAG][0])]) call(dbg, ["/usr/lib64/qemu-dp/bin/qemu-img", "rebase", "-u", "-f", clone_meta[TYPE_TAG], "-b", self.Datapathes[datapath].DatapathOpsHandler.gen_vol_uri(dbg, base_meta[URI_TAG][0]), self.Datapathes[datapath].DatapathOpsHandler.gen_vol_uri(dbg, clone_meta[URI_TAG][0])]) self.Datapathes[datapath].DatapathOpsHandler.unmap_vol(dbg, clone_meta[URI_TAG][0], chained=None) # swap backing images uuids for base vdi and new base vdi in metadata self.VolOpsHendler.swap(dbg, base_meta[URI_TAG][0], new_base_meta[URI_TAG][0]) swapped = True base_meta = self.MetadataHandler.get_vdi_meta(dbg, base_meta[URI_TAG][0]) new_base_meta = self.MetadataHandler.get_vdi_meta(dbg, new_base_meta[URI_TAG][0]) clone_meta = self.MetadataHandler.get_vdi_meta(dbg, clone_meta[URI_TAG][0]) merge(base_meta, new_base_meta, snap_merge_pattern) new_base_meta[NAME_TAG] = "(base) %s" % new_base_meta[NAME_TAG] new_base_meta[READ_WRITE_TAG] = False base_meta[PARENT_URI_TAG] = new_base_meta[URI_TAG] base_meta[REF_COUNT_TAG] = 1 clone_parent = new_base_meta[URI_TAG] self.MetadataHandler.update_vdi_meta(dbg, new_base_meta[URI_TAG][0], new_base_meta) self.MetadataHandler.update_vdi_meta(dbg, base_meta[URI_TAG][0], base_meta) if ACTIVE_ON_TAG in base_meta: base_meta[QEMU_IMAGE_URI_TAG] = self.Datapathes[datapath].DatapathOpsHandler.gen_vol_uri(dbg, base_meta[URI_TAG][0]) self.MetadataHandler.update_vdi_meta(dbg, base_meta[URI_TAG][0], base_meta) self.Datapathes[datapath].snapshot(dbg, base_meta[URI_TAG][0], base_meta[URI_TAG][0], 0) else: self.Datapathes[datapath].DatapathOpsHandler.unmap_vol(dbg, base_meta[URI_TAG][0], chained=None) else: # create clone clone_meta = self.create(dbg, sr, base_meta[NAME_TAG], base_meta[DESCRIPTION_TAG], base_meta[VIRTUAL_SIZE_TAG], base_meta[SHARABLE_TAG]) clone_uri_for_exception = clone_meta[URI_TAG][0] self.Datapathes[datapath].DatapathOpsHandler.map_vol(dbg, clone_meta[URI_TAG][0], chained=None) call(dbg, ["/usr/lib64/qemu-dp/bin/qemu-img", "rebase", "-u", "-f", base_meta[TYPE_TAG], "-b", self.Datapathes[datapath].DatapathOpsHandler.gen_vol_uri(dbg, base_meta[URI_TAG][0]), self.Datapathes[datapath].DatapathOpsHandler.gen_vol_uri(dbg, clone_meta[URI_TAG][0])]) self.Datapathes[datapath].DatapathOpsHandler.unmap_vol(dbg, clone_meta[URI_TAG][0], chained=None) clone_parent = base_meta[URI_TAG] merge(base_meta, clone_meta, clone_merge_pattern) clone_meta[PARENT_URI_TAG] = clone_parent if mode is 'snapshot': clone_meta[READ_WRITE_TAG] = False elif mode is 'clone': clone_meta[READ_WRITE_TAG] = True self.MetadataHandler.update_vdi_meta(dbg, clone_meta[URI_TAG][0], clone_meta) return clone_meta except Exception as e: log.error("%s: xcpng.volume.QCOW2Volume._clone: Failed to clone/snapshot volume: key %s: SR: %s" % (dbg, key, sr)) try: if clone_uri_for_exception is not None: self.Datapathes[datapath].DatapathOpsHandler.unmap_vol(dbg, clone_uri_for_exception) except: pass if clone_uri_for_exception is not None: self.destroy(dbg, sr, get_vdi_uuid_by_uri(dbg, clone_uri_for_exception)) if swapped is True: self.VolOpsHendler.swap(dbg, new_base_uri_for_exception, base_meta[URI_TAG][0]) try: if new_base_uri_for_exception is not None: self.Datapathes[datapath].DatapathOpsHandler.unmap_vol(dbg, new_base_uri_for_exception) except: pass if new_base_uri_for_exception is not None: self.destroy(dbg, sr, get_vdi_uuid_by_uri(dbg, new_base_uri_for_exception)) raise Exception(e)