Beispiel #1
0
def zeroImgVolumes(sdUUID, imgUUID, volUUIDs):
    ProcVol = namedtuple("ProcVol", "proc, vol")
    # Put a sensible value for dd zeroing a 128 M or 1 G chunk and lvremove
    # spent time.
    ZEROING_TIMEOUT = 60000  # [miliseconds]
    log.debug("sd: %s, LVs: %s, img: %s", sdUUID, volUUIDs, imgUUID)
    # Following call to changelv is separate since setting rw permission on an
    # LV fails if the LV is already set to the same value, hence we would not
    # be able to differentiate between a real failure of deltag/addtag and one
    # we would like to ignore (permission is the same)
    try:
        lvm.changelv(sdUUID, volUUIDs, ("--permission", "rw"))
    except se.StorageException as e:
        # Hope this only means that some volumes were already writable.
        log.debug("Ignoring failed permission change: %s", e)
    # blank the volumes.
    zerofds = {}
    poller = select.poll()
    for volUUID in volUUIDs:
        proc = _zeroVolume(sdUUID, volUUID)
        fd = proc.stdout.fileno()
        zerofds[fd] = ProcVol(proc, volUUID)
        poller.register(fd, select.EPOLLHUP)

    # Wait until all the asyncs procs return
    # Yes, this is a potentially infinite loop. Kill the vdsm task.
    while zerofds:
        fdevents = poller.poll(ZEROING_TIMEOUT)  # [(fd, event)]
        toDelete = []
        for fd, event in fdevents:
            proc, vol = zerofds[fd]
            if not proc.wait(0):
                continue
            else:
                poller.unregister(fd)
                zerofds.pop(fd)
                if proc.returncode != 0:
                    log.error(
                        "zeroing %s/%s failed. Zero and remove this "
                        "volume manually. rc=%s %s", sdUUID, vol,
                        proc.returncode, proc.stderr.read(1000))
                else:
                    log.debug("%s/%s was zeroed and will be deleted", sdUUID,
                              volUUID)
                    toDelete.append(vol)
        if toDelete:
            try:
                deleteVolumes(sdUUID, toDelete)
            except se.CannotRemoveLogicalVolume:
                # TODO: Add the list of removed fail volumes to the exception.
                log.error(
                    "Remove failed for some of VG: %s zeroed volumes: "
                    "%s",
                    sdUUID,
                    toDelete,
                    exc_info=True)

    log.debug("finished with VG:%s LVs: %s, img: %s", sdUUID, volUUIDs,
              imgUUID)
    return
Beispiel #2
0
    def __markForDelVols(self, sdUUID, imgUUID, volUUIDs, opTag):
        """
        Mark volumes that will be zeroed or removed.

        Mark for delete just in case that lvremove [lvs] success partialy.
        Mark for zero just in case that zero process is interrupted.

        Tagging is preferable to rename since it can be done in a single lvm
        operation and is resilient to open LVs, etc.
        """
        try:
            lvm.changelv(
                sdUUID,
                volUUIDs,
                (
                    ("-a", "y"),
                    ("--deltag", blockVolume.TAG_PREFIX_IMAGE + imgUUID),
                    ("--addtag", blockVolume.TAG_PREFIX_IMAGE + opTag + imgUUID),
                ),
            )
        except se.StorageException as e:
            log.error(
                "Can't activate or change LV tags in SD %s. " "failing Image %s %s operation for vols: %s. %s",
                sdUUID,
                imgUUID,
                opTag,
                volUUIDs,
                e,
            )
            raise
Beispiel #3
0
def _postZero(sdUUID, volumes):
    # Assumed that there is no any thread that can deactivate these LVs
    # on this host or change the rw permission on this or any other host.

    lvNames = tuple(vol.volUUID for vol in volumes)
    # Assert volumes are writable. (Don't do this at home.)
    try:
        lvm.changelv(sdUUID, lvNames, ("--permission", "rw"))
    except se.StorageException:
        # Hope this only means that some volumes were already writable.
        pass

    lvm.activateLVs(sdUUID, lvNames)

    for lv in lvm.getLV(sdUUID):
        if lv.name in lvNames:
            # wipe out the whole volume
            try:
                misc.ddWatchCopy(
                    "/dev/zero", lvm.lvPath(sdUUID, lv.name),
                    vars.task.aborting, int(lv.size),
                    recoveryCallback=volume.baseAsyncTasksRollback)
            except utils.ActionStopped:
                raise
            except Exception:
                raise se.VolumesZeroingError(lv.name)
