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:
Dan Williams 2009-10-13 17:37:02 -07:00
parent b928b5a038
commit 9f1da82421
6 changed files with 26 additions and 12 deletions

View File

@ -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) {

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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)

View File

@ -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