diff options
author | Martin Whitaker <mageia@martin-whitaker.me.uk> | 2017-04-02 19:45:27 +0100 |
---|---|---|
committer | RĂ©mi Verschelde <rverschelde@gmail.com> | 2017-04-04 20:04:47 +0200 |
commit | 23db13194282cfff24d4bc88a7790ebd272953a0 (patch) | |
tree | 02292c9df552239a8a191040829798db42d2f4a9 /perl-install/partition_table | |
parent | 6753abe33da73245f22908724f671334de56cd09 (diff) | |
download | drakx-23db13194282cfff24d4bc88a7790ebd272953a0.tar drakx-23db13194282cfff24d4bc88a7790ebd272953a0.tar.gz drakx-23db13194282cfff24d4bc88a7790ebd272953a0.tar.bz2 drakx-23db13194282cfff24d4bc88a7790ebd272953a0.tar.xz drakx-23db13194282cfff24d4bc88a7790ebd272953a0.zip |
Add safety net for informing the kernel after writing a DOS partition table.
There is an unidentified condition that prevents udevd calling the
BLKRRPART ioctl after a partition table is written. It looks like
either the kernel or udevd drops device change events if they are
too closely spaced in time. So, in the case where we expect udevd
to call BLKRRPART, check /proc/partitions to make sure it has done
so. Arbitrarily try 5 times, 100ms apart, before giving up and
informing the kernel ourselves.
Diffstat (limited to 'perl-install/partition_table')
-rw-r--r-- | perl-install/partition_table/dos.pm | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/perl-install/partition_table/dos.pm b/perl-install/partition_table/dos.pm index a97fcf89d..92b28beee 100644 --- a/perl-install/partition_table/dos.pm +++ b/perl-install/partition_table/dos.pm @@ -6,9 +6,11 @@ use vars qw(@ISA); @ISA = qw(partition_table::raw); +use Time::HiRes qw(usleep); use common; use partition_table::raw; use partition_table; +use fs::proc_partitions; use fs::type; use c; @@ -291,7 +293,24 @@ sub need_to_tell_kernel { # diskdrake will not let the user delete an individual partition that is mounted, but will let the # user clear all partitions. So initialize() records if any partitions were mounted and we take note # of that here. - return ! -e '/usr/lib/udev/rules.d/60-block.rules' || delete $hd->{hadMountedPartitions} || any { $_->{isMounted} } partition_table::get_normal_parts($hd); + return 1 if ! -e '/usr/lib/udev/rules.d/60-block.rules' || delete $hd->{hadMountedPartitions} || any { $_->{isMounted} } partition_table::get_normal_parts($hd); + + # No further actions must be performed until the kernel has been informed of the changes. There is + # no easy way to check that udevd has received the uevent and called the BLKRRPART ioctl, so do it + # the hard way. + my $tries = 0; + do { + usleep(100000); + log::l("checking that udevd has informed the kernel of partition table changes"); + eval { fs::proc_partitions::compare($hd) }; + return 0 if !$@; + $tries++; + } while $tries < 5; + + # We don't expect to get here, but fail safe if so. + log::l("udevd failed to inform kernel of partition table changes"); + $hd->{rebootNeeded} = 1; + 1; } sub empty_raw { { raw => [ ({}) x $nb_primary ] } } |