def getMpathModel(drive): info = "Unknown Multipath Device" fulldev = "/dev/%s" % (drive,) # get minor number if os.path.exists(fulldev): minor = os.minor(os.stat(fulldev).st_rdev) else: return info.strip() # get slaves slaves = [] slavepath = "/sys/block/dm-%d/slaves" % (minor,) if os.path.isdir(slavepath): slaves = os.listdir(slavepath) else: return info.strip() # collect "vendor", "model" and "wwid" from a slave vendor = "" model = "" wwid = "" for slave in slaves: # get "vendor" sarg = "/sys/block/%s/device/vendor" % (slave,) f = open(sarg, "r") vendor = f.readline().strip() f.close() # get "model" sarg = "/sys/block/%s/device/model" % (slave,) f = open(sarg, "r") model = f.readline().strip() f.close() # get "wwid" sarg = "/block/%s" % (slave,) output = iutil.execWithCapture("scsi_id", ["-g", "-u", "-s", sarg], stderr = "/dev/tty5") # may be an EMC device, try special option if output == "": output = iutil.execWithCapture("scsi_id", ["-g", "-u", "-ppre-spc3-83", "-s", sarg], stderr = "/dev/tty5") if output != "": for line in output.split("\n"): if line == '': continue wwid = line # This loop is enough only the first slave break if vendor != "" and model != "" and wwid != "": info = vendor + "," + model + "," + wwid return info.strip()
def minSize(self): """ The minimum filesystem size in megabytes. """ if self._minInstanceSize is None: # we try one time to determine the minimum size. size = self._minSize if self.exists and os.path.exists(self.device): minSize = None buf = iutil.execWithCapture(self.resizefsProg, ["-m", self.device], stderr="/dev/tty5") for l in buf.split("\n"): if not l.startswith("Minsize"): continue try: min = l.split(":")[1].strip() minSize = int(min) + 250 except Exception, e: minSize = None log.warning( "Unable to parse output for minimum size on %s: %s" % (self.device, e)) if minSize is None: log.warning( "Unable to discover minimum size of filesystem " "on %s" % (self.device, )) else: size = minSize self._minInstanceSize = size
def lvs(vg_name): args = ["lvs", "-a", "--unit", "k", "--nosuffix", "--nameprefixes", "--rows", "--unquoted", "--noheadings", "-olv_name,lv_uuid,lv_size,lv_attr,segtype"] + \ config_args + \ [vg_name] buf = iutil.execWithCapture("lvm", args, stderr="/dev/tty5") _vars = buf.split() info = {} for var in _vars: (name, equals, value) = var.partition("=") if not equals: continue val = value.strip() if name not in info: info[name] = [] info[name].append(val) return info
def minSize(self): """ The minimum filesystem size in megabytes. """ if self._minInstanceSize is None: # we try one time to determine the minimum size. size = self._minSize if self.exists and os.path.exists(self.device): minSize = None buf = iutil.execWithCapture(self.resizefsProg, ["-m", self.device], stderr = "/dev/tty5") for l in buf.split("\n"): if not l.startswith("Minsize"): continue try: min = l.split(":")[1].strip() minSize = int(min) + 250 except Exception, e: minSize = None log.warning("Unable to parse output for minimum size on %s: %s" %(self.device, e)) if minSize is None: log.warning("Unable to discover minimum size of filesystem " "on %s" %(self.device,)) else: size = minSize self._minInstanceSize = size
def getFreeLoopDev(): loopdev = iutil.execWithCapture("losetup", ["-f"], fatal=True) loopdev = loopdev.strip() if not loopdev: raise RuntimeError("No free loop device available") return loopdev
def lvlist(): global lvmDevicePresent if lvmDevicePresent == 0: return [] lvs = [] # field names for "options" are in LVM2.2.01.01/lib/report/columns.h args = ["lvdisplay", "-C", "--noheadings", "--units", "b", "--nosuffix", "--separator", ":", "--options", "vg_name,lv_name,lv_size,origin" ] lvscanout = iutil.execWithCapture("lvm", args, stderr = "/dev/tty5") for line in lvscanout.split("\n"): try: (vg, lv, size, origin) = line.strip().split(':') size = long(math.floor(long(size) / (1024 * 1024))) if origin == '': origin = None except: continue logmsg = "lv is %s/%s, size of %s" % (vg, lv, size) if origin: logmsg += ", snapshot from %s" % (origin,) log.info(logmsg) lvs.append( (vg, lv, size, origin) ) return lvs
def pvinfo(device): """ If the PV was created with '--metadacopies 0', lvm will do some scanning of devices to determine from their metadata which VG this PV belongs to. pvs -o pv_name,pv_mda_count,vg_name,vg_uuid --config \ 'devices { scan = "/dev" filter = ["a/loop0/", "r/.*/"] }' """ #cfg = "'devices { scan = \"/dev\" filter = [\"a/%s/\", \"r/.*/\"] }'" args = ["pvs", "--noheadings"] + \ ["--units", "m"] + \ ["-o", "pv_name,pv_mda_count,vg_name,vg_uuid"] + \ config_args + \ [device] rc = iutil.execWithCapture("lvm", args, stderr = "/dev/tty5") vals = rc.split() if not vals: raise LVMError("pvinfo failed for %s" % device) # don't raise an exception if pv is not a part of any vg pv_name = vals[0] try: vg_name, vg_uuid = vals[2], vals[3] except IndexError: vg_name, vg_uuid = "", "" info = {'pv_name': pv_name, 'vg_name': vg_name, 'vg_uuid': vg_uuid} return info
def lvlist(): global lvmDevicePresent if lvmDevicePresent == 0: return [] lvs = [] # field names for "options" are in LVM2.2.01.01/lib/report/columns.h args = [ "lvdisplay", "-C", "--noheadings", "--units", "b", "--nosuffix", "--separator", ":", "--options", "vg_name,lv_name,lv_size,origin" ] lvscanout = iutil.execWithCapture("lvm", args, stderr="/dev/tty5") for line in lvscanout.split("\n"): try: (vg, lv, size, origin) = line.strip().split(':') size = long(math.floor(long(size) / (1024 * 1024))) if origin == '': origin = None except: continue logmsg = "lv is %s/%s, size of %s" % (vg, lv, size) if origin: logmsg += ", snapshot from %s" % (origin, ) log.info(logmsg) lvs.append((vg, lv, size, origin)) return lvs
def lvs(vg_name): args = ["lvs", "--noheadings", "--nosuffix"] + \ ["--units", "m"] + \ ["-o", "lv_name,lv_uuid,lv_size,lv_attr"] + \ config_args + \ [vg_name] buf = iutil.execWithCapture("lvm", args, stderr="/dev/tty5") lvs = {} for line in buf.splitlines(): line = line.strip() if not line: continue (name, uuid, size, attr) = line.split() lvs[name] = {"size": size, "uuid": uuid, "attr": attr} if not lvs: raise LVMError(_("lvs failed for %s" % vg_name)) return lvs
def minSize(self): """ Minimum size for this filesystem in MB. """ if self._minInstanceSize is None: # try once in the beginning to get the minimum size for an # existing filesystem. size = self._minSize blockSize = None if self.exists and os.path.exists(self.device): # get block size buf = iutil.execWithCapture(self.infofsProg, ["-h", self.device], stderr="/dev/tty5") for line in buf.splitlines(): if line.startswith("Block size:"): blockSize = int(line.split(" ")[-1]) break if blockSize is None: raise FSError("failed to get block size for %s filesystem " "on %s" % (self.mountType, self.device)) # get minimum size according to resize2fs buf = iutil.execWithCapture(self.resizefsProg, ["-P", self.device], stderr="/dev/tty5") for line in buf.splitlines(): if "minimum size of the filesystem:" not in line: continue # line will look like: # Estimated minimum size of the filesystem: 1148649 # # NOTE: The minimum size reported is in blocks. Convert # to bytes, then megabytes, and finally round up. (text, sep, minSize) = line.partition(": ") size = long(minSize) * blockSize size = math.ceil(size / 1024.0 / 1024.0) break if size is None: log.warning("failed to get minimum size for %s filesystem " "on %s" % (self.mountType, self.device)) self._minInstanceSize = size return self._minInstanceSize
def modulesWithPaths(): mods = [] for modline in open("/proc/modules", "r"): modName = modline.split(" ", 1)[0] modInfo = iutil.execWithCapture("modinfo", ["-F", "filename", modName]).splitlines() modPaths = [line.strip() for line in modInfo if line != ""] mods.extend(modPaths) return mods
def _mdadm(*args): try: lines = iutil.execWithCapture("mdadm", args, stderr=mdadmOutput) lines = string.split(lines, "\n") lines = reduce(lambda x, y: x + [y.strip()], lines, []) return lines except: raise MdadmError, args
def writeZipl(self, instRoot, bl, kernelList, chainList, defaultDev, justConfigFile): rootDev = self.storage.rootDevice cf = '/etc/zipl.conf' self.perms = 0600 if os.access(instRoot + cf, os.R_OK): self.perms = os.stat(instRoot + cf)[0] & 0777 os.rename(instRoot + cf, instRoot + cf + '.rpmsave') f = open(instRoot + cf, "w+") f.write('[defaultboot]\n') if self.timeout: f.write('timeout=%d\n' % self.timeout) defaultList = filter( lambda x: not (x[0].endswith('debug') or x[0].endswith('kdump')), kernelList) f.write('default=' + defaultList[-1][0] + '-' + defaultList[-1][2] + '\n') f.write('target=%s\n' % (self.kernelLocation)) cfPath = "/boot/" for (label, longlabel, version) in kernelList: kernelTag = "-" + version kernelFile = "%svmlinuz%s" % (cfPath, kernelTag) initrd = self.makeInitrd(kernelTag, instRoot) f.write('[%s-%s]\n' % (label, version)) f.write('\timage=%s\n' % (kernelFile)) if initrd: f.write('\tramdisk=%s%s\n' % (self.kernelLocation, initrd)) realroot = rootDev.fstabSpec f.write('\tparameters="root=%s' % (realroot, )) if bl.args.get(): f.write(' %s' % (bl.args.get())) f.write('"\n') f.close() if not justConfigFile: rc = iutil.execWithCapture("zipl", [], root=instRoot, stderr="/dev/stderr", fatal=True) for line in rc.splitlines(): if line.startswith("Preparing boot device: "): # Output here may look like: # Preparing boot device: dasdb (0200). # Preparing boot device: dasdl. # We want to extract the device name and pass that. fields = line[23:].split() self.setDevice(fields[0].replace('.', '')) return 0
def modulesWithPaths(): mods = [] for modline in open("/proc/modules", "r"): modName = modline.split(" ", 1)[0] modInfo = iutil.execWithCapture("modinfo", ["-F", "filename", modName]).splitlines() modPaths = [ line.strip() for line in modInfo if line!="" ] mods.extend(modPaths) return mods
def createWidgets (self): """ Sets up the widgets in the main installler window. """ self.window.set_title(_("%s Installer") %(productName,)) i = self.mainxml.get_widget("headerImage") p = readImageFromFile("anaconda_header.png", dither = False, image = i) if p is None: print(_("Unable to load title bar")) if flags.livecdInstall: i.hide() self.window.set_resizable(True) self.window.maximize() elif flags.preexisting_x11: # Forwarded X11, don't take over their whole screen i.hide() self.window.set_resizable(True) else: # Normal install, full screen self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DESKTOP) if gtk.gdk.screen_height() < 600: i.hide() # Find a window size that will fit on whatever display gets picked # Parse the connected lines from xrandr, which look like this: # DVI-I-1 connected 1680x1050+1680+0 (normal left inverted right x axis y axis) 473mm x 296mm try: widths = [] heights= [] xrandr = iutil.execWithCapture("xrandr", ["-q"], stderr="/dev/tty5") lines = [l.split() for l in xrandr.splitlines()] displays = filter(lambda x: "connected" in x, lines) for fields in displays: log.debug("display: %s", (fields,)) m = re.match("(\d+)x(\d+).*", fields[2]) if m and len(m.groups()) == 2: widths.append(int(m.group(1))) heights.append(int(m.group(2))) # Pick the smallest size that will fit width = min(widths) height = min(heights) except Exception as e: log.info("screen size detection failed: %s", (str(e),)) width = 800 height= 600 # Set the window size, but no smaller than 800x600 log.info("Setting window size to %dx%d" % (width, height)) self.window.set_size_request(max(width, 800), max(height, 600)) self.window.show() if flags.debug: self.mainxml.get_widget("debugButton").show_now() self.installFrame = self.mainxml.get_widget("installFrame")
def luksUUID(device): if not device.startswith("/"): device = "/dev/" + device if not isLuks(device): return None uuid = iutil.execWithCapture("cryptsetup", ["luksUUID", device]) uuid = uuid.strip() return uuid
def _get_backing_devnums_from_map(map_name): ret = [] buf = iutil.execWithCapture( "dmsetup", ["info", "--columns", "--noheadings", "-o", "devnos_used", map_name], stderr="/dev/tty5") dev_nums = buf.split() for dev_num in dev_nums: (major, colon, minor) = dev_num.partition(":") ret.append((int(major), int(minor))) return ret
def lvorigin(vg_name, lv_name): args = ["lvs", "--noheadings", "-o", "origin"] + \ config_args + \ ["%s/%s" % (vg_name, lv_name)] buf = iutil.execWithCapture("lvm", args, stderr="/dev/tty5") try: origin = buf.splitlines()[0].strip() except IndexError: origin = '' return origin
def prepBootDev(self, instRoot): rc = iutil.execWithCapture("zipl", [], root = instRoot, stderr = "/dev/stderr", fatal = True) for line in rc.splitlines(): if line.startswith("Preparing boot device: "): # Output here may look like: # Preparing boot device: dasdb (0200). # Preparing boot device: dasdl. # We want to extract the device name and pass that. fields = line[23:].split() self.setDevice(fields[0].replace('.', ''))
def prepBootDev(self, instRoot): rc = iutil.execWithCapture("zipl", [], root=instRoot, stderr="/dev/stderr", fatal=True) for line in rc.splitlines(): if line.startswith("Preparing boot device: "): # Output here may look like: # Preparing boot device: dasdb (0200). # Preparing boot device: dasdl. # We want to extract the device name and pass that. fields = line[23:].split() self.setDevice(fields[0].replace('.', ''))
def writeZipl(self, instRoot, bl, kernelList, chainList, defaultDev, justConfigFile): rootDev = self.storage.rootDevice cf = "/etc/zipl.conf" self.perms = 0600 if os.access(instRoot + cf, os.R_OK): self.perms = os.stat(instRoot + cf)[0] & 0777 os.rename(instRoot + cf, instRoot + cf + ".rpmsave") f = open(instRoot + cf, "w+") f.write("[defaultboot]\n") if self.timeout: f.write("timeout=%d\n" % self.timeout) defaultList = filter(lambda x: not (x[0].endswith("debug") or x[0].endswith("kdump")), kernelList) f.write("default=" + defaultList[-1][0] + "-" + defaultList[-1][2] + "\n") f.write("target=%s\n" % (self.kernelLocation)) cfPath = "/boot/" for (label, longlabel, version) in kernelList: kernelTag = "-" + version kernelFile = "%svmlinuz%s" % (cfPath, kernelTag) initrd = self.makeInitrd(kernelTag, instRoot) f.write("[%s-%s]\n" % (label, version)) f.write("\timage=%s\n" % (kernelFile)) if initrd: f.write("\tramdisk=%s%s\n" % (self.kernelLocation, initrd)) realroot = rootDev.fstabSpec f.write('\tparameters="root=%s' % (realroot,)) if bl.args.get(): f.write(" %s" % (bl.args.get())) f.write('"\n') f.close() if not justConfigFile: rc = iutil.execWithCapture("zipl", [], root=instRoot, stderr="/dev/stderr", fatal=True) for line in rc.splitlines(): if line.startswith("Preparing boot device: "): # Output here may look like: # Preparing boot device: dasdb (0200). # Preparing boot device: dasdl. # We want to extract the device name and pass that. fields = line[23:].split() self.setDevice(fields[0].replace(".", "")) return 0
def _get_backing_devnums_from_map(map_name): ret = [] buf = iutil.execWithCapture("dmsetup", ["info", "--columns", "--noheadings", "-o", "devnos_used", map_name], stderr="/dev/tty5") dev_nums = buf.split() for dev_num in dev_nums: (major, colon, minor) = dev_num.partition(":") ret.append((int(major), int(minor))) return ret
def lvorigin(vg_name, lv_name): args = ["lvs", "--noheadings", "-o", "origin"] + \ ["%s/%s" % (vg_name, lv_name)] buf = iutil.execWithCapture("lvm", args, stderr="/dev/tty5") try: origin = buf.splitlines()[0].strip() except IndexError: origin = '' return origin
def ifaceForHostIP(host): route = iutil.execWithCapture("ip", ["route", "get", "to", host]) if not route: log.error("Could not get interface for route to %s" % host) return "" routeInfo = route.split() if routeInfo[0] != host or len(routeInfo) < 5 or \ "dev" not in routeInfo or routeInfo.index("dev") > 3: log.error('Unexpected "ip route get to %s" reply: %s' % (host, routeInfo)) return "" return routeInfo[routeInfo.index("dev") + 1]
def ifaceForHostIP(host): route = iutil.execWithCapture("ip", [ "route", "get", "to", host ]) if not route: log.error("Could not get interface for route to %s" % host) return "" routeInfo = route.split() if routeInfo[0] != host or len(routeInfo) < 5 or \ "dev" not in routeInfo or routeInfo.index("dev") > 3: log.error('Unexpected "ip route get to %s" reply: %s' % (host, routeInfo)) return "" return routeInfo[routeInfo.index("dev") + 1]
def _startEDD(self, intf = None): rc = iutil.execWithCapture("/usr/libexec/fcoe/fcoe_edd.sh", [ "-i" ], stderr="/dev/tty5") if not rc.startswith("NIC="): log.info("No FCoE EDD info found: %s" % rc) return (key, val) = rc.split("=", 1) if val not in isys.getDeviceProperties(): log.error("Unknown FCoE NIC found in EDD: %s, ignoring" % val) return log.info("FCoE NIC found in EDD: %s" % val) self.addSan(val, dcb=True, auto_vlan=True, intf=intf)
def name_from_dm_node(dm_node): name = block.getNameFromDmNode(dm_node) if name is not None: return name st = os.stat("/dev/%s" % dm_node) major = os.major(st.st_rdev) minor = os.minor(st.st_rdev) name = iutil.execWithCapture("dmsetup", ["info", "--columns", "--noheadings", "-o", "name", "-j", str(major), "-m", str(minor)], stderr="/dev/tty5") log.debug("name_from_dm(%s) returning '%s'" % (dm_node, name.strip())) return name.strip()
def default_route_device(): routes = iutil.execWithCapture("ip", ["route", "show"]) if not routes: log.error("Could not get default route device") return None for line in routes.split("\n"): if line.startswith("default"): parts = line.split() if parts[3] == "dev": return parts[4] else: log.error("Could not parse default route device") return None return None
def dm_node_from_name(map_name): dm_node = block.getDmNodeFromName(map_name) if dm_node is not None: return dm_node devnum = iutil.execWithCapture( "dmsetup", ["info", "--columns", "--noheadings", "-o", "devno", map_name], stderr="/dev/tty5") (major, sep, minor) = devnum.strip().partition(":") if not sep: raise DMError("dm device does not exist") dm_node = "dm-%d" % int(minor) log.debug("dm_node_from_name(%s) returning '%s'" % (map_name, dm_node)) return dm_node
def name_from_dm_node(dm_node): name = block.getNameFromDmNode(dm_node) if name is not None: return name st = os.stat("/dev/%s" % dm_node) major = os.major(st.st_rdev) minor = os.minor(st.st_rdev) name = iutil.execWithCapture("dmsetup", [ "info", "--columns", "--noheadings", "-o", "name", "-j", str(major), "-m", str(minor) ], stderr="/dev/tty5") log.debug("name_from_dm(%s) returning '%s'" % (dm_node, name.strip())) return name.strip()
def vginfo(vg_name): args = ["vgs", "--noheadings", "--nosuffix"] + \ ["--units", "m"] + \ ["-o", "uuid,size,free,extent_size,extent_count,free_count,pv_count"] + \ config_args + \ [vg_name] buf = iutil.execWithCapture("lvm", args, stderr="/dev/tty5") info = buf.split() if len(info) != 7: raise LVMError(_("vginfo failed for %s" % vg_name)) d = {} (d['uuid'], d['size'], d['free'], d['pe_size'], d['pe_count'], d['pe_free'], d['pv_count']) = info return d
def vginfo(vg_name): args = ["vgs", "--noheadings", "--nosuffix"] + \ ["--units", "m"] + \ ["-o", "uuid,size,free,extent_size,extent_count,free_count,pv_count"] + \ [vg_name] buf = iutil.execWithCapture("lvm", args, stderr="/dev/tty5") info = buf.split() if len(info) != 7: raise LVMError(_("vginfo failed for %s" % vg_name)) d = {} (d['uuid'],d['size'],d['free'],d['pe_size'], d['pe_count'],d['pe_free'],d['pv_count']) = info return d
def getTimezoneList(self): if os.access("/usr/lib/timezones.gz", os.R_OK): cmd = "/usr/bin/gunzip" stdin = os.open("/usr/lib/timezones.gz", 0) else: zoneList = iutil.findtz('/usr/share/zoneinfo', '') cmd = "" stdin = None if cmd != "": zones = iutil.execWithCapture(cmd, [cmd], stdin=stdin) zoneList = string.split(zones) if (stdin != None): os.close(stdin) return zoneList
def dm_node_from_name(map_name): dm_node = block.getDmNodeFromName(map_name) if dm_node is not None: return dm_node devnum = iutil.execWithCapture("dmsetup", ["info", "--columns", "--noheadings", "-o", "devno", map_name], stderr="/dev/tty5") (major, sep, minor) = devnum.strip().partition(":") if not sep: raise DMError("dm device does not exist") dm_node = "dm-%d" % int(minor) log.debug("dm_node_from_name(%s) returning '%s'" % (map_name, dm_node)) return dm_node
def partialvgs(): global lvmDevicePresent if lvmDevicePresent == 0: return [] vgs = [] args = ["vgdisplay", "-C", "-P", "--noheadings", "--units", "b"] scanout = iutil.execWithCapture("lvm", args, stderr = "/dev/tty5") for line in scanout.split("\n"): try: (vg, numpv, numlv, numsn, attr, size, free) = line.strip()[:-1].split() except: continue if attr.find("p") != -1: log.info("vg %s, attr is %s" %(vg, attr)) vgs.append(vg) return vgs
def lvlist(): global lvmDevicePresent if lvmDevicePresent == 0: return [] lvs = [] args = ["lvm", "lvdisplay", "-C", "--noheadings", "--units", "b"] lvscanout = iutil.execWithCapture(args[0], args, searchPath=1) for line in lvscanout.split("\n"): try: (lv, vg, attr, size) = line.strip()[:-1].split() except: continue size = size[:-1] log("lv is %s/%s, size of %s" % (vg, lv, size)) lvs.append((vg, lv, size)) return lvs
def pvlist(): global lvmDevicePresent if lvmDevicePresent == 0: return [] pvs = [] args = ["lvm", "pvdisplay", "-C", "--noheadings", "--units", "b"] scanout = iutil.execWithCapture(args[0], args, searchPath=1) for line in scanout.split("\n"): try: (dev, vg, format, attr, size, free) = line.strip()[:-1].split() except: continue size = size[:-1] log("pv is %s in vg %s, size is %s" % (dev, vg, size)) pvs.append((dev, vg, size)) return pvs
def totalCylinders(self): """ Total number of cylinders of all unformatted DASD devices. """ if self._totalCylinders: return self._totalCylinders argv = ["-t", "-v", "-y", "-d", "cdl", "-b", "4096"] for dasd in self._dasdlist: buf = iutil.execWithCapture("/sbin/dasdfmt", argv + [dasd], stderr="/dev/tty5") for line in buf.splitlines(): if line.startswith("Drive Geometry: "): # line will look like this: # Drive Geometry: 3339 Cylinders * 15 Heads = 50085 Tracks cyls = long(filter(lambda s: s, line.split(' '))[2]) self._totalCylinders += cyls break return self._totalCylinders
def mdexamine(device): vars = iutil.execWithCapture("mdadm", ["--examine", "--brief", device], stderr="/dev/tty5").split() info = {} if vars: try: info["device"] = vars[1] vars = vars[2:] except IndexError: return {} for var in vars: (name, equals, value) = var.partition("=") if not equals: continue info[name.lower()] = value.strip() return info
def partialvgs(): global lvmDevicePresent if lvmDevicePresent == 0: return [] vgs = [] args = ["vgdisplay", "-C", "-P", "--noheadings", "--units", "b"] scanout = iutil.execWithCapture("lvm", args, stderr="/dev/tty5") for line in scanout.split("\n"): try: (vg, numpv, numlv, numsn, attr, size, free) = line.strip()[:-1].split() except: continue if attr.find("p") != -1: log.info("vg %s, attr is %s" % (vg, attr)) vgs.append(vg) return vgs
def vglist(): global lvmDevicePresent if lvmDevicePresent == 0: return [] vgs = [] args = ["lvm", "vgdisplay", "-C", "--noheadings", "--units", "b"] scanout = iutil.execWithCapture(args[0], args, searchPath=1) for line in scanout.split("\n"): try: (vg, numpv, numlv, numsn, attr, size, free) = line.strip()[:-1].split() except: continue size = size[:-1] log("vg %s, size is %s" % (vg, size)) vgs.append((vg, size)) return vgs
def vglist(): global lvmDevicePresent if lvmDevicePresent == 0: return [] vgs = [] args = [ "vgdisplay", "-C", "--noheadings", "--units", "b", "--nosuffix", "--separator", ":", "--options", "vg_name,vg_size,vg_extent_size" ] scanout = iutil.execWithCapture("lvm", args, stderr="/dev/tty5") for line in scanout.split("\n"): try: (vg, size, pesize) = line.strip().split(':') size = long(math.floor(long(size) / (1024 * 1024))) pesize = long(pesize) / 1024 except: continue log.info("vg %s, size is %s, pesize is %s" % (vg, size, pesize)) vgs.append((vg, size, pesize)) return vgs
def vglist(): global lvmDevicePresent if lvmDevicePresent == 0: return [] vgs = [] args = ["vgdisplay", "-C", "--noheadings", "--units", "b", "--nosuffix", "--separator", ":", "--options", "vg_name,vg_size,vg_extent_size" ] scanout = iutil.execWithCapture("lvm", args, stderr = "/dev/tty5") for line in scanout.split("\n"): try: (vg, size, pesize) = line.strip().split(':') size = long(math.floor(long(size) / (1024 * 1024))) pesize = long(pesize)/1024 except: continue log.info("vg %s, size is %s, pesize is %s" %(vg, size, pesize)) vgs.append( (vg, size, pesize) ) return vgs
def pvlist(): global lvmDevicePresent if lvmDevicePresent == 0: return [] pvs = [] args = [ "pvdisplay", "-C", "--noheadings", "--units", "b", "--nosuffix", "--separator", ":", "--options", "pv_name,vg_name,dev_size" ] scanout = iutil.execWithCapture("lvm", args, stderr="/dev/tty5") for line in scanout.split("\n"): try: (dev, vg, size) = line.strip().split(':') size = long(math.floor(long(size) / (1024 * 1024))) except: continue log.info("pv is %s in vg %s, size is %s" % (dev, vg, size)) # We only append if the device is valid if dev.strip().lower() == "unknown device": continue pvs.append((dev, vg, size)) return pvs
def pvlist(): global lvmDevicePresent if lvmDevicePresent == 0: return [] pvs = [] args = ["pvdisplay", "-C", "--noheadings", "--units", "b", "--nosuffix", "--separator", ":", "--options", "pv_name,vg_name,dev_size" ] scanout = iutil.execWithCapture("lvm", args, stderr = "/dev/tty5") for line in scanout.split("\n"): try: (dev, vg, size) = line.strip().split(':') size = long(math.floor(long(size) / (1024 * 1024))) except: continue log.info("pv is %s in vg %s, size is %s" %(dev, vg, size)) # We only append if the device is valid if dev.strip().lower() == "unknown device": continue pvs.append( (dev, vg, size) ) return pvs
def format_dasds(self, intf, askUser, dasdlist): """ Iterate through a given list of DASDs and run dasdfmt on them. """ out = "/dev/tty5" err = "/dev/tty5" c = len(dasdlist) if intf and askUser: devs = '' for dasd, bypath in dasdlist: devs += "%s\n" % (bypath, ) rc = intf.questionInitializeDASD(c, devs) if rc == 1: log.info(" not running dasdfmt, continuing installation") return # gather total cylinder count argv = ["-t", "-v"] + self.commonArgv for dasd, bypath in dasdlist: buf = iutil.execWithCapture(self.dasdfmt, argv + ["/dev/" + dasd], stderr=err) for line in buf.splitlines(): if line.startswith("Drive Geometry: "): # line will look like this: # Drive Geometry: 3339 Cylinders * 15 Heads = 50085 Tracks cyls = long(filter(lambda s: s, line.split(' '))[2]) self.totalCylinders += cyls break # format DASDs argv = ["-P"] + self.commonArgv update = self._updateProgressWindow title = P_("Formatting DASD Device", "Formatting DASD Devices", c) msg = P_("Preparing %d DASD device for use with Linux..." % c, "Preparing %d DASD devices for use with Linux..." % c, c) if intf: if self.totalCylinders: pw = intf.progressWindow(title, msg, 1.0) else: pw = intf.progressWindow(title, msg, 100, pulse=True) for dasd, bypath in dasdlist: log.info("Running dasdfmt on %s" % (bypath, )) arglist = argv + ["/dev/" + dasd] try: if intf and self.totalCylinders: rc = iutil.execWithCallback(self.dasdfmt, arglist, stdout=out, stderr=err, callback=update, callback_data=pw, echo=False) elif intf: rc = iutil.execWithPulseProgress(self.dasdfmt, arglist, stdout=out, stderr=err, progress=pw) else: rc = iutil.execWithRedirect(self.dasdfmt, arglist, stdout=out, stderr=err) except Exception as e: raise DasdFormatError(e, bypath) if rc: raise DasdFormatError("dasdfmt failed: %s" % rc, bypath) if intf: pw.pop()
def startup(self, intf, exclusiveDisks, zeroMbr): """ Look for any unformatted DASDs in the system and offer the user the option for format them with dasdfmt or exit the installer. """ if self.started: return self.started = True out = "/dev/tty5" err = "/dev/tty5" if not iutil.isS390(): return # Trigger udev data about the dasd devices on the system udev_trigger(action="change", name="dasd*") log.info("Checking for unformatted DASD devices:") for device in os.listdir("/sys/block"): if not device.startswith("dasd"): continue statusfile = "/sys/block/%s/device/status" % (device,) if not os.path.isfile(statusfile): continue f = open(statusfile, "r") status = f.read().strip() f.close() if status in ["unformatted"] and device not in exclusiveDisks: bypath = deviceNameToDiskByPath(device) if not bypath: bypath = "/dev/" + device log.info(" %s (%s) status is %s, needs dasdfmt" % (device, bypath, status,)) self._dasdlist.append((device, bypath)) if not len(self._dasdlist): log.info(" no unformatted DASD devices found") return askUser = True if zeroMbr: askUser = False elif not intf and not zeroMbr: log.info(" non-interactive kickstart install without zerombr " "command, unable to run dasdfmt, exiting installer") sys.exit(0) c = len(self._dasdlist) if intf and askUser: devs = '' for dasd, bypath in self._dasdlist: devs += "%s\n" % (bypath,) rc = intf.questionInitializeDASD(c, devs) if rc == 1: log.info(" not running dasdfmt, continuing installation") return # gather total cylinder count argv = ["-t", "-v"] + self.commonArgv for dasd, bypath in self._dasdlist: buf = iutil.execWithCapture(self.dasdfmt, argv + ["/dev/" + dasd], stderr=err) for line in buf.splitlines(): if line.startswith("Drive Geometry: "): # line will look like this: # Drive Geometry: 3339 Cylinders * 15 Heads = 50085 Tracks cyls = long(filter(lambda s: s, line.split(' '))[2]) self.totalCylinders += cyls break # format DASDs argv = ["-P"] + self.commonArgv update = self._updateProgressWindow title = P_("Formatting DASD Device", "Formatting DASD Devices", c) msg = P_("Preparing %d DASD device for use with Linux..." % c, "Preparing %d DASD devices for use with Linux..." % c, c) if intf: if self.totalCylinders: pw = intf.progressWindow(title, msg, 1.0) else: pw = intf.progressWindow(title, msg, 100, pulse=True) for dasd, bypath in self._dasdlist: log.info("Running dasdfmt on %s" % (bypath,)) arglist = argv + ["/dev/" + dasd] try: if intf and self.totalCylinders: rc = iutil.execWithCallback(self.dasdfmt, arglist, stdout=out, stderr=err, callback=update, callback_data=pw, echo=False) elif intf: rc = iutil.execWithPulseProgress(self.dasdfmt, arglist, stdout=out, stderr=err, progress=pw) else: rc = iutil.execWithRedirect(self.dasdfmt, arglist, stdout=out, stderr=err) except Exception as e: raise DasdFormatError(e, bypath) if rc: raise DasdFormatError("dasdfmt failed: %s" % rc, bypath) if intf: pw.pop()
def dracutSetupString(self, networkStorageDevice): netargs="" if networkStorageDevice.nic: # Storage bound to a specific nic (ie FCoE) nic = networkStorageDevice.nic else: # Storage bound through ip, find out which interface leads to host host = networkStorageDevice.host_address route = iutil.execWithCapture("ip", [ "route", "get", "to", host ]) if not route: log.error("Could net get interface for route to %s" % host) return "" routeInfo = route.split() if routeInfo[0] != host or len(routeInfo) < 5 or \ "dev" not in routeInfo or routeInfo.index("dev") > 3: log.error('Unexpected "ip route get to %s" reply: %s' % (host, routeInfo)) return "" nic = routeInfo[routeInfo.index("dev") + 1] if nic not in self.netdevices.keys(): log.error('Unknown network interface: %s' % nic) return "" dev = self.netdevices[nic] if networkStorageDevice.host_address: if dev.get('bootproto').lower() == 'dhcp': netargs += "ip=%s:dhcp" % nic else: if dev.get('GATEWAY'): gateway = dev.get('GATEWAY') else: gateway = "" if self.hostname: hostname = self.hostname else: hostname = "" netargs += "ip=%s::%s:%s:%s:%s:none" % (dev.get('ipaddr'), gateway, dev.get('netmask'), hostname, nic) hwaddr = dev.get("HWADDR") if hwaddr: if netargs != "": netargs += " " netargs += "ifname=%s:%s" % (nic, hwaddr.lower()) nettype = dev.get("NETTYPE") subchannels = dev.get("SUBCHANNELS") if iutil.isS390() and nettype and subchannels: if netargs != "": netargs += " " netargs += "rd_CCW=%s,%s" % (nettype, subchannels) options = dev.get("OPTIONS") if options: options = filter(lambda x: x != '', options.split(' ')) netargs += ",%s" % (','.join(options)) return netargs
def identifyMultipaths(devices): # this function does a couple of things # 1) identifies multipath disks # 2) sets their ID_FS_TYPE to multipath_member # 3) removes the individual members of an mpath's partitions # sample input with multipath pair [sdb,sdc] # [sr0, sda, sda1, sdb, sdb1, sdb2, sdc, sdc1, sdd, sdd1, sdd2] # sample output: # [sda, sdd], [[sdb, sdc]], [sr0, sda1, sdd1, sdd2]] log.info("devices to scan for multipath: %s" % [d['name'] for d in devices]) topology = parseMultipathOutput(iutil.execWithCapture("multipath", ["-d",])) # find the devices that aren't in topology, and add them into it... topodevs = reduce(lambda x,y: x.union(y), topology.values(), set()) for name in set([d['name'] for d in devices]).difference(topodevs): topology[name] = [name] devmap = {} non_disk_devices = {} for d in devices: if not udev_device_is_disk(d): non_disk_devices[d['name']] = d log.info("adding %s to non_disk_device list" % (d['name'],)) continue devmap[d['name']] = d singlepath_disks = [] multipaths = [] for name, disks in topology.items(): if len(disks) == 1: if not non_disk_devices.has_key(disks[0]): log.info("adding %s to singlepath_disks" % (disks[0],)) singlepath_disks.append(devmap[disks[0]]) else: # some usb cardreaders use multiple lun's (for different slots) # and report a fake disk serial which is the same for all the # lun's (#517603) all_usb = True # see if we've got any non-disk devices on our mpath list. # If so, they're probably false-positives. non_disks = False for disk in disks: d = devmap[disk] if d.get("ID_USB_DRIVER") != "usb-storage": all_usb = False if (not devmap.has_key(disk)) and non_disk_devices.has_key(disk): log.warning("non-disk device %s is part of an mpath" % (disk,)) non_disks = True if all_usb: log.info("adding multi lun usb mass storage device to singlepath_disks: %s" % (disks,)) singlepath_disks.extend([devmap[d] for d in disks]) continue if non_disks: for disk in disks: if devmap.has_key(disk): del devmap[disk] if topology.has_key(disk): del topology[disk] continue log.info("found multipath set: %s" % (disks,)) for disk in disks: d = devmap[disk] log.info("adding %s to multipath_disks" % (disk,)) d["ID_FS_TYPE"] = "multipath_member" d["ID_MPATH_NAME"] = name multipaths.append([devmap[d] for d in disks]) non_disk_serials = {} for name,device in non_disk_devices.items(): serial = udev_device_get_serial(device) non_disk_serials.setdefault(serial, []) non_disk_serials[serial].append(device) for mpath in multipaths: for serial in [d.get('ID_SERIAL_SHORT') for d in mpath]: if non_disk_serials.has_key(serial): log.info("filtering out non disk devices [%s]" % [d['name'] for d in non_disk_serials[serial]]) for name in [d['name'] for d in non_disk_serials[serial]]: if non_disk_devices.has_key(name): del non_disk_devices[name] partition_devices = [] for device in non_disk_devices.values(): partition_devices.append(device) # this is the list of devices we want to keep from the original # device list, but we want to maintain its original order. singlepath_disks = filter(lambda d: d in devices, singlepath_disks) #multipaths = filter(lambda d: d in devices, multipaths) partition_devices = filter(lambda d: d in devices, partition_devices) mpathStr = "[" for mpath in multipaths: mpathStr += str([d['name'] for d in mpath]) mpathStr += "]" s = "(%s, %s, %s)" % ([d['name'] for d in singlepath_disks], \ mpathStr, \ [d['name'] for d in partition_devices]) log.info("devices post multipath scan: %s" % s) return (singlepath_disks, multipaths, partition_devices)
def _getExistingSize(self): """ Determine the size of this filesystem. Filesystem must exist. Each filesystem varies, but the general procedure is to run the filesystem dump or info utility and read the block size and number of blocks for the filesystem and compute megabytes from that. The loop that reads the output from the infofsProg is meant to be simple, but take in to account variations in output. The general procedure: 1) Capture output from infofsProg. 2) Iterate over each line of the output: a) Trim leading and trailing whitespace. b) Break line into fields split on ' ' c) If line begins with any of the strings in _existingSizeFields, start at the end of fields and take the first one that converts to a long. Store this in the values list. d) Repeat until the values list length equals the _existingSizeFields length. 3) If the length of the values list equals the length of _existingSizeFields, compute the size of this filesystem by multiplying all of the values together to get bytes, then convert to megabytes. Return this value. 4) If we were unable to capture all fields, return 0. The caller should catch exceptions from this method. Any exception raised indicates a need to change the fields we are looking for, the command to run and arguments, or something else. If you catch an exception from this method, assume the filesystem cannot be resized. """ size = self._size if self.infofsProg and self.mountable and self.exists and not size: try: values = [] argv = self._defaultInfoOptions + [ self.device ] buf = iutil.execWithCapture(self.infofsProg, argv, stderr="/dev/tty5") for line in buf.splitlines(): found = False line = line.strip() tmp = line.split(' ') tmp.reverse() for field in self._existingSizeFields: if line.startswith(field): for subfield in tmp: try: values.append(long(subfield)) found = True break except ValueError: continue if found: break if len(values) == len(self._existingSizeFields): break if len(values) != len(self._existingSizeFields): return 0 size = 1 for value in values: size *= value # report current size as megabytes size = math.floor(size / 1024.0 / 1024.0) except Exception as e: log.error("failed to obtain size of filesystem on %s: %s" % (self.device, e)) return size