[Fai-commit] r4881 - in people/michael/features/setup_harddisks_2/implementation: . lib
mt at alioth.debian.org
mt at alioth.debian.org
Fri May 9 09:49:45 UTC 2008
Author: mt
Date: 2008-05-09 09:49:44 +0000 (Fri, 09 May 2008)
New Revision: 4881
Modified:
people/michael/features/setup_harddisks_2/implementation/lib/commands.pm
people/michael/features/setup_harddisks_2/implementation/lib/exec.pm
people/michael/features/setup_harddisks_2/implementation/lib/fstab.pm
people/michael/features/setup_harddisks_2/implementation/lib/init.pm
people/michael/features/setup_harddisks_2/implementation/lib/parser.pm
people/michael/features/setup_harddisks_2/implementation/lib/sizes.pm
people/michael/features/setup_harddisks_2/implementation/lib/volumes.pm
people/michael/features/setup_harddisks_2/implementation/setup-storage
Log:
- cleanup of cciss/i2o/... handling
- most probably buggy: handling dependencies between various commands
Modified: people/michael/features/setup_harddisks_2/implementation/lib/commands.pm
===================================================================
--- people/michael/features/setup_harddisks_2/implementation/lib/commands.pm 2008-05-05 16:31:12 UTC (rev 4880)
+++ people/michael/features/setup_harddisks_2/implementation/lib/commands.pm 2008-05-09 09:49:44 UTC (rev 4881)
@@ -59,12 +59,22 @@
$create_options = $partition->{fs_options} unless $create_options;
print "create_options: $create_options\n" if ($FAI::debug && $create_options);
print "tune_options: $tune_options\n" if ($FAI::debug && $tune_options);
+
+ # check for encryption requests
+ $device = &FAI::encrypt_device($device, $partition);
# create the file system with options
my $create_tool = "mkfs.$fs";
($fs eq "swap") and $create_tool = "mkswap";
($fs eq "xfs") and $create_options = "$create_options -f" unless ($create_options =~ m/-f/);
- push @FAI::commands, "$create_tool $create_options $device";
+ my $pre_encrypt = "exist_$device";
+ $pre_encrypt = "encrypt_$device" if ($partition->{encrypt});
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "$create_tool $create_options $device",
+ pre => $pre_encrypt,
+ post => "has_fs_$device"
+ };
+ $FAI::n_c_i++;
# possibly tune the file system - this depends on whether the file system
# supports tuning at all
@@ -74,11 +84,13 @@
($fs eq "reiserfs") and $tune_tool = "reiserfstune";
die "Don't know how to tune $fs\n" unless $tune_tool;
- # check for encryption requests
- $device = &FAI::encrypt_device($device, $partition);
-
- # add the mkfs command
- push @FAI::commands, "$tune_tool $tune_options $device";
+ # add the tune command
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "$tune_tool $tune_options $device",
+ pre => "has_fs_$device",
+ post => "has_fs_$device"
+ };
+ $FAI::n_c_i++;
}
################################################################################
@@ -105,11 +117,26 @@
my $keyfile = "$ENV{LOGDIR}/$enc_dev_short_name";
# generate a key for encryption
- push @FAI::commands, "head -c 2048 /dev/urandom | head -n 47 | tail -n 46 | od | tee $keyfile";
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "head -c 2048 /dev/urandom | head -n 47 | tail -n 46 | od | tee $keyfile",
+ pre => "",
+ post => "keyfile_$device"
+ };
+ $FAI::n_c_i++;
# prepare encryption
- push @FAI::commands, "yes YES | cryptsetup luksFormat $device $keyfile -c aes-cbc-essiv:sha256 -s 256";
- push @FAI::commands, "cryptsetup luksOpen $device $enc_dev_short_name --key-file $keyfile";
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "yes YES | cryptsetup luksFormat $device $keyfile -c aes-cbc-essiv:sha256 -s 256",
+ pre => "exist_$device,keyfile_$device",
+ post => "crypt_format_$device"
+ };
+ $FAI::n_c_i++;
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "cryptsetup luksOpen $device $enc_dev_short_name --key-file $keyfile",
+ pre => "crypt_format_$device",
+ post => "encrypted_$device"
+ };
+ $FAI::n_c_i++;
# add entries to crypttab
push @FAI::crypttab, "$enc_dev_short_name\t$device\t$keyfile\tluks";
@@ -129,19 +156,18 @@
sub set_partition_type_on_phys_dev {
my ($d, $t) = @_;
- # only match physical partitions (this string of matchings is hopefully complete)
- return unless($d =~
- m{^/dev/(i2o/hd[a-t]|cciss/c\dd\dp|ida/c\dd\dp|rd/c\dd\dp|ataraid/d\dp|sd[a-t]|hd[a-t])(\d+)$});
- my $disk = "/dev/$1";
- my $part_no = $2;
- # in case the name was /dev/cciss/c0d1p or the like, remove the trailing
- # p to get the disk name
- $disk =~ s/(\d)p$/$1/;
+ my ($i_p_d, $disk, $part_no) = &FAI::phys_dev($d);
+ return unless $i_p_d;
# make sure this device really exists (we can't check for the partition
# as that may be created later on
(-b $disk) or die "Specified disk $disk does not exist in this system!\n";
# set the raid flag
- push @FAI::commands, "parted -s $disk set $part_no $t on";
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "parted -s $disk set $part_no $t on",
+ pre => "exist_$d",
+ post => "type_${t}_$d"
+ };
+ $FAI::n_c_i++;
}
################################################################################
@@ -172,6 +198,7 @@
my @devs = keys %{ $vol->{devices} };
my @eff_devs = ();
my @spares = ();
+ my $pre_req;
# set proper partition types for RAID
foreach my $d (@devs) {
@@ -183,15 +210,36 @@
# skip devices marked missing
next if $vol->{devices}{$d}{missing};
&FAI::set_partition_type_on_phys_dev($d, "raid");
+ if ((&FAI::phys_dev($d))[0]) {
+ $pre_req .= ",type_raid_$d";
+ } else {
+ $pre_req .= ",exist_$d";
+ }
}
+ my $pre_req_no_comma = $pre_req;
+ $pre_req_no_comma =~ s/^,//;
# wait for udev to set up all devices
- push @FAI::commands, "udevsettle --timeout=10";
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "udevsettle --timeout=10",
+ pre => $pre_req_no_comma,
+ post => "settle_for_mdadm_create$id"
+ };
+ $FAI::n_c_i++;
# create the command
- push @FAI::commands,
- "yes | mdadm --create /dev/md$id --level=$level --force --run --raid-devices="
- . scalar(@eff_devs) . " --spare-devices=" . scalar(@spares) . " "
- . join(" ", @eff_devs) . " " . join(" ", @spares);
+ if (0 == $id) {
+ $pre_req = "settle_for_mdadm_create$id$pre_req";
+ } else {
+ $pre_req = "settle_for_mdadm_create$id,exist_/dev/md" . ( $id - 1 ) . $pre_req;
+ }
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "yes | mdadm --create /dev/md$id --level=$level --force --run --raid-devices="
+ . scalar(@eff_devs) . " --spare-devices=" . scalar(@spares) . " "
+ . join(" ", @eff_devs) . " " . join(" ", @spares),
+ pre => "$pre_req",
+ post => "exist_/dev/md$id"
+ };
+ $FAI::n_c_i++;
# create the filesystem on the volume
&FAI::build_mkfs_commands("/dev/md$id",
@@ -217,7 +265,12 @@
# foreach ( @{$devices_aref} );
my $device_list = join (" ", @{$devices_aref});
$FAI::debug and print "Erased devices: $device_list\n";
- push @FAI::commands, "pvremove -ff -y $device_list";
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "pvremove -ff -y $device_list",
+ pre => "",
+ post => "pv_sigs_removed"
+ };
+ $FAI::n_c_i++;
# reload module
# push @FAI::commands, "modprobe dm_mod";
@@ -242,9 +295,23 @@
# create all the devices
my @devices = keys %{ $FAI::configs{$config}{devices} };
&FAI::erase_lvm_signature(\@devices);
- push @FAI::commands, "pvcreate $_" foreach (@devices);
+ foreach (@devices) {
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "pvcreate $_",
+ pre => "pv_sigs_removed,exist_$_",
+ post => "pv_done_$_"
+ };
+ $FAI::n_c_i++;
+ }
# create the volume group
- push @FAI::commands, "vgcreate $vg " . join (" ", @devices);
+ my $pre_dev = join(",pv_done_", @devices);
+ $pre_dev =~ s/^,//;
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "vgcreate $vg " . join (" ", @devices),
+ pre => "$pre_dev",
+ post => "vg_created_$vg"
+ };
+ $FAI::n_c_i++;
# we are done
return;
}
@@ -262,10 +329,24 @@
# &FAI::erase_lvm_signature( \@new_devices );
# create all the devices
- push @FAI::commands, "pvcreate $_" foreach (@new_devices);
+ foreach (@new_devices) {
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "pvcreate $_",
+ pre => "exist_$_",
+ post => "pv_done_$_"
+ };
+ $FAI::n_c_i++;
+ }
# extend the volume group by the new devices (includes the current ones)
- push @FAI::commands, "vgextend $vg " . join(" ", @new_devices);
+ my $pre_dev = join(",pv_done_", @new_devices);
+ $pre_dev =~ s/^,//;
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "vgextend $vg " . join (" ", @new_devices),
+ pre => "$pre_dev",
+ post => "vg_extended_$vg"
+ };
+ $FAI::n_c_i++;
# the devices to be removed
my %rm_devs = ();
@@ -275,7 +356,22 @@
delete $rm_devs{$_} foreach (@new_devices);
# run vgreduce to get them removed
- push @FAI::commands, "vgreduce $vg " . join(" ", keys %rm_devs) if (scalar (keys %rm_devs));
+ if (scalar (keys %rm_devs)) {
+ $pre_dev = join(",pv_done_", keys %rm_devs);
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "vgreduce $vg " . join (" ", keys %rm_devs),
+ pre => "vg_extended_$vg$pre_dev",
+ post => "vg_created_$vg"
+ };
+ $FAI::n_c_i++;
+ } else {
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "true",
+ pre => "vg_extended_$vg",
+ post => "vg_created_$vg"
+ };
+ $FAI::n_c_i++;
+ }
}
################################################################################
@@ -292,16 +388,29 @@
($config =~ /^VG_(.+)$/) or &FAI::internal_error("Invalid config $config");
my $vg = $1; # the actual volume group
+ my $lv_rm_pre = "";
+ my $lv_resize_pre = "";
# remove, resize, create the logical volumes
# remove all volumes that do not exist anymore or need not be preserved
foreach my $lv (keys %{ $FAI::current_lvm_config{$vg}{volumes} }) {
# skip preserved/resized volumes
- next if (defined ( $FAI::configs{$config}{volumes}{$lv})
- && ($FAI::configs{$config}{volumes}{$lv}{size}{preserve} == 1
- || $FAI::configs{$config}{volumes}{$lv}{size}{resize}));
+ if (defined ( $FAI::configs{$config}{volumes}{$lv})
+ && ($FAI::configs{$config}{volumes}{$lv}{size}{preserve} == 1)) {
+ $lv_resize_pre .= ",lv_resize_$vg/$lv" if
+ $FAI::configs{$config}{volumes}{$lv}{size}{resize};
+ next;
+ }
- push @FAI::commands, "lvremove -f $vg/$lv";
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "lvremove -f $vg/$lv",
+ pre => "vg_enabled_$vg",
+ post => "lv_rm_$vg/$lv"
+ };
+ $FAI::n_c_i++;
+ $lv_rm_pre .= ",lv_rm_$vg/$lv";
}
+ $lv_rm_pre =~ s/^,//;
+ $lv_resize_pre =~ s/^,//;
# now create or resize the configured logical volumes
foreach my $lv (keys %{ $FAI::configs{$config}{volumes} }) {
@@ -319,15 +428,48 @@
defined ($FAI::current_lvm_config{$vg}{volumes}{$lv})
or die "Resized volume $vg/$lv does not exist\n";
- # note that resizing a volume destroys the data on it
- push @FAI::commands,
- "lvresize -L " . $lv_size->{eff_size} . " $vg/$lv";
+ if ($lv_size->{eff_size} <
+ $FAI::current_lvm_config{$vg}{volumes}{$lv}{size})
+ {
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "parted -s /dev/$vg/$lv resize 1 0 " . $lv_size->{eff_size} . "B",
+ pre => "vg_enabled_$vg,$lv_rm_pre",
+ post => "lv_shrink_$vg/$lv"
+ };
+ $FAI::n_c_i++;
+
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "lvresize -L " . $lv_size->{eff_size} . " $vg/$lv",
+ pre => "vg_enabled_$vg,$lv_rm_pre,lv_shrink_$vg/$lv",
+ post => "lv_created_$vg/$lv"
+ };
+ $FAI::n_c_i++;
+ } else {
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "lvresize -L " . $lv_size->{eff_size} . " $vg/$lv",
+ pre => "vg_enabled_$vg,$lv_rm_pre",
+ post => "lv_grow_$vg/$lv"
+ };
+ $FAI::n_c_i++;
+
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "parted -s /dev/$vg/$lv resize 1 0 " . $lv_size->{eff_size} . "B",
+ pre => "vg_enabled_$vg,$lv_rm_pre,lv_grow_$vg/$lv",
+ post => "exist_/dev/$vg/$lv"
+ };
+ $FAI::n_c_i++;
+ }
+
next;
}
# create a new volume
- push @FAI::commands,
- "lvcreate -n $lv -L " . $lv_size->{eff_size} . " $vg";
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "lvcreate -n $lv -L " . $lv_size->{eff_size} . " $vg",
+ pre => "vg_enabled_$vg,$lv_rm_pre",
+ post => "exist_/dev/$vg/$lv"
+ };
+ $FAI::n_c_i++;
# create the filesystem on the volume
&FAI::build_mkfs_commands("/dev/$vg/$lv",
@@ -355,13 +497,25 @@
# set proper partition types for LVM
&FAI::set_partition_type_on_phys_dev($_, "lvm")
foreach (keys %{ $FAI::configs{$config}{devices} });
+ my $type_pre = join(",type_lvm_", keys %{ $FAI::configs{$config}{devices} });
+ $type_pre =~ s/^,//;
# wait for udev to set up all devices
- push @FAI::commands, "udevsettle --timeout=10";
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "udevsettle --timeout=10",
+ pre => "$type_pre",
+ post => "settle_for_vgchange_$vg"
+ };
+ $FAI::n_c_i++;
# create the volume group or add/remove devices
&FAI::create_volume_group($config);
# enable the volume group
- push @FAI::commands, "vgchange -a y $vg";
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "vgchange -a y $vg",
+ pre => "settle_for_vgchange_$vg,vg_created_$vg",
+ post => "vg_enabled_$vg"
+ };
+ $FAI::n_c_i++;
# perform all necessary operations on the underlying logical volumes
&FAI::setup_logical_volumes($config);
@@ -536,9 +690,16 @@
$part_nr++;
$FAI::current_config{$disk}{partitions}{$mapped_id}{new_id} = $part_nr;
+ my $post = "exist_" . &FAI::make_device_name($disk, $part_nr);
+ $post = "rebuilt_" . &FAI::make_device_name($disk, $part_nr) if
+ $FAI::configs{$config}{partitions}{$part_id}{size}{resize};
# build a parted command to create the partition
- push @FAI::commands,
- "parted -s $disk mkpart $part_type $fs ${start}B ${end}B";
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "parted -s $disk mkpart $part_type $fs ${start}B ${end}B",
+ pre => "cleared1_$disk",
+ post => $post
+ };
+ $FAI::n_c_i++;
}
}
@@ -567,46 +728,75 @@
or die "Can't change disklabel, partitions are to be preserved\n";
# write the disklabel to drop the previous partition table
- push @FAI::commands, "parted -s $disk mklabel "
- . $FAI::configs{$config}{disklabel};
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "parted -s $disk mklabel " . $FAI::configs{$config}{disklabel},
+ pre => "exist_$disk",
+ post => "cleared1_$disk"
+ };
+ $FAI::n_c_i++;
&FAI::rebuild_preserved_partitions($config, \@to_preserve);
- # resize partitions; first we shrink partitions, then grow others;
- # furthermore we start from the end to shrink logical partitions before
- # the extended one, but grow partitions starting from the beginning
- my @shrink_list = ();
- my @grow_list = ();
+ my $pre_all_resize = "";
- # iterate over the worklists
+ # resize partitions while checking for dependencies
foreach my $part_id (reverse sort { $a <=> $b } (@to_preserve)) {
# reference to the current partition
my $part = (\%FAI::configs)->{$config}->{partitions}->{$part_id};
+ # get the existing id
+ my $mapped_id = $part->{maps_to_existing};
+ # get the intermediate partition id
+ my $p = $FAI::current_config{$disk}{partitions}{$mapped_id}{new_id};
# anything to be done?
+ $pre_all_resize .= ",exist_" . &FAI::make_device_name($disk, $p) unless
+ $part->{size}->{resize};
next unless $part->{size}->{resize};
- # get the existing id
- my $mapped_id = $part->{maps_to_existing};
-
- # if partition is to be grown, move it to then grow_list
- if ( $part->{size}->{eff_size} >
- $FAI::current_config{$disk}{partitions}{$mapped_id}{count_byte} ) {
- unshift @grow_list, $part_id;
- } else {
- push @shrink_list, $part_id;
+ $pre_all_resize .= ",resized_" . &FAI::make_device_name($disk, $p);
+ my $deps = "";
+ # now walk all other partitions requiring a resize to check for overlaps
+ foreach my $part_other (reverse sort { $a <=> $b } (@to_preserve)) {
+ # don't compare to self
+ next if ($part_id == $part_other);
+ # reference to the current partition
+ my $part_other_ref = (\%FAI::configs)->{$config}->{partitions}->{$part_other};
+ # anything to be done?
+ next unless $part_other_ref->{size}->{resize};
+ # get the existing id
+ my $mapped_id_other = $part_other_ref->{maps_to_existing};
+ # get the intermediate partition id
+ my $p_other = $FAI::current_config{$disk}{partitions}{$mapped_id_other}{new_id};
+ # check for overlap
+ next if($part->{begin_byte} >
+ $FAI::current_config{$disk}{partitions}{$mapped_id_other}{end_byte});
+ next if($part->{end_byte} <
+ $FAI::current_config{$disk}{partitions}{$mapped_id_other}{begin_byte});
+ # overlap detected - add dependency, but handle extended<->logical with
+ # special care, even though this does not catch all cases (sometimes it
+ # will fail nevertheless
+ if ($part->{size}->{extended} && $part_other > 4) {
+ if($part->{begin_byte} >
+ $FAI::current_config{$disk}{partitions}{$mapped_id_other}{begin_byte}) {
+ $deps .= ",resized_" . &FAI::make_device_name($disk, $p_other);
+ }
+ elsif($part->{end_byte} <
+ $FAI::current_config{$disk}{partitions}{$mapped_id_other}{end_byte}) {
+ $deps .= ",resized_" . &FAI::make_device_name($disk, $p_other);
+ }
+ }
+ elsif ($part_id > 4 && $part_other_ref->{size}->{extended}) {
+ if($part->{begin_byte} <
+ $FAI::current_config{$disk}{partitions}{$mapped_id_other}{begin_byte}) {
+ $deps .= ",resized_" . &FAI::make_device_name($disk, $p_other);
+ }
+ elsif($part->{end_byte} >
+ $FAI::current_config{$disk}{partitions}{$mapped_id_other}{end_byte}) {
+ $deps .= ",resized_" . &FAI::make_device_name($disk, $p_other);
+ }
+ } else {
+ $deps .= ",resized_" . &FAI::make_device_name($disk, $p_other);
+ }
}
- }
-
- # grow the remaining partitions
- foreach my $part_id (@shrink_list, at grow_list) {
- # reference to the current partition
- my $part = (\%FAI::configs)->{$config}->{partitions}->{$part_id};
-
- # get the existing id
- my $mapped_id = $part->{maps_to_existing};
-
- # get the intermediate partition id
- my $p = $FAI::current_config{$disk}{partitions}{$mapped_id}{new_id};
# get the new starts and ends
my $start = $part->{start_byte};
@@ -623,20 +813,47 @@
or &FAI::internal_error("ntfs partition supposed to move");
# ntfsresize requires device names
my $eff_size = $part->{size}->{eff_size};
- my $dev = $disk;
- $dev = "${dev}p" if ($dev =~ m{^/dev/(cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|ataraid/d\d)$});
- $dev = $dev . $p;
- push @FAI::commands, "yes | ntfsresize -s $eff_size $dev";
- push @FAI::commands, "parted -s $disk rm $p";
+
+ # wait for udev to set up all devices
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "udevsettle --timeout=10",
+ pre => "rebuilt_" . &FAI::make_device_name($disk, $p) . $deps,
+ post => "settle_for_resize_" . &FAI::make_device_name($disk, $p)
+ };
+ $FAI::n_c_i++;
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "yes | ntfsresize -s $eff_size " . &FAI::make_device_name($disk, $p),
+ pre => "settle_for_resize_" . &FAI::make_device_name($disk, $p),
+ post => "ntfs_ready_for_rm_" . &FAI::make_device_name($disk, $p)
+ };
+ $FAI::n_c_i++;
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "parted -s $disk rm $p",
+ pre => "ntfs_ready_for_rm_" . &FAI::make_device_name($disk, $p),
+ post => "resized_" . &FAI::make_device_name($disk, $p)
+ };
+ $FAI::n_c_i++;
} else {
- push @FAI::commands, "parted -s $disk resize $p ${start}B ${end}B";
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "parted -s $disk resize $p ${start}B ${end}B",
+ pre => "rebuilt_" . &FAI::make_device_name($disk, $p),
+ post => "resized_" . &FAI::make_device_name($disk, $p)
+ };
+ $FAI::n_c_i++;
}
+
}
# write the disklabel again to drop the partition table and create a new one
# that has the proper ids
- push @FAI::commands, "parted -s $disk mklabel " . $FAI::configs{$config}{disklabel};
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "parted -s $disk mklabel " . $FAI::configs{$config}{disklabel},
+ pre => "cleared1_$disk$pre_all_resize",
+ post => "cleared2_$disk"
+ };
+ $FAI::n_c_i++;
+ my $prev_id = -1;
# generate the commands for creating all partitions
foreach my $part_id (sort { $a <=> $b } keys %{ $FAI::configs{$config}{partitions} }) {
# reference to the current partition
@@ -669,17 +886,27 @@
if ($part->{size}->{preserve} || $part->{size}->{resize});
$fs = "" if ($fs eq "-");
+ my $pre = "";
+ $pre = ",exist_" . &FAI::make_device_name($disk, $prev_id) if ($prev_id > -1);
# build a parted command to create the partition
- push @FAI::commands, "parted -s $disk mkpart $part_type $fs ${start}B ${end}B";
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "parted -s $disk mkpart $part_type $fs ${start}B ${end}B",
+ pre => "cleared2_$disk$pre",
+ post => "exist_" . &FAI::make_device_name($disk, $part_id)
+ };
+ $FAI::n_c_i++;
+ $prev_id = $part_id;
}
# set the bootable flag, if requested at all
- push @FAI::commands, "parted -s $disk set "
- . $FAI::configs{$config}{bootable} . " boot on"
- if ($FAI::configs{$config}{bootable} > -1);
-
- # wait for udev to set up all devices
- push @FAI::commands, "udevsettle --timeout=10";
+ if ($FAI::configs{$config}{bootable} > -1) {
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "parted -s $disk set " . $FAI::configs{$config}{bootable} . " boot on",
+ pre => "exist_" . &FAI::make_device_name($disk, $FAI::configs{$config}{bootable}),
+ post => "boot_set_$disk"
+ };
+ $FAI::n_c_i++;
+ }
}
@@ -711,10 +938,7 @@
|| $part->{size}->{resize} == 1 || $part->{size}->{extended} == 1);
# create the filesystem on the device
- my $dev = $disk;
- $dev = "${dev}p" if ($dev =~ m{^/dev/(cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|ataraid/d\d)$});
- $dev = $dev . $part_id;
- &FAI::build_mkfs_commands( $dev, $part );
+ &FAI::build_mkfs_commands( &FAI::make_device_name($disk, $part_id), $part );
}
}
}
@@ -766,5 +990,47 @@
die "setup-storage failed, but the partition tables have been restored\n";
}
+################################################################################
+#
+# @brief Try to order the queued commands to satisfy all dependencies
+#
+################################################################################
+sub order_commands {
+ die "Not implemented\n";
+
+ my @pre_deps = ();
+ my $i = 1;
+ my $pushed = -1;
+
+ while ($i < $FAI::n_c_i) {
+ my $all_matched = 1;
+ foreach (split(/,/, $FAI::commands{$i}{pre})) {
+ next if scalar(grep(m{^$_$}, @pre_deps));
+ $all_matched = 0;
+ last;
+ }
+ if ($all_matched) {
+ $pushed = -1;
+ $i++;
+ push @pre_deps, split(/,/, $FAI::commands{$i}{post});
+ next;
+ }
+ if (-1 == $pushed) {
+ $pushed = $FAI::n_c_i;
+ }
+ elsif ($i == $pushed) {
+ die "Cannot satisfy pre-depends for " . $FAI::commands{$i}{cmd} . ": " .
+ $FAI::commands{$i}{pre} . " -- system left untouched.\n";
+ }
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => $FAI::commands{$i}{cmd},
+ pre => $FAI::commands{$i}{pre},
+ post => $FAI::commands{$i}{post}
+ };
+ $FAI::n_c_i++;
+ delete $FAI::commands{$i};
+ }
+}
+
1;
Modified: people/michael/features/setup_harddisks_2/implementation/lib/exec.pm
===================================================================
--- people/michael/features/setup_harddisks_2/implementation/lib/exec.pm 2008-05-05 16:31:12 UTC (rev 4880)
+++ people/michael/features/setup_harddisks_2/implementation/lib/exec.pm 2008-05-09 09:49:44 UTC (rev 4881)
@@ -123,6 +123,14 @@
response => "die",
},
{
+ error => "parted_9",
+ message => "Parted failed to resize the partition (is it too small?)\n",
+ stderr_regex => "Error: Unable to satisfy all constraints on the partition",
+ stdout_regex => "",
+ program => "parted",
+ response => "die",
+ },
+ {
error => "ntfsresize_1",
message => "NTFS resize cannot proceed\n",
stderr_regex => "(Error|ERROR)",
Modified: people/michael/features/setup_harddisks_2/implementation/lib/fstab.pm
===================================================================
--- people/michael/features/setup_harddisks_2/implementation/lib/fstab.pm 2008-05-05 16:31:12 UTC (rev 4880)
+++ people/michael/features/setup_harddisks_2/implementation/lib/fstab.pm 2008-05-09 09:49:44 UTC (rev 4881)
@@ -92,9 +92,6 @@
# the file to be returned, a list of lines
my @fstab = ();
- # wait for udev to set up all devices
- push @FAI::commands, "udevsettle --timeout=10";
-
# walk through all configured parts
# the order of entries is most likely wrong, it is fixed at the end
foreach my $c (keys %$config) {
@@ -102,7 +99,6 @@
# entry is a physical device
if ($c =~ /^PHY_(.+)$/) {
my $device = $1;
- $device = "${device}p" if ($device =~ m{^/dev/(cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|ataraid/d\d)$});
# make sure the desired fstabkey is defined at all
defined ($config->{$c}->{fstabkey})
@@ -117,7 +113,7 @@
# skip extended partitions and entries without a mountpoint
next if ($p_ref->{size}->{extended} || $p_ref->{mountpoint} eq "-");
- my $device_name = $device . $p_ref->{number};
+ my $device_name = &FAI::make_device_name($device, $p_ref->{number});
if ($p_ref->{encrypt}) {
# encryption requested, rewrite the device name
$device_name =~ "s#/#_#g";
Modified: people/michael/features/setup_harddisks_2/implementation/lib/init.pm
===================================================================
--- people/michael/features/setup_harddisks_2/implementation/lib/init.pm 2008-05-05 16:31:12 UTC (rev 4880)
+++ people/michael/features/setup_harddisks_2/implementation/lib/init.pm 2008-05-09 09:49:44 UTC (rev 4881)
@@ -108,13 +108,66 @@
################################################################################
#
-# @brief The list of commands to be executed
+# @brief The commands to be executed
#
################################################################################
- at FAI::commands = ();
+%FAI::commands = ();
################################################################################
#
+# @brief Each command is associated with a unique id -- this one aids in
+# counting (next_command_index)
+#
+################################################################################
+$FAI::n_c_i = 1;
+
+################################################################################
+#
+# @brief Check, whether $dev is a physical device, and extract sub-parts
+#
+# @param $dev Device string
+#
+# @return 1, iff it the matches the regexp, and disk device string, and
+# partition number, if any, otherwise -1
+#
+################################################################################
+sub phys_dev {
+ my ($dev) = @_;
+ if ($dev =~ m{^/dev/(i2o/hd[a-t]|sd[a-t]|hd[a-t])(\d+)?$})
+ {
+ defined($2) or return (1, $1, -1);
+ return (1, $1, $2);
+ }
+ elsif ($dev =~ m{^/dev/(cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|ataraid/d\d)p(\d+)?$})
+ {
+ defined($2) or return (1, $1, -1);
+ return (1, $1, $2);
+ }
+ return (0, "", -2);
+}
+
+################################################################################
+#
+# @brief Convert a device name and a partition id to a proper device name,
+# handling cciss and the like
+#
+# @param $dev Device name of disk
+# @param $id Partition id
+#
+# @return Full device name
+#
+################################################################################
+sub make_device_name {
+ my ($dev, $p) = @_;
+ $dev .= "p" if ($dev =~
+ m{^/dev/(cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|ataraid/d\d)$});
+ $dev .= $p;
+ internal_error("Invalid device $dev") unless (&FAI::phys_dev($dev))[0];
+ return $dev;
+}
+
+################################################################################
+#
# @brief Report an error that is due to a bug in the implementation
#
# @param $error_msg Error message
Modified: people/michael/features/setup_harddisks_2/implementation/lib/parser.pm
===================================================================
--- people/michael/features/setup_harddisks_2/implementation/lib/parser.pm 2008-05-05 16:31:12 UTC (rev 4880)
+++ people/michael/features/setup_harddisks_2/implementation/lib/parser.pm 2008-05-09 09:49:44 UTC (rev 4881)
@@ -540,11 +540,7 @@
# might be created later on
unless ($dev =~ m{^/}) {
if ($dev =~ m/^disk(\d+)\.(\d+)/) {
- my $short_dev = $FAI::disks[ $1 - 1 ];
- my $part_no = $2;
- $dev = "/dev/$short_dev";
- $dev = "${dev}p" if ($dev =~ m{^/dev/(cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|ataraid/d\d)$});
- $dev = "$dev$part_no";
+ $dev = &FAI::make_device_name("/dev/" . $FAI::disks[ $1 - 1 ], $2);
} else {
$dev = "/dev/$dev";
}
Modified: people/michael/features/setup_harddisks_2/implementation/lib/sizes.pm
===================================================================
--- people/michael/features/setup_harddisks_2/implementation/lib/sizes.pm 2008-05-05 16:31:12 UTC (rev 4880)
+++ people/michael/features/setup_harddisks_2/implementation/lib/sizes.pm 2008-05-09 09:49:44 UTC (rev 4881)
@@ -95,7 +95,8 @@
# try the entire disk first; we then use the data from the current
# configuration; this matches in fact for than the allowable strings, but
# this should be caught later on
- if ($dev =~ m{^/dev/(i2o/hd[a-t]|cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|ataraid/d\d|sd[a-t]|hd[a-t])$}) {
+ my ($i_p_d, $disk, $part_no) = &FAI::phys_dev($dev);
+ if (1 == $i_p_d && -1 == $part_no) {
defined ($FAI::current_config{$dev}{end_byte})
or die "$dev is not a valid block device\n";
@@ -105,16 +106,16 @@
}
# try a partition
- elsif ($dev =~ m{^(/dev/(i2o/hd[a-t]|cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|ataraid/d\d|sd[a-t]|hd[a-t]))p?(\d+)$}) {
+ elsif (1 == $i_p_d && $part_no > -1) {
# the size is configured, return it
- defined ($FAI::configs{"PHY_$1"}{partitions}{$3}{size}{eff_size})
- and return $FAI::configs{"PHY_$1"}{partitions}{$3}{size}{eff_size} /
+ defined ($FAI::configs{"PHY_$disk"}{partitions}{$part_no}{size}{eff_size})
+ and return $FAI::configs{"PHY_$disk"}{partitions}{$part_no}{size}{eff_size} /
(1024 * 1024);
# the size is known from the current configuration on disk, return it
- defined ($FAI::current_config{$1}{partitions}{$3}{count_byte})
- and return $FAI::current_config{$1}{partitions}{$3}{count_byte} /
+ defined ($FAI::current_config{$disk}{partitions}{$part_no}{count_byte})
+ and return $FAI::current_config{$disk}{partitions}{$part_no}{count_byte} /
(1024 * 1024);
# the size is not known (yet?)
Modified: people/michael/features/setup_harddisks_2/implementation/lib/volumes.pm
===================================================================
--- people/michael/features/setup_harddisks_2/implementation/lib/volumes.pm 2008-05-05 16:31:12 UTC (rev 4880)
+++ people/michael/features/setup_harddisks_2/implementation/lib/volumes.pm 2008-05-09 09:49:44 UTC (rev 4881)
@@ -51,6 +51,12 @@
# make sure, $disk is a proper block device
(-b $disk) or die "$disk is not a block special device!\n";
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "true",
+ pre => "",
+ post => "exist_$disk"
+ };
+ $FAI::n_c_i++;
# initialise the hash
$FAI::current_config{$disk}{partitions} = {};
@@ -295,6 +301,12 @@
foreach my $vg (get_volume_group_list()) {
# initialise the hash entry
$FAI::current_lvm_config{$vg}{physical_volumes} = ();
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "true",
+ pre => "",
+ post => "vg_created_$vg"
+ };
+ $FAI::n_c_i++;
# store the vg size in MB
my %vg_info = get_volume_group_information($vg);
@@ -310,6 +322,12 @@
$FAI::current_lvm_config{$vg}{volumes}{$short_name}{size} =
&FAI::convert_unit($lv_info{$lv_name}->{lv_size} .
$lv_info{$lv_name}->{lv_size_unit});
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "true",
+ pre => "",
+ post => "exist_/dev/$vg/$short_name"
+ };
+ $FAI::n_c_i++;
}
# store the physical volumes
@@ -351,6 +369,12 @@
if ($line =~ /^ARRAY \/dev\/md(\d+) level=(\S+) num-devices=\d+ UUID=/) {
$id = $1;
$FAI::current_raid_config{$id}{mode} = $2;
+ $FAI::commands{$FAI::n_c_i} = {
+ cmd => "true",
+ pre => "",
+ post => "exist_/dev/md$id"
+ };
+ $FAI::n_c_i++;
} elsif ($line =~ /^\s*devices=(\S+)$/) {
@{ $FAI::current_raid_config{$id}{devices} } = split (",", $1);
}
Modified: people/michael/features/setup_harddisks_2/implementation/setup-storage
===================================================================
--- people/michael/features/setup_harddisks_2/implementation/setup-storage 2008-05-05 16:31:12 UTC (rev 4880)
+++ people/michael/features/setup_harddisks_2/implementation/setup-storage 2008-05-09 09:49:44 UTC (rev 4881)
@@ -151,18 +151,21 @@
&FAI::build_disk_commands;
&FAI::build_raid_commands;
&FAI::build_lvm_commands;
+&FAI::order_commands;
# run all commands
# debugging only: print the command script
-$FAI::debug and print "$_\n" foreach (@FAI::commands);
+$FAI::debug and print $FAI::commands{$_}{cmd} . "\n" foreach (sort { $a <=> $b } keys %FAI::commands);
# run the commands (if $FAI::no_dry_run is set)
# load the modules to support encryption
`modprobe aes`;
`modprobe dm-crypt`;
-&FAI::execute_command($_) foreach (@FAI::commands);
+&FAI::execute_command($FAI::commands{$_}{cmd}) foreach (sort { $a <=> $b } keys %FAI::commands);
# generate the proposed fstab contents
+# wait for udev to set up all devices
+`udevsettle --timeout=10`;
my @fstab = &FAI::generate_fstab(\%FAI::configs);
# print fstab
More information about the Fai-commit
mailing list