return -1;
}
+ if (detect_shared_rootfs()) {
+ if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
+ SYSERROR("Failed to make / rslave");
+ ERROR("Continuing...");
+ }
+ }
+
/* assume /proc is always mounted, so remount it */
ret = umount2("/proc", MNT_DETACH);
if (ret < 0) {
if (unshare(CLONE_NEWNS) < 0)
exit(1);
+ if (detect_shared_rootfs()) {
+ if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
+ SYSERROR("Failed to make / rslave");
+ ERROR("Continuing...");
+ }
+ }
+
ret = mount_unknown_fs(srcdev, bdev->dest, bdev->mntopts);
if (ret < 0) {
ERROR("failed mounting %s onto %s to detect fstype", srcdev, bdev->dest);
}
if (detect_shared_rootfs()) {
if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
- SYSERROR("Failed to make / rslave to run rsync");
+ SYSERROR("Failed to make / rslave");
ERROR("Continuing...");
}
}
return 0;
}
-/*
- * Detect whether / is mounted MS_SHARED. The only way I know of to
- * check that is through /proc/self/mountinfo.
- * I'm only checking for /. If the container rootfs or mount location
- * is MS_SHARED, but not '/', then you're out of luck - figuring that
- * out would be too much work to be worth it.
- */
-#define LINELEN 4096
-int detect_shared_rootfs(void)
-{
- char buf[LINELEN], *p;
- FILE *f;
- int i;
- char *p2;
-
- f = fopen("/proc/self/mountinfo", "r");
- if (!f)
- return 0;
- while (fgets(buf, LINELEN, f)) {
- for (p = buf, i=0; p && i < 4; i++)
- p = index(p+1, ' ');
- if (!p)
- continue;
- p2 = index(p+1, ' ');
- if (!p2)
- continue;
- *p2 = '\0';
- if (strcmp(p+1, "/") == 0) {
- // this is '/'. is it shared?
- p = index(p2+1, ' ');
- if (p && strstr(p, "shared:")) {
- fclose(f);
- return 1;
- }
- }
- }
- fclose(f);
- return 0;
-}
-
/*
* I'll forgive you for asking whether all of this is needed :) The
* answer is yes.
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/mount.h>
#include <sys/wait.h>
#include <sched.h>
#include <pwd.h>
perror("unshare CLONE_NEWNS");
return -1;
}
+ if (detect_shared_rootfs()) {
+ if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
+ printf("Failed to make / rslave");
+ return -1;
+ }
+ }
execvp(argv[0], argv);
perror("execvpe");
return -1;
bdev_put(bdev);
return -1;
}
+ if (detect_shared_rootfs()) {
+ if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
+ SYSERROR("Failed to make / rslave");
+ ERROR("Continuing...");
+ }
+ }
if (bdev->ops->mount(bdev) < 0) {
bdev_put(bdev);
return -1;
return hval;
}
+
+/*
+ * Detect whether / is mounted MS_SHARED. The only way I know of to
+ * check that is through /proc/self/mountinfo.
+ * I'm only checking for /. If the container rootfs or mount location
+ * is MS_SHARED, but not '/', then you're out of luck - figuring that
+ * out would be too much work to be worth it.
+ */
+#define LINELEN 4096
+int detect_shared_rootfs(void)
+{
+ char buf[LINELEN], *p;
+ FILE *f;
+ int i;
+ char *p2;
+
+ f = fopen("/proc/self/mountinfo", "r");
+ if (!f)
+ return 0;
+ while (fgets(buf, LINELEN, f)) {
+ for (p = buf, i=0; p && i < 4; i++)
+ p = index(p+1, ' ');
+ if (!p)
+ continue;
+ p2 = index(p+1, ' ');
+ if (!p2)
+ continue;
+ *p2 = '\0';
+ if (strcmp(p+1, "/") == 0) {
+ // this is '/'. is it shared?
+ p = index(p2+1, ' ');
+ if (p && strstr(p, "shared:")) {
+ fclose(f);
+ return 1;
+ }
+ }
+ }
+ fclose(f);
+ return 0;
+}
#define FNV1A_64_INIT ((uint64_t)0xcbf29ce484222325ULL)
uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval);
#endif
+
+int detect_shared_rootfs(void);