示例#1
0
    def create_template_from_volume(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        rsp = AgentRsp()
        volume_abs_path = translate_absolute_path_from_install_path(
            cmd.volumePath)
        install_abs_path = translate_absolute_path_from_install_path(
            cmd.installPath)

        if cmd.sharedVolume:
            lvm.do_active_lv(volume_abs_path, lvm.LvmlockdLockType.SHARE, True)

        with lvm.RecursiveOperateLv(volume_abs_path,
                                    shared=cmd.sharedVolume,
                                    skip_deactivate_tag=IMAGE_TAG):
            virtual_size = linux.qcow2_virtualsize(volume_abs_path)
            if not lvm.lv_exists(install_abs_path):
                lvm.create_lv_from_absolute_path(
                    install_abs_path, virtual_size,
                    "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time()))
            with lvm.OperateLv(install_abs_path,
                               shared=False,
                               delete_when_exception=True):
                linux.create_template(volume_abs_path, install_abs_path)
                logger.debug(
                    'successfully created template[%s] from volume[%s]' %
                    (cmd.installPath, cmd.volumePath))
                if cmd.compareQcow2 is True:
                    logger.debug("comparing qcow2 between %s and %s")
                    bash.bash_errorout("time qemu-img compare %s %s" %
                                       (volume_abs_path, install_abs_path))
                    logger.debug("confirmed qcow2 %s and %s are identical" %
                                 (volume_abs_path, install_abs_path))

        rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid)
        return jsonobject.dumps(rsp)
示例#2
0
def install_drbd():
    mod_installed = bash.bash_r("lsmod | grep drbd") == 0
    mod_exists = bash.bash_r("modinfo drbd") == 0
    utils_installed = bash.bash_r(
        "rpm -ql drbd-utils || rpm -ql drbd84-utils") == 0
    basearch = platform.machine()
    releasever = bash.bash_o("awk '{print $3}' /etc/zstack-release")
    utils_exists, o = bash.bash_ro(
        "ls /opt/zstack-dvd/{}/{}/Packages/drbd-utils*".format(
            basearch, releasever))

    if mod_installed and utils_exists:
        return

    if not mod_installed:
        if mod_exists:
            bash.bash_errorout("modprobe drbd")
        else:
            raise Exception("drbd mod not installed and not exists!")

    if not utils_installed:
        if utils_exists == 0:
            bash.bash_errorout("rpm -ivh %s" % o)
        else:
            raise Exception("drbd utils not installed and not exists!")
    def create_template_from_volume(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        rsp = AgentRsp()
        volume_abs_path = translate_absolute_path_from_install_path(cmd.volumePath)
        install_abs_path = translate_absolute_path_from_install_path(cmd.installPath)

        if cmd.sharedVolume:
            lvm.do_active_lv(volume_abs_path, lvm.LvmlockdLockType.SHARE, True)

        with lvm.RecursiveOperateLv(volume_abs_path, shared=cmd.sharedVolume, skip_deactivate_tags=[IMAGE_TAG]):
            virtual_size = linux.qcow2_virtualsize(volume_abs_path)
            total_size = 0
            for qcow2 in linux.qcow2_get_file_chain(volume_abs_path):
                total_size += int(lvm.get_lv_size(qcow2))

            if total_size > virtual_size:
                total_size = virtual_size

            if not lvm.lv_exists(install_abs_path):
                lvm.create_lv_from_absolute_path(install_abs_path, total_size,
                                                 "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time()))
            with lvm.OperateLv(install_abs_path, shared=False, delete_when_exception=True):
                linux.create_template(volume_abs_path, install_abs_path)
                logger.debug('successfully created template[%s] from volume[%s]' % (cmd.installPath, cmd.volumePath))
                if cmd.compareQcow2 is True:
                    logger.debug("comparing qcow2 between %s and %s")
                    bash.bash_errorout("time qemu-img compare %s %s" % (volume_abs_path, install_abs_path))
                    logger.debug("confirmed qcow2 %s and %s are identical" % (volume_abs_path, install_abs_path))

        rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid)
        return jsonobject.dumps(rsp)
示例#4
0
def add_pv(vg_uuid, disk_path, metadata_size):
    bash.bash_errorout("vgextend --metadatasize %s %s %s" %
                       (metadata_size, vg_uuid, disk_path))
    if bash.bash_r("pvs --nolocking --readonly %s | grep %s" %
                   (disk_path, vg_uuid)):
        raise Exception("disk %s not added to vg %s after vgextend" %
                        (disk_path, vg_uuid))
    def migrate_volumes(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        rsp = AgentRsp()

        for struct in cmd.migrateVolumeStructs:
            target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
            current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath)
            with lvm.OperateLv(current_abs_path, shared=True):
                virtual_size = lvm.get_lv_size(current_abs_path)

                if lvm.lv_exists(target_abs_path):
                    target_ps_uuid = get_primary_storage_uuid_from_install_path(struct.targetInstallPath)
                    raise Exception("found %s already exists on ps %s" %
                                    (target_abs_path, target_ps_uuid))
                lvm.create_lv_from_absolute_path(target_abs_path, virtual_size,
                                                     "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time()))
                lvm.active_lv(target_abs_path, lvm.LvmlockdLockType.SHARE)

        try:
            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath)

                with lvm.OperateLv(current_abs_path, shared=True):
                    bash.bash_errorout("cp %s %s" % (current_abs_path, target_abs_path))

            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath)
                with lvm.RecursiveOperateLv(current_abs_path, shared=True):
                    previous_ps_uuid = get_primary_storage_uuid_from_install_path(struct.currentInstallPath)
                    target_ps_uuid = get_primary_storage_uuid_from_install_path(struct.targetInstallPath)

                    current_backing_file = linux.qcow2_get_backing_file(current_abs_path)  # type: str
                    target_backing_file = current_backing_file.replace(previous_ps_uuid, target_ps_uuid)

                    if current_backing_file is not None and current_backing_file != "":
                        lvm.do_active_lv(target_backing_file, lvm.LvmlockdLockType.SHARE, False)
                        logger.debug("rebase %s to %s" % (target_abs_path, target_backing_file))
                        linux.qcow2_rebase_no_check(target_backing_file, target_abs_path)
                    if struct.compareQcow2:
                        bash.bash_errorout("time qemu-img compare %s %s" % (current_abs_path, target_abs_path))
        except Exception as e:
            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                if struct.currentInstallPath == struct.targetInstallPath:
                    logger.debug("current install path %s equals target %s, skip to delete" %
                                 (struct.currentInstallPath, struct.targetInstallPath))
                else:
                    logger.debug("error happened, delete lv %s" % target_abs_path)
                    lvm.delete_lv(target_abs_path, False)
            raise e
        finally:
            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                lvm.deactive_lv(target_abs_path)

        rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid)
        return jsonobject.dumps(rsp)
