Example #1
0
class PoolHandler(object):
    log = logging.getLogger("Storage.RepoFileHelper.PoolHandler")

    def __init__(self):
        myRead, hisWrite = os.pipe()
        hisRead, myWrite = os.pipe()

        try:
            # Some imports in vdsm assume /usr/share/vdsm is in your PYTHONPATH
            env = os.environ.copy()
            env['PYTHONPATH'] = "%s:%s" % (env.get("PYTHONPATH",
                                                   ""), constants.P_VDSM)
            env['PYTHONPATH'] = ":".join(
                map(os.path.abspath, env['PYTHONPATH'].split(":")))
            self.process = CPopen(
                [constants.EXT_PYTHON, __file__,
                 str(hisRead),
                 str(hisWrite)],
                close_fds=False,
                env=env)

            self.proxy = CrabRPCProxy(myRead, myWrite)

        except:
            os.close(myWrite)
            os.close(myRead)
            raise
        finally:
            os.close(hisRead)
            os.close(hisWrite)

    def stop(self):
        try:
            os.kill(self.process.pid, signal.SIGKILL)
        except:
            pass

        self.process.poll()
        # Don't try to read if the process is in D state
        if (self.process.returncode is not None
                and self.process.returncode != 0):
            err = self.process.stderr.read()
            out = self.process.stdout.read()
            self.log.debug("Pool handler existed, OUT: '%s' ERR: '%s'", out,
                           err)

        try:
            zombiereaper.autoReapPID(self.process.pid)
        except AttributeError:
            if zombiereaper is not None:
                raise

    def __del__(self):
        self.stop()
Example #2
0
class PoolHandler(object):
    log = logging.getLogger("RepoFileHelper.PoolHandler")

    def __init__(self):
        myRead, hisWrite = os.pipe()
        hisRead, myWrite = os.pipe()

        try:
            # Some imports in vdsm assume /usr/share/vdsm is in your PYTHONPATH
            env = os.environ.copy()
            env['PYTHONPATH'] = "%s:%s" % (
                env.get("PYTHONPATH", ""), constants.P_VDSM)
            env['PYTHONPATH'] = ":".join(map(os.path.abspath,
                                             env['PYTHONPATH'].split(":")))
            self.process = BetterPopen([constants.EXT_PYTHON, __file__,
                                       str(hisRead), str(hisWrite)],
                                       close_fds=False, env=env)

            self.proxy = CrabRPCProxy(myRead, myWrite)

        except:
            os.close(myWrite)
            os.close(myRead)
            raise
        finally:
            os.close(hisRead)
            os.close(hisWrite)

    def stop(self):
        try:
            os.kill(self.process.pid, signal.SIGKILL)
        except:
            pass

        self.process.poll()
        # Don't try to read if the process is in D state
        if (self.process.returncode is not None and
                self.process.returncode != 0):
            err = self.process.stderr.read()
            out = self.process.stdout.read()
            self.log.debug("Pool handler existed, OUT: '%s' ERR: '%s'",
                           out, err)

        try:
            zombieReaper.autoReapPID(self.process.pid)
        except AttributeError:
            if zombieReaper is not None:
                raise

    def __del__(self):
        self.stop()
Example #3
0
class QemuImgOperation(object):
    REGEXPR = re.compile(r'\s*\(([\d.]+)/100%\)\s*')

    def __init__(self, cmd, cwd=None):
        self._aborted = False
        self._progress = 0.0

        self._stdout = bytearray()
        self._stderr = bytearray()

        cmd = cmdutils.wrap_command(cmd, with_nice=utils.NICENESS.HIGH,
                                    with_ioclass=utils.IOCLASS.IDLE)
        _log.debug(cmdutils.command_log_line(cmd, cwd=cwd))
        self._command = CPopen(cmd, cwd=cwd, deathSignal=signal.SIGKILL)
        self._stream = utils.CommandStream(
            self._command, self._recvstdout, self._recvstderr)

    def _recvstderr(self, buffer):
        self._stderr += buffer

    def _recvstdout(self, buffer):
        self._stdout += buffer

        # Checking the presence of '\r' before splitting will prevent
        # generating the array when it's not needed.
        try:
            idx = self._stdout.rindex('\r')
        except ValueError:
            return

        # qemu-img updates progress by printing \r (0.00/100%) to standard out.
        # The output could end with a partial progress so we must discard
        # everything after the last \r and then try to parse a progress record.
        valid_progress = self._stdout[:idx]
        last_progress = valid_progress.rsplit('\r', 1)[-1]

        # No need to keep old progress information around
        del self._stdout[:idx + 1]

        m = self.REGEXPR.match(last_progress)
        if m is None:
            raise ValueError('Unable to parse: "%r"' % last_progress)

        self._progress = float(m.group(1))

    @property
    def progress(self):
        return self._progress

    @property
    def error(self):
        return str(self._stderr)

    @property
    def finished(self):
        return self._command.poll() is not None

    def wait(self, timeout=None):
        self._stream.receive(timeout=timeout)

        if not self._stream.closed:
            return

        self._command.wait()

        if self._aborted:
            raise utils.ActionStopped()

        cmdutils.retcode_log_line(self._command.returncode, self.error)
        if self._command.returncode != 0:
            raise QImgError(self._command.returncode, "", self.error)

    def abort(self):
        if self._command.poll() is None:
            self._aborted = True
            self._command.terminate()
Example #4
0
class QemuImgOperation(object):
    REGEXPR = re.compile(r'\s*\(([\d.]+)/100%\)\s*')

    def __init__(self, cmd, cwd=None):
        self._aborted = False
        self._progress = 0.0

        self._stdout = bytearray()
        self._stderr = bytearray()

        cmd = cmdutils.wrap_command(cmd,
                                    with_nice=utils.NICENESS.HIGH,
                                    with_ioclass=utils.IOCLASS.IDLE)
        _log.debug(cmdutils.command_log_line(cmd, cwd=cwd))
        self._command = CPopen(cmd, cwd=cwd, deathSignal=signal.SIGKILL)
        self._stream = utils.CommandStream(self._command, self._recvstdout,
                                           self._recvstderr)

    def _recvstderr(self, buffer):
        self._stderr += buffer

    def _recvstdout(self, buffer):
        self._stdout += buffer

        # Checking the presence of '\r' before splitting will prevent
        # generating the array when it's not needed.
        try:
            idx = self._stdout.rindex('\r')
        except ValueError:
            return

        # qemu-img updates progress by printing \r (0.00/100%) to standard out.
        # The output could end with a partial progress so we must discard
        # everything after the last \r and then try to parse a progress record.
        valid_progress = self._stdout[:idx]
        last_progress = valid_progress.rsplit('\r', 1)[-1]

        # No need to keep old progress information around
        del self._stdout[:idx + 1]

        m = self.REGEXPR.match(last_progress)
        if m is None:
            raise ValueError('Unable to parse: "%r"' % last_progress)

        self._progress = float(m.group(1))

    @property
    def progress(self):
        return self._progress

    @property
    def error(self):
        return str(self._stderr)

    @property
    def finished(self):
        return self._command.poll() is not None

    def wait(self, timeout=None):
        self._stream.receive(timeout=timeout)

        if not self._stream.closed:
            return

        self._command.wait()

        if self._aborted:
            raise utils.ActionStopped()

        cmdutils.retcode_log_line(self._command.returncode, self.error)
        if self._command.returncode != 0:
            raise QImgError(self._command.returncode, "", self.error)

    def abort(self):
        if self._command.poll() is None:
            self._aborted = True
            self._command.terminate()