Esempio n. 1
0
def getAllVolumes(sdUUID):
    """
    Return dict {volUUID: ((imgUUIDs,), parentUUID)} of the domain.

    imgUUIDs is a list of all images dependant on volUUID.
    For template based volumes, the first image is the template's image.
    For other volumes, there is just a single imageUUID.
    Template self image is the 1st term in template volume entry images.
    """
    vols = _getVolsTree(sdUUID)
    res = {}
    for volName in vols.iterkeys():
        res[volName] = {'imgs': [], 'parent': None}

    for volName, vImg, parentVol in vols.itervalues():
        res[volName]['parent'] = parentVol
        if vImg not in res[volName]['imgs']:
            res[volName]['imgs'].insert(0, vImg)
        if parentVol != sd.BLANK_UUID:
            try:
                imgIsUnknown = vImg not in res[parentVol]['imgs']
            except KeyError:
                log.warning("Found broken image %s, orphan volume %s/%s, "
                            "parent %s", vImg, sdUUID, volName, parentVol)
            else:
                if imgIsUnknown:
                    res[parentVol]['imgs'].append(vImg)

    return dict((k, sd.ImgsPar(tuple(v['imgs']), v['parent']))
                for k, v in res.iteritems())
Esempio n. 2
0
    def getAllVolumes(self):
        """
        Return dict {volUUID: ((imgUUIDs,), parentUUID)} of the domain.

        Template self image is the 1st term in template volume entry images.
        The parent can't be determined in file domain without reading the
        metadata.
        Setting parent = None for compatibility with block version.
        """
        volMetaPattern = os.path.join(self.mountpoint, self.sdUUID,
                                      sd.DOMAIN_IMAGES, "*", "*.meta")
        volMetaPaths = self.oop.glob.glob(volMetaPattern)
        volumes = {}
        for metaPath in volMetaPaths:
            head, tail = os.path.split(metaPath)
            volUUID, volExt = os.path.splitext(tail)
            imgUUID = os.path.basename(head)
            if volUUID in volumes:
                # Templates have no parents
                volumes[volUUID]['parent'] = sd.BLANK_UUID
                # Template volumes are hard linked in every image directory
                # which is derived from that template, therefore:
                # 1. a template volume which is in use will appear at least
                # twice (in the template image dir and in the derived image
                # dir)
                # 2. Any volume which appears more than once in the dir tree is
                # by definition a template volume.
                # 3. Any image which has more than 1 volume is not a template
                # image. Therefore if imgUUID appears in more than one path
                # then it is not a template.
                if len(
                        tuple(vPath for vPath in volMetaPaths
                              if imgUUID in vPath)) > 1:
                    # Add template additonal image
                    volumes[volUUID]['imgs'].append(imgUUID)
                else:
                    # Insert at head the template self image
                    volumes[volUUID]['imgs'].insert(0, imgUUID)
            else:
                volumes[volUUID] = {'imgs': [imgUUID], 'parent': None}
        return dict((k, sd.ImgsPar(tuple(v['imgs']), v['parent']))
                    for k, v in volumes.iteritems())
Esempio n. 3
0
    def getAllVolumesImages(self):
        """
        Return all the images that depend on a volume.

        Return dicts:
        vols = {volUUID: ([imgUUID1, imgUUID2], parentUUID)]}
        for complete images.
        remnants (same) for broken imgs, orphan volumes, etc.
        """
        vols = {}  # The "legal" volumes: not half deleted/removed volumes.
        remnants = {}  # Volumes which are part of failed image deletes.
        allVols = getAllVolumes(self.sdUUID)
        for volName, ip in allVols.iteritems():
            if (volName.startswith(sd.REMOVED_IMAGE_PREFIX) or
                    ip.imgs[0].startswith(sd.REMOVED_IMAGE_PREFIX)):
                        remnants[volName] = ip
            else:
                # Deleted images are not dependencies of valid volumes.
                images = [img for img in ip.imgs
                          if not img.startswith(sd.REMOVED_IMAGE_PREFIX)]
                vols[volName] = sd.ImgsPar(images, ip.parent)
        return vols, remnants
Esempio n. 4
0
    def getAllVolumes(self):
        """
        Return dict {volUUID: ((imgUUIDs,), parentUUID)} of the domain.

        (imgUUIDs,) is a tuple of all the images that contain a certain
        volUUID.  For non-templates volumes, this tuple consists of a single
        image.  For template volume it consists of all the images that are
        based on the template volume. In that case, the first imgUUID in the
        tuple is the self-image of the template.

        The parent of a non-template volume cannot be determined in file domain
        without reading  the metadata. However, in order to have an output
        compatible to block domain, we report parent as None.

        Template volumes have no parent, and thus we report BLANK_UUID as their
        parentUUID.
        """
        volMetaPattern = os.path.join(self.mountpoint, self.sdUUID,
                                      sd.DOMAIN_IMAGES, "*", "*.meta")
        volMetaPaths = self.oop.glob.glob(volMetaPattern)

        # First create mapping from images to volumes
        images = collections.defaultdict(list)
        for metaPath in volMetaPaths:
            head, tail = os.path.split(metaPath)
            volUUID, volExt = os.path.splitext(tail)
            imgUUID = os.path.basename(head)
            images[imgUUID].append(volUUID)

        # Using images to volumes mapping, we can create volumes to images
        # mapping, detecting template volumes and template images, based on
        # these rules:
        #
        # Template volumes are hard linked in every image directory
        # which is derived from that template, therefore:
        #
        # 1. A template volume which is in use will appear at least twice
        #    (in the template image dir and in the derived image dir)
        #
        # 2. Any volume which appears more than once in the dir tree is
        #    by definition a template volume.
        #
        # 3. Any image which has more than 1 volume is not a template
        #    image.

        volumes = {}
        for imgUUID, volUUIDs in images.iteritems():
            for volUUID in volUUIDs:
                if volUUID in volumes:
                    # This must be a template volume (rule 2)
                    volumes[volUUID]['parent'] = sd.BLANK_UUID
                    if len(volUUIDs) > 1:
                        # This image is not a template (rule 3)
                        volumes[volUUID]['imgs'].append(imgUUID)
                    else:
                        # This image is a template (rule 3)
                        volumes[volUUID]['imgs'].insert(0, imgUUID)
                else:
                    volumes[volUUID] = {'imgs': [imgUUID], 'parent': None}

        return dict((k, sd.ImgsPar(tuple(v['imgs']), v['parent']))
                    for k, v in volumes.iteritems())