Exemplo n.º 1
0
def suggest_swap_size(quiet=False, hibernation=False, disk_space=None):
    """Suggest the size of the swap partition that will be created.

    :param bool quiet: whether to log size information or not
    :param bool hibernation: calculate swap size big enough for hibernation
    :param disk_space: how much disk space is available
    :return: calculated swap size
    """
    mem = total_memory()
    mem = ((mem / 16) + 1) * 16

    if not quiet:
        log.info("Detected %s of memory", mem)

    sixty_four_gib = Size("64 GiB")

    # the succeeding if-statement implements the following formula for
    # suggested swap size.
    #
    # swap(mem) = 2 * mem, if mem < 2 GiB
    #           = mem,     if 2 GiB <= mem < 8 GiB
    #           = mem / 2, if 8 GIB <= mem < 64 GiB
    #           = 4 GiB,   if mem >= 64 GiB
    if mem < Size("2 GiB"):
        swap = 2 * mem

    elif mem < Size("8 GiB"):
        swap = mem

    elif mem < sixty_four_gib:
        swap = mem / 2

    else:
        swap = Size("4 GiB")

    if hibernation:
        if mem <= sixty_four_gib:
            swap = mem + swap
        else:
            log.info(
                "Ignoring --hibernation option on systems with %s of RAM or more",
                sixty_four_gib)

    if disk_space is not None and not hibernation:
        max_swap = disk_space * MAX_SWAP_DISK_RATIO
        if swap > max_swap:
            log.info(
                "Suggested swap size (%(swap)s) exceeds %(percent)d %% of "
                "disk space, using %(percent)d %% of disk space (%(size)s) "
                "instead.", {
                    "percent": MAX_SWAP_DISK_RATIO * 100,
                    "swap": swap,
                    "size": max_swap
                })
            swap = max_swap

    if not quiet:
        log.info("Swap attempt of %s", swap)

    return swap
Exemplo n.º 2
0
def verify_swap(storage, constraints, report_error, report_warning):
    """ Verify the existence of swap.

    :param storage: a storage to check
    :param constraints: a dictionary of constraints
    :param report_error: a function for error reporting
    :param report_warning: a function for warning reporting
    """
    swaps = storage.fsset.swap_devices

    if not swaps:
        installed = util.total_memory()
        required = Size("%s MiB" % (constraints[STORAGE_MIN_RAM] + isys.NO_SWAP_EXTRA_RAM))

        if not constraints[STORAGE_SWAP_IS_RECOMMENDED]:
            if installed < required:
                report_warning(_("You have not specified a swap partition. "
                                 "%(requiredMem)s of memory is recommended to continue "
                                 "installation without a swap partition, but you only "
                                 "have %(installedMem)s.")
                               % {"requiredMem": required, "installedMem": installed})
        else:
            if installed < required:
                report_error(_("You have not specified a swap partition. "
                               "%(requiredMem)s of memory is required to continue "
                               "installation without a swap partition, but you only "
                               "have %(installedMem)s.")
                             % {"requiredMem": required, "installedMem": installed})
            else:
                report_warning(_("You have not specified a swap partition. "
                                 "Although not strictly required in all cases, "
                                 "it will significantly improve performance "
                                 "for most installations."))
Exemplo n.º 3
0
def swap_suggestion(quiet=False, hibernation=False, disk_space=None):
    """
    Suggest the size of the swap partition that will be created.

    :param quiet: whether to log size information or not
    :type quiet: bool
    :param hibernation: calculate swap size big enough for hibernation
    :type hibernation: bool
    :param disk_space: how much disk space is available
    :type disk_space: :class:`blivet.size.Size`
    :return: calculated swap size

    """

    mem = util.total_memory()
    mem = ((mem / 16) + 1) * 16
    if not quiet:
        log.info("Detected %s of memory", mem)

    sixtyfour_GiB = Size("64 GiB")

    # the succeeding if-statement implements the following formula for
    # suggested swap size.
    #
    # swap(mem) = 2 * mem, if mem < 2 GiB
    #           = mem,     if 2 GiB <= mem < 8 GiB
    #           = mem / 2, if 8 GIB <= mem < 64 GiB
    #           = 4 GiB,   if mem >= 64 GiB
    if mem < Size("2 GiB"):
        swap = 2 * mem

    elif mem < Size("8 GiB"):
        swap = mem

    elif mem < sixtyfour_GiB:
        swap = mem / 2

    else:
        swap = Size("4 GiB")

    if hibernation:
        if mem <= sixtyfour_GiB:
            swap = mem + swap
        else:
            log.info("Ignoring --hibernation option on systems with %s of RAM or more", sixtyfour_GiB)

    if disk_space is not None and not hibernation:
        max_swap = disk_space * MAX_SWAP_DISK_RATIO
        if swap > max_swap:
            log.info("Suggested swap size (%(swap)s) exceeds %(percent)d %% of "
                     "disk space, using %(percent)d %% of disk space (%(size)s) "
                     "instead.", {"percent": MAX_SWAP_DISK_RATIO * 100,
                                  "swap": swap,
                                  "size": max_swap})
            swap = max_swap

    if not quiet:
        log.info("Swap attempt of %s", swap)

    return swap
