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