示例#6
0
def active_lv(path, shared=False):
    flag = "-ay"
    if shared:
        flag = "-asy"

    bash.bash_errorout("lvchange %s %s" % (flag, path))
    if lv_is_active(path) is False:
        raise Exception("active lv %s with %s failed" % (path, flag))
示例#7
0
def active_lv(path, shared=False):
    flag = "-ay"
    if shared:
        flag = "-asy"

    bash.bash_errorout("lvchange %s %s" % (flag, path))
    if lv_is_active(path) is False:
        raise Exception("active lv %s with %s failed" % (path, flag))
示例#8
0
 def dd_out(self, dst_path, sparse=True):
     need_promte_first = self.get_role() == DrbdRole.Secondary
     need_promte_first and self.promote()
     try:
         bash.bash_errorout('dd if=%s of=%s bs=1M %s' %
                            (self.get_dev_path(), dst_path,
                             'conv=sparse' if sparse else ''))
     finally:
         need_promte_first and self.demote()
示例#9
0
def deactive_lv(path, raise_exception=True):
    if not lv_exists(path):
        return
    if not lv_is_active(path):
        return
    if raise_exception:
        bash.bash_errorout("lvchange -an %s" % path)
    else:
        bash.bash_r("lvchange -an %s" % path)
    if lv_is_active(path):
        raise RetryException("lv %s is still active after lvchange -an" % path)
示例#10
0
def create_lv_from_absolute_path(path, size, tag="zs::sharedblock::volume"):
    vgName = path.split("/")[2]
    lvName = path.split("/")[3]

    bash.bash_errorout("lvcreate -an --addtag %s --size %sb --name %s %s" %
                       (tag, calcLvReservedSize(size), lvName, vgName))
    if not lv_exists(path):
        raise Exception("can not find lv %s after create", path)

    with OperateLv(path, shared=False):
        dd_zero(path)
示例#11
0
def deactive_lv(path, raise_exception=True):
    if not lv_exists(path):
        return
    if not lv_is_active(path):
        return
    if raise_exception:
        bash.bash_errorout("lvchange -an %s" % path)
    else:
        bash.bash_r("lvchange -an %s" % path)
    if lv_is_active(path):
        raise RetryException("lv %s is still active after lvchange -an" % path)