Exemplo n.º 4
0
def verify_swap(storage, constraints, report_error, report_warning):
    """ Verify the existence of swap.

    :param storage: a storage to check
    :param constraints: a dictionary of constraints
    :param report_error: a function for error reporting
    :param report_warning: a function for warning reporting
    """
    swaps = storage.fsset.swap_devices

    if not swaps:
        installed = util.total_memory()
        required = Size(
            "%s MiB" % (constraints[STORAGE_MIN_RAM] + isys.NO_SWAP_EXTRA_RAM))

        if not constraints[STORAGE_SWAP_IS_RECOMMENDED]:
            if installed < required:
                report_warning(
                    _("You have not specified a swap partition. "
                      "%(requiredMem)s of memory is recommended to continue "
                      "installation without a swap partition, but you only "
                      "have %(installedMem)s.") % {
                          "requiredMem": required,
                          "installedMem": installed
                      })
        else:
            if installed < required:
                report_error(
                    _("You have not specified a swap partition. "
                      "%(requiredMem)s of memory is required to continue "
                      "installation without a swap partition, but you only "
                      "have %(installedMem)s.") % {
                          "requiredMem": required,
                          "installedMem": installed
                      })
            else:
                report_warning(
                    _("You have not specified a swap partition. "
                      "Although not strictly required in all cases, "
                      "it will significantly improve performance "
                      "for most installations."))

    else:
        swap_space = sum((device.size for device in swaps), Size(0))
        disk_space = sum(
            (device.size for device in storage.mountpoints.values()), Size(0))
        recommended = swap_suggestion(disk_space=disk_space, quiet=True)

        log.debug("Total swap space: %s", swap_space)
        log.debug("Used disk space: %s", disk_space)
        log.debug("Recommended swaps space: %s", recommended)

        if swap_space < recommended:
            report_warning(
                _("Your swap space is less than %(size)s "
                  "which is lower than recommended.") % {"size": recommended})
Exemplo n.º 5
0
def verify_swap(storage, constraints, report_error, report_warning):
    """ Verify the existence of swap.

    :param storage: a storage to check
    :param constraints: a dictionary of constraints
    :param report_error: a function for error reporting
    :param report_warning: a function for warning reporting
    """
    swaps = storage.fsset.swap_devices

    if not swaps:
        installed = util.total_memory()
        required = Size("%s MiB" % (constraints[STORAGE_MIN_RAM] + isys.NO_SWAP_EXTRA_RAM))

        if not constraints[STORAGE_SWAP_IS_RECOMMENDED]:
            if installed < required:
                report_warning(_("You have not specified a swap partition. "
                                 "%(requiredMem)s of memory is recommended to continue "
                                 "installation without a swap partition, but you only "
                                 "have %(installedMem)s.")
                               % {"requiredMem": required, "installedMem": installed})
        else:
            if installed < required:
                report_error(_("You have not specified a swap partition. "
                               "%(requiredMem)s of memory is required to continue "
                               "installation without a swap partition, but you only "
                               "have %(installedMem)s.")
                             % {"requiredMem": required, "installedMem": installed})
            else:
                report_warning(_("You have not specified a swap partition. "
                                 "Although not strictly required in all cases, "
                                 "it will significantly improve performance "
                                 "for most installations."))

    else:
        swap_space = sum((device.size for device in swaps), Size(0))
        disk_space = sum((device.size for device in storage.mountpoints.values()), Size(0))
        recommended = swap_suggestion(disk_space=disk_space, quiet=True)

        log.debug("Total swap space: %s", swap_space)
        log.debug("Used disk space: %s", disk_space)
        log.debug("Recommended swaps space: %s", recommended)

        if swap_space < recommended:
            report_warning(_("Your swap space is less than %(size)s "
                             "which is lower than recommended.")
                           % {"size": recommended})
