Re: Dualboot-Installations fails for boot to Windows 10 after running fai

Sven Schumacher <[email protected]>
Newsgroups gmane.linux.debian.fai
Message-ID <[email protected]>
Hello Markus,

thanks for your hint regarding the PARTUUIDs.

I modified setup-storage (see attached file, Thomas, might by of 
interest) so it takes a look for preserved or resized partitions, and 
saves the PARTUUID before recreating the partition-table and setting 
them back afterwards using the mechanisms setup-storage already has.

But that doesn't help. Windows still gets a bluescreen (Errorcode 
0xc000000e) on reboot after fai-install and tries to do the "automatic 
repair" before that (before saving the PARTUUIDs the "automatic repair" 
wans't started.

the output before running setup-storage of sgdisk was (partition 4 & 5 
are created by fai, so shouldn't keep their part unique guid):

partuuids before setup-storage
         Disk info of partition 1:
Partition GUID code: C12A7328-F81F-11D2-BA4B-00A0C93EC93B (EFI system 
partition)
Partition unique GUID: FE08D6AE-2648-11EC-9CA9-806E6F6E6963
First sector: 2048 (at 1024.0 KiB)
Last sector: 204800 (at 100.0 MiB)
Partition size: 202753 sectors (99.0 MiB)
Attribute flags: 0000000000000000
Partition name: 'primary'
         Disk info of partition 2:
Partition GUID code: E3C9E316-0B5C-4DB8-817D-F92DF00215AE (Microsoft 
reserved)
Partition unique GUID: FE08D6AF-2648-11EC-9CA9-806E6F6E6963
First sector: 206848 (at 101.0 MiB)
Last sector: 468991 (at 229.0 MiB)
Partition size: 262144 sectors (128.0 MiB)
Attribute flags: 0000000000000000
Partition name: 'primary'
         Disk info of partition 3:
Partition GUID code: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 (Microsoft 
basic data)
Partition unique GUID: 95BAE942-B396-47EE-B5C3-A00BC349D877
First sector: 468992 (at 229.0 MiB)
Last sector: 840382463 (at 400.7 GiB)
Partition size: 839913472 sectors (400.5 GiB)
Attribute flags: 0000000000000000
Partition name: 'primary'
         Disk info of partition 6:
Partition GUID code: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 (Microsoft 
basic data)
Partition unique GUID: 1287D7DE-E2D8-43EC-9358-2E5AF80B56DA
First sector: 978794496 (at 466.7 GiB)
Last sector: 1000215182 (at 476.9 GiB)
Partition size: 21420687 sectors (10.2 GiB)
Attribute flags: 0000000000000000
Partition name: 'primary'


and afterwards:

partuuids after setup-storage
         Disk info of partition 1:
Partition GUID code: C12A7328-F81F-11D2-BA4B-00A0C93EC93B (EFI system 
partition)
Partition unique GUID: FE08D6AE-2648-11EC-9CA9-806E6F6E6963
First sector: 2048 (at 1024.0 KiB)
Last sector: 204800 (at 100.0 MiB)
Partition size: 202753 sectors (99.0 MiB)
Attribute flags: 0000000000000000
Partition name: 'primary'
         Disk info of partition 2:
Partition GUID code: E3C9E316-0B5C-4DB8-817D-F92DF00215AE (Microsoft 
reserved)
Partition unique GUID: FE08D6AF-2648-11EC-9CA9-806E6F6E6963
First sector: 206848 (at 101.0 MiB)
Last sector: 468991 (at 229.0 MiB)
Partition size: 262144 sectors (128.0 MiB)
Attribute flags: 0000000000000000
Partition name: 'primary'
         Disk info of partition 3:
Partition GUID code: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 (Microsoft 
basic data)
Partition unique GUID: 95BAE942-B396-47EE-B5C3-A00BC349D877
First sector: 468992 (at 229.0 MiB)
Last sector: 840382463 (at 400.7 GiB)
Partition size: 839913472 sectors (400.5 GiB)
Attribute flags: 0000000000000000
Partition name: 'primary'
         Disk info of partition 6:
Partition GUID code: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 (Microsoft 
basic data)
Partition unique GUID: 1287D7DE-E2D8-43EC-9358-2E5AF80B56DA
First sector: 978794496 (at 466.7 GiB)
Last sector: 1000215182 (at 476.9 GiB)
Partition size: 21420687 sectors (10.2 GiB)
Attribute flags: 0000000000000000
Partition name: 'primary'

So here doesn't it seem to matter...

Any more hints?

Thanks in advance

Sven


Am 04.10.21 um 20:29 schrieb Markus Köberl:
> On Monday, 4 October 2021 12:34:35 CEST Sven Schumacher wrote:
>
>> What does setup-storage do (or the used programs behind that tool), that
>> the windows-bootloader can't find the C: partition after using fai?
> setup-storage recreates the partition table. therefore the partition table and
> all partitions get different ids.
> at least with MS-DOS partition table this was the case for the partition id,
> with GPT partition table I never searched what exactly is necessary.
>
> I am using a mountdisks hook to restore the ids using sgdisk.
>
>> Thanks for any input... If I didn't find the solution I have to boot 140
>> PCs with Windows-USB-Stick to type the bcdedit lines mentioned above...
> I do have a windows 10 image which I restore on all my laboratory hosts.
> after the restore I mount the C: partition and edit the registry using chntpw
> to replace the hostname.
>
> If you are interested I can give you my scripts (which are very particular to
> my system) but they might help you finding a solution.
>
>
> regards
> Markus Köberl


-- 
Sven Schumacher                       Tel: (0511)762-2753
Leibniz Universitaet Hannover
Fakultät für Maschinenbau, Head of Systemadministration
An der Universität 1 - 30823 Garbsen

Institut für Turbomaschinen und Fluid-Dynamik       - TFD
Institut für Kraftwerkstechnik und Wärmeübertragung - IKW
Institut für Technische Verbrennung                 - ITV
setup-storage (text/plain, 12.8 KB)
#!/usr/bin/perl -w

#*********************************************************************
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 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
# General Public License for more details.
#
# A copy of the GNU General Public License is available as
# `/usr/share/common-licences/GPL' in the Debian GNU/Linux distribution
# or on the World Wide Web at http://www.gnu.org/copyleft/gpl.html. You
# can also obtain it by writing to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#*********************************************************************

use strict;

# treat all warnings about uninitialised values as errors
use warnings FATAL => qw(uninitialized);

################################################################################
#
# @file setup-storage
#
# @brief The main function of setup-storage - the tool to configure the
# partitioning from within FAI.
#
# This is an implementation from scratch to properly support LVM and RAID. The
# input format is documented in @ref parser.pm
#
# Some (developer) documentation may be found on
# https://wiki.fai-project.org/index.php/Setup-storage
#
# Some coding conventions:
# - no whitespace after ( and before )
# - keyword<whitespace>(...)
# - do not start a new line for {
# - } goes on a line on its own
# - one blank line after sub ...
#
# $Id$
#
# @author Christian Kern, Michael Tautschnig
# @date Sun Jul 23 16:09:36 CEST 2006
#
################################################################################

package FAI;

my $version = "2.3";
$|=1;

# command line parameter handling
use Getopt::Std;
$main::VERSION = $version;
$Getopt::Std::STANDARD_HELP_VERSION = 1;
our ($opt_X, $opt_f, $opt_h, $opt_d, $opt_s, $opt_D, $opt_L,$opt_y); # the variables for getopt
(&getopts('Xf:hdsD:L:y') && !$opt_h) || die <<EOF;
setup-storage version $version

USAGE: [-X]                     no test, your harddisks will be formated
                                default: only test, no real formating
       [-f<config-filename>]    default: parse classes
       [-d]                     enable debug output (equivalent to debug=1)
       [-s]                     perform syntax check only and exit
       [-D<disks>]              override disklist variable by space-separated <disks>
       [-L<logdir>]             use <logdir> instead of LOGDIR variable
       [-h]                     print this help message
       [-y]                     print disk variables as YAML file into disk_var.yml
EOF

# include all subparts, which are part of the FAI perl package
use lib "/usr/share/fai/setup-storage/";
use Init;
use Volumes;
use Parser;
use Sizes;
use Commands;
use Fstab;
use Exec;

sub prtdebug {

  # for debugging purposes to print the hash structures
  use Data::Dumper;

  print "Current disk layout in \%current_config\n";
  print Dumper \%FAI::current_config;

  print "Current LVM layout in \%current_lvm_config\n";
  print Dumper \%FAI::current_lvm_config;

  print "Current RAID layout in \%current_raid_config\n";
  print Dumper \%FAI::current_raid_config;

  print "Current device tree in \%current_dev_children\n";
  print Dumper \%FAI::current_dev_children;
}

# enable debug mode, if requested using -d
$opt_d and $FAI::debug = 1;

# Really write any changes to disk
$opt_X and $FAI::no_dry_run = 1;
warn "setup-storage is running in test-only mode\n" unless ($FAI::no_dry_run);

# syntactic checks only
$opt_s and $FAI::check_only = 1;

# Find out whether $LOGDIR is usable or default to /tmp/fai
$opt_L and $FAI::DATADIR = $opt_L;
if (! -d $FAI::DATADIR) {
  !defined($opt_L) and defined ($ENV{LOGDIR}) and die
    "Environment variable LOGDIR is set, but $FAI::DATADIR is not a directory\n";
  mkdir $FAI::DATADIR or die
    "Failed to create directory $FAI::DATADIR\n";
  warn "Created data directory $FAI::DATADIR\n";
}

# $disklist may be provided by the environment
my $disklist = $ENV{disklist};
$opt_D and $disklist = $opt_D;
if (! defined($disklist)) {
  &FAI::in_path("/usr/lib/fai/fai-disk-info") or die "/usr/lib/fai/fai-disk-info not found\n";
  $disklist = `/usr/lib/fai/fai-disk-info | sort`;
}

@FAI::disks = split( /[\n ]/, $disklist);
if ($FAI::debug) {
  print "disklist: ";
  print "$_\n" foreach(@FAI::disks);
}
warn "No disks defined in \$disklist\n" unless (@FAI::disks);

# the config source file
my $config_file = undef;
# use the config file, if given
open($config_file, $opt_f) or die "Failed to open config file $opt_f\n" if ($opt_f);
unless ($opt_f) {
  defined ($ENV{classes}) or
    die "Environment variable classes is not set and -f was not given\n";
  # see which class file to use
  foreach my $classfile (reverse split(/\s+/, $ENV{classes})) {
    next unless (-r "$ENV{FAI}/disk_config/$classfile");
    open($config_file, "$ENV{FAI}/disk_config/$classfile")
      or die "Failed to open $ENV{FAI}/disk_config/$classfile\n";
    $opt_f = "$ENV{FAI}/disk_config/$classfile";
    last;
  }
}

# if we could not find any matching class file, bail out
defined ($config_file) or die "No matching disk_config found\n";

# start the parsing - thereby $FAI::configs is filled
warn "Starting setup-storage $version\n";
print "Using config file: $opt_f\n";
&FAI::run_parser($config_file);

# make sure there are no empty disk_config stanzas
&FAI::check_config;

if ($FAI::check_only) {
  print "Syntax ok\n";
  exit 0;
}

# first find the proper way to tell udev to settle
$FAI::udev_settle = "udevadm settle --timeout=10" if (&FAI::in_path("udevadm"));
$FAI::udev_settle = "udevsettle --timeout=10" if (&FAI::in_path("udevsettle"));
defined($FAI::udev_settle) or die "Failed to find determine a proper way to tell udev to settle; is udev installed?";

# start all RAID arrays in case some of the aren't running yet
&FAI::in_path("mdadm-startall") and `mdadm-startall`;
`$FAI::udev_settle`;

# read the sizes and partition tables of all disks listed in $FAI::disks
&FAI::get_current_disks;

# see whether there are any existing LVMs
$FAI::uses_lvm and &FAI::in_path("pvdisplay") and &FAI::get_current_lvm;

# see whether there are any existing RAID devices
$FAI::uses_raid and &FAI::in_path("mdadm") and &FAI::get_current_raid;

# mark devices as preserve, where not all already done so and check that only
# defined devices are marked preserve
&FAI::propagate_and_check_preserve;

################################################################################
# 
# @brief get partuuid for specified partition
#
# Added by Sven Schumacher, 2021-10-04
################################################################################
sub find_partuuid {
	my ($device_name,$missing) = @_;
	my $partuuid=`/usr/sbin/blkid -s PARTUUID -o value $device_name`;
	chomp($partuuid);
	return $partuuid;
}


################################################################################
#
# @brief build commands for restoring old partuuids for preserved partitions
#
# Added by Sven Schumacher, 2021-10-04
# ##############################################################################
sub build_partuuids_commands() {
  my $setpartuuid_tool="/usr/sbin/sgdisk";
  foreach my $disk (keys(%FAI::configs)) {
	  if ($disk=~m/PHY_(.*)/) {
		  my $device_name=$1;
		  if (defined $FAI::configs{$disk}->{'partitions'}) {
			  my %part=%{$FAI::configs{$disk}->{'partitions'}};
			  foreach my $part_no (keys(%part)) {
				if (defined($part{$part_no}->{OLDPARTUUID})) {
					my $prereqs = "exist_$device_name$part_no";
					my $desired_partuuid=$part{$part_no}->{OLDPARTUUID};
					my $setpartuuid_tool_options="--partition-guid=".$part_no.":".$desired_partuuid;
					my $provides = "has_restoredpartuuid_$device_name$part_no";
					&FAI::push_command( "$setpartuuid_tool $setpartuuid_tool_options $device_name", $prereqs, $provides);
				}
			  }
		  }
			
	  }
  }
}

###### Sven Schumacher, 2021-10-04
# Added for retaining partuuid
#
######
sub retain_partuuids {
  use Data::Dumper;
  $FAI::debug and print Dumper \%FAI::configs;
  # loop through %FAI::configs looking for preserved partitions
  foreach my $disk (keys(%FAI::configs)) {
	  if ($disk=~m/PHY_(.*)/) {
		  my $device_name=$1;
		  if (defined $FAI::configs{$disk}->{'partitions'}) {
			  my %part=%{$FAI::configs{$disk}->{'partitions'}};
			  foreach my $part_no (keys(%part)) {
				if ($part{$part_no}->{size}->{preserve}==1 || $part{$part_no}->{size}->{resize}==1) {
					$part{$part_no}->{OLDPARTUUID}=&FAI::find_partuuid($device_name.$part_no);
				}
			  }
		  }
			
	  }
  }
  $FAI::debug and print Dumper \%FAI::configs;
}

# debugging only: print the current configuration
if ($FAI::debug) {
  use Data::Dumper;
  prtdebug;
}

# compute the new LVM and partition sizes; do the partition sizes first to have
# them available for the the volume group size estimation
&FAI::compute_partition_sizes;
&FAI::compute_lv_sizes;

# print the current contents of $FAI::configs
$FAI::debug and print "Desired disk layout in %FAI::configs\n";
$FAI::debug and print Dumper \%FAI::configs;
$FAI::debug and print "Desired device tree in %FAI::dev_children\n";
$FAI::debug and print Dumper \%FAI::dev_children;

# generate the command script
&FAI::get_parted_version;
&FAI::retain_partuuids;           #### Sven Schumacher, 2021-10-04
&FAI::build_disk_commands;
$FAI::uses_raid and &FAI::build_raid_commands;
&FAI::build_btrfs_commands;
$FAI::uses_lvm and &FAI::build_lvm_commands;
&FAI::build_cryptsetup_commands;
&FAI::build_partuuids_commands;   #### Sven Schumacher, 2021-10-04
&FAI::order_commands;

# run all commands
# debugging only: print the command script
if ($FAI::debug) {
  foreach (&numsort(keys %FAI::commands)) {
    defined($FAI::commands{$_}{cmd}) or &FAI::internal_error("Missing command entry for $_");
    print "$_:" . $FAI::commands{$_}{cmd} . "\n";
    defined($FAI::commands{$_}{pre}) and print "\tpre: " . $FAI::commands{$_}{pre} . "\n";
    defined($FAI::commands{$_}{post}) and print "\tpost: " . $FAI::commands{$_}{post} . "\n";
  }
}

# run the commands (if $FAI::no_dry_run is set)
foreach (&numsort(keys %FAI::commands)) {
  `$FAI::udev_settle`;
  next if ($FAI::commands{$_}{cmd} eq "true");
  &FAI::execute_command($FAI::commands{$_}{cmd});
}

# generate the proposed fstab contents
# wait for udev to set up all devices
`$FAI::udev_settle`;
my @fstab = &FAI::generate_fstab(\%FAI::configs);

# print fstab
$FAI::debug and print "$_\n" foreach (@fstab);

# write the proposed contents of fstab to $FAI::DATADIR/fstab
if ($FAI::no_dry_run) {
  open(FSTAB, ">$FAI::DATADIR/fstab")
    or die "Failed to open $FAI::DATADIR/fstab for writing\n";
  print FSTAB "$_\n" foreach (@fstab);
  close FSTAB;
}

# write variables to $FAI::DATADIR/disk_var.sh
# debugging
$FAI::debug and print "$_=\${$_:-$FAI::disk_var{$_}}\n"
  foreach (keys %FAI::disk_var);

if ($FAI::no_dry_run) {
  # List all bootable devices. Can be used by later tasks to install a
  # boot loader. Using Variable PHYSICAL_BOOT_DEVICES.
  my @boot_devices;
  foreach (keys %FAI::configs) {
    $_ =~ /PHY_(.+)/;
    if ( $1 && defined $FAI::configs{$_}{'bootable'}
      &&  $FAI::configs{$_}{'bootable'} > 0 )  {
      push @boot_devices, $1;
    }
  }
  @boot_devices = sort @boot_devices;

  open(DISK_VAR, ">$FAI::DATADIR/disk_var.sh")
    or die "Unable to write to file $FAI::DATADIR/disk_var.sh\n";
  print DISK_VAR "$_=\${$_:-$FAI::disk_var{$_}}\n" foreach (keys %FAI::disk_var);
  print DISK_VAR "PHYSICAL_BOOT_DEVICES=\"", join(" ", @boot_devices), "\"\n";
  close DISK_VAR;

  if ($opt_y) {
    open(DISK_YML, ">$FAI::DATADIR/disk_var.yml")
      or die "Unable to write to file $FAI::DATADIR/disk_var.yml\n";

    print DISK_YML "---\n# disk_var.sh as YAML\n";
    foreach (keys %FAI::disk_var) {
      $FAI::disk_var{$_} =~ s/"//g;
      if ( $FAI::disk_var{$_} =~ m/\s/ ) {
	# print an array
	print DISK_YML "$_:\n";
	my $a = join("\n  - ", split(/ /,$FAI::disk_var{$_}));
	print DISK_YML "  - $a\n";
      } else {
	print DISK_YML "$_: $FAI::disk_var{$_}\n";
      }
    }
    print DISK_YML "PHYSICAL_BOOT_DEVICES:\n";
    my $a = join("\n  - ", @boot_devices);
    print DISK_YML "  - $a\n";
    close DISK_YML;
  }
}

# print crypttab
$FAI::debug and print "$_\n" foreach (@FAI::crypttab);

# write the proposed contents of fstab to $FAI::DATADIR/fstab
if ($FAI::no_dry_run && scalar(@FAI::crypttab)) {
  open(CRYPTTAB, ">$FAI::DATADIR/crypttab")
    or die "Failed to open $FAI::DATADIR/crypttab for writing\n";
  print CRYPTTAB "$_\n" foreach (@FAI::crypttab);
  close CRYPTTAB;
}


# at the end print the whole config again
if ($FAI::debug) {
  print "==========================================\n";
  print "=  Variables at the end of setup-storage =\n";
  print "==========================================\n";
  prtdebug;
}
smime.p7s (application/pkcs7-signature, 5.3 KB) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.