diff options
author | Dan Williams <dan.j.williams@intel.com> | 2009-10-13 17:37:02 -0700 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2009-10-13 17:41:58 -0700 |
commit | 9f1da8242161ba684f2867f211eb7e9d4baa84bb (patch) | |
tree | e396bffdec4ef5915f4eb138f343809431042dc0 | |
parent | b928b5a0384e7181425a282a0586cbbb3c85fbc3 (diff) | |
download | mdadm-9f1da8242161ba684f2867f211eb7e9d4baa84bb.tar.gz mdadm-9f1da8242161ba684f2867f211eb7e9d4baa84bb.tar.xz mdadm-9f1da8242161ba684f2867f211eb7e9d4baa84bb.zip |
mdmon: preserve socket over chroot
Connect to the monitor in the old namespace and use that connection for
WaitClean requests when stopping the victim mdmon instance. This allows
ping_monitor() to work post chroot().
Cc: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | mdadm.c | 4 | ||||
-rw-r--r-- | mdadm.h | 2 | ||||
-rw-r--r-- | mdmon.c | 12 | ||||
-rw-r--r-- | msg.c | 14 | ||||
-rw-r--r-- | msg.h | 1 | ||||
-rw-r--r-- | sysfs.c | 5 |
6 files changed, 26 insertions, 12 deletions
@@ -1276,7 +1276,7 @@ int main(int argc, char *argv[]) export, test, homehost); else - rv |= WaitClean(name, v); + rv |= WaitClean(name, -1, v); put_md_name(name); } free_mdstat(ms); @@ -1337,7 +1337,7 @@ int main(int argc, char *argv[]) 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) { @@ -753,7 +753,7 @@ extern int Monitor(mddev_dev_t devlist, 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, @@ -175,7 +175,7 @@ pid_t devname2mdmon(char *devname) 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; @@ -205,7 +205,7 @@ static void try_kill_monitor(pid_t pid, char *devname) 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); } @@ -366,6 +366,7 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot) int status; int ignore; pid_t victim = -1; + int victim_sock = -1; dprintf("starting mdmon for %s in %s\n", devname, switchroot ? : "/"); @@ -502,6 +503,7 @@ int mdmon(char *devname, int devnum, int scan, char *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)); @@ -551,8 +553,10 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot) 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); @@ -177,10 +177,8 @@ int connect_monitor(char *devname) 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) @@ -194,6 +192,16 @@ int ping_monitor(char *devname) 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; } @@ -27,6 +27,7 @@ extern int ack(int fd, int tmo); 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) @@ -764,7 +764,7 @@ int sysfs_unique_holder(int devnum, long rdev) 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; @@ -840,7 +840,8 @@ int WaitClean(char *dev, int verbose) } 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 |