Exemplo n.º 6
0
def sanity_check(storage, min_ram=isys.MIN_RAM):
    """
    Run a series of tests to verify the storage configuration.

    This function is called at the end of partitioning so that
    we can make sure you don't have anything silly (like no /,
    a really small /, etc).

    :param storage: an instance of the :class:`blivet.Blivet` class to check
    :param min_ram: minimum RAM (in MiB) needed for the installation with swap
                    space available
    :rtype: a list of SanityExceptions
    :return: a list of accumulated errors and warnings

    """

    exns = []

    checkSizes = [('/usr', Size("250 MiB")), ('/tmp', Size("50 MiB")), ('/var', Size("384 MiB")),
                  ('/home', Size("100 MiB")), ('/boot', Size("200 MiB"))]
    mustbeonlinuxfs = ['/', '/var', '/tmp', '/usr', '/home', '/usr/share', '/usr/lib']
    mustbeonroot = ['/bin', '/dev', '/sbin', '/etc', '/lib', '/root', '/mnt', 'lost+found', '/proc']

    filesystems = storage.mountpoints
    root = storage.fsset.rootDevice
    swaps = storage.fsset.swapDevices

    if root:
        if root.size < Size("250 MiB"):
            exns.append(
               SanityWarning(_("Your root partition is less than 250 "
                              "megabytes which is usually too small to "
                              "install %s.") % (productName,)))
    else:
        exns.append(
           SanityError(_("You have not defined a root partition (/), "
                        "which is required for installation of %s "
                        "to continue.") % (productName,)))

    # Prevent users from installing on s390x with (a) no /boot volume, (b) the
    # root volume on LVM, and (c) the root volume not restricted to a single
    # PV
    # NOTE: There is not really a way for users to create a / volume
    # restricted to a single PV.  The backend support is there, but there are
    # no UI hook-ups to drive that functionality, but I do not personally
    # care.  --dcantrell
    if arch.isS390() and '/boot' not in storage.mountpoints and root:
        if root.type == 'lvmlv' and not root.singlePV:
            exns.append(
               SanityError(_("This platform requires /boot on a dedicated "
                            "partition or logical volume.  If you do not "
                            "want a /boot volume, you must place / on a "
                            "dedicated non-LVM partition.")))

    # FIXME: put a check here for enough space on the filesystems. maybe?

    for (mount, size) in checkSizes:
        if mount in filesystems and filesystems[mount].size < size:
            exns.append(
               SanityWarning(_("Your %(mount)s partition is less than "
                              "%(size)s which is lower than recommended "
                              "for a normal %(productName)s install.")
                            % {'mount': mount, 'size': size,
                               'productName': productName}))

    for (mount, device) in filesystems.items():
        problem = filesystems[mount].checkSize()
        if problem < 0:
            exns.append(
               SanityError(_("Your %(mount)s partition is too small for %(format)s formatting "
                            "(allowable size is %(minSize)s to %(maxSize)s)")
                          % {"mount": mount, "format": device.format.name,
                             "minSize": device.minSize, "maxSize": device.maxSize}))
        elif problem > 0:
            exns.append(
               SanityError(_("Your %(mount)s partition is too large for %(format)s formatting "
                            "(allowable size is %(minSize)s to %(maxSize)s)")
                          % {"mount":mount, "format": device.format.name,
                             "minSize": device.minSize, "maxSize": device.maxSize}))

    if storage.bootloader and not storage.bootloader.skip_bootloader:
        stage1 = storage.bootloader.stage1_device
        if not stage1:
            exns.append(
               SanityError(_("No valid boot loader target device found. "
                            "See below for details.")))
            pe = _platform.stage1MissingError
            if pe:
                exns.append(SanityError(_(pe)))
        else:
            storage.bootloader.is_valid_stage1_device(stage1)
            exns.extend(SanityError(msg) for msg in storage.bootloader.errors)
            exns.extend(SanityWarning(msg) for msg in storage.bootloader.warnings)

        stage2 = storage.bootloader.stage2_device
        if stage1 and not stage2:
            exns.append(SanityError(_("You have not created a bootable partition.")))
        else:
            storage.bootloader.is_valid_stage2_device(stage2)
            exns.extend(SanityError(msg) for msg in storage.bootloader.errors)
            exns.extend(SanityWarning(msg) for msg in storage.bootloader.warnings)
            if not storage.bootloader.check():
                exns.extend(SanityError(msg) for msg in storage.bootloader.errors)

        #
        # check that GPT boot disk on BIOS system has a BIOS boot partition
        #
        if _platform.weight(fstype="biosboot") and \
           stage1 and stage1.isDisk and \
           getattr(stage1.format, "labelType", None) == "gpt":
            missing = True
            for part in [p for p in storage.partitions if p.disk == stage1]:
                if part.format.type == "biosboot":
                    missing = False
                    break

            if missing:
                exns.append(
                   SanityError(_("Your BIOS-based system needs a special "
                                "partition to boot from a GPT disk label. "
                                "To continue, please create a 1MiB "
                                "'biosboot' type partition.")))

    if not swaps:
        installed = util.total_memory()
        required = Size("%s MiB" % (min_ram + isys.NO_SWAP_EXTRA_RAM))

        if installed < required:
            exns.append(
               SanityError(_("You have not specified a swap partition.  "
                            "%(requiredMem)s of memory is required to continue installation "
                            "without a swap partition, but you only have %(installedMem)s.")
                          % {"requiredMem": required,
                             "installedMem": installed}))
        else:
            exns.append(
               SanityWarning(_("You have not specified a swap partition.  "
                              "Although not strictly required in all cases, "
                              "it will significantly improve performance "
                              "for most installations.")))
    no_uuid = [s for s in swaps if s.format.exists and not s.format.uuid]
    if no_uuid:
        exns.append(
           SanityWarning(_("At least one of your swap devices does not have "
                          "a UUID, which is common in swap space created "
                          "using older versions of mkswap. These devices "
                          "will be referred to by device path in "
                          "/etc/fstab, which is not ideal since device "
                          "paths can change under a variety of "
                          "circumstances. ")))

    for (mountpoint, dev) in filesystems.items():
        if mountpoint in mustbeonroot:
            exns.append(
               SanityError(_("This mount point is invalid.  The %s directory must "
                            "be on the / file system.") % mountpoint))

        if mountpoint in mustbeonlinuxfs and (not dev.format.mountable or not dev.format.linuxNative):
            exns.append(
               SanityError(_("The mount point %s must be on a linux file system.") % mountpoint))

    if storage.rootDevice and storage.rootDevice.format.exists:
        e = storage.mustFormat(storage.rootDevice)
        if e:
            exns.append(SanityError(e))

    exns += verify_LUKS_devices_have_key(storage)

    return exns
