Example #1
0
def test_bootstrap(tmp_storage, read_only):
    dev_size = 20 * 1024**3

    lvm.set_read_only(False)

    dev1 = tmp_storage.create_device(dev_size)
    vg1_name = str(uuid.uuid4())
    lvm.createVG(vg1_name, [dev1], "initial-tag", 128)

    dev2 = tmp_storage.create_device(dev_size)
    vg2_name = str(uuid.uuid4())
    lvm.createVG(vg2_name, [dev2], "initial-tag", 128)

    vgs = (vg1_name, vg2_name)

    for vg_name in vgs:
        # Create active lvs.
        for lv_name in ("skip", "prepared", "opened", "unused"):
            lvm.createLV(vg_name, lv_name, 1024)

        # Create links to prepared lvs.
        img_dir = os.path.join(sc.P_VDSM_STORAGE, vg_name, "img")
        os.makedirs(img_dir)
        os.symlink(
            lvm.lvPath(vg_name, "prepared"),
            os.path.join(img_dir, "prepared"))

    # Open some lvs during bootstrap.
    vg1_opened = lvm.lvPath(vg1_name, "opened")
    vg2_opened = lvm.lvPath(vg2_name, "opened")
    with open(vg1_opened), open(vg2_opened):

        lvm.set_read_only(read_only)

        lvm.bootstrap(skiplvs=["skip"])

        # Lvs in skiplvs, prepared lvs, and opened lvs should be active.
        for vg_name in vgs:
            for lv_name in ("skip", "prepared", "opened"):
                lv = lvm.getLV(vg_name, lv_name)
                assert lv.active

        # Unused lvs should not be active.
        for vg_name in vgs:
            lv = lvm.getLV(vg_name, "unused")
            assert not lv.active
Example #2
0
def test_bootstrap(tmp_storage, read_only):
    dev_size = 20 * GiB

    lvm.set_read_only(False)

    dev1 = tmp_storage.create_device(dev_size)
    vg1_name = str(uuid.uuid4())
    lvm.createVG(vg1_name, [dev1], "initial-tag", 128)

    dev2 = tmp_storage.create_device(dev_size)
    vg2_name = str(uuid.uuid4())
    lvm.createVG(vg2_name, [dev2], "initial-tag", 128)

    vgs = (vg1_name, vg2_name)

    for vg_name in vgs:
        # Create active lvs.
        for lv_name in ("skip", "prepared", "opened", "unused"):
            lvm.createLV(vg_name, lv_name, 1024)

        # Create links to prepared lvs.
        img_dir = os.path.join(sc.P_VDSM_STORAGE, vg_name, "img")
        os.makedirs(img_dir)
        os.symlink(
            lvm.lvPath(vg_name, "prepared"),
            os.path.join(img_dir, "prepared"))

    # Open some lvs during bootstrap.
    vg1_opened = lvm.lvPath(vg1_name, "opened")
    vg2_opened = lvm.lvPath(vg2_name, "opened")
    with open(vg1_opened), open(vg2_opened):

        lvm.set_read_only(read_only)

        lvm.bootstrap(skiplvs=["skip"])

        # Lvs in skiplvs, prepared lvs, and opened lvs should be active.
        for vg_name in vgs:
            for lv_name in ("skip", "prepared", "opened"):
                lv = lvm.getLV(vg_name, lv_name)
                assert lv.active

        # Unused lvs should not be active.
        for vg_name in vgs:
            lv = lvm.getLV(vg_name, "unused")
            assert not lv.active
Example #3
0
 def _create_image_path(self):
     image_path = self._get_image_path()
     if not os.path.isdir(image_path):
         self.log.info("Create placeholder %s for image's volumes",
                       image_path)
         os.mkdir(image_path)
     os.symlink(lvm.lvPath(self.sd_manifest.sdUUID, self.vol_id),
                self.volume_path)
Example #4
0
 def _create_image_path(self):
     image_path = self._get_image_path()
     if not os.path.isdir(image_path):
         self.log.info("Create placeholder %s for image's volumes",
                       image_path)
         os.mkdir(image_path)
     os.symlink(lvm.lvPath(self.sd_manifest.sdUUID, self.vol_id),
                self.volume_path)
Example #5
0
    def _putMetadata(cls, metaId, meta):
        vgname, offs = metaId

        data = cls.formatMetadata(meta)
        data += "\0" * (sc.METADATA_SIZE - len(data))

        metavol = lvm.lvPath(vgname, sd.METADATA)
        with directio.DirectFile(metavol, "r+") as f:
            f.seek(offs * sc.METADATA_SIZE)
            f.write(data)
Example #6
0
    def _putMetadata(cls, metaId, meta):
        vgname, offs = metaId

        data = cls.formatMetadata(meta)
        data += "\0" * (sc.METADATA_SIZE - len(data))

        metavol = lvm.lvPath(vgname, sd.METADATA)
        with directio.DirectFile(metavol, "r+") as f:
            f.seek(offs * sc.METADATA_SIZE)
            f.write(data)
