mirror of
https://github.com/AuxXxilium/eudev.git
synced 2024-12-28 06:35:34 +07:00
main: corrected do_switch_root()
do_switch_root now mount moves "/dev", "/proc", "/sys", "/run" and removes the old root recursively.
This commit is contained in:
parent
386da8589b
commit
f67cc036ba
@ -1168,30 +1168,73 @@ static void test_cgroups(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int do_switch_root(const char *switch_root) {
|
static int do_switch_root(const char *switch_root) {
|
||||||
int r;
|
int r=0;
|
||||||
|
/* Don't try to unmount the old "/", there's no way to do it. */
|
||||||
|
const char *umounts[] = { "/dev", "/proc", "/sys", "/run", NULL };
|
||||||
|
int i;
|
||||||
|
int cfd = -1;
|
||||||
|
struct stat switch_root_stat, sb;
|
||||||
|
|
||||||
if (path_equal(switch_root, "/"))
|
if (path_equal(switch_root, "/"))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (chdir(switch_root) < 0) {
|
if (stat(switch_root, &switch_root_stat) != 0) {
|
||||||
r = -errno;
|
r = -errno;
|
||||||
|
log_error("failed to stat directory %s", switch_root);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; umounts[i] != NULL; i++) {
|
||||||
|
char newmount[PATH_MAX];
|
||||||
|
|
||||||
|
snprintf(newmount, sizeof(newmount), "%s%s", switch_root, umounts[i]);
|
||||||
|
|
||||||
|
if ((stat(newmount, &sb) != 0) || (sb.st_dev != switch_root_stat.st_dev)) {
|
||||||
|
/* mount point seems to be mounted already or stat failed */
|
||||||
|
umount2(umounts[i], MNT_DETACH);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mount(umounts[i], newmount, NULL, MS_MOVE, NULL) < 0) {
|
||||||
|
log_error("failed to mount moving %s to %s",
|
||||||
|
umounts[i], newmount);
|
||||||
|
log_error("forcing unmount of %s", umounts[i]);
|
||||||
|
umount2(umounts[i], MNT_FORCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chdir(switch_root)) {
|
||||||
|
r = -errno;
|
||||||
|
log_error("failed to change directory to %s", switch_root);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfd = open("/", O_RDONLY);
|
||||||
|
|
||||||
if (mount(switch_root, "/", NULL, MS_MOVE, NULL) < 0) {
|
if (mount(switch_root, "/", NULL, MS_MOVE, NULL) < 0) {
|
||||||
r = -errno;
|
r = -errno;
|
||||||
chdir("/");
|
log_error("failed to mount moving %s to /", switch_root);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chroot(".") < 0)
|
if (chroot(".")) {
|
||||||
log_warning("Failed to change root, ignoring: %m");
|
r = -errno;
|
||||||
|
log_error("failed to change root");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: remove old root */
|
if (cfd >= 0) {
|
||||||
|
rm_rf_children(cfd, false, false);
|
||||||
|
close(cfd);
|
||||||
|
cfd=-1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
if (cfd >= 0)
|
||||||
|
close(cfd);
|
||||||
|
|
||||||
log_error("Failed to switch root, ignoring: %s", strerror(-r));
|
log_error("Failed to switch root, ignoring: %s", strerror(-r));
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
@ -3139,7 +3139,7 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rm_rf_children(int fd, bool only_dirs, bool honour_sticky) {
|
int rm_rf_children(int fd, bool only_dirs, bool honour_sticky) {
|
||||||
DIR *d;
|
DIR *d;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -349,6 +349,7 @@ int get_ctty(pid_t, dev_t *_devnr, char **r);
|
|||||||
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
|
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
|
||||||
int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
|
int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
|
||||||
|
|
||||||
|
int rm_rf_children(int fd, bool only_dirs, bool honour_sticky);
|
||||||
int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
|
int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
|
||||||
|
|
||||||
int pipe_eof(int fd);
|
int pipe_eof(int fd);
|
||||||
|
Loading…
Reference in New Issue
Block a user