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()
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()
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()
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()