mdmon: improve switchroot handling.
The change to get mdmon to re-exec itself from the switchroot filesystem broken switchroot in various ways. This fixes it. If the switchroot path is not '/', mdmon will find the pid and socket for the monitor, chroot to the new root, and exec mdmon passing the pid in argv[2] and the socket in stdin. If the switchroot path is actually a number, mdmon will not chroot, but will kill that pid before taking over the array. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
af7ca33487
commit
e98ef22509
65
mdmon.c
65
mdmon.c
|
@ -368,15 +368,35 @@ static int mdmon(char *devname, int devnum, int must_fork, char *switchroot)
|
||||||
dprintf("starting mdmon for %s in %s\n",
|
dprintf("starting mdmon for %s in %s\n",
|
||||||
devname, switchroot ? : "/");
|
devname, switchroot ? : "/");
|
||||||
|
|
||||||
/* try to spawn mdmon instances from the target file system */
|
/* switchroot is either a path name starting with '/', or a
|
||||||
if (switchroot && strcmp(switchroot, "/") != 0) {
|
* pid of the original mdmon (we have already done the chroot).
|
||||||
char path[1024];
|
* In the latter case, stdin is a socket connected to the original
|
||||||
pid_t pid;
|
* mdmon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* try to spawn mdmon instances from the target file system */
|
||||||
|
if (switchroot && switchroot[0] == '/' &&
|
||||||
|
strcmp(switchroot, "/") != 0) {
|
||||||
|
pid_t pid;
|
||||||
|
char buf[20];
|
||||||
|
|
||||||
sprintf(path, "%s/sbin/mdmon", switchroot);
|
|
||||||
switch (fork()) {
|
switch (fork()) {
|
||||||
case 0:
|
case 0:
|
||||||
execl(path, "mdmon", devname, NULL);
|
victim = devname2mdmon(devname);
|
||||||
|
victim_sock = connect_monitor(devname);
|
||||||
|
if (chroot(switchroot) != 0) {
|
||||||
|
fprintf(stderr, "mdmon: failed to chroot to '%s': %s\n",
|
||||||
|
switchroot, strerror(errno));
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
ignore = chdir("/");
|
||||||
|
sprintf(buf, "%d", victim);
|
||||||
|
if (victim_sock) {
|
||||||
|
close(0);
|
||||||
|
dup(victim_sock);
|
||||||
|
close(victim_sock);
|
||||||
|
}
|
||||||
|
execl("/sbin/mdmon", "mdmon", devname, buf, NULL);
|
||||||
exit(1);
|
exit(1);
|
||||||
case -1:
|
case -1:
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -499,12 +519,12 @@ static int mdmon(char *devname, int devnum, int must_fork, char *switchroot)
|
||||||
/* we assume we assume that /sys /proc /dev are available in
|
/* we assume we assume that /sys /proc /dev are available in
|
||||||
* the new root
|
* the new root
|
||||||
*/
|
*/
|
||||||
victim = devname2mdmon(container->devname);
|
if (switchroot[0] == '/') {
|
||||||
victim_sock = connect_monitor(container->devname);
|
victim = devname2mdmon(container->devname);
|
||||||
if (chroot(switchroot) != 0) {
|
victim_sock = connect_monitor(container->devname);
|
||||||
fprintf(stderr, "mdmon: failed to chroot to '%s': %s\n",
|
} else {
|
||||||
switchroot, strerror(errno));
|
victim = atoi(switchroot);
|
||||||
exit(4);
|
victim_sock = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,16 +552,6 @@ static int mdmon(char *devname, int devnum, int must_fork, char *switchroot)
|
||||||
getppid());
|
getppid());
|
||||||
close(pfd[1]);
|
close(pfd[1]);
|
||||||
|
|
||||||
setsid();
|
|
||||||
close(0);
|
|
||||||
open("/dev/null", O_RDWR);
|
|
||||||
close(1);
|
|
||||||
ignore = dup(0);
|
|
||||||
#ifndef DEBUG
|
|
||||||
close(2);
|
|
||||||
ignore = dup(0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mlockall(MCL_CURRENT | MCL_FUTURE);
|
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||||
|
|
||||||
if (clone_monitor(container) < 0) {
|
if (clone_monitor(container) < 0) {
|
||||||
|
@ -554,6 +564,17 @@ static int mdmon(char *devname, int devnum, int must_fork, char *switchroot)
|
||||||
try_kill_monitor(victim, container->devname, victim_sock);
|
try_kill_monitor(victim, container->devname, victim_sock);
|
||||||
close(victim_sock);
|
close(victim_sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setsid();
|
||||||
|
close(0);
|
||||||
|
open("/dev/null", O_RDWR);
|
||||||
|
close(1);
|
||||||
|
ignore = dup(0);
|
||||||
|
#ifndef DEBUG
|
||||||
|
close(2);
|
||||||
|
ignore = dup(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
do_manager(container);
|
do_manager(container);
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
Loading…
Reference in New Issue