summaryrefslogtreecommitdiffstats
path: root/pyanaconda
diff options
context:
space:
mode:
Diffstat (limited to 'pyanaconda')
-rw-r--r--pyanaconda/bootloader.py22
-rw-r--r--pyanaconda/installclass.py7
-rw-r--r--pyanaconda/installclasses/rhel.py3
-rw-r--r--pyanaconda/iutil.py47
-rw-r--r--pyanaconda/kickstart.py16
-rw-r--r--pyanaconda/storage/devicelibs/swap.py41
-rw-r--r--pyanaconda/storage/devices.py33
-rw-r--r--pyanaconda/storage/devicetree.py44
-rw-r--r--pyanaconda/storage/fcoe.py6
-rw-r--r--pyanaconda/storage/formats/fs.py1
-rw-r--r--pyanaconda/storage/formats/swap.py3
-rw-r--r--pyanaconda/storage/udev.py35
-rw-r--r--pyanaconda/text.py2
-rw-r--r--pyanaconda/textw/add_drive_text.py2
-rw-r--r--pyanaconda/vnc.py6
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()