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)
Exemple #2
0
    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')
Exemple #3
0
    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)
Exemple #4
0
    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)
Exemple #8
0
    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)
Exemple #9
0
    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]
Exemple #10
0
    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)