示例#12
0
    def create_thin_pool_if_not_found(vgUuid, init_pool_ratio):
        def round_sector(size, sector):
            return round(float(size) / float(sector)) * sector

        if lvm.lv_exists("/dev/%s/%s_thinpool" % (vgUuid, vgUuid)):
            return
        tot, avil = lvm.get_vg_size(vgUuid)
        init_pool_size = float(tot) * float(init_pool_ratio)
        # meta_size = "%s" % ((tot / DEFAULT_CHUNK_SIZE) * 48 * 2)  # ref: https://www.kernel.org/doc/Documentation/device-mapper/thin-provisioning.txt
        meta_size = 1024**3  # ref: https://www.systutorials.com/docs/linux/man/7-lvmthin/#lbBD
        bash.bash_errorout(
            "lvcreate --type thin-pool -L %sB -c %sB --poolmetadatasize %sB -n %s_thinpool %s"
            % (int(round_sector(init_pool_size, 4096)), DEFAULT_CHUNK_SIZE,
               meta_size, vgUuid, vgUuid))
示例#13
0
    def promote(self, force=False, retry=60, sleep=2):
        @bash.in_bash
        @linux.retry(times=retry, sleep_time=sleep)
        def do_promote():
            f = " --force" if force else ""
            r, o, e = bash.bash_roe("drbdadm primary %s %s" % (self.name, f))
            if self.get_role() != DrbdRole.Primary:
                raise RetryException(
                    "promote failed, return: %s, %s, %s. resource %s still not in role %s"
                    % (r, o, e, self.name, DrbdRole.Primary))

        if not force:
            do_promote()
        else:
            bash.bash_errorout("drbdadm primary %s --force" % self.name)
示例#14
0
 def initialize(self, primary, cmd, backing=None, skip_clear_bits=False):
     bash.bash_errorout("echo yes | drbdadm create-md %s" % self.name)
     self.up()
     if skip_clear_bits:
         return
     if not primary:
         self.clear_bits()
     else:
         self.promote()
         if backing:
             linux.qcow2_create_with_backing_file_and_cmd(
                 backing, self.get_dev_path(), cmd)
         else:
             linux.qcow2_create_with_cmd(self.get_dev_path(), cmd.size, cmd)
         self.demote()
示例#15
0
    def run_self_test(busNumber, deviceNumber, wwn):
        @linux.retry(10, 1)
        @bash.in_bash
        def self_test_is_running(bus, device):
            r = bash.bash_r(
                "smartctl -l selftest -d megaraid,%s /dev/bus/%s | grep 'Self-test routine in progress'"
                % (device, bus))
            if r == 0:
                return
            r, o, e = bash.bash_roe("smartctl -a /dev/bus/%s -d megaraid,%s" %
                                    (bus, device))
            if "Self-test routine in progress" in o + e:
                return
            raise RetryException(
                "can not find self test in progress on drive %s" % wwn)

        @linux.retry(10, 30)
        @bash.in_bash
        def get_self_test_result(bus, device):
            r, o = bash.bash_ro(
                "smartctl -l selftest -d megaraid,%s /dev/bus/%s | grep -E '^# 1'"
                % (device, bus))
            if r != 0 or "00%" not in o:
                raise RetryException(
                    "latest self test not finished on drive %s" % wwn)
            return o.split("Short offline")[1].split("00%")[0].strip()

        @bash.in_bash
        def check_no_running_test(bus, device):
            r, o = bash.bash_ro(
                "smartctl -a /dev/bus/%s -d megaraid,%s | grep 'Self-test routine in progress' -C 5"
                % (bus, device))
            if r == 0:
                return False
            return True

        for i in range(5):
            if check_no_running_test(busNumber, deviceNumber) is True:
                break
            if i == 4:
                # bash.bash_r("smartctl -X /dev/bus/%s -d megaraid,%s")
                raise Exception("there is running test on drive wwn %s" % wwn)
            time.sleep(30)

        bash.bash_errorout("smartctl --test=short /dev/bus/%s -d megaraid,%s" %
                           (busNumber, deviceNumber))
        self_test_is_running(busNumber, deviceNumber)
        return get_self_test_result(busNumber, deviceNumber)
