diff options
author | NeilBrown <neilb@suse.de> | 2014-10-29 08:48:02 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2014-11-25 11:44:29 +1100 |
commit | 9a518d81fe614d4fd8391c94bc99d5458cd3324f (patch) | |
tree | b848ac11ad55d774d0630e179d714c01ba30c612 | |
parent | 7ae077587156db9a015103da79145c454eccd8b6 (diff) | |
download | mdadm-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.c | 23 |
1 files changed, 22 insertions, 1 deletions
@@ -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) |