Add ping_monitor() to mdadm --wait
The action we are waiting for may not be complete until the monitor has had a chance to take action on the result. The following script can now remove the device on the first attempt, versus a few attempts with the original Wait(): #!/bin/bash #export MDADM_NO_MDMON=1 export IMSM_DEVNAME_AS_SERIAL=1 ./mdadm -Ss ./mdadm --zero-superblock /dev/loop[0-3] echo 2 > /proc/sys/dev/raid/speed_limit_max ./mdadm --create /dev/imsm /dev/loop[0-3] -n 4 -e imsm -a md ./mdadm --create /dev/md/r1 /dev/loop[0-3] -n 4 -l 5 --force -a mdp ./mdadm --fail /dev/md/r1 /dev/loop3 ./mdadm --wait /dev/md/r1 x=0 while ! ./mdadm --remove /dev/imsm /dev/loop3 > /dev/null 2>&1 do x=$((x+1)) done echo "removed after $x attempts" ./mdadm --add /dev/imsm /dev/loop3 Include 2 small cleanups: * remove the almost open coded fd2devnum() in Wait() by introducing a new utility routine stat2devnum() * teach connect_monitor() to parse the container device from a subarray string Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
0c0c44db5a
commit
c94709e83f
7
Manage.c
7
Manage.c
|
@ -167,8 +167,6 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet)
|
||||||
if (mdi &&
|
if (mdi &&
|
||||||
mdi->array.level > 0 &&
|
mdi->array.level > 0 &&
|
||||||
is_subarray(mdi->text_version)) {
|
is_subarray(mdi->text_version)) {
|
||||||
char *cp;
|
|
||||||
|
|
||||||
/* This is mdmon managed. */
|
/* This is mdmon managed. */
|
||||||
close(fd);
|
close(fd);
|
||||||
if (sysfs_set_str(mdi, NULL,
|
if (sysfs_set_str(mdi, NULL,
|
||||||
|
@ -181,10 +179,7 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Give monitor a chance to act */
|
/* Give monitor a chance to act */
|
||||||
cp = strchr(mdi->text_version+1, '/');
|
ping_monitor(mdi->text_version);
|
||||||
if (*cp)
|
|
||||||
*cp = 0;
|
|
||||||
ping_monitor(mdi->text_version+1);
|
|
||||||
|
|
||||||
fd = open(devname, O_RDONLY);
|
fd = open(devname, O_RDONLY);
|
||||||
} else if (mdi &&
|
} else if (mdi &&
|
||||||
|
|
12
Monitor.c
12
Monitor.c
|
@ -602,10 +602,7 @@ int Wait(char *dev)
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
if (major(stb.st_rdev) == MD_MAJOR)
|
devnum = stat2devnum(&stb);
|
||||||
devnum = minor(stb.st_rdev);
|
|
||||||
else
|
|
||||||
devnum = -1-(minor(stb.st_rdev)/64);
|
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
struct mdstat_ent *ms = mdstat_read(1, 0);
|
struct mdstat_ent *ms = mdstat_read(1, 0);
|
||||||
|
@ -616,6 +613,13 @@ int Wait(char *dev)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!e || e->percent < 0) {
|
if (!e || e->percent < 0) {
|
||||||
|
if (e &&
|
||||||
|
strncmp(e->metadata_version, "external:", 9) == 0) {
|
||||||
|
if (is_subarray(&e->metadata_version[9]))
|
||||||
|
ping_monitor(&e->metadata_version[9]);
|
||||||
|
else
|
||||||
|
ping_monitor(devnum2devname(devnum));
|
||||||
|
}
|
||||||
free_mdstat(ms);
|
free_mdstat(ms);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
1
mdadm.h
1
mdadm.h
|
@ -785,6 +785,7 @@ extern int start_mdmon(int devnum);
|
||||||
|
|
||||||
extern char *devnum2devname(int num);
|
extern char *devnum2devname(int num);
|
||||||
extern int devname2devnum(char *name);
|
extern int devname2devnum(char *name);
|
||||||
|
extern int stat2devnum(struct stat *st);
|
||||||
extern int fd2devnum(int fd);
|
extern int fd2devnum(int fd);
|
||||||
|
|
||||||
static inline int dev2major(int d)
|
static inline int dev2major(int d)
|
||||||
|
|
15
msg.c
15
msg.c
|
@ -144,8 +144,21 @@ int connect_monitor(char *devname)
|
||||||
int sfd;
|
int sfd;
|
||||||
long fl;
|
long fl;
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
|
int pos;
|
||||||
|
char *c;
|
||||||
|
|
||||||
|
pos = sprintf(path, "/var/run/mdadm/");
|
||||||
|
if (is_subarray(devname)) {
|
||||||
|
devname++;
|
||||||
|
c = strchr(devname, '/');
|
||||||
|
if (!c)
|
||||||
|
return -1;
|
||||||
|
snprintf(&path[pos], c - devname + 1, "%s", devname);
|
||||||
|
pos += c - devname;
|
||||||
|
} else
|
||||||
|
pos += sprintf(&path[pos], "%s", devname);
|
||||||
|
sprintf(&path[pos], ".sock");
|
||||||
|
|
||||||
sprintf(path, "/var/run/mdadm/%s.sock", devname);
|
|
||||||
sfd = socket(PF_LOCAL, SOCK_STREAM, 0);
|
sfd = socket(PF_LOCAL, SOCK_STREAM, 0);
|
||||||
if (sfd < 0)
|
if (sfd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
21
util.c
21
util.c
|
@ -1022,16 +1022,23 @@ int devname2devnum(char *name)
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int stat2devnum(struct stat *st)
|
||||||
|
{
|
||||||
|
if ((S_IFMT & st->st_mode) == S_IFBLK) {
|
||||||
|
if (major(st->st_rdev) == MD_MAJOR)
|
||||||
|
return minor(st->st_rdev);
|
||||||
|
else
|
||||||
|
return -1- (minor(st->st_rdev)>>6);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int fd2devnum(int fd)
|
int fd2devnum(int fd)
|
||||||
{
|
{
|
||||||
struct stat stb;
|
struct stat stb;
|
||||||
if (fstat(fd, &stb) == 0 &&
|
if (fstat(fd, &stb) == 0)
|
||||||
(S_IFMT&stb.st_mode)==S_IFBLK) {
|
return stat2devnum(&stb);
|
||||||
if (major(stb.st_rdev) == MD_MAJOR)
|
|
||||||
return minor(stb.st_rdev);
|
|
||||||
else
|
|
||||||
return -1- (minor(stb.st_rdev)>>6);
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue