def cmd(self, cmd, devices=tuple()): finalCmd = self._addExtraCfg(cmd, devices) rc, out, err = misc.execCmd(finalCmd, sudo=True) if rc != 0: # Filter might be stale self.invalidateFilter() newCmd = self._addExtraCfg(cmd) # Before blindly trying again make sure # that the commands are not identical, because # the devlist is sorted there is no fear # of two identical filters looking differently if newCmd != finalCmd: return misc.execCmd(newCmd, sudo=True) return rc, out, err
def _checkForMail(self): # Lock is acquired in order to make sure that neither _numHosts nor # incomingMail are changed during checkForMail self._inLock.acquire() try: # self.log.debug("SPM_MailMonitor -_checking for mail") cmd = self._inCmd + ['bs=' + str(self._outMailLen)] # self.log.debug("SPM_MailMonitor - reading incoming mail, " # "command: " + str(cmd)) (rc, in_mail, err) = misc.execCmd(cmd, raw=True) if rc: raise IOError(errno.EIO, "_handleRequests._checkForMail - " "Could not read mailbox: %s" % self._inbox) if (len(in_mail) != (self._outMailLen)): self.log.error('SPM_MailMonitor: _checkForMail - dd succeeded ' 'but read %d bytes instead of %d, cannot check ' 'mail. Read mail contains: %s', len(in_mail), self._outMailLen, repr(in_mail[:80])) raise RuntimeError("_handleRequests._checkForMail - Could not " "read mailbox") # self.log.debug("Parsing inbox content: %s", in_mail) if self._handleRequests(in_mail): self._outLock.acquire() try: cmd = self._outCmd + ['bs=' + str(self._outMailLen)] (rc, out, err) = _mboxExecCmd(cmd, data=self._outgoingMail) if rc: self.log.warning("SPM_MailMonitor couldn't write " "outgoing mail, dd failed") finally: self._outLock.release() finally: self._inLock.release()
def initLock(self): lockUtil = constants.EXT_SAFELEASE initCommand = [lockUtil, "release", "-f", self._leasesPath, "0"] rc, out, err = misc.execCmd(initCommand, cwd=self.lockUtilPath) if rc != 0: self.log.warn("could not initialise spm lease (%s): %s", rc, out) raise se.ClusterLockInitError()
def _multipath_status(): cmd = [EXT_DMSETUP, "status", "--target", "multipath"] rc, out, err = misc.execCmd(cmd, raw=True) if rc != 0: raise cmdutils.Error(cmd, rc, out, err) res = {} lines = out.decode("utf-8").splitlines() for line in lines: try: guid, paths = line.split(":", 1) except ValueError: # TODO check if this output is relevant if len(lines) != 1: raise # return an empty dict when status output is: No devices found return res statuses = [] for m in PATH_STATUS_RE.finditer(paths): major_minor, status = m.groups() name = device_name(major_minor) statuses.append(PathStatus(name, status)) res[guid] = statuses return res
def acquire(self, hostID, lease): if lease != self._lease: raise MultipleLeasesNotSupported("acquire", lease) leaseTimeMs = self._leaseTimeSec * 1000 ioOpTimeoutMs = self._ioOpTimeoutSec * 1000 with self._lock: self.log.debug("Acquiring cluster lock for domain %s" % self._sdUUID) lockUtil = self.getLockUtilFullPath() acquireLockCommand = subprocess.list2cmdline([ lockUtil, "start", self._sdUUID, str(hostID), str(self._lockRenewalIntervalSec), str(lease.path), str(leaseTimeMs), str(ioOpTimeoutMs), str(self._leaseFailRetry), str(os.getpid()) ]) cmd = [constants.EXT_SU, misc.IOUSER, '-s', constants.EXT_SH, '-c', acquireLockCommand] (rc, out, err) = misc.execCmd(cmd, cwd=self.lockUtilPath, sudo=True, ioclass=utils.IOCLASS.REALTIME, ioclassdata=0, setsid=True) if rc != 0: raise se.AcquireLockFailure(self._sdUUID, rc, out, err) self.log.debug("Clustered lock acquired successfully")
def runScanArgs(*args): cmd = [_virtAlignmentScan.cmd] cmd.extend(args) # TODO: remove the environment variable when the issue in # virt-alignment-scan/libvirt is resolved # http://bugzilla.redhat.com/1151838 return execCmd(cmd, env={'LIBGUESTFS_BACKEND': 'direct'})
def _genInitramfs(): logging.warning('Generating a temporary initramfs image') fd, path = tempfile.mkstemp() cmd = [_mkinitrd.cmd, "-f", path, _kernelVer] rc, out, err = execCmd(cmd) os.chmod(path, 0o644) return path
def initLock(self, lease): if lease != self._lease: raise MultipleLeasesNotSupported("init", lease) lockUtil = constants.EXT_SAFELEASE initCommand = [lockUtil, "release", "-f", lease.path, "0"] rc, out, err = misc.execCmd(initCommand, cwd=self.lockUtilPath) if rc != 0: self.log.warn("could not initialise spm lease (%s): %s", rc, out) raise se.ClusterLockInitError()
def rescan(): """ Forces multipath daemon to rescan the list of available devices and refresh the mapping table. New devices can be found under /dev/mapper Should only be called from hsm._rescanDevices() """ # First rescan iSCSI and FCP connections iscsi.rescan() hba.rescan() # Now let multipath daemon pick up new devices misc.execCmd([constants.EXT_MULTIPATH], sudo=True) # Scanning SCSI interconnects starts a storm of udev events. Wait until all # events are processed, ensuring detection of new devices and creation or # update of multipath devices. timeout = config.getint('irs', 'scsi_settle_timeout') udevadm.settle(timeout)
def fuser(path, mountPoint=False): cmd = [constants.EXT_FUSER] if mountPoint: cmd.append("-m") cmd.append(path) (rc, out, err) = misc.execCmd(cmd, raw=True) if rc != 0: return [] return [int(pid) for pid in out.split()]
def _checkForMail(self): # self.log.debug("HSM_MailMonitor - checking for mail") # self.log.debug("Running command: " + str(self._inCmd)) (rc, in_mail, err) = misc.execCmd(self._inCmd, raw=True) if rc: raise RuntimeError("_handleResponses.Could not read mailbox - rc " "%s" % rc) if (len(in_mail) != MAILBOX_SIZE): raise RuntimeError("_handleResponses.Could not read mailbox - len " "%s != %s" % (len(in_mail), MAILBOX_SIZE)) # self.log.debug("Parsing inbox content: %s", in_mail) return self._handleResponses(in_mail)
def getScsiSerial(physdev): blkdev = os.path.join("/dev", physdev) cmd = [ _SCSI_ID.cmd, "--page=0x80", "--whitelisted", "--export", "--replace-whitespace", "--device=" + blkdev ] (rc, out, err) = misc.execCmd(cmd) if rc == 0: for line in out: if line.startswith("ID_SERIAL="): return line.split("=")[1] return ""
def createFloppyImage(size): fd, path = mkstemp() with os.fdopen(fd, "w") as f: f.seek(size) f.write('\0') try: rc, out, err = execCmd(['/sbin/mkfs.ext2', "-F", path]) except OSError: try: rc, out, err = execCmd(['/usr/sbin/mkfs.ext2', "-F", path]) except OSError as e: if e.errno == errno.ENOENT: raise SkipTest("cannot execute mkfs.ext2") raise if rc != 0: raise Exception("Could not format image", out, err) try: yield path finally: os.unlink(path)
def getScsiSerial(physdev): blkdev = os.path.join("/dev", physdev) cmd = [_SCSI_ID.cmd, "--page=0x80", "--whitelisted", "--export", "--replace-whitespace", "--device=" + blkdev] (rc, out, err) = misc.execCmd(cmd) if rc == 0: for line in out: if line.startswith("ID_SERIAL="): return line.split("=")[1] return ""
def createLV(vgName, lvName, size, activate=True, contiguous=False, initialTags=()): """ Size units: MB (1024 ** 2 = 2 ** 20)B. """ # WARNING! From man vgs: # All sizes are output in these units: (h)uman-readable, (b)ytes, # (s)ectors, (k)ilobytes, (m)egabytes, (g)igabytes, (t)erabytes, # (p)etabytes, (e)xabytes. # Capitalise to use multiples of 1000 (S.I.) instead of 1024. log.info( "Creating LV (vg=%s, lv=%s, size=%sm, activate=%s, " "contiguous=%s, initialTags=%s)", vgName, lvName, size, activate, contiguous, initialTags) cont = {True: "y", False: "n"}[contiguous] cmd = ["lvcreate"] cmd.extend(LVM_NOBACKUP) cmd.extend(("--contiguous", cont, "--size", "%sm" % size)) for tag in initialTags: cmd.extend(("--addtag", tag)) cmd.extend(("--name", lvName, vgName)) rc, out, err = _lvminfo.cmd(cmd, _lvminfo._getVGDevs((vgName, ))) if rc == 0: _lvminfo._invalidatevgs(vgName) _lvminfo._invalidatelvs(vgName, lvName) else: raise se.CannotCreateLogicalVolume(vgName, lvName, err) # TBD: Need to explore the option of running lvcreate w/o devmapper # so that if activation is not needed it would be skipped in the # first place if activate: lv_path = lvPath(vgName, lvName) st = os.stat(lv_path) uName = pwd.getpwuid(st.st_uid).pw_name gName = grp.getgrgid(st.st_gid).gr_name if ":".join((uName, gName)) != USER_GROUP: cmd = [constants.EXT_CHOWN, USER_GROUP, lv_path] if misc.execCmd(cmd, sudo=True)[0] != 0: log.warning( "Could not change ownership of one or more " "volumes in vg (%s) - %s", vgName, lvName) else: _setLVAvailability(vgName, lvName, "n")
def testSymlinkMount(self): with namedTemporaryDir() as root_dir: backing_image = os.path.join(root_dir, 'backing.img') link_to_image = os.path.join(root_dir, 'link_to_image') mountpoint = os.path.join(root_dir, 'mountpoint') with open(backing_image, 'w') as f: os.ftruncate(f.fileno(), 1024 ** 3) rc, out, err = execCmd(['/sbin/mkfs.ext2', "-F", backing_image], raw=True) if rc != 0: raise RuntimeError("Error creating filesystem: %s" % err) os.symlink(backing_image, link_to_image) os.mkdir(mountpoint) m = mount.Mount(link_to_image, mountpoint) with loop_mount(m): self.assertTrue(m.isMounted())
def testSymlinkMount(self): with namedTemporaryDir() as root_dir: backing_image = os.path.join(root_dir, 'backing.img') link_to_image = os.path.join(root_dir, 'link_to_image') mountpoint = os.path.join(root_dir, 'mountpoint') with open(backing_image, 'w') as f: os.ftruncate(f.fileno(), 1024**3) rc, out, err = execCmd(['/sbin/mkfs.ext2', "-F", backing_image], raw=True) if rc != 0: raise RuntimeError("Error creating filesystem: %s" % err) os.symlink(backing_image, link_to_image) os.mkdir(mountpoint) m = mount.Mount(link_to_image, mountpoint) with loop_mount(m): self.assertTrue(m.isMounted())
def release(self): with self._lock: freeLockUtil = os.path.join(self.lockUtilPath, self.freeLockCmd) releaseLockCommand = [freeLockUtil, self._sdUUID] self.log.info("Releasing cluster lock for domain %s" % self._sdUUID) (rc, out, err) = misc.execCmd(releaseLockCommand, raw=True, cwd=self.lockUtilPath) if rc != 0: # TODO: should raise self.log.error("Could not release cluster lock for domain %s " "(rc=%d, out=%s, err=%s)" % (self._sdUUID, rc, out, err)) return self.log.debug("Cluster lock for domain %s released successfully", self._sdUUID)
def _runCmd(args, hideValue=False, sync=True): # FIXME: I don't use supervdsm because this entire module has to just be # run as root and there is no such feature yet in supervdsm. When such # feature exists please change this. with _iscsiadmLock: cmd = [constants.EXT_ISCSIADM] + args printCmd = None if hideValue: printCmd = cmd[:] for i, arg in enumerate(printCmd): if arg != "-v": continue if i < (len(printCmd) - 1): printCmd[i + 1] = "****" return misc.execCmd(cmd, printable=printCmd, sudo=True, sync=sync)
def createLV(vgName, lvName, size, activate=True, contiguous=False, initialTags=()): """ Size units: MB (1024 ** 2 = 2 ** 20)B. """ # WARNING! From man vgs: # All sizes are output in these units: (h)uman-readable, (b)ytes, # (s)ectors, (k)ilobytes, (m)egabytes, (g)igabytes, (t)erabytes, # (p)etabytes, (e)xabytes. # Capitalise to use multiples of 1000 (S.I.) instead of 1024. log.info("Creating LV (vg=%s, lv=%s, size=%sm, activate=%s, " "contiguous=%s, initialTags=%s)", vgName, lvName, size, activate, contiguous, initialTags) cont = {True: "y", False: "n"}[contiguous] cmd = ["lvcreate"] cmd.extend(LVM_NOBACKUP) cmd.extend(("--contiguous", cont, "--size", "%sm" % size)) for tag in initialTags: cmd.extend(("--addtag", tag)) cmd.extend(("--name", lvName, vgName)) rc, out, err = _lvminfo.cmd(cmd, _lvminfo._getVGDevs((vgName, ))) if rc == 0: _lvminfo._invalidatevgs(vgName) _lvminfo._invalidatelvs(vgName, lvName) else: raise se.CannotCreateLogicalVolume(vgName, lvName) # TBD: Need to explore the option of running lvcreate w/o devmapper # so that if activation is not needed it would be skipped in the # first place if activate: lv_path = lvPath(vgName, lvName) st = os.stat(lv_path) uName = pwd.getpwuid(st.st_uid).pw_name gName = grp.getgrgid(st.st_gid).gr_name if ":".join((uName, gName)) != USER_GROUP: cmd = [constants.EXT_CHOWN, USER_GROUP, lv_path] if misc.execCmd(cmd, sudo=True)[0] != 0: log.warning("Could not change ownership of one or more " "volumes in vg (%s) - %s", vgName, lvName) else: _setLVAvailability(vgName, lvName, "n")
def testSymlinkMount(self): with namedTemporaryDir() as root_dir: backing_image = os.path.join(root_dir, 'backing.img') link_to_image = os.path.join(root_dir, 'link_to_image') mountpoint = os.path.join(root_dir, 'mountpoint') with open(backing_image, 'w') as f: os.ftruncate(f.fileno(), 1024 ** 3) rc, out, err = execCmd(['/sbin/mkfs.ext2', "-F", backing_image], raw=True) if rc != 0: raise RuntimeError("Error creating filesystem: %s" % err) os.symlink(backing_image, link_to_image) os.mkdir(mountpoint) m = mount.Mount(link_to_image, mountpoint) m.mount(mntOpts="loop") try: self.assertTrue(m.isMounted()) finally: m.umount(force=True, freeloop=True) # TODO: Use libudev to wait for specific event with stopwatch("Wait for udev events"): udevadm.settle(5)
def _getPathsStatus(): cmd = [EXT_DMSETUP, "status", "--target", "multipath"] rc, out, err = misc.execCmd(cmd) if rc != 0: raise Exception("Could not get device statuses") res = {} for statusLine in out: try: devName, statusLine = statusLine.split(":", 1) except ValueError: if len(out) == 1: # return an empty dict when status output is: No devices found return res else: raise for m in PATH_STATUS_RE.finditer(statusLine): devNum, status = m.groups() physdevName = device_name(devNum) res[physdevName] = {"A": "active", "F": "failed"}[status] return res
def _getPathsStatus(): cmd = [EXT_DMSETUP, "status"] rc, out, err = misc.execCmd(cmd) if rc != 0: raise Exception("Could not get device statuses") res = {} for statusLine in out: try: devName, statusLine = statusLine.split(":", 1) except ValueError: if len(out) == 1: # return an empty dict when status output is: No devices found return res else: raise for m in PATH_STATUS_RE.finditer(statusLine): devNum, status = m.groups() physdevName = device_name(devNum) res[physdevName] = {"A": "active", "F": "failed"}[status] return res
def _removeMapping(deviceName): cmd = [EXT_DMSETUP, "remove", deviceName] rc = misc.execCmd(cmd)[0] if rc != 0: raise Exception("Could not remove mapping `%s`" % deviceName)
def _mboxExecCmd(*args, **kwargs): return misc.execCmd(*args, **kwargs)
def _mboxExecCmd(*args, **kwargs): kwargs['deathSignal'] = signal.SIGKILL return misc.execCmd(*args, **kwargs)
def mkimage(imagepath, aligned=True): open(imagepath, "wb").truncate(4 * 1024**3) cmd = ["/sbin/sfdisk", "-uS", "--force", imagepath] cmd_input = "128,,\n" if aligned else "1,,\n" rc, out, err = execCmd(cmd, data=cmd_input) assert rc == 0
def mkimage(imagepath, aligned=True): open(imagepath, "wb").truncate(4 * 1024 ** 3) cmd = ["/sbin/sfdisk", "-uS", "--force", imagepath] cmd_input = "128,,\n" if aligned else "1,,\n" rc, out, err = execCmd(cmd, data=cmd_input) assert rc == 0