Exemplo n.º 7
0
def sanity_check(storage, min_ram=isys.MIN_RAM):
    """
    Run a series of tests to verify the storage configuration.

    This function is called at the end of partitioning so that
    we can make sure you don't have anything silly (like no /,
    a really small /, etc).

    :param storage: an instance of the :class:`blivet.Blivet` class to check
    :param min_ram: minimum RAM (in MiB) needed for the installation with swap
                    space available
    :rtype: a list of SanityExceptions
    :return: a list of accumulated errors and warnings

    """

    exns = []

    checkSizes = [('/usr', Size("250 MiB")), ('/tmp', Size("50 MiB")),
                  ('/var', Size("384 MiB")), ('/home', Size("100 MiB")),
                  ('/boot', Size("200 MiB"))]
    mustbeonlinuxfs = [
        '/', '/var', '/tmp', '/usr', '/home', '/usr/share', '/usr/lib'
    ]
    mustbeonroot = [
        '/bin', '/dev', '/sbin', '/etc', '/lib', '/root', '/mnt', 'lost+found',
        '/proc'
    ]

    filesystems = storage.mountpoints
    root = storage.fsset.rootDevice
    swaps = storage.fsset.swapDevices

    if root:
        if root.size < Size("250 MiB"):
            exns.append(
                SanityWarning(
                    _("Your root partition is less than 250 "
                      "megabytes which is usually too small to "
                      "install %s.") % (productName, )))
    else:
        exns.append(
            SanityError(
                _("You have not defined a root partition (/), "
                  "which is required for installation of %s "
                  "to continue.") % (productName, )))

    # FIXME: put a check here for enough space on the filesystems. maybe?

    for (mount, size) in checkSizes:
        if mount in filesystems and filesystems[mount].size < size:
            exns.append(
                SanityWarning(
                    _("Your %(mount)s partition is less than "
                      "%(size)s which is lower than recommended "
                      "for a normal %(productName)s install.") % {
                          'mount': mount,
                          'size': size,
                          'productName': productName
                      }))

    for (mount, device) in filesystems.items():
        problem = filesystems[mount].checkSize()
        if problem < 0:
            exns.append(
                SanityError(
                    _("Your %(mount)s partition is too small for %(format)s formatting "
                      "(allowable size is %(minSize)s to %(maxSize)s)") % {
                          "mount": mount,
                          "format": device.format.name,
                          "minSize": device.minSize,
                          "maxSize": device.maxSize
                      }))
        elif problem > 0:
            exns.append(
                SanityError(
                    _("Your %(mount)s partition is too large for %(format)s formatting "
                      "(allowable size is %(minSize)s to %(maxSize)s)") % {
                          "mount": mount,
                          "format": device.format.name,
                          "minSize": device.minSize,
                          "maxSize": device.maxSize
                      }))

    if storage.bootloader and not storage.bootloader.skip_bootloader:
        stage1 = storage.bootloader.stage1_device
        if not stage1:
            exns.append(
                SanityError(
                    _("No valid boot loader target device found. "
                      "See below for details.")))
            pe = _platform.stage1MissingError
            if pe:
                exns.append(SanityError(_(pe)))
        else:
            storage.bootloader.is_valid_stage1_device(stage1)
            exns.extend(SanityError(msg) for msg in storage.bootloader.errors)
            exns.extend(
                SanityWarning(msg) for msg in storage.bootloader.warnings)

        stage2 = storage.bootloader.stage2_device
        if stage1 and not stage2:
            exns.append(
                SanityError(_("You have not created a bootable partition.")))
        else:
            storage.bootloader.is_valid_stage2_device(stage2)
            exns.extend(SanityError(msg) for msg in storage.bootloader.errors)
            exns.extend(
                SanityWarning(msg) for msg in storage.bootloader.warnings)
            if not storage.bootloader.check():
                exns.extend(
                    SanityError(msg) for msg in storage.bootloader.errors)

        #
        # check that GPT boot disk on BIOS system has a BIOS boot partition
        #
        if _platform.weight(fstype="biosboot") and \
           stage1 and stage1.isDisk and \
           getattr(stage1.format, "labelType", None) == "gpt":
            missing = True
            for part in [p for p in storage.partitions if p.disk == stage1]:
                if part.format.type == "biosboot":
                    missing = False
                    break

            if missing:
                exns.append(
                    SanityError(
                        _("Your BIOS-based system needs a special "
                          "partition to boot from a GPT disk label. "
                          "To continue, please create a 1MiB "
                          "'biosboot' type partition.")))

    if not swaps:
        installed = util.total_memory()
        required = Size("%s MiB" % (min_ram + isys.NO_SWAP_EXTRA_RAM))

        if installed < required:
            exns.append(
                SanityError(
                    _("You have not specified a swap partition.  "
                      "%(requiredMem)s of memory is required to continue installation "
                      "without a swap partition, but you only have %(installedMem)s."
                      ) % {
                          "requiredMem": required,
                          "installedMem": installed
                      }))
        else:
            exns.append(
                SanityWarning(
                    _("You have not specified a swap partition.  "
                      "Although not strictly required in all cases, "
                      "it will significantly improve performance "
                      "for most installations.")))
    no_uuid = [s for s in swaps if s.format.exists and not s.format.uuid]
    if no_uuid:
        exns.append(
            SanityWarning(
                _("At least one of your swap devices does not have "
                  "a UUID, which is common in swap space created "
                  "using older versions of mkswap. These devices "
                  "will be referred to by device path in "
                  "/etc/fstab, which is not ideal since device "
                  "paths can change under a variety of "
                  "circumstances. ")))

    for (mountpoint, dev) in filesystems.items():
        if mountpoint in mustbeonroot:
            exns.append(
                SanityError(
                    _("This mount point is invalid.  The %s directory must "
                      "be on the / file system.") % mountpoint))

        if mountpoint in mustbeonlinuxfs and (not dev.format.mountable
                                              or not dev.format.linuxNative):
            exns.append(
                SanityError(
                    _("The mount point %s must be on a linux file system.") %
                    mountpoint))

    if storage.rootDevice and storage.rootDevice.format.exists:
        e = storage.mustFormat(storage.rootDevice)
        if e:
            exns.append(SanityError(e))

    exns += verify_LUKS_devices_have_key(storage)

    return exns