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>
This commit is contained in:
parent
b928b5a038
commit
9f1da82421
4
mdadm.c
4
mdadm.c
|
@ -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) {
|
||||
|
|
2
mdadm.h
2
mdadm.h
|
@ -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,
|
||||
|
|
12
mdmon.c
12
mdmon.c
|
@ -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);
|
||||
|
|
14
msg.c
14
msg.c
|
@ -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;
|
||||
}
|
||||
|
|
1
msg.h
1
msg.h
|
@ -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)
|
||||
|
|
5
sysfs.c
5
sysfs.c
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue