diff options
Diffstat (limited to 'pyanaconda')
-rw-r--r-- | pyanaconda/bootloader.py | 22 | ||||
-rw-r--r-- | pyanaconda/installclass.py | 7 | ||||
-rw-r--r-- | pyanaconda/installclasses/rhel.py | 3 | ||||
-rw-r--r-- | pyanaconda/iutil.py | 47 | ||||
-rw-r--r-- | pyanaconda/kickstart.py | 16 | ||||
-rw-r--r-- | pyanaconda/storage/devicelibs/swap.py | 41 | ||||
-rw-r--r-- | pyanaconda/storage/devices.py | 33 | ||||
-rw-r--r-- | pyanaconda/storage/devicetree.py | 44 | ||||
-rw-r--r-- | pyanaconda/storage/fcoe.py | 6 | ||||
-rw-r--r-- | pyanaconda/storage/formats/fs.py | 1 | ||||
-rw-r--r-- | pyanaconda/storage/formats/swap.py | 3 | ||||
-rw-r--r-- | pyanaconda/storage/udev.py | 35 | ||||
-rw-r--r-- | pyanaconda/text.py | 2 | ||||
-rw-r--r-- | pyanaconda/textw/add_drive_text.py | 2 | ||||
-rw-r--r-- | pyanaconda/vnc.py | 6 |
15 files changed, 189 insertions, 79 deletions
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py index 971c0dc16..ed8040ff5 100644 --- a/pyanaconda/bootloader.py +++ b/pyanaconda/bootloader.py @@ -1475,6 +1475,10 @@ class GRUB2(GRUB): def write_config(self): self.write_config_console(None) + # See if we have a password and if so update the boot args before we + # write out the defaults file. + if self.password or self.encrypted_password: + self.boot_args.add("rd.shell=0") self.write_defaults() # if we fail to setup password auth we should complete the @@ -1658,6 +1662,8 @@ class YabootSILOBase(BootLoader): continue args = Arguments() + if self.password or self.encrypted_password: + args.add("rd.shell=0") if image.initrd: initrd_line = "\tinitrd=%s/%s\n" % (self.boot_prefix, image.initrd) @@ -1986,7 +1992,21 @@ class ZIPL(BootLoader): # DWL FIXME: resolve the boot device to a StorageDevice from storage buf = iutil.execWithCapture("zipl", [], stderr="/dev/tty5", - root=ROOT_PATH) + root=ROOT_PATH, + fatal=True) + for line in buf.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. + name = re.sub(".+?: ", "", line) + name = re.sub("(\s\(.+\))?\.$", "", name) + device = self.storage.devicetree.getDeviceByName(name) + if not device: + raise BootLoaderError("could not find IPL device") + + self.stage1_device = device class SILO(YabootSILOBase): name = "SILO" diff --git a/pyanaconda/installclass.py b/pyanaconda/installclass.py index 17a0c11b4..de4259f46 100644 --- a/pyanaconda/installclass.py +++ b/pyanaconda/installclass.py @@ -32,6 +32,7 @@ import types from constants import * from product import * from storage.partspec import * +from storage.devicelibs import swap import gettext _ = lambda x: gettext.ldgettext("anaconda", x) @@ -116,9 +117,9 @@ class BaseInstallClass(object): if bootreq: autorequests.extend(bootreq) - (minswap, maxswap) = iutil.swapSuggestion() - autorequests.append(PartSpec(fstype="swap", size=minswap, maxSize=maxswap, - grow=True, lv=True, encrypted=True)) + swap = swap.swapSuggestion() + autorequests.append(PartSpec(fstype="swap", size=swap, grow=False, + lv=True, encrypted=True)) storage.autoPartitionRequests = autorequests diff --git a/pyanaconda/installclasses/rhel.py b/pyanaconda/installclasses/rhel.py index 339b5b833..25edbae41 100644 --- a/pyanaconda/installclasses/rhel.py +++ b/pyanaconda/installclasses/rhel.py @@ -96,6 +96,9 @@ class InstallClass(BaseInstallClass): return False def versionMatches(self, oldver): + if oldver is None: + return False + oldMajor = oldver.split(".")[0] newMajor = productVersion.split(".")[0] diff --git a/pyanaconda/iutil.py b/pyanaconda/iutil.py index 5e4053465..9ffee0b84 100644 --- a/pyanaconda/iutil.py +++ b/pyanaconda/iutil.py @@ -200,8 +200,10 @@ def execWithRedirect(command, argv, stdin = None, stdout = None, # @param stdin The file descriptor to read stdin from. # @param stderr The file descriptor to redirect stderr to. # @param root The directory to chroot to before running command. +# @param fatal Boolean to determine if non-zero exit is fatal. # @return The output of command from stdout. def execWithCapture(command, argv, stdin = None, stderr = None, root='/'): + fatal = False): if flags.testing: log.info("not running command because we're testing: %s %s" % (command, " ".join(argv))) @@ -257,6 +259,10 @@ def execWithCapture(command, argv, stdin = None, stderr = None, root='/'): if proc.returncode is not None: break + # if we have anything other than a clean exit, and we get the fatal + # option, raise the OSError. + if proc.returncode and fatal: + raise OSError('Non-zero return code: %s' % proc.returncode) except OSError as e: log.error ("Error running " + command + ": " + e.strerror) closefds() @@ -459,34 +465,6 @@ def memInstalled(): return long(mem) -## Suggest the size of the swap partition that will be created. -# @param quiet Should size information be logged? -# @return A tuple of the minimum and maximum swap size, in megabytes. -def swapSuggestion(quiet=0): - mem = memInstalled()/1024 - mem = ((mem/16)+1)*16 - if not quiet: - log.info("Detected %sM of memory", mem) - - if mem <= 256: - minswap = 256 - maxswap = 512 - else: - if mem > 2048: - minswap = 1024 - maxswap = 2048 + mem - else: - minswap = mem - maxswap = 2*mem - - if isS390(): - minswap = 1 - - if not quiet: - log.info("Swap attempt of %sM to %sM", minswap, maxswap) - - return (minswap, maxswap) - ## Create a directory path. Don't fail if the directory already exists. # @param dir The directory path to create. def mkdirChain(dir): @@ -501,19 +479,6 @@ def mkdirChain(dir): log.error("could not create directory %s: %s" % (dir, e.strerror)) -## Get the total amount of swap memory. -# @return The total amount of swap memory in kilobytes, or 0 if unknown. -def swapAmount(): - f = open("/proc/meminfo", "r") - lines = f.readlines() - f.close() - - for l in lines: - if l.startswith("SwapTotal:"): - fields = string.split(l) - return int(fields[1]) - return 0 - ## Copy a device node. # Copies a device node by looking at the device type, major and minor device # numbers, and doing a mknod on the new device name. diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py index 7e2022ae9..d484b055b 100644 --- a/pyanaconda/kickstart.py +++ b/pyanaconda/kickstart.py @@ -24,7 +24,7 @@ from storage.devices import LUKSDevice from storage.devicelibs.lvm import getPossiblePhysicalExtents from storage.devicelibs.mpath import MultipathConfigWriter, MultipathTopology from storage.formats import getFormat -from storage.partitioning import doPartitioning +from storage.partitioning import doPartitioning, clearPartitions, shouldClear, swap import storage.iscsi import storage.fcoe import storage.zfcp @@ -546,9 +546,9 @@ class LogVolData(commands.logvol.F17_LogVolData): if self.mountpoint == "swap": type = "swap" self.mountpoint = "" - if self.recommended: - (self.size, self.maxSizeMB) = iutil.swapSuggestion() - self.grow = True + if self.recommended or self.hibernation: + self.size = swap.swapSuggestion(hibernation=self.hibernation) + self.grow = False else: if self.fstype != "": type = self.fstype @@ -856,15 +856,15 @@ class PartitionData(commands.partition.F17_PartData): self.disk = disk break - if self.disk == "": + if not self.disk: raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified BIOS disk %s cannot be determined" % self.onbiosdisk) if self.mountpoint == "swap": type = "swap" self.mountpoint = "" - if self.recommended: - (self.size, self.maxSizeMB) = iutil.swapSuggestion() - self.grow = True + if self.recommended or self.hibernation: + self.size = swap.swapSuggestion(hibernation=self.hibernation) + self.grow = False # if people want to specify no mountpoint for some reason, let them # this is really needed for pSeries boot partitions :( elif self.mountpoint == "None": diff --git a/pyanaconda/storage/devicelibs/swap.py b/pyanaconda/storage/devicelibs/swap.py index 274b4d03a..5113787c3 100644 --- a/pyanaconda/storage/devicelibs/swap.py +++ b/pyanaconda/storage/devicelibs/swap.py @@ -31,6 +31,8 @@ from . import dm import gettext _ = lambda x: gettext.ldgettext("anaconda", x) +import logging +log = logging.getLogger("anaconda") def mkswap(device, label=''): # We use -f to force since mkswap tends to refuse creation on lvs with @@ -122,3 +124,42 @@ def swapstatus(device): return status +def swapSuggestion(quiet=False, hibernation=False): + """ + Suggest the size of the swap partition that will be created. + + @param quiet: log size information + @param hibernation: calculate swap size big enough for hibernation + @return: calculated swap size + + """ + + mem = iutil.memInstalled()/1024 + mem = ((mem/16)+1)*16 + if not quiet: + log.info("Detected %sM of memory", mem) + + #chart suggested in the discussion with other teams + if mem < 2048: + swap = 2 * mem + + elif 2048 <= mem < 8192: + swap = mem + + elif 8192 <= mem < 65536: + swap = mem / 2 + + else: + swap = 4096 + + if hibernation: + if mem <= 65536: + swap = mem + swap + else: + log.info("Ignoring --hibernation option on systems with 64 GB of RAM or more") + + if not quiet: + log.info("Swap attempt of %sM", swap) + + return swap + diff --git a/pyanaconda/storage/devices.py b/pyanaconda/storage/devices.py index c99c3c25d..8fef3d168 100644 --- a/pyanaconda/storage/devices.py +++ b/pyanaconda/storage/devices.py @@ -3642,19 +3642,36 @@ class iScsiDiskDevice(DiskDevice, NetworkStorageDevice): self.ibft = kwargs.pop("ibft") self.nic = kwargs.pop("nic") self.initiator = kwargs.pop("initiator") - DiskDevice.__init__(self, device, **kwargs) - NetworkStorageDevice.__init__(self, host_address=self.node.address, - nic=self.nic) - log.debug("created new iscsi disk %s %s:%d via %s:%s" % (self.node.name, - self.node.address, - self.node.port, - self.node.iface, - self.nic)) + + if self.node is None: + # qla4xxx partial offload + name = kwargs.pop("fw_name") + address = kwargs.pop("fw_address") + port = kwargs.pop("fw_port") + DiskDevice.__init__(self, device, **kwargs) + NetworkStorageDevice.__init__(self, + host_address=address, + nic=self.nic) + log.debug("created new iscsi disk %s %s:%s using fw initiator %s" + % (name, address, port, self.initiator)) + else: + DiskDevice.__init__(self, device, **kwargs) + NetworkStorageDevice.__init__(self, host_address=self.node.address, + nic=self.nic) + log.debug("created new iscsi disk %s %s:%d via %s:%s" % (self.node.name, + self.node.address, + self.node.port, + self.node.iface, + self.nic)) def dracutSetupArgs(self): if self.ibft: return set(["iscsi_firmware"]) + # qla4xxx partial offload + if self.node is None: + return set() + address = self.node.address # surround ipv6 addresses with [] if ":" in address: diff --git a/pyanaconda/storage/devicetree.py b/pyanaconda/storage/devicetree.py index 4d317c9b4..df0d15f81 100644 --- a/pyanaconda/storage/devicetree.py +++ b/pyanaconda/storage/devicetree.py @@ -599,6 +599,20 @@ class DeviceTree(object): self.addIgnoredDisk(name) return True + # Ignore any readonly disks + if (udev_device_is_disk(info) and not + (udev_device_is_cdrom(info) or + udev_device_is_partition(info) or + udev_device_is_dm_partition(info) or + udev_device_is_dm_lvm(info) or + udev_device_is_dm_crypt(info) or + (udev_device_is_md(info) and not + udev_device_get_md_container(info)))): + if iutil.get_sysfs_attr(info["sysfs_path"], 'ro') == '1': + log.debug("Ignoring read only device %s" % name) + self.addIgnoredDisk(name) + return True + # FIXME: check for virtual devices whose slaves are on the ignore list def addUdevLVDevice(self, info): @@ -846,16 +860,26 @@ class DeviceTree(object): kwargs = { "serial": serial, "vendor": vendor, "bus": bus } if udev_device_is_iscsi(info): diskType = iScsiDiskDevice - node = self.iscsi.getNode( - udev_device_get_iscsi_name(info), - udev_device_get_iscsi_address(info), - udev_device_get_iscsi_port(info), - udev_device_get_iscsi_nic(info)) - kwargs["node"] = node - kwargs["nic"] = self.iscsi.ifaces.get(node.iface, node.iface) - kwargs["ibft"] = node in self.iscsi.ibftNodes - kwargs["initiator"] = self.iscsi.initiator - log.info("%s is an iscsi disk" % name) + initiator = udev_device_get_iscsi_initiator(info) + target = udev_device_get_iscsi_name(info) + address = udev_device_get_iscsi_address(info) + port = udev_device_get_iscsi_port(info) + nic = udev_device_get_iscsi_nic(info) + kwargs["initiator"] = initiator + if initiator == self.iscsi.initiator: + node = self.iscsi.getNode(target, address, port, nic) + kwargs["node"] = node + kwargs["ibft"] = node in self.iscsi.ibftNodes + kwargs["nic"] = self.iscsi.ifaces.get(node.iface, node.iface) + log.info("%s is an iscsi disk" % name) + else: + # qla4xxx partial offload + kwargs["node"] = None + kwargs["ibft"] = False + kwargs["nic"] = "offload:not_accessible_via_iscsiadm" + kwargs["fw_address"] = address + kwargs["fw_port"] = port + kwargs["fw_name"] = name elif udev_device_is_fcoe(info): diskType = FcoeDiskDevice kwargs["nic"] = udev_device_get_fcoe_nic(info) diff --git a/pyanaconda/storage/fcoe.py b/pyanaconda/storage/fcoe.py index d263dcf80..fc2ad4017 100644 --- a/pyanaconda/storage/fcoe.py +++ b/pyanaconda/storage/fcoe.py @@ -122,14 +122,16 @@ class fcoe(object): iutil.execWithRedirect("dcbtool", [ "sc", nic, "app:fcoe", "e:1", "a:1", "w:1" ], stdout = "/dev/tty5", stderr="/dev/tty5") - iutil.execWithRedirect("fipvlan", [ nic, "-c", "-s" ], + iutil.execWithRedirect("fipvlan", [ "-c", "-s", "-f", + "'-fcoe'", nic], stdout = "/dev/tty5", stderr="/dev/tty5") else: if auto_vlan: # certain network configrations require the VLAN layer module: iutil.execWithRedirect("modprobe", ["8021q"], stdout = "/dev/tty5", stderr="/dev/tty5") - iutil.execWithRedirect("fipvlan", ['-c', '-s', nic], + iutil.execWithRedirect("fipvlan", ['-c', '-s', '-f', + "'-fcoe'", nic], stdout = "/dev/tty5", stderr="/dev/tty5") else: f = open("/sys/module/libfcoe/parameters/create", "w") diff --git a/pyanaconda/storage/formats/fs.py b/pyanaconda/storage/formats/fs.py index f94606b5c..eaf2405d3 100644 --- a/pyanaconda/storage/formats/fs.py +++ b/pyanaconda/storage/formats/fs.py @@ -408,6 +408,7 @@ class FS(DeviceFormat): # the other option is to actually replace this instance with an # instance of the new filesystem type. self._type = self.migrationTarget + self._mountType = self.migrationTarget @property def resizeArgs(self): diff --git a/pyanaconda/storage/formats/swap.py b/pyanaconda/storage/formats/swap.py index 42458d595..e961afe49 100644 --- a/pyanaconda/storage/formats/swap.py +++ b/pyanaconda/storage/formats/swap.py @@ -45,6 +45,9 @@ class SwapSpace(DeviceFormat): _supported = True # is supported _linuxNative = True # for clearpart + #see rhbz#744129 for details + _maxSize = 128 * 1024 + def __init__(self, *args, **kwargs): """ Create a SwapSpace instance. diff --git a/pyanaconda/storage/udev.py b/pyanaconda/storage/udev.py index 09e9c25dd..855ee70a3 100644 --- a/pyanaconda/storage/udev.py +++ b/pyanaconda/storage/udev.py @@ -556,19 +556,48 @@ def udev_device_get_iscsi_port(info): # IPV6 contains : within the address, the part after the last : is the port return path_components[address_field].split(":")[-1] -def udev_device_get_iscsi_nic(info): +def udev_device_get_iscsi_session(info): # '/devices/pci0000:00/0000:00:02.0/0000:09:00.0/0000:0a:01.0/0000:0e:00.2/host3/session1/target3:0:0/3:0:0:0/block/sda' # The position of sessionX part depends on device # (e.g. offload vs. sw; also varies for different offload devs) + session = None match = re.match('/.*/(session\d+)', info["sysfs_path"]) if match: session = match.groups()[0] + else: + log.error("udev_device_get_iscsi_session: session not found in %s" % info) + return session + + +def udev_device_get_iscsi_nic(info): + iface = None + session = udev_device_get_iscsi_session(info) + if session: iface = open("/sys/class/iscsi_session/%s/ifacename" % session).read().strip() - else: - iface = None return iface +def udev_device_get_iscsi_initiator(info): + initiator = None + if udev_device_is_partoff_iscsi(info): + host = re.match('.*/(host\d+)', info["sysfs_path"]).groups()[0] + if host: + initiator_file = "/sys/class/iscsi_host/%s/initiatorname" % host + if os.access(initiator_file, os.R_OK): + initiator = open(initiator_file).read().strip() + log.debug("found offload iscsi initiatorname %s in file %s" % + (initiator, initiator_file)) + if initiator.lstrip("(").rstrip(")").lower() == "null": + initiator = None + if initiator is None: + session = udev_device_get_iscsi_session(info) + if session: + initiator = open("/sys/class/iscsi_session/%s/initiatorname" % + session).read().strip() + log.debug("found iscsi initiatorname %s" % initiator) + return initiator + + # fcoe disks have ID_PATH in the form of: # For FCoE directly over the NIC (so no VLAN and thus no DCB): # pci-eth#-fc-${id} diff --git a/pyanaconda/text.py b/pyanaconda/text.py index 020f92a55..c924ae338 100644 --- a/pyanaconda/text.py +++ b/pyanaconda/text.py @@ -241,7 +241,7 @@ class PassphraseEntryWindow: res = buttons.buttonPressed(rc) passphrase = None - if res == TEXT_OK_CHECK: + if res == TEXT_OK_CHECK or rc == "F12": passphrase = passphraseentry.value().strip() self.rc = passphrase diff --git a/pyanaconda/textw/add_drive_text.py b/pyanaconda/textw/add_drive_text.py index 5c9384dc9..768681437 100644 --- a/pyanaconda/textw/add_drive_text.py +++ b/pyanaconda/textw/add_drive_text.py @@ -173,7 +173,7 @@ class iSCSITextWizard(pih.iSCSIWizard): result = grid.run() button = grid.buttons.buttonPressed(result) self.screen.popWindow() - return True if button == TEXT_OK_CHECK else False + return bool(button == TEXT_OK_CHECK or result == "F12") def destroy_dialogs(self): pass diff --git a/pyanaconda/vnc.py b/pyanaconda/vnc.py index 64c2ce15d..b06ac8743 100644 --- a/pyanaconda/vnc.py +++ b/pyanaconda/vnc.py @@ -186,7 +186,11 @@ class VncServer: self.log.info(_("Starting VNC...")) # Lets call it from here for now. - self.initialize() + try: + self.initialize() + except Exception, e: + stdoutLog.critical("Could not initialize the VNC server: %s" % e) + sys.exit(1) if self.password and len(self.password) < 6: self.changeVNCPasswdWindow() |