Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP3:GA
grub2.2049
grub2-s390x-04-grub2-install.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File grub2-s390x-04-grub2-install.patch of Package grub2.2049
From: Raymund Will <rw@suse.com> Subject: Allow s390x-emu to be "installed" References: fate#314213, bnc#866867, bnc#868909, bnc#874155, bnc#876743, bnc#879136, bnc#889562, bnc#889572 Patch-Mainline: no V2: * try harder to find root filesystem (incl. subvol-handling). * read /etc/sysconfig/bootloader as final fallback. V3: * refresh initrd by default, prefer running kernel and re-zipl despite minor issues. [bnc#866867, fate#314213] V4: * append 'quiet splash=silent' for 'initgrub'-boot. * properly check for dracut script during 'grub2-install'. * move 'zipl2grub.pl' to '/usr/sbin/grub2-zipl-setup'. V5: * actually call 'grub2-zipl-setup' from 'grub2-install'. * handle 'GRUB{,_EMU}_CONMODE'. [bnc#868909] V6: * grub2-zipl-setup: support 'xz' initrd compression. [bnc#874155] V7: * dracut-grub2.sh: use 'showconsole' to determine console device. [bnc#876743] * dracut-grub2.sh: and fall back to '/dev/console' (instead of 'tty1'). * dracut-grub2.sh: introduce "debug()" helper function. V8: * grub2-zipl-setup: replace poor choice in '/sysroot/sys' check. [bnc#879136] * grub2-zipl-setup: fix typo in '/sysroot/proc' check. V9: * grub2-zipl-setup: honor GRUB_DISABLE_LINUX_UUID. [bnc#885854] V10: * grub2-zipl-setup: fix stupid typo in previous fix. [bnc#889562, bnc#889572] V11: * grub2-zipl-setup: disable 'grub-mkrelpath' acrobatics. [bnc#889572] V12: * dracut-grub2.sh: try to mount '/.snapshots' if missing. [bnc#892014] * dracut-grub2.sh: use '/dev/shm' for debug output, so it's accessible from grub2-emu's shell. V13: * grub2-zipl-setup: make initrd mount '/boot', if needed. [bnc#873951, bnc#892088] * dracut-grub2.sh: provide /boot from above to grub2-emu in chroot. V14: * grub2-zipl-setup: actually remove obsolete kernel/initrds. [bnc#892810] V15: * zipl2grub.conf: turn of zipl-prompt and quiescent plymouth. [bsc#898198] --- Makefile.util.def | 39 +++ configure.ac | 9 grub-core/Makefile.core.def | 7 grub-core/osdep/basic/no_platform.c | 7 grub-core/osdep/unix/platform.c | 11 grub-core/osdep/windows/platform.c | 6 include/grub/util/install.h | 4 util/grub-install-common.c | 1 util/grub-install.c | 43 +++ util/s390x/dracut-grub2.sh.in | 106 ++++++++ util/s390x/dracut-module-setup.sh.in | 19 + util/s390x/zipl2grub.conf.in | 26 ++ util/s390x/zipl2grub.pl.in | 424 +++++++++++++++++++++++++++++++++++ 13 files changed, 698 insertions(+), 4 deletions(-) --- a/Makefile.util.def +++ b/Makefile.util.def @@ -350,6 +350,7 @@ program = { ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; cppflags = '-DGRUB_SETUP_FUNC=grub_util_bios_setup'; + emu_condition = COND_NOT_s390x; }; program = { @@ -370,6 +371,7 @@ program = { ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; cppflags = '-DGRUB_SETUP_FUNC=grub_util_sparc_setup'; + emu_condition = COND_NOT_s390x; }; program = { @@ -385,6 +387,7 @@ program = { ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBGEOM)'; + emu_condition = COND_NOT_s390x; }; program = { @@ -415,6 +418,7 @@ program = { ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + emu_condition = COND_NOT_s390x; }; data = { @@ -620,7 +624,7 @@ program = { common = grub-core/disk/host.c; common = util/resolve.c; - enable = noemu; + emu_condition = COND_s390x; common = grub-core/kern/emu/argp_common.c; common = grub-core/osdep/init.c; @@ -688,6 +692,38 @@ script = { }; script = { + name = grub-zipl-setup; + installdir = sbin; + common = util/s390x/zipl2grub.pl.in; + enable = emu; + emu_condition = COND_s390x; +}; + +data = { + name = zipl2grub.conf.in; + common = util/s390x/zipl2grub.conf.in; + installdir = grubconf; + enable = emu; + emu_condition = COND_s390x; +}; + +script = { + name = dracut-module-setup.sh; + common = util/s390x/dracut-module-setup.sh.in; + enable = emu; + emu_condition = COND_s390x; + installdir = platform; +}; + +script = { + name = dracut-grub.sh; + common = util/s390x/dracut-grub2.sh.in; + enable = emu; + emu_condition = COND_s390x; + installdir = platform; +}; + +script = { name = grub-mkconfig_lib; common = util/grub-mkconfig_lib.in; installdir = noinst; @@ -1281,6 +1317,7 @@ program = { ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + emu_condition = COND_NOT_s390x; }; program = { --- a/configure.ac +++ b/configure.ac @@ -177,9 +177,9 @@ if test x$platform != xemu ; then esac fi -if test x"$target_cpu-$platform" = xsparc64-emu ; then - target_m64=1 ; -fi +case x"$target_cpu-$platform" in + xsparc64-emu | xs390x-emu) target_m64=1 ;; +esac case "$target_os" in windows* | mingw32*) target_os=cygwin ;; @@ -1665,6 +1665,9 @@ AM_CONDITIONAL([COND_arm_uboot], [test x AM_CONDITIONAL([COND_arm_efi], [test x$target_cpu = xarm -a x$platform = xefi]) AM_CONDITIONAL([COND_arm64], [test x$target_cpu = xarm64 ]) AM_CONDITIONAL([COND_arm64_efi], [test x$target_cpu = xarm64 -a x$platform = xefi]) +AM_CONDITIONAL([COND_s390x], [test x$target_cpu = xs390x ]) +AM_CONDITIONAL([COND_NOT_s390x], [test x$target_cpu != xs390x ]) +AM_CONDITIONAL([COND_s390x_emu], [test x$target_cpu = xs390x -a x$platform = xemu]) AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd]) AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux]) --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1064,6 +1064,7 @@ module = { module = { name = videotest; common = commands/videotest.c; + emu_condition = COND_NOT_s390x; }; module = { @@ -1477,6 +1478,7 @@ module = { common = gfxmenu/gui_progress_bar.c; common = gfxmenu/gui_util.c; common = gfxmenu/gui_string_util.c; + emu_condition = COND_NOT_s390x; }; module = { @@ -1856,11 +1858,13 @@ module = { name = gfxterm; common = term/gfxterm.c; enable = videomodules; + emu_condition = COND_NOT_s390x; }; module = { name = gfxterm_background; common = term/gfxterm_background.c; + emu_condition = COND_NOT_s390x; }; module = { @@ -1975,6 +1979,7 @@ module = { enable = x86_64_efi; enable = emu; enable = xen; + emu_condition = COND_NOT_s390x; }; module = { @@ -1990,6 +1995,7 @@ module = { module = { name = gfxterm_menu; common = tests/gfxterm_menu.c; + emu_condition = COND_NOT_s390x; }; module = { @@ -2142,6 +2148,7 @@ module = { enable = x86_64_efi; enable = emu; enable = xen; + emu_condition = COND_NOT_s390x; }; module = { --- a/grub-core/osdep/basic/no_platform.c +++ b/grub-core/osdep/basic/no_platform.c @@ -44,3 +44,10 @@ grub_install_sgi_setup (const char *inst { grub_util_error ("%s", _("no SGI routines are available for your platform")); } + +void +grub_install_zipl (const char *d, int i, int f) +{ + grub_util_error ("%s", _("no zIPL routines are available for your platform")); +} + --- a/grub-core/osdep/unix/platform.c +++ b/grub-core/osdep/unix/platform.c @@ -233,3 +233,14 @@ grub_install_sgi_setup (const char *inst imgfile, destname, NULL }); grub_util_warn ("%s", _("You will have to set `SystemPartition' and `OSLoader' manually.")); } + +void +grub_install_zipl (const char *dest, int install, int force) +{ + if (grub_util_exec ((const char * []){ PACKAGE"-zipl-setup", + verbosity ? "-v" : "", + install ? "" : "--debug", + !force ? "" : "--force", + "-z", dest, NULL })) + grub_util_error (_("`%s' failed.\n"), PACKAGE"-zipl-setup"); +} --- a/grub-core/osdep/windows/platform.c +++ b/grub-core/osdep/windows/platform.c @@ -422,3 +422,9 @@ grub_install_sgi_setup (const char *inst { grub_util_error ("%s", _("no SGI routines are available for your platform")); } + +void +grub_install_zipl (const char *d, int i, int f) +{ + grub_util_error ("%s", _("no zIPL routines are available for your platform")); +} --- a/include/grub/util/install.h +++ b/include/grub/util/install.h @@ -99,6 +99,7 @@ enum grub_install_plat GRUB_INSTALL_PLATFORM_I386_XEN, GRUB_INSTALL_PLATFORM_X86_64_XEN, GRUB_INSTALL_PLATFORM_ARM64_EFI, + GRUB_INSTALL_PLATFORM_S390X_EMU, GRUB_INSTALL_PLATFORM_MAX }; @@ -217,6 +218,9 @@ void grub_install_sgi_setup (const char *install_device, const char *imgfile, const char *destname); +void +grub_install_zipl (const char *d, int i, int f); + int grub_install_compress_gzip (const char *src, const char *dest); int --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -665,6 +665,7 @@ static struct [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" }, [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64", "efi" }, [GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" }, + [GRUB_INSTALL_PLATFORM_S390X_EMU] = { "s390x", "emu" }, }; char * --- a/util/grub-install.c +++ b/util/grub-install.c @@ -66,6 +66,7 @@ static int force_file_id = 0; static char *disk_module = NULL; static char *efidir = NULL; static char *macppcdir = NULL; +static char *zipldir = NULL; static int force = 0; static int have_abstractions = 0; static int have_cryptodisk = 0; @@ -107,6 +108,7 @@ enum OPTION_NO_BOOTSECTOR, OPTION_NO_RS_CODES, OPTION_MACPPC_DIRECTORY, + OPTION_ZIPL_DIRECTORY, OPTION_LABEL_FONT, OPTION_LABEL_COLOR, OPTION_LABEL_BGCOLOR, @@ -182,6 +184,11 @@ argp_parser (int key, char *arg, struct efidir = xstrdup (arg); return 0; + case OPTION_ZIPL_DIRECTORY: + free (zipldir); + zipldir = xstrdup (arg); + return 0; + case OPTION_DISK_MODULE: free (disk_module); disk_module = xstrdup (arg); @@ -299,6 +306,8 @@ static struct argp_option options[] = { N_("use DIR as the EFI System Partition root."), 2}, {"macppc-directory", OPTION_MACPPC_DIRECTORY, N_("DIR"), 0, N_("use DIR for PPC MAC install."), 2}, + {"zipl-directory", OPTION_ZIPL_DIRECTORY, N_("DIR"), 0, + N_("use DIR as the zIPL Boot Partition root."), 2}, {"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2}, {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2}, {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2}, @@ -325,6 +334,8 @@ get_default_platform (void) return "arm64-efi"; #elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__) return grub_install_get_default_x86_platform (); +#elif defined (__s390x__) + return "s390x-emu"; #else return NULL; #endif @@ -484,6 +495,8 @@ have_bootdev (enum grub_install_plat pl) case GRUB_INSTALL_PLATFORM_I386_XEN: case GRUB_INSTALL_PLATFORM_X86_64_XEN: + + case GRUB_INSTALL_PLATFORM_S390X_EMU: return 0; /* pacify warning. */ @@ -895,6 +908,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_ARM_UBOOT: case GRUB_INSTALL_PLATFORM_I386_XEN: case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_S390X_EMU: break; case GRUB_INSTALL_PLATFORM_I386_QEMU: @@ -940,6 +954,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_I386_XEN: case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_S390X_EMU: free (install_device); install_device = NULL; break; @@ -1201,6 +1216,20 @@ main (int argc, char *argv[]) } } + if (platform == GRUB_INSTALL_PLATFORM_S390X_EMU) + { + if (!zipldir) + { + char *d = grub_util_path_concat (2, bootdir, "zipl"); + if (!grub_util_is_directory (d)) + { + free (d); + grub_util_error ("%s", _("cannot find zIPL directory")); + } + zipldir = d; + } + } + grub_install_copy_files (grub_install_source_directory, grubdir, platform); @@ -1445,6 +1474,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_ARM_UBOOT: case GRUB_INSTALL_PLATFORM_I386_XEN: case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_S390X_EMU: grub_util_warn ("%s", _("no hints available for your platform. Expect reduced performance")); break; /* pacify warning. */ @@ -1557,6 +1587,10 @@ main (int argc, char *argv[]) strcpy (mkimage_target, "sparc64-ieee1275-raw"); core_name = "core.img"; break; + case GRUB_INSTALL_PLATFORM_S390X_EMU: + strcpy (mkimage_target, "grub2-emu"); + core_name = mkimage_target; + break; /* pacify warning. */ case GRUB_INSTALL_PLATFORM_MAX: break; @@ -1572,6 +1606,7 @@ main (int argc, char *argv[]) core_name); char *prefix = xasprintf ("%s%s", prefix_drive ? : "", relative_grubdir); + if (core_name != mkimage_target) grub_install_make_image_wrap (/* source dir */ grub_install_source_directory, /*prefix */ prefix, /* output */ imgfile, @@ -1610,6 +1645,10 @@ main (int argc, char *argv[]) /* image target */ mkimage_target, 0); } break; + + case GRUB_INSTALL_PLATFORM_S390X_EMU: + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: @@ -1871,6 +1910,10 @@ main (int argc, char *argv[]) } break; + case GRUB_INSTALL_PLATFORM_S390X_EMU: + grub_install_zipl (zipldir, install_bootsector, force); + break; + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: --- /dev/null +++ b/util/s390x/dracut-grub2.sh.in @@ -0,0 +1,106 @@ +#!/bin/sh +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh +#getargbool() { true; } + +if getargbool 0 initgrub && [ ! -e /grub2skip ] || [ -e /grub2force ]; then + #type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh + checkro() { + local dev mp fs opts dc + local rofs=false + while read dev mp fs opts dc; do + [ "$mp" = "/sysroot" ] || continue + case ",$opts," in + (*,ro,*) rofs=true;; + esac + done < /proc/mounts + echo $rofs + } + checkd() { + [ -d $1 ] && echo true || echo false + } + checke() { + [ -e $1 ] && echo true || echo false + } + checksnap() { + if [ -e /sysroot/.snapshots/grub-snapshot.cfg ]; then + echo true + elif grep -qE '^[^#\s]+\s+/.snapshots\s+' /sysroot/etc/fstab; then + echo false + else + echo true + fi + } + checkboot() { + [ -d /boot/grub2 ] && echo false || echo true + } + getterm() { + local term="$(getarg TERM)" + [ -z "$term" ] && term=dumb + echo $term + } + debug() { + if [ -n "$1" ]; then + echo "$1" >> /dev/.grub2.debug + fi + shift; + [ -n "$*" ] || return 0 + echo "+ $*" >> /dev/.grub2.debug + "$@" >> /dev/.grub2.debug + } + + exec_prefix=@exec_prefix@ + bindir=@bindir@ + if [ -e /sysroot$bindir/grub2-emu ]; then + + + export TERM=$(getterm) + export grub2rofs=$(checkro) + export grub2sysfs=$(checkd /sysroot/sys/devices/system/memory) + export grub2procfs=$(checkd /sysroot/proc/self) + export grub2bootfs=$(checkboot) + export grub2devfs=$(checkd /sysroot/dev/disk) + export grub2snap=$(checksnap) + debug "" export -p + + _ctty="$(RD_DEBUG= getarg rd.ctty=)" && _ctty="/dev/${_ctty##*/}" + if [ -z "$_ctty" ]; then + _ctty=$(showconsole) + fi + if [ -z "$_ctty" ]; then + _ctty=console + while [ -f /sys/class/tty/$_ctty/active ]; do + _ctty=$(cat /sys/class/tty/$_ctty/active) + _ctty=${_ctty##* } # last one in the list + done + _ctty=/dev/$_ctty + fi + [ -c "$_ctty" ] || _ctty=/dev/console + case "$(/usr/bin/setsid --help 2>&1)" in *--ctty*) CTTY="--ctty";; esac + + CTTY="$CTTY --wait" + $grub2rofs || mount -o remount,ro /sysroot + $grub2sysfs || mount --bind {,/sysroot}/sys + $grub2procfs || mount --bind {,/sysroot}/proc + $grub2bootfs || mount --bind {,/sysroot}/boot + $grub2devfs || mount --bind {,/sysroot}/dev + $grub2snap || chroot /sysroot mount -rn /.snapshots + debug "" cat /proc/mounts + + debug "Trying grub2-emu (ro=$grub2rofs, TERM=$TERM, ctty=$_ctty)..." + setsid $CTTY -- chroot /sysroot $bindir/grub2-emu -X -X 0<>$_ctty 1>&0 2>&0 + if [ -e /grub2force ] && [ $(cat /sys/kernel/kexec_loaded) = 1 ]; then + systemctl kexec + fi + + $grub2snap || umount /sysroot/.snapshots + $grub2devfs || umount /sysroot/dev + $grub2bootfs || umount /sysroot/boot + $grub2procfs || umount /sysroot/proc + $grub2sysfs || umount /sysroot/sys + $grub2rofs || mount -o remount,rw /sysroot + else + info "No $bindir/grub2-emu in /sysroot--trying to proceed without kexec..." + fi +fi + --- /dev/null +++ b/util/s390x/dracut-module-setup.sh.in @@ -0,0 +1,19 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +# called by dracut +check() { + local _arch=$(uname -m) + [ "$_arch" = "s390" -o "$_arch" = "s390x" ] || return 1 + return 0 +} + +# called by dracut +install() { + inst_hook cleanup 99 "$moddir/grub2.sh" + inst_multiple showconsole + inst_multiple mount umount chroot cat grep /usr/bin/setsid + #inst_multiple grub2-emu kexec +} + --- /dev/null +++ b/util/s390x/zipl2grub.conf.in @@ -0,0 +1,26 @@ +## This is the template for '@zipldir@/config' and is subject to +## rpm's %config file handling in case of grub2-s390x-emu package update. + +[defaultboot] +defaultmenu = menu + +[grub2] + target = @zipldir@ + ramdisk = @zipldir@/initrd,0x2000000 + image = @zipldir@/image + parameters = "root=@GRUB_DEVICE@ @GRUB_EMU_CONMODE@ @GRUB_CMDLINE_LINUX@ @GRUB_CMDLINE_LINUX_DEFAULT@ initgrub quiet splash=silent plymouth.enable=0 " + +[skip-grub2] + target = @zipldir@ + ramdisk = @zipldir@/initrd,0x2000000 + image = @zipldir@/image + parameters = "root=@GRUB_DEVICE@ @GRUB_CONMODE@ @GRUB_CMDLINE_LINUX@ @GRUB_CMDLINE_LINUX_DEFAULT@ " + +:menu + target = @zipldir@ + timeout = 16 + default = 1 + prompt = 0 + 1 = grub2 + 2 = skip-grub2 + --- /dev/null +++ b/util/s390x/zipl2grub.pl.in @@ -0,0 +1,424 @@ +#!/usr/bin/perl +use strict; + +my $C = $0; $C =~ s{^.*/}{}; + +my $in = '@sysconfdir@/default/zipl2grub.conf.in'; +my $default = '@sysconfdir@/default/grub'; +my $fallback = '@sysconfdir@/zipl.conf'; +my $sysconfbl = '@sysconfdir@/sysconfig/bootloader'; +my $zipldir = ""; +my $running = ""; +my $refresh = 1; # needs to default to "on" until most bugs are shaken out! +my $force = 0; +my $verbose = 0; +my $debug = 0; +my $miss = 0; +my $cfg = ""; +my %fsdev = (); +my %fstype = (); + +my %C = ( + GRUB_CMDLINE_LINUX_DEFAULT => "quiet splash=silent", + GRUB_DISABLE_LINUX_UUID => "false", +); + +my %Mandatory = ( + GRUB_CMDLINE_LINUX_DEFAULT => 1, + GRUB_DEVICE => 1, +); + +sub Panic($$) { + printf( STDERR "%s", $_[1]); + exit( $_[0]); +} +sub Info($$) { + printf( STDERR "%s", $_[1]) if ($_[0] <= $verbose); +} +sub System(@) { + my (@C) =@_; + Info( 1, "+ " . join( " ", @C) . "\n"); + return 0 if ($debug); + system( @C); + if ($? == -1) { + Panic( $?, "$C[0]: Failed to execute: $!\n"); + } elsif ($? & 127) { + Panic( $?, sprintf( "$C[0]: Died with signal %d with%s coredump\n", + ($? & 127), ($? & 128) ? '' : 'out')); + } elsif ( $? >> 8 != 0 ) { + Panic( $?, "$C[0]: Failed\n"); + } + return( 0); +} +sub cp($$) { + my @C = ( "cp", "-p", $_[0], $_[1]); + System( @C); +} +sub rm($) { + return( 0) unless ( -l $_[0] || -e $_[0]); + Info( 2, "+ rm $_[0]\n"); + return 0 if ($debug); + unlink( $_[0]) || Panic( 1, "$C: unlink: $!.\n"); +} +sub mv($$) { + Info( 1, "+ mv $_[0] $_[1]\n"); + return 0 if ($debug); + rename($_[0], $_[1]) || Panic( 1, "$C: rename: $!.\n"); +} +sub ln($$) { + Info( 1, "+ ln -sf $_[0] $_[1]\n"); + return 0 if ($debug); + unlink( $_[1]) || Panic( 1, "$C: unlink: $!.\n") if ( -e $_[1]); + symlink($_[0], $_[1]) || Panic( 1, "$C: symlink: $!.\n"); +} +sub BootCopy($$$) { + my( $file, $dir, $tgt) = @_; + my $curr = "$dir/$tgt"; + my $prev = "$dir/$tgt.prev"; + Info(4, "Copy /boot/$file $dir $tgt\n"); + if ( -l $curr ) { + my $curf = readlink( $curr); + if ( $curf ne $file ) { + if ( -l $prev ) { + my $pref = readlink( $prev); + $pref = "$dir/$pref" unless ($pref =~ m{^/}); + rm( $pref); + } + mv( $curr, $prev); + } + } + cp( "/boot/$file", "$dir/$file"); + ln( $file, $curr); +} +sub MkInitrd($$$) { + my( $initrd, $dir, $version) = @_; + my @C = ( "dracut", "--hostonly", "--force"); + my $uuid; + if ( exists( $fsdev{"/boot"}) ) { + chomp( $uuid = qx{grub2-probe --target=fs_uuid /boot}); + my ($dev, $type) = ($fsdev{"/boot"}, $fstype{"/boot"}); + if ( $type eq "auto" ) { + chomp( $type = qx{grub2-probe --target=fs /boot}); + } + if ($C{GRUB_DISABLE_LINUX_UUID} eq "true" && + $dev =~ m{^(UUID=|/dev/disk/by-uuid/)}) { + chomp( $dev = qx{grub2-probe --target=device /boot}); + } + push @C, "--mount", "$dev /boot $type ro"; + } + push @C, "$dir/$initrd", $version; + System( @C); + ln( $initrd, "$dir/initrd"); +} +sub ChkInitrd($$) { + my( $dir, $initrd) = @_; + my $found = -1; + my $d = $dir; + my $pattern = qr{lib/dracut/hooks/cleanup/99-grub2.sh}; + my $show = "cleanup/99-grub2.sh"; + my $cat = undef; + my $magic; + + return $found unless (-r "$dir/$initrd"); + open( IN, "< $dir/$initrd") || return $found; + my $rd = sysread( IN, $magic, 6); + close( IN); + return $found unless (defined( $rd) && $rd == 6); + $cat = "xzcat" if ($magic eq "\xFD7zXZ\x00"); + $cat = "zcat" if (substr($magic, 0, 2) eq "\037\213"); + $cat = "cat" if (substr($magic, 0, 5) eq "07070"); + return $found unless (defined($cat)); + + my $modinst = "/usr/lib/dracut/modules.d/99grub2/module-setup.sh"; + if ( -r $modinst ) { + my( $hook, $ord, $script); + my $pat = qr{^\s*inst_hook\s+(\S+)\s+([0-9]+)\s+\"\$moddir/(grub2\.sh)\"}; + open( IN, "< $modinst") || die; + while ( <IN> ) { + next unless ($_ =~ $pat); + $show = "$1/$2-$3"; + $pattern = qr{lib/dracut/hooks/$show}o; + last; + } + close( IN); + } + + $found = 0; + Info( 3, "+ $cat $d/$initrd | cpio -it | grep '$show'\n"); + open( IN, "$cat $d/$initrd | cpio -it 2>/dev/null |") || + Panic( 1, "$C: cpio: $!.\n"); + while ( <IN> ) { + $found = 1 if ($_ =~ $pattern); + } + close( IN); + return $found; +} + +sub Usage($) { + my @cat = ("", + "Parameter error.", + "zIPL directory missing.", + "Configuration template missing.", + "Configuration template unreadable.", + "zIPL directory not accesible.", + "" + ); + my $msg = ""; + + $msg .= sprintf( "%s: %s\n", $C, $cat[$_[0]]) if ($_[0] > 0); + $msg .= "Usage: $C [-v] [-d] [-f] [-T template] [-z ZIPLDIR]\n"; + Panic( $_[0], $msg . "\n"); +} + +die if ($[ != 0); +while ( $#ARGV >= 0 ) { + $_ = shift; + next if /^$/; + last if /^--$/; + (/^--verbose$/ || /^-v$/) && ($verbose++, next); + (/^--quiet$/ || /^-q$/) && ($verbose = 0, next); + (/^--debug$/ || /^-d$/) && ($debug = 1, $verbose++, next); + (/^--force$/ || /^-f$/) && ($force = $refresh = 1, next); + (/^--refresh$/ || /^-r$/) && ($refresh = 1, next); + (/^--keep$/ || /^-k$/) && ($refresh = 0, next); + (/^--?help/ || /^-h/) && (Usage(0)); + (/^--zipldir$/ || /^-z$/) && ($zipldir = shift || Usage(2), next); + (/^--template$/ || /^-T$/) && ($in = shift || Usage(3), next); + (/^-/) && (Usage(1)); + Usage(1); +} +Usage(4) if (! -r $in); + +if ($zipldir) { + $C{zipldir} = $zipldir; # command-line wins +} elsif ( exists( $C{zipldir}) ) { + $zipldir = $C{zipldir}; # otherwise fall back to config +} else { + $zipldir = $C{zipldir} = "/boot/zipl"; # but don't proceed without... +} +Usage(5) if (! -d $zipldir); +if ( $zipldir eq "/boot" ) { + Panic( 5, "$C: zIPL directory '/boot' not supported!\n"); +} + +if ( ! -r $default && ! -r $fallback && ! -r $sysconfbl ) { + Panic( 0, "$C: No configuration files found. Retry later!\n"); +} +if ( -r $default ) { + open( IN, "< $default") || die; + while ( <IN> ) { + chomp; + s{^\s*#.*$}{}; + next if m{^\s*$}; + s{x}{\x01xx\x01}g; + s{\\\"}{\x01x1\x01}g; + s{\\\'}{\x01x2\x01}g; + Info( 5, "<$_>\n"); + if ( m{^([^\s=]+)='([^']*)'\s*(?:#.*)?$} || + m{^([^\s=]+)="([^"]*)"\s*(?:#.*)?$} || + m{^([^\s=]+)=(\S*)\s*(?:#.*)?$} ) { + my ( $k, $v) = ($1, $2); + $v =~ s{\x01x2\x01}{\\'}g; + $v =~ s{\x01x1\x01}{\\"}g; + $v =~ s{\x01xx\x01}{x}g; + $C{$k} = $v; + next; + } + print( STDERR "$default:$.: parse error ignored.\n"); + } + close( IN); +} +if ( -r "/etc/fstab" ) { + my $regex = qr{^(\S+)\s+(\S+)\s+(\S+)\s+\S+\s+\S+\s+\S+\s*(?:#.*)?$}; + open( IN, "< /etc/fstab") || die; + while ( <IN> ) { + next if ( m{^\s*#} ); + my ($dev, $mp, $type) = (m{$regex}o); + $fsdev{$mp} = $dev; + $fstype{$mp} = $type; + } + close( IN); +} + +if ( ! exists( $C{GRUB_DEVICE}) && + $C{GRUB_CMDLINE_LINUX_DEFAULT} eq "quiet splash=silent" && + -r $fallback ) { + # configuration incomplete, let's try fallback + open( IN, "< $fallback") || die; + my $section = ""; + while( <IN> ){ + if ( m{^\[([^\]]+)\]\s*$} ) { + $section = $1; + } + if ( $section eq "ipl" && + m{^\s*parameters\s*=\s*\"root=(\S+)(?:\s*|\s+([^\"]+))\"} ) { + $C{GRUB_DEVICE} = $1; + $C{GRUB_CMDLINE_LINUX_DEFAULT} = $2 if (defined($2) && $2 !~ m{^\s*$}); + last; + } + } + close( IN); + $default = $fallback; +} + +if ( ! exists( $C{GRUB_DEVICE}) && exists( $fsdev{"/"}) ) { + my( $dev, $type, $subvol) = ( $fsdev{"/"}, $fstype{"/"}, ""); + if ( $dev !~ m{^(UUID=|/dev/disk/by-uuid/)} || + $C{GRUB_DISABLE_LINUX_UUID} ne "true" ) { + $C{GRUB_DEVICE} = $dev; + # grub2-mkrelpath fails on rollback -- and provides no known merit... + #chomp( $subvol = qx{grub2-mkrelpath /}) if ( $type eq "btrfs" ); + #$subvol =~ s{^/}{}; + #$C{GRUB_DEVICE} .= " rootflags=subvol=$subvol" if ($subvol); + } +} +if ( ! exists( $C{GRUB_DEVICE}) ) { + my( $dev, $uuid, $type, $subvol) = ("", "", "", ""); + chomp( $dev = qx{grub2-probe --target=device /}); + chomp( $uuid = qx{grub2-probe --device $dev --target=fs_uuid}); + if ( $dev ) { + if ( $uuid && $C{GRUB_DISABLE_LINUX_UUID} ne "true" ) { + $C{GRUB_DEVICE} = "UUID=$uuid"; + } else { + $C{GRUB_DEVICE} = "$dev"; + } + chomp( $type = qx{stat -f --printf='%T' /}); + # grub2-mkrelpath fails on rollback -- and provides no known merit... + #chomp( $subvol = qx{grub2-mkrelpath /}) if ( $type eq "btrfs" ); + #$subvol =~ s{^/}{}; + #$C{GRUB_DEVICE} .= " rootflags=subvol=$subvol" if ($subvol); + } +} +if ( $C{GRUB_CMDLINE_LINUX_DEFAULT} eq "quiet splash=silent" && + -r $sysconfbl) { + open( IN, "< $sysconfbl") || die; + while ( <IN> ) { + next if ( m{^\s*#} ); + if ( m{^DEFAULT_APPEND=".*"(?:\s*|\s+#.*)$} ) { + $C{GRUB_CMDLINE_LINUX_DEFAULT} = $1; + } + } + close( IN); +} + +if ( ! exists( $C{GRUB_DEVICE})) { + Panic( 0, "$C: Default not ready and no fallback. Please retry later!\n"); +} + +if ( ! exists( $C{GRUB_EMU_CONMODE}) && exists( $C{GRUB_CONMODE}) ) { + # GRUB_CONMODE is used for 'grub2-emu' as well + $C{GRUB_EMU_CONMODE} = $C{GRUB_CONMODE}; +} +if ( exists( $C{GRUB_EMU_CONMODE}) && !exists( $C{GRUB_CONMODE}) ) { + # pick up 'conmode=' from CMDLINE + my $found = ""; + foreach ( "GRUB_CMDLINE_LINUX", "GRUB_CMDLINE_LINUX_DEFAULT" ) { + next unless ($C{$_} =~ m{ ?conmode=(\S+) ?}); + $C{GRUB_CONMODE} = $1; + last; + } + if ( !exists( $C{GRUB_CONMODE}) && $C{GRUB_EMU_CONMODE} eq "3270" ) { + # force GRUB_CONMODE to 3215 for least surprise + $C{GRUB_CONMODE}="3215"; + } +} +if ( exists( $C{GRUB_EMU_CONMODE}) && exists( $C{GRUB_CONMODE})) { + # strip "conmode=" from GRUB_CMDLINE{,_LINUX}_DEFAULT + foreach ( "GRUB_CMDLINE_LINUX", "GRUB_CMDLINE_LINUX_DEFAULT" ) { + $C{$_} =~ s{( ?)conmode=\S+ ?}{$1}g; + } +} +foreach ("GRUB_EMU_CONMODE", "GRUB_CONMODE") { + next unless( exists( $C{$_}) ); + $C{$_} = "conmode=" . $C{$_}; +} + +if ( $debug && $verbose > 2 ) { + foreach ( sort( keys( %C)) ) { + printf( "%s=\"%s\"\n", $_, $C{$_}); + } +} + +open( IN, "< $in") || + Panic( 1, "$C: Failed to open 'zipl.conf' template: $!.\n"); +while ( <IN> ) { + Info( 3, "$.. <$_$.. >"); + if ( $. == 1 && m{^## This} ) { + $_ = "## This file was written by 'grub2-install/$C'\n" . + "## filling '$in' as template\n"; + } elsif ( $. == 2 && m{^## rpm's} ) { + $_ = "## with values from '$default'.\n" . + "## In-place modifications will eventually go missing!\n"; + } + while ( m{\@([^\@\s]+)\@} ) { + my $k = $1; + my $v; + if ( exists( $C{$k}) ) { + $v = $C{$k}; + } elsif ( exists( $Mandatory{$k}) ) { + $v = "$k"; + $miss++; + } else { + $v = ""; + } + s{\@$k\@}{$v}g; + } + Info( 2, $_); + $cfg .= $_; +} +if ( $miss ) { + Info( 1, "Partially filled config:\n===\n$cfg===\n"); + Panic( 1, "$C: 'zipl.conf' template could not be filled. \n"); +} + +my $ziplconf = "$zipldir/config"; +if ( ! $debug ) { + open( OUT, "> $ziplconf") || die; + print( OUT $cfg) || die; + close( OUT); +} + +# copy out kernel and initrd +my $defimage = "/boot/image"; +my $definitrd = "/boot/initrd"; +my $ziplimage = "$zipldir/image"; +my $ziplinitrd = "$zipldir/initrd"; +my $Image = "$defimage"; + +if ( ! $running && ! $force ) { + chomp( $running = qx{uname -r}); + Info( 1, "preferred kernel: '$running'\n"); + $Image .= "-$running"; +} +if ( ! -r $Image ) { + $Image = $defimage; +} +Panic( 1, "$C: kernel '$Image' not readable!?\n") unless (-r $Image); + +if ( -l $Image ) { + $Image = readlink( $Image); +} +my ($image, $version) = ($Image =~ m{^(?:/boot/)?([^-]+-(.+))$}); +my $initrd = "initrd-$version"; + +if ( !defined($image) || !defined($version) || ! -r "/boot/$image" ) { + Panic( 1, "$C: weird $Image. This should never happen!\n"); +} + +if ( ! -r $ziplimage || ! -r $ziplinitrd || $refresh ) { + BootCopy( $image, $zipldir, "image"); + BootCopy( $initrd, $zipldir, "initrd") if (-r "/boot/$initrd"); +} +if ( $refresh || ChkInitrd( $zipldir, "initrd") <= 0 ) { + MkInitrd( $initrd, $zipldir, $version); +} +if ( ChkInitrd( $zipldir, "initrd") == 0 ) { + Info( 0, "$C: dracut does not work as expected! Help needed!\n"); + $miss++; +} + +# now: go for it! +my @C = ( "/sbin/zipl", (($verbose) ? "-Vnc" : "-nc"), "$ziplconf" ); +System( @C); +exit( $miss); +
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor