^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* fd-based mount test.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <sys/prctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <sys/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define E(x) do { if ((x) == -1) { perror(#x); exit(1); } } while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static void check_messages(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) char buf[4096];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int err, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) err = errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) n = read(fd, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) n -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) switch (buf[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) case 'e':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) fprintf(stderr, "Error: %*.*s\n", n, n, buf + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) case 'w':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) fprintf(stderr, "Warning: %*.*s\n", n, n, buf + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) fprintf(stderr, "Info: %*.*s\n", n, n, buf + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) errno = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static __attribute__((noreturn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) void mount_error(int fd, const char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) check_messages(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) fprintf(stderr, "%s: %m\n", s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* Hope -1 isn't a syscall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #ifndef __NR_fsopen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define __NR_fsopen -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #ifndef __NR_fsmount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define __NR_fsmount -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #ifndef __NR_fsconfig
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define __NR_fsconfig -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #ifndef __NR_move_mount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define __NR_move_mount -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static inline int fsopen(const char *fs_name, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return syscall(__NR_fsopen, fs_name, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static inline int fsmount(int fsfd, unsigned int flags, unsigned int ms_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return syscall(__NR_fsmount, fsfd, flags, ms_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static inline int fsconfig(int fsfd, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) const char *key, const void *val, int aux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return syscall(__NR_fsconfig, fsfd, cmd, key, val, aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static inline int move_mount(int from_dfd, const char *from_pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int to_dfd, const char *to_pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return syscall(__NR_move_mount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) from_dfd, from_pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) to_dfd, to_pathname, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define E_fsconfig(fd, cmd, key, val, aux) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (fsconfig(fd, cmd, key, val, aux) == -1) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) mount_error(fd, key ?: "create"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int main(int argc, char *argv[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int fsfd, mfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Mount a publically available AFS filesystem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) fsfd = fsopen("afs", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (fsfd == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) perror("fsopen");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) E_fsconfig(fsfd, FSCONFIG_SET_STRING, "source", "#grand.central.org:root.cell.", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) E_fsconfig(fsfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mfd = fsmount(fsfd, 0, MOUNT_ATTR_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (mfd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) mount_error(fsfd, "fsmount");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) E(close(fsfd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (move_mount(mfd, "", AT_FDCWD, "/mnt", MOVE_MOUNT_F_EMPTY_PATH) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) perror("move_mount");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) E(close(mfd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) exit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }