summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2014-10-29 08:48:02 +1100
committerNeilBrown <neilb@suse.de>2014-11-25 11:44:29 +1100
commit9a518d81fe614d4fd8391c94bc99d5458cd3324f (patch)
treeb848ac11ad55d774d0630e179d714c01ba30c612
parent7ae077587156db9a015103da79145c454eccd8b6 (diff)
downloadmdadm-9a518d81fe614d4fd8391c94bc99d5458cd3324f.tar.gz
Monitor: don't open md array that doesn't exist.
Opening a block-special-device for an array that doesn't exist causes that array to be instantiated (as an empty array). Races at array shutdown can cause the array to spontaneously re-appear if some deamon notices a 'change' event and goes to investigate. Teach "mdadm --monitor" to avoid this race by checking the "array_state" before opening the device. Reported-by: Francis Moreau <francis.moro@gmail.com> Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--Monitor.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/Monitor.c b/Monitor.c
index 5cb24fa..971d2ec 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -460,7 +460,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
mdu_array_info_t array;
struct mdstat_ent *mse = NULL, *mse2;
char *dev = st->devname;
- int fd;
+ int fd = -1;
int i;
int remaining_disks;
int last_disk;
@@ -468,6 +468,27 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (test)
alert("TestMessage", dev, NULL, ainfo);
+ if (st->devnm[0])
+ fd = open("/sys/block", O_RDONLY|O_DIRECTORY);
+ if (fd >= 0) {
+ /* Don't open the device unless it is present and
+ * active in sysfs.
+ */
+ char buf[10];
+ close(fd);
+ fd = sysfs_open(st->devnm, NULL, "array_state");
+ if (fd < 0 ||
+ read(fd, buf, 10) < 5 ||
+ strncmp(buf,"clear",5) == 0 ||
+ strncmp(buf,"inact",5) == 0) {
+ if (fd >= 0)
+ close(fd);
+ if (!st->err)
+ alert("DeviceDisappeared", dev, NULL, ainfo);
+ st->err++;
+ return 0;
+ }
+ }
fd = open(dev, O_RDONLY);
if (fd < 0) {
if (!st->err)