Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package mksusecd for openSUSE:Factory checked in at 2023-03-22 22:30:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/mksusecd (Old) and /work/SRC/openSUSE:Factory/.mksusecd.new.31432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "mksusecd" Wed Mar 22 22:30:47 2023 rev:74 rq:1073616 version:2.10 Changes: -------- --- /work/SRC/openSUSE:Factory/mksusecd/mksusecd.changes 2022-12-16 17:51:47.640064652 +0100 +++ /work/SRC/openSUSE:Factory/.mksusecd.new.31432/mksusecd.changes 2023-03-22 22:30:47.738239597 +0100 @@ -1,0 +2,13 @@ +Tue Mar 21 17:21:28 UTC 2023 - wfe...@opensuse.org + +- merge gh#openSUSE/mksusecd#65 +- create efi boot image, if missing +- support grub hybrid boot code +- update doc +- show missing s390x file name correctly +- adjust boot info table checksum in grub +- better warning of insufficient file permissions +- support Live media (jsc#PED-2975) +- 2.10 + +-------------------------------------------------------------------- Old: ---- mksusecd-2.9.tar.xz New: ---- mksusecd-2.10.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ mksusecd.spec ++++++ --- /var/tmp/diff_new_pack.guloHM/_old 2023-03-22 22:30:48.258242213 +0100 +++ /var/tmp/diff_new_pack.guloHM/_new 2023-03-22 22:30:48.262242233 +0100 @@ -18,7 +18,7 @@ Name: mksusecd -Version: 2.9 +Version: 2.10 Release: 0 Summary: Tool to create SUSE Linux installation ISOs License: GPL-3.0+ ++++++ mksusecd-2.9.tar.xz -> mksusecd-2.10.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mksusecd-2.9/VERSION new/mksusecd-2.10/VERSION --- old/mksusecd-2.9/VERSION 2022-12-15 20:22:07.000000000 +0100 +++ new/mksusecd-2.10/VERSION 2023-03-21 18:21:28.000000000 +0100 @@ -1 +1 @@ -2.9 +2.10 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mksusecd-2.9/changelog new/mksusecd-2.10/changelog --- old/mksusecd-2.9/changelog 2022-12-15 20:22:07.000000000 +0100 +++ new/mksusecd-2.10/changelog 2023-03-21 18:21:28.000000000 +0100 @@ -1,3 +1,13 @@ +2023-03-21: 2.10 + - merge gh#openSUSE/mksusecd#65 + - create efi boot image, if missing + - support grub hybrid boot code + - update doc + - show missing s390x file name correctly + - adjust boot info table checksum in grub + - better warning of insufficient file permissions + - support Live media (jsc#PED-2975) + 2022-12-15: 2.9 - merge gh#openSUSE/mksusecd#64 - much improved usrmerge kernel support (bsc#1206181) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mksusecd-2.9/isohybrid.c new/mksusecd-2.10/isohybrid.c --- old/mksusecd-2.9/isohybrid.c 2022-12-15 20:22:07.000000000 +0100 +++ new/mksusecd-2.10/isohybrid.c 2023-03-21 18:21:28.000000000 +0100 @@ -46,7 +46,7 @@ uuid_t disk_uuid, part_uuid, iso_uuid; uint8_t mode = 0; -enum { VERBOSE = 1 , EFI = 2 , MAC = 4 , MODE_GPT = 8 , MODE_MBR = 0x10 , LEGACY = 0x20 }; +enum { VERBOSE = 1 , EFI = 2 , MAC = 4 , MODE_GPT = 8 , MODE_MBR = 0x10 , LEGACY = 0x20, GRUB = 0x40 }; /* partition numbers (1 based) */ int part_data = 0; @@ -77,6 +77,7 @@ unsigned no_code:1; /* no mbr boot code */ unsigned no_chs:1; /* fill in 0xffffff instead of real chs values */ off_t size; /* total size MBR partition table should cover */ + char *mbr_file; /* read mbr from file (432 bytes) */ } opt; @@ -256,6 +257,8 @@ printf(FMT, " --size", "Specify disk size to assume when writing MBR (in 512 byte units)"); printf(FMT, " --legacy", "Expect an El Torito boot record (default)"); printf(FMT, " --no-legacy", "Do not expect an El Torito boot record"); + printf(FMT, " --mbr-file FILE", "Use MBR from FILE"); + printf(FMT, " --grub", "GRUB mode"); printf("\n"); printf(FMT, " --forcehd0", "Assume we are loaded as disk ID 0"); @@ -286,6 +289,7 @@ { "size", required_argument, NULL, 1006 }, { "type", required_argument, NULL, 't' }, { "id", required_argument, NULL, 'i' }, + { "mbr-file", required_argument, NULL, 1009 }, { "gpt", no_argument, NULL, 1001 }, { "mbr", no_argument, NULL, 1002 }, { "no-mbr", no_argument, NULL, 1003 }, @@ -293,6 +297,8 @@ { "no-chs", no_argument, NULL, 1005 }, { "legacy", no_argument, NULL, 1007 }, { "no-legacy", no_argument, NULL, 1008 }, + { "mbr-file", required_argument, NULL, 1009 }, + { "grub", no_argument, NULL, 1010 }, { "forcehd0", no_argument, NULL, 'f' }, { "ctrlhd0", no_argument, NULL, 'c' }, @@ -407,6 +413,14 @@ mode &= ~LEGACY; break; + case 1009: + opt.mbr_file = optarg; + break; + + case 1010: + mode |= GRUB; + break; + case 'V': printf("%s version %s\n", prog, VERSION); exit(0); @@ -650,6 +664,7 @@ initialise_mbr(uint8_t *mbr) { int i = 0; + uint64_t tmp64 = 0; uint32_t tmp = 0, chs; uint8_t *rbm = mbr; @@ -657,7 +672,23 @@ extern unsigned char isohdpfx[][MBRSIZE]; - if (catoffset && !opt.no_code) memcpy(mbr, &isohdpfx[hd0 + 3 * partok], MBRSIZE); + if (catoffset && !opt.no_code) { + if(opt.mbr_file) { + int fd = open(opt.mbr_file, O_RDONLY); + if(fd == -1) { + perror(opt.mbr_file); + exit(1); + } + if(read(fd, mbr, MBRSIZE) != MBRSIZE) { + fprintf(stderr, "%s: failed to read MBR\n", opt.mbr_file); + exit(1); + } + close(fd); + } + else { + memcpy(mbr, &isohdpfx[hd0 + 3 * partok], MBRSIZE); + } + } if (mode & MAC) { memcpy(mbr, afp_header, sizeof(afp_header)); @@ -665,13 +696,9 @@ mbr += MBRSIZE; /* offset 432 */ - tmp = lendian_int(de_lba * 4); - if(!opt.no_code) memcpy(mbr, &tmp, sizeof(tmp)); - mbr += sizeof(tmp); /* offset 436 */ - - tmp = 0; - memcpy(mbr, &tmp, sizeof(tmp)); - mbr += sizeof(tmp); /* offset 440 */ + tmp64 = lendian_64(((mode & GRUB) ? (uint64_t) de_lba + 1 : (uint64_t) de_lba) * 4); + if(!opt.no_code) memcpy(mbr, &tmp64, sizeof(tmp64)); + mbr += sizeof(tmp64); /* offset 440 */ tmp = lendian_int(id); memcpy(mbr, &tmp, sizeof(tmp)); @@ -1114,12 +1141,34 @@ if (fread(buf, sizeof(char), 4, fp) != 4) err(1, "%s", argv[0]); - if(mode & LEGACY) + if (mode & LEGACY) { - if (memcmp(buf, "\xFB\xC0\x78\x70", 4)) + if (mode & GRUB) { + uint64_t tmp, old; + uint32_t crc; + + if (fseek(fp, ((uint64_t) de_lba * 2048 + 0x9f4), SEEK_SET)) err(1, "%s: seek error - 4", argv[0]); + if (fread(&old, 1, 8, fp) != 8) err(1, "%s", argv[0]); + + tmp = lendian_64((uint64_t) de_lba * 4 + 5); + + if (fseek(fp, ((uint64_t) de_lba * 2048 + 0x9f4), SEEK_SET)) err(1, "%s: seek error - 4", argv[0]); + if (fwrite(&tmp, 1, 8, fp) != 8) err(1, "%s", argv[0]); + + if (fseek(fp, ((uint64_t) de_lba * 2048 + 20), SEEK_SET)) err(1, "%s: seek error - 4", argv[0]); + if (fread(&crc, 1, 4, fp) != 4) err(1, "%s", argv[0]); + + crc += tmp - old; + crc += (tmp >> 32) - (old >> 32); + + if (fseek(fp, ((uint64_t) de_lba * 2048 + 20), SEEK_SET)) err(1, "%s: seek error - 4", argv[0]); + if (fwrite(&crc, 1, 4, fp) != 4) err(1, "%s", argv[0]); + } + else if (memcmp(buf, "\xFB\xC0\x78\x70", 4)) { warnx("%s: boot loader does not have an isolinux.bin hybrid " \ "signature. Note that isolinux-debug.bin does not support " \ "hybrid booting", argv[0]); + } } no_cat: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mksusecd-2.9/mksusecd new/mksusecd-2.10/mksusecd --- old/mksusecd-2.9/mksusecd 2022-12-15 20:22:07.000000000 +0100 +++ new/mksusecd-2.10/mksusecd 2023-03-21 18:21:28.000000000 +0100 @@ -178,6 +178,7 @@ sub unpack_orig_initrd; sub extract_installkeys; sub create_cd_ikr; +sub merge_options; sub isolinux_add_option; sub grub2_add_option; sub yaboot_add_option; @@ -213,12 +214,14 @@ sub add_linuxrc_option; sub wipe_iso; sub get_media_style; +sub get_media_variant; sub analyze_products; sub check_product; sub crypto_cleanup; sub run_crypto_disk; sub read_ini; sub write_ini; +sub create_efi_image; my %config; my $sudo; @@ -427,6 +430,8 @@ my $initrd_format; my $rebuild_initrd; my $hybrid_part_type; +my $hybrid_mbr_code; # mbr code to use for iso hybrid mode +my $hybrid_grub; # grub instead of isolinux is used for iso hybrid boot my $kernel; my $warned; my $read_write; @@ -439,6 +444,7 @@ my $repomd_instsys_location; my $sign_passwd_option; my $media_style = 'suse'; +my $media_variant = 'install'; my $progress_start = 0; my $progress_end = 100; @@ -482,6 +488,9 @@ s#/*$##; next if $_ eq ""; if(-d) { + if(`find $_ -xdev \\! -readable`) { + die "Some files in $_ are not readable; you need root privileges.\n"; + } my $d_skel = (<$_/usr/lib/skelcd/*>)[0]; my $d_tftp = (<$_/usr/share/tftpboot-installation/*>)[0]; if(-d $d_skel ) { @@ -505,6 +514,9 @@ my $d = $tmp->mnt(sprintf("mnt_%04d", $iso_cnt)); susystem "mount -oro,loop $_ $d"; push @sources, { dir => $d, real_name => $_, type => 'iso' }; + if(`find $d -xdev \\! -readable`) { + die "Some files in $_ are not readable; you need root privileges.\n"; + } } elsif($t =~ /RPM /) { $iso_cnt++; @@ -546,6 +558,7 @@ } $media_style = get_media_style \@sources; + $media_variant = get_media_variant \@sources; analyze_products \@sources; build_filelist \@sources; $boot = analyze_boot; @@ -703,7 +716,7 @@ { print <<"= = = = = = = ="; Usage: mksusecd [OPTIONS] [SOURCES] -Create bootable installation media. +Create and modify bootable media. General options: @@ -995,10 +1008,10 @@ $boot->{$_}{kernel} = "boot/$_/vmrdr.ikr" if -f fname("boot/$_/vmrdr.ikr"); $boot->{$_}{kernel} = "boot/$_/linux" if -f fname("boot/$_/linux"); - if(-f fname("boot/$_/loader/isolinux.bin")) { + if(-f fname("boot/$_/loader/isolinux.bin") && -f fname("boot/$_/loader/isolinux.cfg")) { $boot->{$_}{bl}{isolinux} = { base => "boot/$_/loader", file => "isolinux.bin", arch => $_ }; } - if(-f fname("boot/$_/isolinux/isolinux.bin")) { + if(-f fname("boot/$_/isolinux/isolinux.bin") && -f fname("boot/$_/isolinux/isolinux.cfg")) { $boot->{$_}{bl}{isolinux} = { base => "boot/$_/isolinux", file => "isolinux.bin", arch => $_ }; } if(-f fname("boot/$_/cd.ikr")) { @@ -1013,6 +1026,14 @@ if(-f fname("boot/$_/grub2/cd.img")) { $boot->{$_}{bl}{grub2} = { base => "boot/$_/grub2", file => "cd.img", arch => $_ }; } + if(-f fname("boot/$_/loader/eltorito.img")) { + $boot->{$_}{bl}{grub2} = { base => "boot/$_/loader", file => "eltorito.img", config => "boot/grub2/grub.cfg", arch => $_ }; + $boot->{$_}{bl}{efi} = { base => "boot/$_/loader/efiboot.img", arch => $_ }; + if(-f fname("boot/$_/loader/boot_hybrid.img")) { + $hybrid_mbr_code = fname("boot/$_/loader/boot_hybrid.img"); + $hybrid_grub = 1; + } + } if(-f fname("boot/$_/grub2-ieee1275/core.elf")) { $boot->{$_}{bl}{grub2} = { base => "boot/$_/grub2-ieee1275", file => "core.elf", arch => $_ }; } @@ -1034,7 +1055,7 @@ } } - if (-d fname("isolinux")) { + if (-d fname("isolinux") && -f fname("isolinux/isolinux.bin") && -f fname("isolinux/isolinux.cfg")) { $_ = "x86_64"; $boot->{$_} = { base => "isolinux" }; $boot->{$_}{initrd} = "isolinux/initrd.img" if -f fname("isolinux/initrd.img"); @@ -1209,7 +1230,7 @@ if(-d $f) { $n = "$tmp_new/$_[0]"; - system "mdir -p '$n'"; + system "mkdir -p '$n'"; } elsif(-f $f) { if($_[0] =~ m#(.+)/([^/]+)#) { @@ -1281,6 +1302,10 @@ elsif($opt_efi && $t eq 'efi') { $has_efi = 1; my $f = fname($_->{$t}{base}); + if(!$f) { + create_efi_image $_->{$t}{base}; + $f = fname($_->{$t}{base}); + } my $s = -s $f; $s = (($s + 2047) >> 11) << 2; $s = 1 if $s == 0 || $s > 0xffff; @@ -1400,6 +1425,8 @@ $ok = 0 if $?; } + $ok = 0 if $log =~ /mkisofs: Permission denied/; + print $log if $opt_verbose >= 3 || !$ok; die "Error: $mkisofs->{command} failed\n" if !$ok; @@ -1648,6 +1675,8 @@ $opt .= sprintf(" --type 0x%x", $part_type) if $part_type; $opt .= " --offset $mkisofs->{partition_start}" if $mkisofs->{partition_start}; $opt .= " --size $image_size" if $image_size; + $opt .= " --mbr-file $hybrid_mbr_code" if $hybrid_mbr_code; + $opt .= " --grub" if $hybrid_grub; my $cmd = "$LIBEXECDIR/mksusecd/isohybrid $opt '$iso_file'"; @@ -2196,6 +2225,8 @@ $compr = "gzip --quiet -9c" if $initrd_format eq "gz"; $compr = "zstd --quiet -c -T0" if $initrd_format eq "zst"; + chmod 0755, $tmp_dir; + system "( cd $tmp_dir; find . | cpio --quiet -o -H newc --owner 0:0 | $compr ) >> $tmp_initrd"; # system "ls -lR $tmp_dir"; @@ -2548,7 +2579,7 @@ if(open my $s, fname($ins)) { while(<$s>) { next if /^\s*\*/; - push @layout, { file => fname("$src/$1"), ofs => oct($2) } if /^\s*(\S+)\s+(\S+)/; + push @layout, { name => "$src/$1", file => fname("$src/$1"), ofs => oct($2) } if /^\s*(\S+)\s+(\S+)/; } close $s; } @@ -2577,7 +2608,7 @@ # print "$fname: $_->{ofs} ", length($buf), "\n"; } else { - die "$_->{file}: $!\n"; + die "$_->{name}: $!\n"; } } @@ -2594,6 +2625,64 @@ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# merge_options(options, new_options) +# +# Update boot options with new_options and return updated option string. +# +sub merge_options +{ + my $opts = $_[0]; + my $new_opts = $_[1]; + + # avoid tricky stuff... + if($opts =~ /"/ || $new_opts =~ /"/) { + $opts .= " $new_opts"; + } + else { + my @opts; + my %new_opts; + my @new_opts_order; + for my $n (split " ", $new_opts) { + if($n =~ /(.*?)=(.*)/) { + push @new_opts_order, $1; + $new_opts{$1} = $2; + } + else { + push @new_opts_order, $n; + $new_opts{$n} = undef; + } + } + + for my $opt (split " ", $opts) { + my $k = $opt; + $k =~ s/=.*//; + if(exists $new_opts{$k}) { + $opt = $k; + $opt .= "=$new_opts{$k}" if defined $new_opts{$k}; + delete $new_opts{$k}; + } + push @opts, $opt; + } + + for my $opt (@new_opts_order) { + my $k = $opt; + if(exists $new_opts{$opt}) { + $opt .= "=$new_opts{$opt}" if defined $new_opts{$opt}; + delete $new_opts{$k}; + push @opts, $opt; + } + } + + $opts = join ' ', @opts; + } + + print "boot options update:\n \"$_[0]\"\n+ \"$_[1]\"\n= \"$opts\"\n" if $opt_verbose >= 2; + + return $opts; +} + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # isolinux_add_option() # # Add new boot option to isolinux.cfg. @@ -2655,7 +2744,7 @@ } else { if($b) { - @f = map { chomp; $_ .= " $b" if /^\s*append\s.*initrd=/; "$_\n" } @f; + @f = map { chomp; $_ = "$1 " . merge_options($2, $b) if /^(\s*append\s.*initrd=\S+)\s(.*)/; "$_\n" } @f; } } @@ -2681,6 +2770,8 @@ my @f = <$f>; close $f; + print "updating grub2 config file: $n\n" if $opt_verbose >= 2; + # if we should add a new entry, base it loosely on the 'Installation' entry if($opt_new_boot_entry) { my $ent; @@ -2707,7 +2798,7 @@ } else { if($b) { - @f = map { chomp; $_ .= " $b" if /^\s*linux(efi)?\s/; "$_\n" } @f; + @f = map { chomp; $_ = "$1 " . merge_options($3, $b) if /^(\s*\$?linux(efi)?)\s(.*)/; "$_\n" } @f; } } @@ -2806,7 +2897,7 @@ isolinux_add_option $n, $opt_boot_options, $m; } if($boot->{$b}{bl}{grub2}) { - my $n = copy_file "$boot->{$b}{bl}{grub2}{base}/grub.cfg"; + my $n = copy_file $boot->{$b}{bl}{grub2}{config} || copy_file "$boot->{$b}{bl}{grub2}{base}/grub.cfg"; grub2_add_option $n, $opt_boot_options; } if($boot->{$b}{bl}{yaboot}) { @@ -3071,6 +3162,16 @@ my $vol_id_from_config; + if(open my $f, "<", fname("boot/grub2/grub.cfg")) { + while(<$f>) { + if(/\sroot=live:CDLABEL=(\S+)/) { + $vol_id_from_config = trim_volume_id $1; + last; + } + } + close $f; + } + if(open my $f, "<", fname("isolinux/isolinux.cfg")) { while(<$f>) { if(/append .* inst.stage2=hd:LABEL=(\S+)/) { @@ -3158,7 +3259,7 @@ # sub update_content_or_checksums { - return 0 if $media_style eq 'rh'; + return 0 if $media_style eq 'rh' || $media_variant eq 'live'; return $has_content ? update_content : update_checksums; } @@ -3748,6 +3849,10 @@ return undef; } + if(! -r $file) { + die "$orig: not readable; you need root privileges.\n"; + } + do { my $t = file_magic $file, $cmd; @@ -3983,6 +4088,9 @@ $cmd = "tar -C '$file' -cf - ."; $type = 'tar'; } + elsif(! -r $file) { + die "$file: not readable; you need root privileges.\n"; + } for (reverse split /\./, $type) { if(/^(gz|xz|zst|rpm)$/) { @@ -4751,7 +4859,7 @@ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# set_media_style(sources) +# get_media_style(sources) # # - sources: array_ref containing a list of directories # @@ -4783,6 +4891,31 @@ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# get_media_variant(sources) +# +# - sources: array_ref containing a list of directories +# +# Look at sources and determine media variant (install vs. live). +# +# Assume a Live medium if there's an '/LiveOS' dir. +# +sub get_media_variant +{ + my $src = $_[0]; + my $variant = 'install'; + + for my $s (@$src) { + if(-d "$s->{dir}/LiveOS") { + $variant = 'live'; + last; + } + } + + return $variant; +} + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # analyze_products(sources) # # sources is an array_ref containing a list of directories to be scanned and @@ -4861,7 +4994,7 @@ exit 0 if $opt_list_repos; - return if $media_style eq 'rh'; + return if $media_style eq 'rh' || $media_variant eq 'live'; # don't merge repos if the user doesn't want to return if !$opt_merge_repos; @@ -5518,3 +5651,32 @@ close $f; } } + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create_efi_image(file) +# +# - file: image file name +# +# Create FAT image of sufficient size and copy 'EFI' directory into it. +# +sub create_efi_image +{ + my $file = new_file($_[0]); + + my $efi_dir = fname "EFI"; + + return if ! $efi_dir; + + # efi image size in 512 byte blocks; giving one extra MiB free space + my $efi_size = ((split "", `du --apparent-size -x -B 1M -s $efi_dir`)[0] + 1) << 11; + + # create FAT fs + open my $fh, ">", $file; + close $fh; + truncate $file, $efi_size << 9; + system "mformat -i '$file' -s 32 -h 64 -c 1 -d 1 -v 'EFIBOOT' ::"; + + # copy files + system "mcopy -i '$file' -s -D o $efi_dir ::"; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mksusecd-2.9/mksusecd_man.adoc new/mksusecd-2.10/mksusecd_man.adoc --- old/mksusecd-2.9/mksusecd_man.adoc 2022-12-15 20:22:07.000000000 +0100 +++ new/mksusecd-2.10/mksusecd_man.adoc 2023-03-21 18:21:28.000000000 +0100 @@ -5,7 +5,7 @@ == Name -mksusecd - create and modify bootable installation media. +mksusecd - create and modify bootable media. == Synopsis @@ -15,14 +15,13 @@ == Description -mksusecd can modify or create bootable installation media. They can be +mksusecd can modify or create bootable installation or Live media. They can be either ISO images or disk images (to be used on USB sticks, for example). -Note that Live media are not supported. mksusecd supports media in both openSUSE/SLES and Fedora/RHEL layout. See Fedora/RHEL notes for details. -The main purpose is to adjust existing installation media. For example +The main purpose is to adjust existing media. For example - change boot options - add boot menu entries