Example #7
0
    def _create(cls, dom, imgUUID, volUUID, capacity, volFormat, preallocate,
                volParent, srcImgUUID, srcVolUUID, volPath, initial_size=None,
                add_bitmaps=False):
        """
        Class specific implementation of volumeCreate. All the exceptions are
        properly handled and logged in volume.create()
        """

        lv_size = cls.calculate_volume_alloc_size(
            preallocate, volFormat, capacity, initial_size)
        lv_size_mb = utils.round(lv_size, MiB) // MiB

        lvm.createLV(dom.sdUUID, volUUID, lv_size_mb, activate=True,
                     initialTags=(sc.TAG_VOL_UNINIT,))

        fileutils.rm_file(volPath)
        lvPath = lvm.lvPath(dom.sdUUID, volUUID)
        cls.log.info("Creating volume symlink from %r to %r", lvPath, volPath)
        os.symlink(lvPath, volPath)

        if not volParent:
            cls.log.info("Request to create %s volume %s with capacity = %s",
                         sc.type2name(volFormat), volPath, capacity)
            if volFormat == sc.COW_FORMAT:
                operation = qemuimg.create(volPath,
                                           size=capacity,
                                           format=sc.fmt2str(volFormat),
                                           qcow2Compat=dom.qcow2_compat())
                operation.run()
        else:
            # Create hardlink to template and its meta file
            cls.log.info("Request to create snapshot %s/%s of volume %s/%s "
                         "with capacity %s",
                         imgUUID, volUUID, srcImgUUID, srcVolUUID, capacity)
            volParent.clone(volPath, volFormat, capacity)

        with dom.acquireVolumeMetadataSlot(volUUID) as slot:
            mdTags = ["%s%s" % (sc.TAG_PREFIX_MD, slot),
                      "%s%s" % (sc.TAG_PREFIX_PARENT, srcVolUUID),
                      "%s%s" % (sc.TAG_PREFIX_IMAGE, imgUUID)]
            lvm.changeLVsTags(
                dom.sdUUID,
                (volUUID,),
                delTags=[sc.TAG_VOL_UNINIT],
                addTags=mdTags)

        try:
            lvm.deactivateLVs(dom.sdUUID, [volUUID])
        except se.CannotDeactivateLogicalVolume:
            cls.log.warn("Cannot deactivate new created volume %s/%s",
                         dom.sdUUID, volUUID, exc_info=True)

        return (dom.sdUUID, slot)
Example #8
0
 def validateVolumePath(self):
     """
     Block SD supports lazy volume link creation. Note that the volume can
     be still inactive.
     An explicit prepare is required to validate that the volume is active.
     """
     if not self._imagePath:
         self.validateImagePath()
     volPath = os.path.join(self._imagePath, self.volUUID)
     if not os.path.lexists(volPath):
         srcPath = lvm.lvPath(self.sdUUID, self.volUUID)
         self.log.info("Creating symlink from %s to %s", srcPath, volPath)
         os.symlink(srcPath, volPath)
     self._volumePath = volPath
Example #9
0
 def validateVolumePath(self):
     """
     Block SD supports lazy volume link creation. Note that the volume can
     be still inactive.
     An explicit prepare is required to validate that the volume is active.
     """
     if not self._imagePath:
         self.validateImagePath()
     volPath = os.path.join(self._imagePath, self.volUUID)
     if not os.path.lexists(volPath):
         srcPath = lvm.lvPath(self.sdUUID, self.volUUID)
         self.log.info("Creating symlink from %s to %s", srcPath, volPath)
         os.symlink(srcPath, volPath)
     self._volumePath = volPath
Example #10
0
    def _create(cls, dom, imgUUID, volUUID, size, volFormat, preallocate,
                volParent, srcImgUUID, srcVolUUID, volPath, initialSize=None):
        """
        Class specific implementation of volumeCreate. All the exceptions are
        properly handled and logged in volume.create()
        """

        lvSize = cls.calculate_volume_alloc_size(preallocate,
                                                 size, initialSize)

        lvm.createLV(dom.sdUUID, volUUID, lvSize, activate=True,
                     initialTags=(sc.TAG_VOL_UNINIT,))

        fileutils.rm_file(volPath)
        lvPath = lvm.lvPath(dom.sdUUID, volUUID)
        cls.log.info("Creating volume symlink from %r to %r", lvPath, volPath)
        os.symlink(lvPath, volPath)

        if not volParent:
            cls.log.info("Request to create %s volume %s with size = %s "
                         "blocks", sc.type2name(volFormat), volPath,
                         size)
            if volFormat == sc.COW_FORMAT:
                operation = qemuimg.create(volPath,
                                           size=size * BLOCK_SIZE,
                                           format=sc.fmt2str(volFormat),
                                           qcow2Compat=dom.qcow2_compat())
                operation.run()
        else:
            # Create hardlink to template and its meta file
            cls.log.info("Request to create snapshot %s/%s of volume %s/%s "
                         "with size %s (blocks)",
                         imgUUID, volUUID, srcImgUUID, srcVolUUID, size)
            volParent.clone(volPath, volFormat, size)

        with dom.acquireVolumeMetadataSlot(volUUID) as slot:
            mdTags = ["%s%s" % (sc.TAG_PREFIX_MD, slot),
                      "%s%s" % (sc.TAG_PREFIX_PARENT, srcVolUUID),
                      "%s%s" % (sc.TAG_PREFIX_IMAGE, imgUUID)]
            lvm.changeLVTags(dom.sdUUID, volUUID, delTags=[sc.TAG_VOL_UNINIT],
                             addTags=mdTags)

        try:
            lvm.deactivateLVs(dom.sdUUID, [volUUID])
        except se.CannotDeactivateLogicalVolume:
            cls.log.warn("Cannot deactivate new created volume %s/%s",
                         dom.sdUUID, volUUID, exc_info=True)

        return (dom.sdUUID, slot)
Example #11
0
    def _create(cls, dom, imgUUID, volUUID, size, volFormat, preallocate,
                volParent, srcImgUUID, srcVolUUID, volPath, initialSize=None):
        """
        Class specific implementation of volumeCreate. All the exceptions are
        properly handled and logged in volume.create()
        """

        lvSize = cls.calculate_volume_alloc_size(preallocate,
                                                 size, initialSize)

        lvm.createLV(dom.sdUUID, volUUID, "%s" % lvSize, activate=True,
                     initialTags=(sc.TAG_VOL_UNINIT,))

        fileutils.rm_file(volPath)
        os.symlink(lvm.lvPath(dom.sdUUID, volUUID), volPath)

        if not volParent:
            cls.log.info("Request to create %s volume %s with size = %s "
                         "sectors", sc.type2name(volFormat), volPath,
                         size)
            if volFormat == sc.COW_FORMAT:
                qemuimg.create(volPath,
                               size=size * BLOCK_SIZE,
                               format=sc.fmt2str(volFormat),
                               qcow2Compat=dom.qcow2_compat())
        else:
            # Create hardlink to template and its meta file
            cls.log.info("Request to create snapshot %s/%s of volume %s/%s",
                         imgUUID, volUUID, srcImgUUID, srcVolUUID)
            volParent.clone(volPath, volFormat)

        with dom.acquireVolumeMetadataSlot(
                volUUID, sc.VOLUME_MDNUMBLKS) as slot:
            mdTags = ["%s%s" % (sc.TAG_PREFIX_MD, slot),
                      "%s%s" % (sc.TAG_PREFIX_PARENT, srcVolUUID),
                      "%s%s" % (sc.TAG_PREFIX_IMAGE, imgUUID)]
            lvm.changeLVTags(dom.sdUUID, volUUID, delTags=[sc.TAG_VOL_UNINIT],
                             addTags=mdTags)

        try:
            lvm.deactivateLVs(dom.sdUUID, [volUUID])
        except se.CannotDeactivateLogicalVolume:
            cls.log.warn("Cannot deactivate new created volume %s/%s",
                         dom.sdUUID, volUUID, exc_info=True)

        return (dom.sdUUID, slot)
Example #12
0
    def getMetadata(self, metaId=None):
        """
        Get Meta data array of key,values lines
        """
        if not metaId:
            metaId = self.getMetadataId()

        vgname, offs = metaId

        try:
            lines = misc.readblock(lvm.lvPath(vgname, sd.METADATA),
                                   offs * sc.METADATA_SIZE, sc.METADATA_SIZE)
        except Exception as e:
            self.log.error(e, exc_info=True)
            raise se.VolumeMetadataReadError("%s: %s" % (metaId, e))

        md = VolumeMetadata.from_lines(lines)
        return md.legacy_info()
Example #13
0
    def getMetadata(self, metaId=None):
        """
        Get Meta data array of key,values lines
        """
        if not metaId:
            metaId = self.getMetadataId()

        vgname, offs = metaId

        try:
            lines = misc.readblock(lvm.lvPath(vgname, sd.METADATA),
                                   offs * sc.METADATA_SIZE,
                                   sc.METADATA_SIZE)
        except Exception as e:
            self.log.error(e, exc_info=True)
            raise se.VolumeMetadataReadError("%s: %s" % (metaId, e))

        md = VolumeMetadata.from_lines(lines)
        return md.legacy_info()
Example #14
0
 def getDevPath(self):
     """
     Return the underlying device (for sharing)
     """
     return lvm.lvPath(self.sdUUID, self.volUUID)
Example #15
0
 def getDevPath(self):
     """
     Return the underlying device (for sharing)
     """
     return lvm.lvPath(self.sdUUID, self.volUUID)