summaryrefslogtreecommitdiffstats
path: root/Monitor.c
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2006-12-14 17:32:53 +1100
committerNeil Brown <neilb@suse.de>2006-12-14 17:32:53 +1100
commitab5303d695eb7249b9462f9ad4e973711622a9c5 (patch)
treea9599db5e14cce7402615d72084ddb826c09d060 /Monitor.c
parent4a39c6f236fba4065c7b74f03791eb50759289ad (diff)
downloadmdadm-ab5303d695eb7249b9462f9ad4e973711622a9c5.tar.gz
mdadm-ab5303d695eb7249b9462f9ad4e973711622a9c5.tar.xz
mdadm-ab5303d695eb7249b9462f9ad4e973711622a9c5.zip
Don't hold md device open for so long in --monitor mode
map_dev can be slow and interferes with trying to stop the array.
Diffstat (limited to 'Monitor.c')
-rw-r--r--Monitor.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/Monitor.c b/Monitor.c
index f7bb48c..6a4c8de 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -215,6 +215,7 @@ int Monitor(mddev_dev_t devlist,
mdstat = mdstat_read(oneshot?0:1, 0);
for (st=statelist; st; st=st->next) {
+ struct { int state, major, minor; } info[MaxDisks];
mdu_array_info_t array;
struct mdstat_ent *mse = NULL, *mse2;
char *dev = st->devname;
@@ -323,6 +324,19 @@ int Monitor(mddev_dev_t devlist,
if (mse)
st->percent = mse->percent;
+
+ for (i=0; i<MaxDisks && i <= array.raid_disks + array.nr_disks;
+ i++) {
+ mdu_disk_info_t disc;
+ if (ioctl(fd, GET_DISK_INFO, &disc) >= 0) {
+ info[i].state = disc.state;
+ info[i].major = disc.major;
+ info[i].minor = disc.minor;
+ } else
+ info[i].major = info[i].minor = 0;
+ }
+ close(fd);
+
for (i=0; i<MaxDisks; i++) {
mdu_disk_info_t disc;
int newstate=0;
@@ -332,9 +346,12 @@ int Monitor(mddev_dev_t devlist,
if (i > array.raid_disks + array.nr_disks) {
newstate = 0;
disc.major = disc.minor = 0;
- } else if (ioctl(fd, GET_DISK_INFO, &disc)>= 0) {
- newstate = disc.state;
- dv = map_dev(disc.major, disc.minor, 1);
+ } else if (info[i].major || info[i].minor) {
+ newstate = info[i].state;
+ dv = map_dev(info[i].major, info[i].minor, 1);
+ disc.state = newstate;
+ disc.major = info[i].major;
+ disc.minor = info[i].minor;
} else if (mse && mse->pattern && i < strlen(mse->pattern)) {
switch(mse->pattern[i]) {
case 'U': newstate = 6 /* ACTIVE/SYNC */; break;
@@ -369,7 +386,6 @@ int Monitor(mddev_dev_t devlist,
st->devstate[i] = disc.state;
st->devid[i] = makedev(disc.major, disc.minor);
}
- close(fd);
st->active = array.active_disks;
st->working = array.working_disks;
st->spare = array.spare_disks;