示例#16
0
def lv_rename(old_abs_path, new_abs_path, overwrite=False):
    if not lv_exists(new_abs_path):
        return bash.bash_roe("lvrename %s %s" % (old_abs_path, new_abs_path))

    if overwrite is False:
        raise Exception("lv with name %s is already exists, can not rename lv %s to it" %
                        (new_abs_path, old_abs_path))

    tmp_path = new_abs_path + "_%s" % int(time.time())
    r, o, e = lv_rename(new_abs_path, tmp_path)
    if r != 0:
        raise Exception("rename lv %s to tmp name %s failed: stdout: %s, stderr: %s" %
                        (new_abs_path, tmp_path, o, e))

    r, o, e = lv_rename(old_abs_path, new_abs_path)
    if r != 0:
        bash.bash_errorout("lvrename %s %s" % (tmp_path, new_abs_path))
        raise Exception("rename lv %s to tmp name %s failed: stdout: %s, stderr: %s" %
                        (old_abs_path, new_abs_path, o, e))

    delete_lv(tmp_path, False)
示例#17
0
def install_drbd():
    mod_installed = bash.bash_r("lsmod | grep drbd") == 0
    mod_exists = bash.bash_r("modinfo drbd") == 0
    utils_installed = bash.bash_r(
        "rpm -ql drbd-utils || rpm -ql drbd84-utils") == 0
    utils_exists, o = bash.bash_ro("ls /opt/zstack-dvd/Packages/drbd-utils*")

    if mod_installed and utils_exists:
        return

    if not mod_installed:
        if mod_exists:
            bash.bash_errorout("modprobe drbd")
        else:
            raise Exception("drbd mod not installed and not exists!")

    if not utils_installed:
        if utils_exists == 0:
            bash.bash_errorout("rpm -ivh %s" % o)
        else:
            raise Exception("drbd utils not installed and not exists!")
示例#18
0
def lv_rename(old_abs_path, new_abs_path, overwrite=False):
    if not lv_exists(new_abs_path):
        return bash.bash_roe("lvrename %s %s" % (old_abs_path, new_abs_path))

    if overwrite is False:
        raise Exception("lv with name %s is already exists, can not rename lv %s to it" %
                        (new_abs_path, old_abs_path))

    tmp_path = new_abs_path + "_%s" % int(time.time())
    r, o, e = lv_rename(new_abs_path, tmp_path)
    if r != 0:
        raise Exception("rename lv %s to tmp name %s failed: stdout: %s, stderr: %s" %
                        (new_abs_path, tmp_path, o, e))

    r, o, e = lv_rename(old_abs_path, new_abs_path)
    if r != 0:
        bash.bash_errorout("lvrename %s %s" % (tmp_path, new_abs_path))
        raise Exception("rename lv %s to tmp name %s failed: stdout: %s, stderr: %s" %
                        (old_abs_path, new_abs_path, o, e))

    delete_lv(tmp_path, False)
示例#19
0
def delete_lv(path, raise_exception=True):
    logger.debug("deleting lv %s" % path)
    # remove meta-lv if any
    if lv_exists(get_meta_lv_path(path)):
        shell.run("lvremove -y %s" % get_meta_lv_path(path))
    if not lv_exists(path):
        return
    if raise_exception:
        o = bash.bash_errorout("lvremove -y %s" % path)
    else:
        o = bash.bash_o("lvremove -y %s" % path)
    return o
示例#20
0
def delete_lv(path, raise_exception=True):
    logger.debug("deleting lv %s" % path)
    # remove meta-lv if any
    if lv_exists(get_meta_lv_path(path)):
        shell.run("lvremove -y %s" % get_meta_lv_path(path))
    if not lv_exists(path):
        return
    if raise_exception:
        o = bash.bash_errorout("lvremove -y %s" % path)
    else:
        o = bash.bash_o("lvremove -y %s" % path)
    return o
示例#21
0
 def initialize_with_file(self,
                          primary,
                          src_path,
                          backing=None,
                          backing_fmt=None,
                          skip_clear_bits=False):
     bash.bash_errorout("echo yes | drbdadm create-md %s --force" %
                        self.name)
     self.up()
     if skip_clear_bits:
         return
     if not primary:
         self.clear_bits()
     else:
         self.promote()
         bash.bash_errorout('dd if=%s of=%s bs=1M oflag=direct' %
                            (src_path, self.get_dev_path()))
         if backing:
             linux.qcow2_rebase_no_check(backing,
                                         self.get_dev_path(),
                                         backing_fmt=backing_fmt)
         self.demote()
