diff options
author | Chris Lumens <clumens@redhat.com> | 2012-08-03 10:35:34 -0400 |
---|---|---|
committer | Chris Lumens <clumens@redhat.com> | 2012-08-03 10:35:34 -0400 |
commit | 3671cc86e836990077820556387cbb416e709bbd (patch) | |
tree | c8754fc1809bd175304f51bb11776022e9b7ec9d | |
parent | ed8bf92fc65050f54463df959a9209ae43af0c54 (diff) | |
parent | db84929284ce85a7af580738551fcc6e172cc690 (diff) | |
download | anaconda-3671cc86e836990077820556387cbb416e709bbd.tar.gz anaconda-3671cc86e836990077820556387cbb416e709bbd.tar.xz anaconda-3671cc86e836990077820556387cbb416e709bbd.zip |
Merge branch 'master' into newui-merge
Conflicts:
Makefile.am
anaconda
data/systemd/anaconda.target
pyanaconda/bootloader.py
pyanaconda/constants.py
pyanaconda/iutil.py
pyanaconda/kickstart.py
pyanaconda/network.py
pyanaconda/vnc.py
scripts/makeupdates
42 files changed, 284 insertions, 2020 deletions
diff --git a/Makefile.am b/Makefile.am index b44aa2d9b..9470447de 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,7 +19,7 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = pyanaconda gptsync po data \ +SUBDIRS = pyanaconda po data \ tests utils scripts docs dracut widgets EXTRA_DIST = config.rpath COPYING \ @@ -71,13 +71,13 @@ def exitHandler(rebootData, storage, exitCode=None): dracut_eject(drive.path) if rebootData.action == KS_SHUTDOWN: - os.system("systemctl --force --no-wall poweroff") + os.system("systemctl --no-wall poweroff") elif rebootData.action == KS_WAIT: - os.system("systemctl --force --no-wall halt") + os.system("systemctl --no-wall halt") else: # reboot action is KS_REBOOT or None - os.system("systemctl --force --no-wall reboot") + os.system("systemctl --no-wall reboot") elif flags.livecdInstall: - os.system("systemctl --force --no-wall reboot") + os.system("systemctl --no-wall reboot") def startMetacityWM(): childpid = os.fork() @@ -615,23 +615,11 @@ def prompt_for_ssh(): # see if we can sniff out network info netinfo = network.Network() - devices = netinfo.netdevices - active_devs = network.getActiveNetDevs() + ip = netinfo.getFirstRealIP() - ip = None - if active_devs != []: - devname = devices[active_devs[0]].iface - try: - ips = (isys.getIPAddresses(devname, version=4) + - isys.getIPAddresses(devname, version=6)) - except Exception as e: - stdoutLog.warning("Got an exception trying to get the ip addr " - "of %s: %s" % (devname, e)) - else: - if ips and ips[0] not in ("127.0.0.1", "::1"): - stdoutLog.debug("IPs (using first) of device %s: %s" % (devname, - ips)) - ip = ips[0] + if not ip: + stdoutLog.error("No IP addresses found, cannot continue installation.") + sys.exit(1) ipstr = ip @@ -662,6 +650,8 @@ def prompt_for_ssh(): if __name__ == "__main__": + print "Starting installer, one moment..." + setupPythonPath() # Allow a file to be loaded as early as possible @@ -725,10 +715,12 @@ if __name__ == "__main__": from pyanaconda import kickstart from pyanaconda import ntp - # to set UTF8 mode on the terminal, we need LANG to be set usefully - if os.environ.get("LANG", "C") == "C": - os.environ['LANG'] = DEFAULT_LANG - print "\033%G" # UTF8 power go! + verdesc = "%s for %s %s" % (getAnacondaVersion(), + product.productName, product.productVersion) + if product.isFinal: + print "anaconda %s started." + else: + print "anaconda %s (pre-release) started." import gettext _ = lambda x: gettext.ldgettext("anaconda", x) diff --git a/anaconda.spec.in b/anaconda.spec.in index 955974fa3..6cadbc096 100644 --- a/anaconda.spec.in +++ b/anaconda.spec.in @@ -263,7 +263,6 @@ update-desktop-database &> /dev/null || : %{_sbindir}/logpicker %{_sbindir}/anaconda-cleanup-initramfs %ifarch i386 i486 i586 i686 x86_64 -%{_sbindir}/gptsync %{_sbindir}/showpart %endif %{_datadir}/anaconda diff --git a/configure.ac b/configure.ac index 1f41374c6..9be6da90c 100644 --- a/configure.ac +++ b/configure.ac @@ -259,7 +259,6 @@ AC_CONFIG_FILES([Makefile data/command-stubs/Makefile docs/Makefile dracut/Makefile - gptsync/Makefile pyanaconda/installclasses/Makefile data/liveinst/Makefile data/liveinst/console.apps/Makefile diff --git a/data/Makefile.am b/data/Makefile.am index 49b68c48c..18e165f47 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -32,6 +32,9 @@ langdir = $(datadir)/$(PACKAGE_NAME) lang_DATA = lang-names dist_lang_DATA = lang-table +tmuxdir = $(datadir)/$(PACKAGE_NAME) +dist_tmux_DATA = tmux.conf + if IS_S390 shareddir = $(datadir)/$(PACKAGE_NAME) dist_shared_SCRIPTS = linuxrc.s390 diff --git a/data/post-scripts/80-setfilecons.ks b/data/post-scripts/80-setfilecons.ks index 7b0c8c963..93ac9620c 100644 --- a/data/post-scripts/80-setfilecons.ks +++ b/data/post-scripts/80-setfilecons.ks @@ -1,6 +1,6 @@ %post -restorecon -ir /etc/sysconfig/network-scripts /var/lib/rpm /var/lib/yum /etc/lvm \ +restorecon -ir /etc/sysconfig/network-scripts /var/lib /etc/lvm \ /dev /etc/iscsi /var/lib/iscsi /root /var/lock /var/log \ /etc/modprobe.d /etc/sysconfig /var/cache/yum @@ -8,7 +8,11 @@ restorecon -i /etc/rpm/macros /etc/dasd.conf /etc/zfcp.conf /lib64 /usr/lib64 \ /etc/blkid.tab* /etc/mtab /etc/fstab /etc/resolv.conf \ /etc/modprobe.conf* /var/log/*tmp /etc/crypttab \ /etc/mdadm.conf /etc/sysconfig/network /root/install.log* \ - /etc/udev/rules.d/70-persistent-net.rules /etc/*shadow* \ - /etc/dhcp/dhclient-*.conf /etc/localtime + /etc/*shadow* /etc/dhcp/dhclient-*.conf /etc/localtime \ + /root/install.log* + +if [ -e /etc/zipl.conf ]; then + restorecon -i /etc/zipl.conf +fi %end diff --git a/data/systemd/Makefile.am b/data/systemd/Makefile.am index 8579ece04..96bd8f0cb 100644 --- a/data/systemd/Makefile.am +++ b/data/systemd/Makefile.am @@ -20,8 +20,9 @@ systemddir = /lib/systemd/system generatordir = /lib/systemd/system-generators -dist_systemd_DATA = anaconda@.service \ +dist_systemd_DATA = anaconda.service \ anaconda.target \ + anaconda-tmux@.service \ anaconda-shell@.service \ instperf.service \ anaconda-sshd.service \ diff --git a/data/systemd/anaconda-cleanup-initramfs.service b/data/systemd/anaconda-cleanup-initramfs.service index 1d10bfc7a..cc493572d 100644 --- a/data/systemd/anaconda-cleanup-initramfs.service +++ b/data/systemd/anaconda-cleanup-initramfs.service @@ -1,6 +1,6 @@ [Unit] Description=Clean Up Initramfs -Before=anaconda@.service +Before=anaconda.service ConditionPathIsDirectory=/run/initramfs/usr/lib/modules [Service] diff --git a/data/systemd/anaconda-generator b/data/systemd/anaconda-generator index cb4704023..71e35e718 100755 --- a/data/systemd/anaconda-generator +++ b/data/systemd/anaconda-generator @@ -25,7 +25,7 @@ done consoletty="$tty" # put anaconda on the real console -service_on_tty anaconda@.service $consoletty +service_on_tty anaconda-tmux@.service $consoletty # put a shell on tty2 and the first virtualization console we find for tty in tty2 hvc0 hvc1 xvc0 hvsi0 hvsi1 hvsi2; do diff --git a/data/systemd/anaconda-tmux@.service b/data/systemd/anaconda-tmux@.service new file mode 100644 index 000000000..0b8376588 --- /dev/null +++ b/data/systemd/anaconda-tmux@.service @@ -0,0 +1,15 @@ +[Unit] +Description=Anaconda Text Console +Requires=anaconda.service +After=anaconda.target anaconda.service + +[Service] +Type=simple +WorkingDirectory=/root +Environment=LANG=en_US.UTF-8 +ExecStartPre=/usr/bin/echo -e \033%G +ExecStart=/usr/bin/tmux -u attach -t anaconda +StandardInput=tty-force +TTYPath=/dev/%I +TTYReset=yes +Restart=always diff --git a/data/systemd/anaconda@.service b/data/systemd/anaconda.service index 03ecabb17..5629e00a8 100644 --- a/data/systemd/anaconda@.service +++ b/data/systemd/anaconda.service @@ -3,11 +3,7 @@ Description=Anaconda After=anaconda.target [Service] -Environment=HOME=/root MALLOC_CHECK_=2 MALLOC_PERTURB_=204 PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sysimage/bin:/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:/mnt/sysimage/sbin -Type=oneshot +Type=forking +Environment=HOME=/root MALLOC_CHECK_=2 MALLOC_PERTURB_=204 PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sysimage/bin:/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:/mnt/sysimage/sbin LANG=en_US.UTF-8 WorkingDirectory=/root -ExecStart=/usr/sbin/anaconda -StandardInput=tty-force -TTYPath=/dev/%I -TTYReset=yes -TimeoutSec=0 +ExecStart=/usr/bin/tmux -u -f /etc/anaconda-tmux.conf start diff --git a/data/systemd/anaconda.target b/data/systemd/anaconda.target index 9a95c6615..597adfde3 100644 --- a/data/systemd/anaconda.target +++ b/data/systemd/anaconda.target @@ -3,7 +3,6 @@ Description=Anaconda System Services Requires=basic.target After=basic.target AllowIsolate=yes -Before=anaconda@.service Wants=anaconda-cleanup-initramfs.service Wants=instperf.service Wants=rsyslog.service diff --git a/data/systemd/fedora-import-state b/data/systemd/fedora-import-state deleted file mode 100644 index a853ab9cd..000000000 --- a/data/systemd/fedora-import-state +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -# fedora-import-state: import state files from initramfs (e.g. network config) - -# exit early if root isn't writeable -[ -w / ] || exit 0 - -# copy state into root -cd /run/initramfs/state -cp -a -t / . - -# run restorecon on the copied files -if [ -e /sys/fs/selinux/enforce ]; then - find . | ( cd /; restorecon -i -f -; ) || : -fi diff --git a/data/systemd/fedora-import-state.service b/data/systemd/fedora-import-state.service deleted file mode 100644 index 5294fe172..000000000 --- a/data/systemd/fedora-import-state.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Import network configuration from initramfs -DefaultDependencies=no -ConditionDirectoryNotEmpty=/run/initramfs/state -Conflicts=shutdown.target -Before=shutdown.target emergency.service emergency.target systemd-tmpfiles-setup.service -After=remount-rootfs.service - -[Service] -ExecStart=/lib/systemd/fedora-import-state -Type=oneshot -TimeoutSec=0 -RemainAfterExit=yes diff --git a/data/tmux.conf b/data/tmux.conf new file mode 100644 index 000000000..3639fcbec --- /dev/null +++ b/data/tmux.conf @@ -0,0 +1,16 @@ +# tmux.conf for the anaconda environment +set-option -s exit-unattached off +set-option -g base-index 1 + +new-session -s anaconda -n main "anaconda" + +set-option set-remain-on-exit on +set-option status-right "" +set-option status-right-length 0 + +new-window -d -n shell "bash --login" +new-window -d -n log "tail -F /tmp/anaconda.log" +new-window -d -n storage-log "tail -F /tmp/storage.log" +new-window -d -n program-log "tail -F /tmp/program.log" + +detach-client -s anaconda diff --git a/dracut/parse-kickstart b/dracut/parse-kickstart index aa4e0e83e..13a0e8f43 100755 --- a/dracut/parse-kickstart +++ b/dracut/parse-kickstart @@ -23,6 +23,15 @@ from collections import OrderedDict # Default logging: none log = logging.getLogger('parse-kickstart').addHandler(logging.NullHandler()) +# Helper function for reading simple files in /sys +def readsysfile(f): + '''Return the contents of f, or "" if missing.''' + try: + val = open(f).readline().strip() + except IOError: + val = "" + return val + # Here are the kickstart commands we care about: class Method(commands.method.F14_Method): @@ -108,7 +117,6 @@ class DracutHandler(handlerclass): command = self.commands[cmd] if hasattr(command, "dracut_args"): log.debug("kickstart line %u: handling %s", lineno, cmd) - line = " ".join(args) self.output.append(command.dracut_args(args, lineno, obj)) return obj @@ -120,12 +128,16 @@ class KmsgFormatter(logging.Formatter): elif record.levelno <= logging.WARNING: tag = "<28>" else: tag = "<24>" return tag + logging.Formatter.format(self, record) -def init_logger(): +def init_logger(level=logging.WARNING): + if 'rd.debug' in proc_cmdline: + level = logging.DEBUG + elif 'rd.info' in proc_cmdline: + level = logging.INFO logfmt = "%(name)s %(levelname)s: %(message)s" stderr = logging.StreamHandler() stderr.setFormatter(logging.Formatter(logfmt)) logger = logging.getLogger('parse-kickstart') - logger.setLevel(logging.WARNING) + logger.setLevel(level) logger.addHandler(stderr) try: kmsg = logging.FileHandler("/dev/kmsg", "w") @@ -140,13 +152,9 @@ def is_mac(addr): def find_devname(mac): for netif in os.listdir("/sys/class/net"): - try: - thismac = readfile("/sys/class/net/%s/address" % netif) - except IOError: - pass - else: - if thismac.lower() == mac.lower(): - return netif + thismac = readsysfile("/sys/class/net/%s/address" % netif) + if thismac.lower() == mac.lower(): + return netif def ksnet_to_dracut(args, lineno, net, bootdev=False): '''Translate the kickstart network data into dracut network data.''' @@ -195,9 +203,9 @@ def ksnet_to_dracut(args, lineno, net, bootdev=False): if net.mtu: # XXX FIXME: dracut doesn't support mtu= (yet) if net.device: - line.append("mtu=%s:%u" % (net.device, net.mtu)) + line.append("mtu=%s:%s" % (net.device, net.mtu)) else: - line.append("mtu=%u" % net.mtu) + line.append("mtu=%s" % net.mtu) # TODO: nodefroute, noipv[46], nodns: pass along to 'ifcfg' module somehow # TODO FIXME dhcpclass: dracut only uses one dhclient.conf for all ifaces @@ -215,13 +223,6 @@ def ksnet_to_dracut(args, lineno, net, bootdev=False): return " ".join(line) -def readfile(f): - try: - val = open(f).readline().strip() - except IOError: - val = None - return val - def ksnet_to_ifcfg(net, filename=None): '''Write an ifcfg file for the given kickstart network config''' dev = net.device @@ -235,8 +236,8 @@ def ksnet_to_ifcfg(net, filename=None): if not os.path.isdir("/tmp/ifcfg"): os.makedirs("/tmp/ifcfg") ifcfg['DEVICE'] = dev - ifcfg['HWADDR'] = readfile("/sys/class/net/%s/address" % dev) - ifcfg['UUID'] = readfile("/proc/sys/kernel/random/uuid") + ifcfg['HWADDR'] = readsysfile("/sys/class/net/%s/address" % dev) + ifcfg['UUID'] = readsysfile("/proc/sys/kernel/random/uuid") ifcfg['ONBOOT'] = "yes" if net.onboot else "no" # dhcp etc. @@ -270,6 +271,7 @@ def ksnet_to_ifcfg(net, filename=None): # TODO: handle essid/wepkey/wpakey (maybe inside anaconda) try: + log.info("writing ifcfg for %s", dev) outf = open(filename, "w") outf.write('# Generated by parse-kickstart\n') for k,v in ifcfg.items(): @@ -284,6 +286,7 @@ def process_kickstart(ksfile): handler = DracutHandler() handler.ksdevice = os.environ.get('ksdevice') parser = KickstartParser(handler) + log.info("processing kickstart file %s", ksfile) processed_file = preprocessKickstart(ksfile) try: parser.readKickstart(processed_file) @@ -291,6 +294,7 @@ def process_kickstart(ksfile): log.error(str(e)) with open("/tmp/ks.info", "a") as f: f.write('parsed_kickstart="%s"\n' % processed_file) + log.info("finished parsing kickstart") return processed_file, handler.output if __name__ == '__main__': diff --git a/gptsync/.gitignore b/gptsync/.gitignore deleted file mode 100644 index 4971cfa19..000000000 --- a/gptsync/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -gptsync -showpart diff --git a/gptsync/Makefile.am b/gptsync/Makefile.am deleted file mode 100644 index 7f664325d..000000000 --- a/gptsync/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -# gptsync/Makefile.am for anaconda -# -# Copyright (C) 2009 Red Hat, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -# Author: David Cantrell <dcantrell@redhat.com> - -COMMON_SRCS = lib.c os_unix.c -noinst_HEADERS = gptsync.h syslinux_mbr.h - -if IS_GPTSYNC_ARCH -sbin_PROGRAMS = gptsync showpart - -gptsync_CFLAGS = -DPROGNAME=gptsync -gptsync_SOURCES = gptsync.c $(COMMON_SRCS) - -showpart_CFLAGS = -DPROGNAME=showpart -showpart_SOURCES = showpart.c $(COMMON_SRCS) -endif - -EXTRA_DIST = README - -MAINTAINERCLEANFILES = Makefile.in diff --git a/gptsync/README b/gptsync/README deleted file mode 100644 index cb306bd76..000000000 --- a/gptsync/README +++ /dev/null @@ -1,41 +0,0 @@ -gptsync is from refit (refit.sf.net). It has been modified to -1) Not prompt if you want to copy -2) Default to Linux native (0x83) instead of fat32 partition id - -The original license follows. - - - rEFIt License -=============== - -Copyright (c) 2006-2007 Christoph Pfisterer -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the - distribution. - - * Neither the name of Christoph Pfisterer nor the names of the - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/gptsync/gptsync.c b/gptsync/gptsync.c deleted file mode 100644 index 94c37eb33..000000000 --- a/gptsync/gptsync.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * gptsync/gptsync.c - * Platform-independent code for syncing GPT and MBR - * - * Copyright (c) 2006-2007 Christoph Pfisterer - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Christoph Pfisterer nor the names of the - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "gptsync.h" - -#include "syslinux_mbr.h" - -// -// MBR functions -// - -static UINTN check_mbr(VOID) -{ - UINTN i, k; - - // check each entry - for (i = 0; i < mbr_part_count; i++) { - // check for overlap - for (k = 0; k < mbr_part_count; k++) { - if (k != i && !(mbr_parts[i].start_lba > mbr_parts[k].end_lba || mbr_parts[k].start_lba > mbr_parts[i].end_lba)) { - Print(L"Status: MBR partition table is invalid, partitions overlap.\n"); - return 1; - } - } - - // check for extended partitions - if (mbr_parts[i].mbr_type == 0x05 || mbr_parts[i].mbr_type == 0x0f || mbr_parts[i].mbr_type == 0x85) { - Print(L"Status: Extended partition found in MBR table, will not touch this disk.\n", - gpt_parts[i].gpt_parttype->name); - return 1; - } - } - - return 0; -} - -static UINTN write_mbr(VOID) -{ - UINTN status; - UINTN i, k; - UINT8 active; - UINT64 lba; - MBR_PARTITION_INFO *table; - BOOLEAN have_bootcode; - - Print(L"\nWriting new MBR...\n"); - - // read MBR data - status = read_sector(0, sector); - if (status != 0) - return status; - - // write partition table - *((UINT16 *)(sector + 510)) = 0xaa55; - - table = (MBR_PARTITION_INFO *)(sector + 446); - active = 0x80; - for (i = 0; i < 4; i++) { - for (k = 0; k < new_mbr_part_count; k++) { - if (new_mbr_parts[k].index == i) - break; - } - if (k >= new_mbr_part_count) { - // unused entry - table[i].flags = 0; - table[i].start_chs[0] = 0; - table[i].start_chs[1] = 0; - table[i].start_chs[2] = 0; - table[i].type = 0; - table[i].end_chs[0] = 0; - table[i].end_chs[1] = 0; - table[i].end_chs[2] = 0; - table[i].start_lba = 0; - table[i].size = 0; - } else { - if (new_mbr_parts[k].active) { - table[i].flags = active; - active = 0x00; - } else - table[i].flags = 0x00; - table[i].start_chs[0] = 0xfe; - table[i].start_chs[1] = 0xff; - table[i].start_chs[2] = 0xff; - table[i].type = new_mbr_parts[k].mbr_type; - table[i].end_chs[0] = 0xfe; - table[i].end_chs[1] = 0xff; - table[i].end_chs[2] = 0xff; - - lba = new_mbr_parts[k].start_lba; - if (lba > 0xffffffffULL) { - Print(L"Warning: Partition %d starts beyond 2 TiB limit\n", i+1); - lba = 0xffffffffULL; - } - table[i].start_lba = (UINT32)lba; - - lba = new_mbr_parts[k].end_lba + 1 - new_mbr_parts[k].start_lba; - if (lba > 0xffffffffULL) { - Print(L"Warning: Partition %d extends beyond 2 TiB limit\n", i+1); - lba = 0xffffffffULL; - } - table[i].size = (UINT32)lba; - } - } - - // add boot code if necessary - have_bootcode = FALSE; - for (i = 0; i < MBR_BOOTCODE_SIZE; i++) { - if (sector[i] != 0) { - have_bootcode = TRUE; - break; - } - } - if (!have_bootcode) { - // no boot code found in the MBR, add the syslinux MBR code - SetMem(sector, 0, MBR_BOOTCODE_SIZE); - CopyMem(sector, syslinux_mbr, SYSLINUX_MBR_SIZE); - } - - // write MBR data - status = write_sector(0, sector); - if (status != 0) - return status; - - Print(L"MBR updated successfully!\n"); - - return 0; -} - -// -// GPT functions -// - -static UINTN check_gpt(VOID) -{ - UINTN i, k; - BOOLEAN found_data_parts; - - if (gpt_part_count == 0) { - Print(L"Status: No GPT partition table, no need to sync.\n"); - return 1; - } - - // check each entry - found_data_parts = FALSE; - for (i = 0; i < gpt_part_count; i++) { - // check sanity - if (gpt_parts[i].end_lba < gpt_parts[i].start_lba) { - Print(L"Status: GPT partition table is invalid.\n"); - return 1; - } - // check for overlap - for (k = 0; k < gpt_part_count; k++) { - if (k != i && !(gpt_parts[i].start_lba > gpt_parts[k].end_lba || gpt_parts[k].start_lba > gpt_parts[i].end_lba)) { - Print(L"Status: GPT partition table is invalid, partitions overlap.\n"); - return 1; - } - } - - // check for partitions kind - if (gpt_parts[i].gpt_parttype->kind == GPT_KIND_FATAL) { - Print(L"Status: GPT partition of type '%s' found, will not touch this disk.\n", - gpt_parts[i].gpt_parttype->name); - return 1; - } - if (gpt_parts[i].gpt_parttype->kind == GPT_KIND_DATA || - gpt_parts[i].gpt_parttype->kind == GPT_KIND_BASIC_DATA) - found_data_parts = TRUE; - } - - if (!found_data_parts) { - Print(L"Status: GPT partition table has no data partitions, no need to sync.\n"); - return 1; - } - - return 0; -} - -// -// compare GPT and MBR tables -// - -#define ACTION_NONE (0) -#define ACTION_NOP (1) -#define ACTION_REWRITE (2) - -static UINTN analyze(VOID) -{ - UINTN action; - UINTN i, k, iter, count_active, detected_parttype; - CHARN *fsname; - UINT64 min_start_lba; - BOOLEAN have_esp; - - new_mbr_part_count = 0; - - // determine correct MBR types for GPT partitions - if (gpt_part_count == 0) { - Print(L"Status: No GPT partitions defined, nothing to sync.\n"); - return 0; - } - have_esp = FALSE; - for (i = 0; i < gpt_part_count; i++) { - gpt_parts[i].mbr_type = gpt_parts[i].gpt_parttype->mbr_type; - if (gpt_parts[i].gpt_parttype->kind == GPT_KIND_BASIC_DATA) { - // Basic Data: need to look at data in the partition - detect_mbrtype_fs(gpt_parts[i].start_lba, &detected_parttype, &fsname); - if (detected_parttype) - gpt_parts[i].mbr_type = detected_parttype; - else - gpt_parts[i].mbr_type = 0x0b; // fallback: FAT32 - } else if (gpt_parts[i].mbr_type == 0xef) { - // EFI System Partition: GNU parted can put this on any partition, - // need to detect file systems - detect_mbrtype_fs(gpt_parts[i].start_lba, &detected_parttype, &fsname); - if (!have_esp && (detected_parttype == 0x01 || detected_parttype == 0x0e || detected_parttype == 0x0c)) - ; // seems to be a legitimate ESP, don't change - else if (detected_parttype) - gpt_parts[i].mbr_type = detected_parttype; - else if (have_esp) // make sure there's no more than one ESP per disk - gpt_parts[i].mbr_type = 0x83; // fallback: Linux - } - // NOTE: mbr_type may still be 0 if content detection fails for exotic GPT types or file systems - - if (gpt_parts[i].mbr_type == 0xef) - have_esp = TRUE; - } - - // check for common scenarios - action = ACTION_NONE; - if (mbr_part_count == 0) { - // current MBR is empty - action = ACTION_REWRITE; - } else if (mbr_part_count == 1 && mbr_parts[0].mbr_type == 0xee) { - // MBR has just the EFI Protective partition (i.e. untouched) - action = ACTION_REWRITE; - } - if (action == ACTION_NONE && mbr_part_count > 0) { - if (mbr_parts[0].mbr_type == 0xee && - gpt_parts[0].mbr_type == 0xef && - mbr_parts[0].start_lba == 1 && - mbr_parts[0].end_lba == gpt_parts[0].end_lba) { - // The Apple Way, "EFI Protective" covering the tables and the ESP - action = ACTION_NOP; - if ((mbr_part_count != gpt_part_count && gpt_part_count <= 4) || - (mbr_part_count != 4 && gpt_part_count > 4)) { - // number of partitions has changed - action = ACTION_REWRITE; - } else { - // check partition ranges and types - for (i = 1; i < mbr_part_count; i++) { - if (mbr_parts[i].start_lba != gpt_parts[i].start_lba || - mbr_parts[i].end_lba != gpt_parts[i].end_lba || - (gpt_parts[i].mbr_type && mbr_parts[i].mbr_type != gpt_parts[i].mbr_type)) - // position or type has changed - action = ACTION_REWRITE; - } - } - // check number of active partitions - count_active = 0; - for (i = 0; i < mbr_part_count; i++) - if (mbr_parts[i].active) - count_active++; - if (count_active!= 1) - action = ACTION_REWRITE; - } - } - if (action == ACTION_NONE && mbr_part_count > 0 && mbr_parts[0].mbr_type == 0xef) { - // The XOM Way, all partitions mirrored 1:1 - action = ACTION_REWRITE; - // check partition ranges and types - for (i = 0; i < mbr_part_count; i++) { - if (mbr_parts[i].start_lba != gpt_parts[i].start_lba || - mbr_parts[i].end_lba != gpt_parts[i].end_lba || - (gpt_parts[i].mbr_type && mbr_parts[i].mbr_type != gpt_parts[i].mbr_type)) - // position or type has changed -> better don't touch - action = ACTION_NONE; - } - } - - if (action == ACTION_NOP) { - Print(L"Status: Tables are synchronized, no need to sync.\n"); - return 0; - } else if (action == ACTION_REWRITE) { - Print(L"Status: MBR table must be updated.\n"); - } else { - Print(L"Status: Analysis inconclusive, will not touch this disk.\n"); - return 1; - } - - // generate the new table - - // first entry: EFI Protective - new_mbr_parts[0].index = 0; - new_mbr_parts[0].start_lba = 1; - new_mbr_parts[0].mbr_type = 0xee; - new_mbr_part_count = 1; - - if (gpt_parts[0].mbr_type == 0xef) { - new_mbr_parts[0].end_lba = gpt_parts[0].end_lba; - i = 1; - } else { - min_start_lba = gpt_parts[0].start_lba; - for (k = 0; k < gpt_part_count; k++) { - if (min_start_lba > gpt_parts[k].start_lba) - min_start_lba = gpt_parts[k].start_lba; - } - new_mbr_parts[0].end_lba = min_start_lba - 1; - i = 0; - } - - // add other GPT partitions until the table is full - // TODO: in the future, prioritize partitions by kind - for (; i < gpt_part_count && new_mbr_part_count < 4; i++) { - new_mbr_parts[new_mbr_part_count].index = new_mbr_part_count; - new_mbr_parts[new_mbr_part_count].start_lba = gpt_parts[i].start_lba; - new_mbr_parts[new_mbr_part_count].end_lba = gpt_parts[i].end_lba; - new_mbr_parts[new_mbr_part_count].mbr_type = gpt_parts[i].mbr_type; - new_mbr_parts[new_mbr_part_count].active = FALSE; - - // find matching partition in the old MBR table - for (k = 0; k < mbr_part_count; k++) { - if (mbr_parts[k].start_lba == gpt_parts[i].start_lba) { - // keep type if not detected - if (new_mbr_parts[new_mbr_part_count].mbr_type == 0) - new_mbr_parts[new_mbr_part_count].mbr_type = mbr_parts[k].mbr_type; - // keep active flag - new_mbr_parts[new_mbr_part_count].active = mbr_parts[k].active; - break; - } - } - - if (new_mbr_parts[new_mbr_part_count].mbr_type == 0) - // final fallback: set to a (hopefully) unused type - new_mbr_parts[new_mbr_part_count].mbr_type = 0xc0; - - new_mbr_part_count++; - } - - // make sure there's exactly one active partition - for (iter = 0; iter < 3; iter++) { - // check - count_active = 0; - for (i = 0; i < new_mbr_part_count; i++) - if (new_mbr_parts[i].active) - count_active++; - if (count_active == 1) - break; - - // set active on the first matching partition - if (count_active == 0) { - for (i = 0; i < new_mbr_part_count; i++) { - if ((iter >= 0 && (new_mbr_parts[i].mbr_type == 0x07 || // NTFS - new_mbr_parts[i].mbr_type == 0x0b || // FAT32 - new_mbr_parts[i].mbr_type == 0x0c)) || // FAT32 (LBA) - (iter >= 1 && (new_mbr_parts[i].mbr_type == 0x83)) || // Linux - (iter >= 2 && i > 0)) { - new_mbr_parts[i].active = TRUE; - break; - } - } - } else if (count_active > 1 && iter == 0) { - // too many active partitions, try deactivating the ESP / EFI Protective entry - if ((new_mbr_parts[0].mbr_type == 0xee || new_mbr_parts[0].mbr_type == 0xef) && - new_mbr_parts[0].active) { - new_mbr_parts[0].active = FALSE; - } - } else if (count_active > 1 && iter > 0) { - // too many active partitions, deactivate all but the first one - count_active = 0; - for (i = 0; i < new_mbr_part_count; i++) - if (new_mbr_parts[i].active) { - if (count_active > 0) - new_mbr_parts[i].active = FALSE; - count_active++; - } - } - } - - // dump table - Print(L"\nProposed new MBR partition table:\n"); - Print(L" # A Start LBA End LBA Type\n"); - for (i = 0; i < new_mbr_part_count; i++) { - Print(L" %d %s %12lld %12lld %02x %s\n", - new_mbr_parts[i].index + 1, - new_mbr_parts[i].active ? STR("*") : STR(" "), - new_mbr_parts[i].start_lba, - new_mbr_parts[i].end_lba, - new_mbr_parts[i].mbr_type, - mbr_parttype_name(new_mbr_parts[i].mbr_type)); - } - - return 0; -} - -// -// sync algorithm entry point -// - -UINTN gptsync(VOID) -{ - UINTN status = 0; - UINTN status_gpt, status_mbr; - // BOOLEAN proceed = FALSE; - - // get full information from disk - status_gpt = read_gpt(); - status_mbr = read_mbr(); - if (status_gpt != 0 || status_mbr != 0) - return (status_gpt || status_mbr); - - // cross-check current situation - Print(L"\n"); - status = check_gpt(); // check GPT for consistency - if (status != 0) - return status; - status = check_mbr(); // check MBR for consistency - if (status != 0) - return status; - status = analyze(); // analyze the situation & compose new MBR table - if (status != 0) - return status; - if (new_mbr_part_count == 0) - return status; - - // offer user the choice what to do - // status = input_boolean(STR("\nMay I update the MBR as printed above? [y/N] "), &proceed); - // if (status != 0 || proceed != TRUE) - // return status; - - // adjust the MBR and write it back - status = write_mbr(); - if (status != 0) - return status; - - return status; -} diff --git a/gptsync/gptsync.h b/gptsync/gptsync.h deleted file mode 100644 index d1bf3c20e..000000000 --- a/gptsync/gptsync.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * gptsync/gptsync.h - * Common header for gptsync and showpart - * - * Copyright (c) 2006 Christoph Pfisterer - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Christoph Pfisterer nor the names of the - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// config -// - -#if defined(EFI32) || defined(EFIX64) -#define CONFIG_EFI -#endif - -// -// platform-dependent types -// - -#ifdef CONFIG_EFI - -#include <efi.h> -#include <efilib.h> - -#define copy_guid(destguid, srcguid) (CopyMem(destguid, srcguid, 16)) -#define guids_are_equal(guid1, guid2) (CompareMem(guid1, guid2, 16) == 0) - -typedef CHAR16 CHARN; -#define STR(x) L##x - -#endif - - -#ifndef CONFIG_EFI - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <unistd.h> -#include <errno.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <fcntl.h> - -typedef int INTN; -typedef unsigned int UINTN; -typedef uint8_t UINT8; -typedef uint16_t UINT16; -typedef uint32_t UINT32; -typedef uint64_t UINT64; -typedef void VOID; - -typedef int BOOLEAN; -#ifndef FALSE -#define FALSE (0) -#endif -#ifndef TRUE -#define TRUE (1) -#endif - -typedef unsigned short CHAR16; -typedef char CHARN; -#define STR(x) x - -void Print(wchar_t *format, ...); - -// FUTURE: use STR(), #define Print printf - -#define CopyMem memcpy -#define SetMem memset -#define CompareMem memcmp - -#define copy_guid(destguid, srcguid) (memcpy(destguid, srcguid, 16)) -#define guids_are_equal(guid1, guid2) (memcmp(guid1, guid2, 16) == 0) - -#endif - -// -// platform-independent types -// - -typedef struct { - UINT8 flags; - UINT8 start_chs[3]; - UINT8 type; - UINT8 end_chs[3]; - UINT32 start_lba; - UINT32 size; -} MBR_PARTITION_INFO; - -typedef struct { - UINT8 type; - CHARN *name; -} MBR_PARTTYPE; - -typedef struct { - UINT64 signature; - UINT32 spec_revision; - UINT32 header_size; - UINT32 header_crc32; - UINT32 reserved; - UINT64 header_lba; - UINT64 alternate_header_lba; - UINT64 first_usable_lba; - UINT64 last_usable_lba; - UINT8 disk_guid[16]; - UINT64 entry_lba; - UINT32 entry_count; - UINT32 entry_size; - UINT32 entry_crc32; -} GPT_HEADER; - -typedef struct { - UINT8 type_guid[16]; - UINT8 partition_guid[16]; - UINT64 start_lba; - UINT64 end_lba; - UINT64 attributes; - CHAR16 name[36]; -} GPT_ENTRY; - -#define GPT_KIND_SYSTEM (0) -#define GPT_KIND_DATA (1) -#define GPT_KIND_BASIC_DATA (2) -#define GPT_KIND_FATAL (3) - -typedef struct { - UINT8 guid[16]; - UINT8 mbr_type; - CHARN *name; - UINTN kind; -} GPT_PARTTYPE; - -typedef struct { - UINTN index; - UINT64 start_lba; - UINT64 end_lba; - UINTN mbr_type; - UINT8 gpt_type[16]; - GPT_PARTTYPE *gpt_parttype; - BOOLEAN active; -} PARTITION_INFO; - -// -// functions provided by the OS-specific module -// - -UINTN read_sector(UINT64 lba, UINT8 *buffer); -UINTN write_sector(UINT64 lba, UINT8 *buffer); -UINTN input_boolean(CHARN *prompt, BOOLEAN *bool_out); - -// -// vars and functions provided by the common lib module -// - -extern UINT8 empty_guid[16]; - -extern PARTITION_INFO mbr_parts[4]; -extern UINTN mbr_part_count; -extern PARTITION_INFO gpt_parts[128]; -extern UINTN gpt_part_count; - -extern PARTITION_INFO new_mbr_parts[4]; -extern UINTN new_mbr_part_count; - -extern UINT8 sector[512]; - -extern MBR_PARTTYPE mbr_types[]; -extern GPT_PARTTYPE gpt_types[]; -extern GPT_PARTTYPE gpt_dummy_type; - -CHARN * mbr_parttype_name(UINT8 type); -UINTN read_mbr(VOID); - -GPT_PARTTYPE * gpt_parttype(UINT8 *type_guid); -UINTN read_gpt(VOID); - -UINTN detect_mbrtype_fs(UINT64 partlba, UINTN *parttype, CHARN **fsname); - -// -// actual platform-independent programs -// - -UINTN gptsync(VOID); -UINTN showpart(VOID); - -/* EOF */ diff --git a/gptsync/lib.c b/gptsync/lib.c deleted file mode 100644 index f2d71b2e1..000000000 --- a/gptsync/lib.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * gptsync/lib.c - * Platform-independent code common to gptsync and showpart - * - * Copyright (c) 2006-2007 Christoph Pfisterer - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Christoph Pfisterer nor the names of the - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "gptsync.h" - -// variables - -UINT8 empty_guid[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; - -PARTITION_INFO mbr_parts[4]; -UINTN mbr_part_count = 0; -PARTITION_INFO gpt_parts[128]; -UINTN gpt_part_count = 0; - -PARTITION_INFO new_mbr_parts[4]; -UINTN new_mbr_part_count = 0; - -UINT8 sector[512]; - -MBR_PARTTYPE mbr_types[] = { - { 0x01, STR("FAT12 (CHS)") }, - { 0x04, STR("FAT16 <32M (CHS)") }, - { 0x05, STR("Extended (CHS)") }, - { 0x06, STR("FAT16 (CHS)") }, - { 0x07, STR("NTFS/HPFS") }, - { 0x0b, STR("FAT32 (CHS)") }, - { 0x0c, STR("FAT32 (LBA)") }, - { 0x0e, STR("FAT16 (LBA)") }, - { 0x0f, STR("Extended (LBA)") }, - { 0x11, STR("Hidden FAT12 (CHS)") }, - { 0x14, STR("Hidden FAT16 <32M (CHS)") }, - { 0x16, STR("Hidden FAT16 (CHS)") }, - { 0x17, STR("Hidden NTFS/HPFS") }, - { 0x1b, STR("Hidden FAT32 (CHS)") }, - { 0x1c, STR("Hidden FAT32 (LBA)") }, - { 0x1e, STR("Hidden FAT16 (LBA)") }, - { 0x82, STR("Linux swap / Solaris") }, - { 0x83, STR("Linux") }, - { 0x85, STR("Linux Extended") }, - { 0x86, STR("NT FAT volume set") }, - { 0x87, STR("NTFS volume set") }, - { 0x8e, STR("Linux LVM") }, - { 0xa5, STR("FreeBSD") }, - { 0xa6, STR("OpenBSD") }, - { 0xa7, STR("NeXTSTEP") }, - { 0xa8, STR("Mac OS X UFS") }, - { 0xa9, STR("NetBSD") }, - { 0xab, STR("Mac OS X Boot") }, - { 0xac, STR("Apple RAID") }, - { 0xaf, STR("Mac OS X HFS+") }, - { 0xbe, STR("Solaris Boot") }, - { 0xbf, STR("Solaris") }, - { 0xeb, STR("BeOS") }, - { 0xee, STR("EFI Protective") }, - { 0xef, STR("EFI System (FAT)") }, - { 0xfd, STR("Linux RAID") }, - { 0, NULL }, -}; - -GPT_PARTTYPE gpt_types[] = { - { "\x28\x73\x2A\xC1\x1F\xF8\xD2\x11\xBA\x4B\x00\xA0\xC9\x3E\xC9\x3B", 0xef, STR("EFI System (FAT)"), GPT_KIND_SYSTEM }, - { "\x41\xEE\x4D\x02\xE7\x33\xD3\x11\x9D\x69\x00\x08\xC7\x81\xF3\x9F", 0x00, STR("MBR partition scheme"), GPT_KIND_FATAL }, - { "\x16\xE3\xC9\xE3\x5C\x0B\xB8\x4D\x81\x7D\xF9\x2D\xF0\x02\x15\xAE", 0x00, STR("MS Reserved"), GPT_KIND_SYSTEM }, - { "\xA2\xA0\xD0\xEB\xE5\xB9\x33\x44\x87\xC0\x68\xB6\xB7\x26\x99\xC7", 0x00, STR("Basic Data"), GPT_KIND_BASIC_DATA }, - { "\xAA\xC8\x08\x58\x8F\x7E\xE0\x42\x85\xD2\xE1\xE9\x04\x34\xCF\xB3", 0x00, STR("MS LDM Metadata"), GPT_KIND_FATAL }, - { "\xA0\x60\x9B\xAF\x31\x14\x62\x4F\xBC\x68\x33\x11\x71\x4A\x69\xAD", 0x00, STR("MS LDM Data"), GPT_KIND_FATAL }, - { "\x1E\x4C\x89\x75\xEB\x3A\xD3\x11\xB7\xC1\x7B\x03\xA0\x00\x00\x00", 0x00, STR("HP/UX Data"), GPT_KIND_DATA }, - { "\x28\xE7\xA1\xE2\xE3\x32\xD6\x11\xA6\x82\x7B\x03\xA0\x00\x00\x00", 0x00, STR("HP/UX Service"), GPT_KIND_SYSTEM }, - { "\x0F\x88\x9D\xA1\xFC\x05\x3B\x4D\xA0\x06\x74\x3F\x0F\x84\x91\x1E", 0xfd, STR("Linux RAID"), GPT_KIND_DATA }, - { "\x6D\xFD\x57\x06\xAB\xA4\xC4\x43\x84\xE5\x09\x33\xC8\x4B\x4F\x4F", 0x82, STR("Linux Swap"), GPT_KIND_SYSTEM }, - { "\x79\xD3\xD6\xE6\x07\xF5\xC2\x44\xA2\x3C\x23\x8F\x2A\x3D\xF9\x28", 0x8e, STR("Linux LVM"), GPT_KIND_DATA }, - { "\x39\x33\xA6\x8D\x07\x00\xC0\x60\xC4\x36\x08\x3A\xC8\x23\x09\x08", 0x00, STR("Linux Reserved"), GPT_KIND_SYSTEM }, - { "\xB4\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0xa5, STR("FreeBSD Data"), GPT_KIND_DATA }, - { "\xB5\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0x00, STR("FreeBSD Swap"), GPT_KIND_SYSTEM }, - { "\xB6\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0xa5, STR("FreeBSD UFS"), GPT_KIND_DATA }, - { "\xB8\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0x00, STR("FreeBSD Vinum"), GPT_KIND_DATA }, - { "\x00\x53\x46\x48\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xaf, STR("Mac OS X HFS+"), GPT_KIND_DATA }, - { "\x00\x53\x46\x55\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xa8, STR("Mac OS X UFS"), GPT_KIND_DATA }, - { "\x74\x6F\x6F\x42\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xab, STR("Mac OS X Boot"), GPT_KIND_DATA }, - { "\x44\x49\x41\x52\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xac, STR("Apple RAID"), GPT_KIND_DATA }, - { "\x44\x49\x41\x52\x4F\x5F\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xac, STR("Apple RAID (Offline)"), GPT_KIND_DATA }, - { "\x65\x62\x61\x4C\x00\x6C\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0x00, STR("Apple Label"), GPT_KIND_SYSTEM }, - { "\x6F\x63\x65\x52\x65\x76\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0x00, STR("Apple Recovery"), GPT_KIND_BASIC_DATA }, - { "\x7f\x23\x96\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Reserved"), GPT_KIND_SYSTEM }, - { "\x45\xCB\x82\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Boot"), GPT_KIND_DATA }, - { "\x4D\xCF\x85\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Root"), GPT_KIND_DATA }, - { "\x6F\xC4\x87\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Swap"), GPT_KIND_SYSTEM }, - { "\xC3\x8C\x89\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Usr"), GPT_KIND_DATA }, - { "\x2B\x64\x8B\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Backup"), GPT_KIND_SYSTEM }, - { "\xC7\x2A\x8D\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Stand"), GPT_KIND_DATA }, - { "\xE9\xF2\x8E\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Var"), GPT_KIND_DATA }, - { "\x39\xBA\x90\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Home"), GPT_KIND_DATA }, - { "\xA5\x83\x92\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris ALTSCTR"), GPT_KIND_DATA }, - { "\x3B\x5A\x94\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Cache"), GPT_KIND_SYSTEM }, - { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 0, NULL, 0 }, -}; -GPT_PARTTYPE gpt_dummy_type = - { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 0, STR("Unknown"), GPT_KIND_FATAL }; - -// -// MBR functions -// - -CHARN * mbr_parttype_name(UINT8 type) -{ - int i; - - for (i = 0; mbr_types[i].name; i++) - if (mbr_types[i].type == type) - return mbr_types[i].name; - return STR("Unknown"); -} - -UINTN read_mbr(VOID) -{ - UINTN status; - UINTN i; - BOOLEAN used; - MBR_PARTITION_INFO *table; - - Print(L"\nCurrent MBR partition table:\n"); - - // read MBR data - status = read_sector(0, sector); - if (status != 0) - return status; - - // check for validity - if (*((UINT16 *)(sector + 510)) != 0xaa55) { - Print(L" No MBR partition table present!\n"); - return 1; - } - table = (MBR_PARTITION_INFO *)(sector + 446); - for (i = 0; i < 4; i++) { - if (table[i].flags != 0x00 && table[i].flags != 0x80) { - Print(L" MBR partition table is invalid!\n"); - return 1; - } - } - - // check if used - used = FALSE; - for (i = 0; i < 4; i++) { - if (table[i].start_lba > 0 && table[i].size > 0) { - used = TRUE; - break; - } - } - if (!used) { - Print(L" No partitions defined\n"); - return 0; - } - - // dump current state & fill internal structures - Print(L" # A Start LBA End LBA Type\n"); - for (i = 0; i < 4; i++) { - if (table[i].start_lba == 0 || table[i].size == 0) - continue; - - mbr_parts[mbr_part_count].index = i; - mbr_parts[mbr_part_count].start_lba = (UINT64)table[i].start_lba; - mbr_parts[mbr_part_count].end_lba = (UINT64)table[i].start_lba + (UINT64)table[i].size - 1; - mbr_parts[mbr_part_count].mbr_type = table[i].type; - mbr_parts[mbr_part_count].active = (table[i].flags == 0x80) ? TRUE : FALSE; - - Print(L" %d %s %12lld %12lld %02x %s\n", - mbr_parts[mbr_part_count].index + 1, - mbr_parts[mbr_part_count].active ? STR("*") : STR(" "), - mbr_parts[mbr_part_count].start_lba, - mbr_parts[mbr_part_count].end_lba, - mbr_parts[mbr_part_count].mbr_type, - mbr_parttype_name(mbr_parts[mbr_part_count].mbr_type)); - - mbr_part_count++; - } - - return 0; -} - -// -// GPT functions -// - -GPT_PARTTYPE * gpt_parttype(UINT8 *type_guid) -{ - int i; - - for (i = 0; gpt_types[i].name; i++) - if (guids_are_equal(gpt_types[i].guid, type_guid)) - return &(gpt_types[i]); - return &gpt_dummy_type; -} - -UINTN read_gpt(VOID) -{ - UINTN status; - GPT_HEADER *header; - GPT_ENTRY *entry; - UINT64 entry_lba; - UINTN entry_count, entry_size, i; - - Print(L"\nCurrent GPT partition table:\n"); - - // read GPT header - status = read_sector(1, sector); - if (status != 0) - return status; - - // check signature - header = (GPT_HEADER *)sector; - if (header->signature != 0x5452415020494645ULL) { - Print(L" No GPT partition table present!\n"); - return 0; - } - if (header->spec_revision != 0x00010000UL) { - Print(L" Warning: Unknown GPT spec revision 0x%08x\n", header->spec_revision); - } - if ((512 % header->entry_size) > 0 || header->entry_size > 512) { - Print(L" Error: Invalid GPT entry size (misaligned or more than 512 bytes)\n"); - return 0; - } - - // read entries - entry_lba = header->entry_lba; - entry_size = header->entry_size; - entry_count = header->entry_count; - - for (i = 0; i < entry_count; i++) { - if (((i * entry_size) % 512) == 0) { - status = read_sector(entry_lba, sector); - if (status != 0) - return status; - entry_lba++; - } - entry = (GPT_ENTRY *)(sector + ((i * entry_size) % 512)); - - if (guids_are_equal(entry->type_guid, empty_guid)) - continue; - if (gpt_part_count == 0) { - Print(L" # Start LBA End LBA Type\n"); - } - - gpt_parts[gpt_part_count].index = i; - gpt_parts[gpt_part_count].start_lba = entry->start_lba; - gpt_parts[gpt_part_count].end_lba = entry->end_lba; - gpt_parts[gpt_part_count].mbr_type = 0; - copy_guid(gpt_parts[gpt_part_count].gpt_type, entry->type_guid); - gpt_parts[gpt_part_count].gpt_parttype = gpt_parttype(gpt_parts[gpt_part_count].gpt_type); - gpt_parts[gpt_part_count].active = FALSE; - - Print(L" %d %12lld %12lld %s\n", - gpt_parts[gpt_part_count].index + 1, - gpt_parts[gpt_part_count].start_lba, - gpt_parts[gpt_part_count].end_lba, - gpt_parts[gpt_part_count].gpt_parttype->name); - - gpt_part_count++; - } - if (gpt_part_count == 0) { - Print(L" No partitions defined\n"); - return 0; - } - - return 0; -} - -// -// detect file system type -// - -UINTN detect_mbrtype_fs(UINT64 partlba, UINTN *parttype, CHARN **fsname) -{ - UINTN status; - UINTN signature, score; - UINTN sectsize, clustersize, reserved, fatcount, dirsize, sectcount, fatsize, clustercount; - - *fsname = STR("Unknown"); - *parttype = 0; - - // READ sector 0 / offset 0K - status = read_sector(partlba, sector); - if (status != 0) - return status; - - // detect XFS - memcpy(&signature, sector, sizeof(UINT32)); - if (signature == 0x42534658) { - *parttype = 0x83; - *fsname = STR("XFS"); - return 0; - } - - // detect FAT and NTFS - sectsize = *((UINT16 *)(sector + 11)); - clustersize = sector[13]; - if (sectsize >= 512 && (sectsize & (sectsize - 1)) == 0 && - clustersize > 0 && (clustersize & (clustersize - 1)) == 0) { - // preconditions for both FAT and NTFS are now met - - if (CompareMem(sector + 3, "NTFS ", 8) == 0) { - *parttype = 0x07; - *fsname = STR("NTFS"); - return 0; - } - - score = 0; - // boot jump - if ((sector[0] == 0xEB && sector[2] == 0x90) || - sector[0] == 0xE9) - score++; - // boot signature - if (sector[510] == 0x55 && sector[511] == 0xAA) - score++; - // reserved sectors - reserved = *((UINT16 *)(sector + 14)); - if (reserved == 1 || reserved == 32) - score++; - // number of FATs - fatcount = sector[16]; - if (fatcount == 2) - score++; - // number of root dir entries - dirsize = *((UINT16 *)(sector + 17)); - // sector count (16-bit and 32-bit versions) - sectcount = *((UINT16 *)(sector + 19)); - if (sectcount == 0) - sectcount = *((UINT32 *)(sector + 32)); - // media byte - if (sector[21] == 0xF0 || sector[21] >= 0xF8) - score++; - // FAT size in sectors - fatsize = *((UINT16 *)(sector + 22)); - if (fatsize == 0) - fatsize = *((UINT32 *)(sector + 36)); - - // determine FAT type - dirsize = ((dirsize * 32) + (sectsize - 1)) / sectsize; - clustercount = sectcount - (reserved + (fatcount * fatsize) + dirsize); - clustercount /= clustersize; - - if (score >= 3) { - if (clustercount < 4085) { - *parttype = 0x01; - *fsname = STR("FAT12"); - } else if (clustercount < 65525) { - *parttype = 0x0e; - *fsname = STR("FAT16"); - } else { - *parttype = 0x0c; - *fsname = STR("FAT32"); - } - // TODO: check if 0e and 0c are okay to use, maybe we should use 06 and 0b instead... - return 0; - } - } - - // READ sector 2 / offset 1K - status = read_sector(partlba + 2, sector); - if (status != 0) - return status; - - // detect HFS+ - memcpy(&signature, sector, sizeof(UINT16)); - if (signature == 0x4442) { - *parttype = 0xaf; - if (*((UINT16 *)(sector + 0x7c)) == 0x2B48) - *fsname = STR("HFS Extended (HFS+)"); - else - *fsname = STR("HFS Standard"); - return 0; - } else if (signature == 0x2B48) { - *parttype = 0xaf; - *fsname = STR("HFS Extended (HFS+)"); - return 0; - } - - // detect ext2/ext3 - signature = *((UINT16 *)(sector + 56)); - if (signature == 0xEF53) { - *parttype = 0x83; - if (*((UINT16 *)(sector + 92)) & 0x0004) - *fsname = STR("ext3"); - else - *fsname = STR("ext2"); - return 0; - } - - // READ sector 128 / offset 64K - status = read_sector(partlba + 128, sector); - if (status != 0) - return status; - - // detect ReiserFS - if (CompareMem(sector + 52, "ReIsErFs", 8) == 0 || - CompareMem(sector + 52, "ReIsEr2Fs", 9) == 0 || - CompareMem(sector + 52, "ReIsEr3Fs", 9) == 0) { - *parttype = 0x83; - *fsname = STR("ReiserFS"); - return 0; - } - - // detect Reiser4 - if (CompareMem(sector, "ReIsEr4", 7) == 0) { - *parttype = 0x83; - *fsname = STR("Reiser4"); - return 0; - } - - // READ sector 64 / offset 32K - status = read_sector(partlba + 64, sector); - if (status != 0) - return status; - - // detect JFS - if (CompareMem(sector, "JFS1", 4) == 0) { - *parttype = 0x83; - *fsname = STR("JFS"); - return 0; - } - - // READ sector 16 / offset 8K - status = read_sector(partlba + 16, sector); - if (status != 0) - return status; - - // detect ReiserFS - if (CompareMem(sector + 52, "ReIsErFs", 8) == 0 || - CompareMem(sector + 52, "ReIsEr2Fs", 9) == 0 || - CompareMem(sector + 52, "ReIsEr3Fs", 9) == 0) { - *parttype = 0x83; - *fsname = STR("ReiserFS"); - return 0; - } - - return 0; -} diff --git a/gptsync/os_unix.c b/gptsync/os_unix.c deleted file mode 100644 index c034031a2..000000000 --- a/gptsync/os_unix.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * gptsync/os_unix.c - * Unix OS glue for gptsync - * - * Copyright (c) 2006 Christoph Pfisterer - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Christoph Pfisterer nor the names of the - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "gptsync.h" - -#include <stdarg.h> - -#define STRINGIFY(s) #s -#define STRINGIFY2(s) STRINGIFY(s) -#define PROGNAME_S STRINGIFY2(PROGNAME) - -// variables - -static int fd; - -// -// error functions -// - -void error(const char *msg, ...) -{ - va_list par; - char buf[4096]; - - va_start(par, msg); - vsnprintf(buf, 4096, msg, par); - va_end(par); - - fprintf(stderr, PROGNAME_S ": %s\n", buf); -} - -void errore(const char *msg, ...) -{ - va_list par; - char buf[4096]; - - va_start(par, msg); - vsnprintf(buf, 4096, msg, par); - va_end(par); - - fprintf(stderr, PROGNAME_S ": %s: %s\n", buf, strerror(errno)); -} - -// -// sector I/O functions -// - -UINTN read_sector(UINT64 lba, UINT8 *buffer) -{ - off_t offset; - off_t result_seek; - ssize_t result_read; - - offset = lba * 512; - result_seek = lseek(fd, offset, SEEK_SET); - if (result_seek != offset) { - errore("Seek to %llu failed", offset); - return 1; - } - - result_read = read(fd, buffer, 512); - if (result_read < 0) { - errore("Data read failed at position %llu", offset); - return 1; - } - if (result_read != 512) { - errore("Data read fell short at position %llu", offset); - return 1; - } - return 0; -} - -UINTN write_sector(UINT64 lba, UINT8 *buffer) -{ - off_t offset; - off_t result_seek; - ssize_t result_write; - - offset = lba * 512; - result_seek = lseek(fd, offset, SEEK_SET); - if (result_seek != offset) { - errore("Seek to %llu failed", offset); - return 1; - } - - result_write = write(fd, buffer, 512); - if (result_write < 0) { - errore("Data write failed at position %llu", offset); - return 1; - } - if (result_write != 512) { - errore("Data write fell short at position %llu", offset); - return 1; - } - return 0; -} - -// -// keyboard input -// - -UINTN input_boolean(CHARN *prompt, BOOLEAN *bool_out) -{ - int c; - - printf("%s", prompt); - fflush(NULL); - - c = getchar(); - if (c == EOF) - return 1; - - if (c == 'y' || c == 'Y') { - printf("Yes\n"); - *bool_out = TRUE; - } else { - printf("No\n"); - *bool_out = FALSE; - } - - return 0; -} - -// -// EFI-style print function -// - -void Print(wchar_t *format, ...) -{ - va_list par; - char formatbuf[256]; - char buf[4096]; - int i; - - for (i = 0; format[i]; i++) - formatbuf[i] = (format[i] > 255) ? '?' : (char)(format[i] & 0xff); - formatbuf[i] = 0; - - va_start(par, format); - vsnprintf(buf, 4096, formatbuf, par); - va_end(par); - - printf("%s", buf); -} - -// -// main entry point -// - -int main(int argc, char *argv[]) -{ - char *filename; - struct stat sb; - int filekind; - char *reason; - int status; - - // argument check - if (argc != 2) { - fprintf(stderr, "Usage: " PROGNAME_S " <device>\n"); - return 1; - } - filename = argv[1]; - - // set input to unbuffered - fflush(NULL); - setvbuf(stdin, NULL, _IONBF, 0); - - // stat check - if (stat(filename, &sb) < 0) { - errore("Can't stat %.300s", filename); - return 1; - } - - filekind = 0; - reason = NULL; - if (S_ISREG(sb.st_mode)) - ; - else if (S_ISBLK(sb.st_mode)) - filekind = 1; - else if (S_ISCHR(sb.st_mode)) - filekind = 2; - else if (S_ISDIR(sb.st_mode)) - reason = "Is a directory"; - else if (S_ISFIFO(sb.st_mode)) - reason = "Is a FIFO"; -#ifdef S_ISSOCK - else if (S_ISSOCK(sb.st_mode)) - reason = "Is a socket"; -#endif - else - reason = "Is an unknown kind of special file"; - - if (reason != NULL) { - error("%.300s: %s", filename, reason); - return 1; - } - - // open file - fd = open(filename, O_RDWR); - if (fd < 0 && errno == EBUSY) { - fd = open(filename, O_RDONLY); -#ifndef NOREADONLYWARN - if (fd >= 0) - printf("Warning: %.300s opened read-only\n", filename); -#endif - } - if (fd < 0) { - errore("Can't open %.300s", filename); - return 1; - } - - // (try to) guard against TTY character devices - if (filekind == 2) { - if (isatty(fd)) { - error("%.300s: Is a TTY device", filename); - return 1; - } - } - - // run sync algorithm - status = PROGNAME(); - printf("\n"); - - // close file - if (close(fd) != 0) { - errore("Error while closing %.300s", filename); - return 1; - } - - return status; -} diff --git a/gptsync/showpart.c b/gptsync/showpart.c deleted file mode 100644 index 3d52ba34e..000000000 --- a/gptsync/showpart.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * gptsync/showpart.c - * Platform-independent code for analyzing hard disk partitioning - * - * Copyright (c) 2006 Christoph Pfisterer - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Christoph Pfisterer nor the names of the - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "gptsync.h" - -// -// memory string search -// - -static INTN FindMem(VOID *Buffer, UINTN BufferLength, VOID *SearchString, UINTN SearchStringLength) -{ - UINT8 *BufferPtr; - UINTN Offset; - - BufferPtr = Buffer; - BufferLength -= SearchStringLength; - for (Offset = 0; Offset < BufferLength; Offset++, BufferPtr++) { - if (CompareMem(BufferPtr, SearchString, SearchStringLength) == 0) - return (INTN)Offset; - } - - return -1; -} - -// -// detect boot code -// - -static UINTN detect_bootcode(UINT64 partlba, CHARN **bootcodename) -{ - UINTN status; - BOOLEAN bootable; - - // read MBR data - status = read_sector(partlba, sector); - if (status != 0) - return status; - - // check bootable signature - if (*((UINT16 *)(sector + 510)) == 0xaa55 && sector[0] != 0) - bootable = TRUE; - else - bootable = FALSE; - *bootcodename = NULL; - - // detect specific boot codes - if (CompareMem(sector + 2, "LILO", 4) == 0 || - CompareMem(sector + 6, "LILO", 4) == 0) { - *bootcodename = STR("LILO"); - - } else if (CompareMem(sector + 3, "SYSLINUX", 8) == 0) { - *bootcodename = STR("SYSLINUX"); - - } else if (FindMem(sector, 512, "ISOLINUX", 8) >= 0) { - *bootcodename = STR("ISOLINUX"); - - } else if (FindMem(sector, 512, "Geom\0Hard Disk\0Read\0 Error\0", 27) >= 0) { - *bootcodename = STR("GRUB"); - - } else if ((*((UINT32 *)(sector + 502)) == 0 && - *((UINT32 *)(sector + 506)) == 50000 && - *((UINT16 *)(sector + 510)) == 0xaa55) || - FindMem(sector, 512, "Starting the BTX loader", 23) >= 0) { - *bootcodename = STR("FreeBSD"); - - } else if (FindMem(sector, 512, "!Loading", 8) >= 0 || - FindMem(sector, 512, "/cdboot\0/CDBOOT\0", 16) >= 0) { - *bootcodename = STR("OpenBSD"); - - } else if (FindMem(sector, 512, "NTLDR", 5) >= 0) { - *bootcodename = STR("Windows NTLDR"); - - } else if (FindMem(sector, 512, "BOOTMGR", 7) >= 0) { - *bootcodename = STR("Windows BOOTMGR (Vista)"); - - } else if (FindMem(sector, 512, "CPUBOOT SYS", 11) >= 0 || - FindMem(sector, 512, "KERNEL SYS", 11) >= 0) { - *bootcodename = STR("FreeDOS"); - - } else if (FindMem(sector, 512, "OS2LDR", 6) >= 0 || - FindMem(sector, 512, "OS2BOOT", 7) >= 0) { - *bootcodename = STR("eComStation"); - - } else if (FindMem(sector, 512, "Be Boot Loader", 14) >= 0) { - *bootcodename = STR("BeOS"); - - } else if (FindMem(sector, 512, "yT Boot Loader", 14) >= 0) { - *bootcodename = STR("ZETA"); - - } else if (FindMem(sector, 512, "\x04" "beos\x06" "system\x05" "zbeos", 18) >= 0) { - *bootcodename = STR("Haiku"); - - } - - if (FindMem(sector, 512, "Non-system disk", 15) >= 0) // dummy FAT boot sector - *bootcodename = STR("None (Non-system disk message)"); - - // TODO: Add a note if a specific code was detected, but the sector is not bootable? - - if (*bootcodename == NULL) { - if (bootable) - *bootcodename = STR("Unknown, but bootable"); - else - *bootcodename = STR("None"); - } - - return 0; -} - -// -// check one partition -// - -static UINTN analyze_part(UINT64 partlba) -{ - UINTN status; - UINTN i; - CHARN *bootcodename; - UINTN parttype; - CHARN *fsname; - - if (partlba == 0) - Print(L"\nMBR contents:\n"); - else - Print(L"\nPartition at LBA %lld:\n", partlba); - - // detect boot code - status = detect_bootcode(partlba, &bootcodename); - if (status) - return status; - Print(L" Boot Code: %s\n", bootcodename); - - if (partlba == 0) - return 0; // short-circuit MBR analysis - - // detect file system - status = detect_mbrtype_fs(partlba, &parttype, &fsname); - if (status) - return status; - Print(L" File System: %s\n", fsname); - - // cross-reference with partition table - for (i = 0; i < gpt_part_count; i++) { - if (gpt_parts[i].start_lba == partlba) { - Print(L" Listed in GPT as partition %d, type %s\n", i+1, - gpt_parts[i].gpt_parttype->name); - } - } - for (i = 0; i < mbr_part_count; i++) { - if (mbr_parts[i].start_lba == partlba) { - Print(L" Listed in MBR as partition %d, type %02x %s%s\n", i+1, - mbr_parts[i].mbr_type, - mbr_parttype_name(mbr_parts[i].mbr_type), - mbr_parts[i].active ? STR(", active") : STR("")); - } - } - - return 0; -} - -// -// check all partitions -// - -static UINTN analyze_parts(VOID) -{ - UINTN i, k; - UINTN status; - BOOLEAN is_dupe; - - // check MBR (bootcode only) - status = analyze_part(0); - if (status) - return status; - - // check partitions listed in GPT - for (i = 0; i < gpt_part_count; i++) { - status = analyze_part(gpt_parts[i].start_lba); - if (status) - return status; - } - - // check partitions listed in MBR, but not in GPT - for (i = 0; i < mbr_part_count; i++) { - if (mbr_parts[i].start_lba == 1 && mbr_parts[i].mbr_type == 0xee) - continue; // skip EFI Protective entry - - is_dupe = FALSE; - for (k = 0; k < gpt_part_count; k++) - if (gpt_parts[k].start_lba == mbr_parts[i].start_lba) - is_dupe = TRUE; - - if (!is_dupe) { - status = analyze_part(mbr_parts[i].start_lba); - if (status) - return status; - } - } - - return 0; -} - -// -// display algorithm entry point -// - -UINTN showpart(VOID) -{ - UINTN status = 0; - UINTN status_gpt, status_mbr; - - // get full information from disk - status_gpt = read_gpt(); - status_mbr = read_mbr(); - if (status_gpt != 0 || status_mbr != 0) - return (status_gpt || status_mbr); - - // analyze all partitions - status = analyze_parts(); - if (status != 0) - return status; - - return status; -} diff --git a/gptsync/syslinux_mbr.h b/gptsync/syslinux_mbr.h deleted file mode 100644 index 1c33e1159..000000000 --- a/gptsync/syslinux_mbr.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * include/syslinux_mbr.h - * MBR boot code - * - * The boot code in this file was taken from syslinux-3.11. It is covered - * by the following license: - * - ; ----------------------------------------------------------------------- - ; - ; Copyright 2003-2004 H. Peter Anvin - All Rights Reserved - ; - ; Permission is hereby granted, free of charge, to any person - ; obtaining a copy of this software and associated documentation - ; files (the "Software"), to deal in the Software without - ; restriction, including without limitation the rights to use, - ; copy, modify, merge, publish, distribute, sublicense, and/or - ; sell copies of the Software, and to permit persons to whom - ; the Software is furnished to do so, subject to the following - ; conditions: - ; - ; The above copyright notice and this permission notice shall - ; be included in all copies or substantial portions of the Software. - ; - ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - ; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - ; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - ; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - ; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - ; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - ; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - ; OTHER DEALINGS IN THE SOFTWARE. - ; - ; ----------------------------------------------------------------------- - * - */ - -#ifndef __SYSLINUX_MBR_H__ -#define __SYSLINUX_MBR_H__ - - -#define MBR_BOOTCODE_SIZE (440) - - -#define SYSLINUX_MBR_SIZE (304) - -static UINT8 syslinux_mbr[SYSLINUX_MBR_SIZE] = { - 0xfa, 0x31, 0xc0, 0x8e, 0xd8, 0x8e, 0xc0, 0x8e, - 0xd0, 0xbc, 0x00, 0x7c, 0xfb, 0xfc, 0x89, 0xe6, - 0xbf, 0x00, 0x06, 0xb9, 0x00, 0x01, 0xf3, 0xa5, - 0xea, 0x1d, 0x06, 0x00, 0x00, 0x88, 0x16, 0x00, - 0x08, 0xb4, 0x08, 0xcd, 0x13, 0x31, 0xc0, 0x88, - 0xf0, 0x40, 0xa3, 0xf0, 0x06, 0x80, 0xe1, 0x3f, - 0x88, 0x0e, 0xf2, 0x06, 0xbe, 0xbe, 0x07, 0x31, - 0xc0, 0xb9, 0x04, 0x00, 0xf6, 0x04, 0x80, 0x74, - 0x03, 0x40, 0x89, 0xf7, 0x83, 0xc6, 0x10, 0xe2, - 0xf3, 0x83, 0xf8, 0x01, 0x75, 0x73, 0x8a, 0x16, - 0x00, 0x08, 0xb8, 0x00, 0x41, 0xbb, 0xaa, 0x55, - 0x31, 0xc9, 0x30, 0xf6, 0xf9, 0xcd, 0x13, 0x72, - 0x23, 0x81, 0xfb, 0x55, 0xaa, 0x75, 0x1d, 0xf6, - 0xc1, 0x01, 0x74, 0x18, 0x57, 0xbe, 0xe0, 0x06, - 0x8b, 0x5d, 0x08, 0x89, 0x5c, 0x08, 0x8b, 0x5d, - 0x0a, 0x89, 0x5c, 0x0a, 0x8a, 0x16, 0x00, 0x08, - 0xb4, 0x42, 0xeb, 0x2a, 0x57, 0x8b, 0x45, 0x08, - 0x8b, 0x55, 0x0a, 0xf7, 0x36, 0xf2, 0x06, 0x42, - 0x89, 0xd1, 0x31, 0xd2, 0xf7, 0x36, 0xf0, 0x06, - 0x88, 0xc5, 0xd1, 0xe8, 0xd1, 0xe8, 0x24, 0xc0, - 0x08, 0xc1, 0x88, 0xd6, 0x8a, 0x16, 0x00, 0x08, - 0xbb, 0x00, 0x7c, 0xb8, 0x01, 0x02, 0xcd, 0x13, - 0x72, 0x16, 0x5e, 0x81, 0x3e, 0xfe, 0x7d, 0x55, - 0xaa, 0x75, 0x08, 0xfa, 0xea, 0x00, 0x7c, 0x00, - 0x00, 0x77, 0x05, 0xbe, 0xf4, 0x06, 0xeb, 0x03, - 0xbe, 0x0f, 0x07, 0xac, 0x20, 0xc0, 0x74, 0x0c, - 0xb4, 0x0e, 0x8a, 0x3e, 0x62, 0x04, 0xb3, 0x07, - 0xcd, 0x10, 0xeb, 0xef, 0xeb, 0xfe, 0x00, 0x00, - 0x10, 0x00, 0x01, 0x00, 0x00, 0x7c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x73, 0x73, - 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x70, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x0d, 0x0a, 0x00, 0x4f, - 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, - 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, - 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x0d, 0x0a, 0x00 -}; - - -#endif /* __SYSLINUX_MBR_H__ */ - -/* EOF */ 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() diff --git a/scripts/makeupdates b/scripts/makeupdates index 3c99a0123..a8ee467a8 100755 --- a/scripts/makeupdates +++ b/scripts/makeupdates @@ -164,7 +164,7 @@ def copyUpdatedFiles(tag, updates, cwd): fields = file.split('/') subdir = fields[0] if subdir in ['po', 'scripts','command-stubs', 'tests', - 'bootdisk', 'docs', 'fonts', 'utils', 'gptsync', + 'bootdisk', 'docs', 'fonts', 'utils', 'liveinst', 'dracut', 'data']: continue else: diff --git a/utils/handle-sshpw b/utils/handle-sshpw index dee5259b2..4b14208fc 100755 --- a/utils/handle-sshpw +++ b/utils/handle-sshpw @@ -28,7 +28,7 @@ from pykickstart.parser import * from pykickstart.version import makeVersion import pyanaconda.users as users -ksfile = '/ks.cfg.done' +ksfile = '/run/install/ks.cfg' # see if we have a file to work with if not os.path.exists(ksfile): @@ -37,9 +37,9 @@ if not os.path.exists(ksfile): ksparser = KickstartParser(makeVersion()) ksparser.readKickstart(ksfile) -# we need to have a libuser.conf that points to the installer root for -# sshpw, but after that we start sshd, we need one that points to the -# install target. +# we need to have a libuser.conf that points to the installer root for +# sshpw, but after that we start sshd, we need one that points to the +# install target. luserConf = users.createLuserConf(instPath="") # Pass a fake anaconda object in because it won't be needed u = users.Users(None) |