/* * Given a bdev (presumably blockdev-based), detect the fstype * by trying mounting (in a private mntns) it. * @bdev: bdev to investigate * @type: preallocated char* in which to write the fstype * @len: length of passed in char* * Returns length of fstype, of -1 on error */ static int detect_fs(struct bdev *bdev, char *type, int len) { int p[2], ret; size_t linelen; pid_t pid; FILE *f; char *sp1, *sp2, *sp3, *line = NULL; if (!bdev || !bdev->src || !bdev->dest) return -1; if (pipe(p) < 0) return -1; if ((pid = fork()) < 0) return -1; if (pid > 0) { int status; close(p[1]); memset(type, 0, len); ret = read(p[0], type, len-1); close(p[0]); if (ret < 0) { SYSERROR("error reading from pipe"); wait(&status); return -1; } else if (ret == 0) { ERROR("child exited early - fstype not found"); wait(&status); return -1; } wait(&status); type[len-1] = '\0'; INFO("detected fstype %s for %s", type, bdev->src); return ret; } if (unshare(CLONE_NEWNS) < 0) exit(1); ret = mount_unknow_fs(bdev->src, bdev->dest, 0); if (ret < 0) { ERROR("failed mounting %s onto %s to detect fstype", bdev->src, bdev->dest); exit(1); } // if symlink, get the real dev name char devpath[MAXPATHLEN]; char *l = linkderef(bdev->src, devpath); if (!l) exit(1); f = fopen("/proc/self/mounts", "r"); if (!f) exit(1); while (getline(&line, &linelen, f) != -1) { sp1 = index(line, ' '); if (!sp1) exit(1); *sp1 = '\0'; if (strcmp(line, l)) continue; sp2 = index(sp1+1, ' '); if (!sp2) exit(1); *sp2 = '\0'; sp3 = index(sp2+1, ' '); if (!sp3) exit(1); *sp3 = '\0'; sp2++; if (write(p[1], sp2, strlen(sp2)) != strlen(sp2)) exit(1); exit(0); } exit(1); }
/* * Given a lxc_storage (presumably blockdev-based), detect the fstype * by trying mounting (in a private mntns) it. * @lxc_storage: bdev to investigate * @type: preallocated char* in which to write the fstype * @len: length of passed in char* * Returns length of fstype, of -1 on error */ int detect_fs(struct lxc_storage *bdev, char *type, int len) { int ret; int p[2]; size_t linelen; pid_t pid; FILE *f; char *sp1, *sp2, *sp3; const char *l, *srcdev; char devpath[PATH_MAX]; char *line = NULL; if (!bdev || !bdev->src || !bdev->dest) return -1; srcdev = lxc_storage_get_path(bdev->src, bdev->type); ret = pipe(p); if (ret < 0) { SYSERROR("Failed to create pipe"); return -1; } pid = fork(); if (pid < 0) { SYSERROR("Failed to fork process"); return -1; } if (pid > 0) { int status; close(p[1]); memset(type, 0, len); ret = read(p[0], type, len - 1); if (ret < 0) { SYSERROR("Failed to read FSType from pipe"); } else if (ret == 0) { ERROR("FSType not found - child exited early"); ret = -1; } close(p[0]); wait(&status); if (ret < 0) return ret; type[len - 1] = '\0'; INFO("Detected FSType \"%s\" for \"%s\"", type, srcdev); return ret; } if (unshare(CLONE_NEWNS) < 0) _exit(EXIT_FAILURE); 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 to mount \"%s\" onto \"%s\" to detect FSType", srcdev, bdev->dest); _exit(EXIT_FAILURE); } l = linkderef(srcdev, devpath); if (!l) _exit(EXIT_FAILURE); f = fopen("/proc/self/mounts", "r"); if (!f) _exit(EXIT_FAILURE); while (getline(&line, &linelen, f) != -1) { sp1 = strchr(line, ' '); if (!sp1) _exit(EXIT_FAILURE); *sp1 = '\0'; if (strcmp(line, l)) continue; sp2 = strchr(sp1 + 1, ' '); if (!sp2) _exit(EXIT_FAILURE); *sp2 = '\0'; sp3 = strchr(sp2 + 1, ' '); if (!sp3) _exit(EXIT_FAILURE); *sp3 = '\0'; sp2++; if (write(p[1], sp2, strlen(sp2)) != strlen(sp2)) _exit(EXIT_FAILURE); _exit(EXIT_SUCCESS); } _exit(EXIT_FAILURE); }
/* * Given a lxc_storage (presumably blockdev-based), detect the fstype * by trying mounting (in a private mntns) it. * @lxc_storage: bdev to investigate * @type: preallocated char* in which to write the fstype * @len: length of passed in char* * Returns length of fstype, of -1 on error */ int detect_fs(struct lxc_storage *bdev, char *type, int len) { int ret; int p[2]; size_t linelen; pid_t pid; FILE *f; char *sp1, *sp2, *sp3; const char *l, *srcdev; char devpath[PATH_MAX]; char *line = NULL; if (!bdev || !bdev->src || !bdev->dest) return -1; srcdev = lxc_storage_get_path(bdev->src, bdev->type); ret = pipe(p); if (ret < 0) return -1; if ((pid = fork()) < 0) return -1; if (pid > 0) { int status; close(p[1]); memset(type, 0, len); ret = read(p[0], type, len - 1); close(p[0]); if (ret < 0) { SYSERROR("error reading from pipe"); wait(&status); return -1; } else if (ret == 0) { ERROR("child exited early - fstype not found"); wait(&status); return -1; } wait(&status); type[len - 1] = '\0'; INFO("detected fstype %s for %s", type, srcdev); return ret; } 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); exit(1); } l = linkderef(srcdev, devpath); if (!l) exit(1); f = fopen("/proc/self/mounts", "r"); if (!f) exit(1); while (getline(&line, &linelen, f) != -1) { sp1 = strchr(line, ' '); if (!sp1) exit(1); *sp1 = '\0'; if (strcmp(line, l)) continue; sp2 = strchr(sp1 + 1, ' '); if (!sp2) exit(1); *sp2 = '\0'; sp3 = strchr(sp2 + 1, ' '); if (!sp3) exit(1); *sp3 = '\0'; sp2++; if (write(p[1], sp2, strlen(sp2)) != strlen(sp2)) exit(1); exit(0); } exit(1); }