summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Whitaker <mageia@martin-whitaker.me.uk>2017-04-02 19:45:27 +0100
committerRĂ©mi Verschelde <rverschelde@gmail.com>2017-04-04 20:04:47 +0200
commit23db13194282cfff24d4bc88a7790ebd272953a0 (patch)
tree02292c9df552239a8a191040829798db42d2f4a9
parent6753abe33da73245f22908724f671334de56cd09 (diff)
downloaddrakx-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.
-rw-r--r--perl-install/partition_table/dos.pm21
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 ] } }