Dualboot-Installations fails for boot to Windows 10 after running fai
Sven Schumacher
schumacher at tfd.uni-hannover.de
Tue Oct 5 19:41:27 CEST 2021
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
-------------- next part --------------
#!/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;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5391 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.uni-koeln.de/pipermail/linux-fai/attachments/20211005/5b24aa9e/attachment.p7s>
More information about the linux-fai
mailing list