export, test,
homehost);
else
- rv |= WaitClean(name, v);
+ rv |= WaitClean(name, -1, v);
put_md_name(name);
}
free_mdstat(ms);
case 'W':
rv |= Wait(dv->devname); continue;
case Waitclean:
- rv |= WaitClean(dv->devname, verbose-quiet); continue;
+ rv |= WaitClean(dv->devname, -1, verbose-quiet); continue;
}
mdfd = open_mddev(dv->devname, 1);
if (mdfd>=0) {
extern int Kill(char *dev, int force, int quiet, int noexcl);
extern int Wait(char *dev);
-extern int WaitClean(char *dev, int verbose);
+extern int WaitClean(char *dev, int sock, int verbose);
extern int Incremental(char *devname, int verbose, int runstop,
struct supertype *st, char *homehost, int require_homehost,
return pid;
}
-static void try_kill_monitor(pid_t pid, char *devname)
+static void try_kill_monitor(pid_t pid, char *devname, int sock)
{
char buf[100];
int fd;
for ( ; mdstat; mdstat = mdstat->next)
if (is_container_member(mdstat, devname)) {
sprintf(buf, "/dev/%s", mdstat->dev);
- WaitClean(buf, 0);
+ WaitClean(buf, sock, 0);
}
free_mdstat(mdstat);
}
int status;
int ignore;
pid_t victim = -1;
+ int victim_sock = -1;
dprintf("starting mdmon for %s in %s\n",
devname, switchroot ? : "/");
* the new root
*/
victim = devname2mdmon(container->devname);
+ victim_sock = connect_monitor(container->devname);
if (chroot(switchroot) != 0) {
fprintf(stderr, "mdmon: failed to chroot to '%s': %s\n",
switchroot, strerror(errno));
exit(2);
}
- if (victim > -1)
- try_kill_monitor(victim, container->devname);
+ if (victim > -1) {
+ try_kill_monitor(victim, container->devname, victim_sock);
+ close(victim_sock);
+ }
do_manager(container);
exit(0);
return sfd;
}
-/* give the monitor a chance to update the metadata */
-int ping_monitor(char *devname)
+int fping_monitor(int sfd)
{
- int sfd = connect_monitor(devname);
int err = 0;
if (sfd < 0)
if (!err && wait_reply(sfd, 20) != 0)
err = -1;
+ return err;
+}
+
+
+/* give the monitor a chance to update the metadata */
+int ping_monitor(char *devname)
+{
+ int sfd = connect_monitor(devname);
+ int err = fping_monitor(sfd);
+
close(sfd);
return err;
}
extern int wait_reply(int fd, int tmo);
extern int connect_monitor(char *devname);
extern int ping_monitor(char *devname);
+extern int fping_monitor(int sock);
extern int ping_manager(char *devname);
#define MSG_MAX_LEN (4*1024*1024)
static char *clean_states[] = {
"clear", "inactive", "readonly", "read-auto", "clean", NULL };
-int WaitClean(char *dev, int verbose)
+int WaitClean(char *dev, int sock, int verbose)
{
int fd;
struct mdinfo *mdi;
}
if (rv < 0)
rv = 1;
- else if (ping_monitor(mdi->text_version) == 0) {
+ else if (fping_monitor(sock) == 0 ||
+ ping_monitor(mdi->text_version) == 0) {
/* we need to ping to close the window between array
* state transitioning to clean and the metadata being
* marked clean