/* cc fsmount.c -o fsmount -Wall */ #include #include #include #include #include #include #include #include #include int fsopen(const char *fs_name, unsigned int flags) { return syscall(__NR_fsopen, fs_name, flags); } int fsconfig(int fsfd, unsigned int cmd, const char *key, const void *val, int aux) { return syscall(__NR_fsconfig, fsfd, cmd, key, val, aux); } int fsmount(int fsfd, unsigned int flags, unsigned int ms_flags) { return syscall(__NR_fsmount, fsfd, flags, ms_flags); } int move_mount(int from_dfd, const char *from_pathname, int to_dfd, const char *to_pathname, unsigned int flags) { return syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd, to_pathname, flags); } #define MAX_OPS 10 int fsconfig_opts(int fd, char *src, char *opts) { int ret, i, max_entries = 0; int cmd[MAX_OPS]; char *key[MAX_OPS], *value[MAX_OPS]; char *src_str = "source"; cmd[0] = FSCONFIG_SET_STRING; key[0] = src_str; value[0] = src; for (i = 1; i < MAX_OPS; i++) { value[i] = strsep(&opts, ","); if (!value[i]) { max_entries = i + 1; break; } cmd[i] = FSCONFIG_SET_STRING; } for (i = 1; value[i] != NULL; i++) { key[i] = strsep(&value[i], "="); if (!value[i]) cmd[i] = FSCONFIG_SET_FLAG; } cmd[i] = FSCONFIG_CMD_CREATE; key[i] = NULL; value[i] = NULL; for (i = 0; i != max_entries; i++) { printf("fsconfig(0x%x, %s, %s, 0)\n", cmd[i], key[i], value[i]); ret = fsconfig(fd, cmd[i], key[i], value[i], 0); if (ret < 0) { fprintf(stderr, "Failed fsconfig(2): %s\n", strerror(errno)); return -1; } } return 0; } int main(int argc, char *argv[]) { int ret, fsfd, mfd; unsigned int mount_attrs = 0; char *opts; if (argc != 5) { fprintf(stderr, "usage: %s \n", argv[0]); return 1; } fsfd = fsopen(argv[1], 0); if (fsfd < 0) { fprintf(stderr, "Failed fsopen(2): %s\n", strerror(errno)); return -1; } if (!strncmp (argv[1], "nfs", 3)) mount_attrs = MS_NODEV; opts = strdup(argv[4]); ret = fsconfig_opts(fsfd, argv[2], opts); if (ret < 0) { fprintf(stderr, "Failed to add options: %s\n", argv[4]); close(fsfd); return -1; } printf("Successfully added options: %s\n", argv[4]); mfd = fsmount(fsfd, 0, mount_attrs); if (mfd < 0) { fprintf(stderr, "Failed fsmount(2): %s\n", strerror(errno)); return -1; } close(fsfd); ret = move_mount(mfd, "", AT_FDCWD, argv[3], MOVE_MOUNT_F_EMPTY_PATH); if (ret < 0) { fprintf(stderr, "Failed move_mount(2): %s\n", strerror(errno)); return -1; } close(mfd); printf("Successfully mounted on: %s\n", argv[3]); return 0; }