Beispiel #4
0
def zeroImgVolumes(sdUUID, imgUUID, volUUIDs):
    ProcVol = namedtuple("ProcVol", "proc, vol")
    # Put a sensible value for dd zeroing a 128 M or 1 G chunk and lvremove
    # spent time.
    ZEROING_TIMEOUT = 60000  # [miliseconds]
    log.debug("sd: %s, LVs: %s, img: %s", sdUUID, volUUIDs, imgUUID)
    # Following call to changelv is separate since setting rw permission on an
    # LV fails if the LV is already set to the same value, hence we would not
    # be able to differentiate between a real failure of deltag/addtag and one
    # we would like to ignore (permission is the same)
    try:
        lvm.changelv(sdUUID, volUUIDs, ("--permission", "rw"))
    except se.StorageException as e:
        # Hope this only means that some volumes were already writable.
        log.debug("Ignoring failed permission change: %s", e)
    # blank the volumes.
    zerofds = {}
    poller = select.poll()
    for volUUID in volUUIDs:
        proc = _zeroVolume(sdUUID, volUUID)
        fd = proc.stdout.fileno()
        zerofds[fd] = ProcVol(proc, volUUID)
        poller.register(fd, select.EPOLLHUP)

    # Wait until all the asyncs procs return
    # Yes, this is a potentially infinite loop. Kill the vdsm task.
    while zerofds:
        fdevents = poller.poll(ZEROING_TIMEOUT)  # [(fd, event)]
        toDelete = []
        for fd, event in fdevents:
            proc, vol = zerofds[fd]
            if not proc.wait(0):
                continue
            else:
                poller.unregister(fd)
                zerofds.pop(fd)
                if proc.returncode != 0:
                    log.error(
                        "zeroing %s/%s failed. Zero and remove this " "volume manually. rc=%s %s",
                        sdUUID,
                        vol,
                        proc.returncode,
                        proc.stderr.read(1000),
                    )
                else:
                    log.debug("%s/%s was zeroed and will be deleted", sdUUID, volUUID)
                    toDelete.append(vol)
        if toDelete:
            try:
                deleteVolumes(sdUUID, toDelete)
            except se.CannotRemoveLogicalVolume:
                # TODO: Add the list of removed fail volumes to the exception.
                log.error("Remove failed for some of VG: %s zeroed volumes: " "%s", sdUUID, toDelete, exc_info=True)

    log.debug("finished with VG:%s LVs: %s, img: %s", sdUUID, volUUIDs, imgUUID)
    return
Beispiel #5
0
def _postZero(sdUUID, volumes):
    #Assumed here that the volume is active.
    #To activate all the volumes of an image at once get its resource.
    #See http://gerrit.usersys.redhat.com/771
    #Assert volumes are writable. (Don't do this at home.)
    lvNames = (vol.volUUID for vol in volumes)
    try:
        lvm.changelv(sdUUID, lvNames, "--permission", "rw")
    except se.StorageException, e:
        #Hope this only means that some volumes were already writable
        pass
Beispiel #6
0
def _postZero(sdUUID, volumes):
    #Assumed here that the volume is active.
    #To activate all the volumes of an image at once get its resource.
    #See http://gerrit.usersys.redhat.com/771
    #Assert volumes are writable. (Don't do this at home.)
    lvNames = (vol.volUUID for vol in volumes)
    try:
        lvm.changelv(sdUUID, lvNames, "--permission", "rw")
    except se.StorageException, e:
        #Hope this only means that some volumes were already writable
        pass
Beispiel #7
0
    def __markForDelVols(self, sdUUID, imgUUID, volUUIDs, opTag):
        """
        Mark volumes that will be zeroed or removed.

        Mark for delete just in case that lvremove [lvs] success partialy.
        Mark for zero just in case that zero process is interrupted.

        Tagging is preferable to rename since it can be done in a single lvm
        operation and is resilient to open LVs, etc.
        """
        try:
            lvm.changelv(sdUUID, volUUIDs, (("-a", "y"),
                         ("--deltag", blockVolume.TAG_PREFIX_IMAGE + imgUUID),
                         ("--addtag", blockVolume.TAG_PREFIX_IMAGE +
                          opTag + imgUUID)))
        except se.StorageException as e:
            log.error("Can't activate or change LV tags in SD %s. "
                      "failing Image %s %s operation for vols: %s. %s",
                      sdUUID, imgUUID, opTag, volUUIDs, e)
            raise