示例#22
0
    def raid_locate(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        rsp = AgentRsp()

        r, raid_info, e = bash.bash_roe(
            "/opt/MegaRAID/MegaCli/MegaCli64 -LdPdInfo -aALL")
        if r != 0:
            raise Exception(
                "can not execute MegaCli: returnCode: %s, stdout: %s, stderr: %s"
                % (r, raid_info, e))
        drive = self.get_raid_device_info(
            "/dev/bus/%d -d megaraid,%d" % (cmd.busNumber, cmd.deviceNumber),
            raid_info)
        if drive.wwn != cmd.wwn:
            raise Exception(
                "expect drive[busNumber %s, deviceId %s, slotNumber %s] wwn is %s, but is %s actually"
                % (cmd.busNumber, cmd.deviceNumber, cmd.slotNumber, cmd.wwn,
                   drive.wwn))

        command = "start" if cmd.locate is True else "stop"
        bash.bash_errorout(
            "/opt/MegaRAID/MegaCli/MegaCli64 -PdLocate -%s -physdrv[%d:%d] -a%d"
            % (command, cmd.enclosureDeviceID, cmd.slotNumber, cmd.busNumber))
        return jsonobject.dumps(rsp)
    def migrate_volumes(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        rsp = AgentRsp()

        for struct in cmd.migrateVolumeStructs:
            target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
            current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath)
            with lvm.OperateLv(current_abs_path, shared=True):
                lv_size = lvm.get_lv_size(current_abs_path)

                if lvm.lv_exists(target_abs_path):
                    target_ps_uuid = get_primary_storage_uuid_from_install_path(struct.targetInstallPath)
                    raise Exception("found %s already exists on ps %s" %
                                    (target_abs_path, target_ps_uuid))
                lvm.create_lv_from_absolute_path(target_abs_path, lvm.getOriginalSize(lv_size),
                                                     "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time()))
                lvm.active_lv(target_abs_path, lvm.LvmlockdLockType.SHARE)

        try:
            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath)

                with lvm.OperateLv(current_abs_path, shared=True):
                    bash.bash_errorout("cp %s %s" % (current_abs_path, target_abs_path))

            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath)
                with lvm.RecursiveOperateLv(current_abs_path, shared=True):
                    previous_ps_uuid = get_primary_storage_uuid_from_install_path(struct.currentInstallPath)
                    target_ps_uuid = get_primary_storage_uuid_from_install_path(struct.targetInstallPath)

                    current_backing_file = linux.qcow2_get_backing_file(current_abs_path)  # type: str
                    target_backing_file = current_backing_file.replace(previous_ps_uuid, target_ps_uuid)

                    if struct.compareQcow2:
                        logger.debug("comparing qcow2 between %s and %s" % (current_abs_path, target_abs_path))
                        if not self.compare(current_abs_path, target_abs_path):
                            raise Exception("qcow2 %s and %s are not identical" % (current_abs_path, target_abs_path))
                        logger.debug("confirmed qcow2 %s and %s are identical" % (current_abs_path, target_abs_path))
                    if current_backing_file is not None and current_backing_file != "":
                        lvm.do_active_lv(target_backing_file, lvm.LvmlockdLockType.SHARE, False)
                        logger.debug("rebase %s to %s" % (target_abs_path, target_backing_file))
                        linux.qcow2_rebase_no_check(target_backing_file, target_abs_path)
        except Exception as e:
            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                if struct.currentInstallPath == struct.targetInstallPath:
                    logger.debug("current install path %s equals target %s, skip to delete" %
                                 (struct.currentInstallPath, struct.targetInstallPath))
                else:
                    logger.debug("error happened, delete lv %s" % target_abs_path)
                    lvm.delete_lv(target_abs_path, False)
            raise e
        finally:
            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                lvm.deactive_lv(target_abs_path)

        rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid)
        return jsonobject.dumps(rsp)
示例#24
0
 def up(self):
     if not self.minor_allocated() or self.get_cstate(
     ) == DrbdNetState.Unconfigured:
         bash.bash_errorout("drbdadm up %s" % self.name)
示例#25
0
 def do_demote():
     bash.bash_errorout("drbdadm secondary %s" % self.name)
示例#26
0
def add_pv(vg_uuid, disk_path, metadata_size):
    bash.bash_errorout("vgextend --metadatasize %s %s %s" % (metadata_size, vg_uuid, disk_path))
    if bash.bash_r("pvs --nolocking --readonly %s | grep %s" % (disk_path, vg_uuid)):
        raise Exception("disk %s not added to vg %s after vgextend" % (disk_path, vg_uuid))
示例#27
0
 def clear_bits(self):
     bash.bash_errorout("drbdadm new-current-uuid --clear-bitmap %s" %
                        self.name)
示例#28
0
 def resize(self):
     bash.bash_errorout("drbdadm -- --assume-clean resize %s" % self.name)