123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /* fd-based mount test.
- *
- * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells ([email protected])
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <sys/prctl.h>
- #include <sys/wait.h>
- #include <linux/mount.h>
- #include <linux/unistd.h>
- #define E(x) do { if ((x) == -1) { perror(#x); exit(1); } } while(0)
- static void check_messages(int fd)
- {
- char buf[4096];
- int err, n;
- err = errno;
- for (;;) {
- n = read(fd, buf, sizeof(buf));
- if (n < 0)
- break;
- n -= 2;
- switch (buf[0]) {
- case 'e':
- fprintf(stderr, "Error: %*.*s\n", n, n, buf + 2);
- break;
- case 'w':
- fprintf(stderr, "Warning: %*.*s\n", n, n, buf + 2);
- break;
- case 'i':
- fprintf(stderr, "Info: %*.*s\n", n, n, buf + 2);
- break;
- }
- }
- errno = err;
- }
- static __attribute__((noreturn))
- void mount_error(int fd, const char *s)
- {
- check_messages(fd);
- fprintf(stderr, "%s: %m\n", s);
- exit(1);
- }
- /* Hope -1 isn't a syscall */
- #ifndef __NR_fsopen
- #define __NR_fsopen -1
- #endif
- #ifndef __NR_fsmount
- #define __NR_fsmount -1
- #endif
- #ifndef __NR_fsconfig
- #define __NR_fsconfig -1
- #endif
- #ifndef __NR_move_mount
- #define __NR_move_mount -1
- #endif
- static inline int fsopen(const char *fs_name, unsigned int flags)
- {
- return syscall(__NR_fsopen, fs_name, flags);
- }
- static inline int fsmount(int fsfd, unsigned int flags, unsigned int ms_flags)
- {
- return syscall(__NR_fsmount, fsfd, flags, ms_flags);
- }
- static inline int fsconfig(int fsfd, unsigned int cmd,
- const char *key, const void *val, int aux)
- {
- return syscall(__NR_fsconfig, fsfd, cmd, key, val, aux);
- }
- static inline 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 E_fsconfig(fd, cmd, key, val, aux) \
- do { \
- if (fsconfig(fd, cmd, key, val, aux) == -1) \
- mount_error(fd, key ?: "create"); \
- } while (0)
- int main(int argc, char *argv[])
- {
- int fsfd, mfd;
- /* Mount a publically available AFS filesystem */
- fsfd = fsopen("afs", 0);
- if (fsfd == -1) {
- perror("fsopen");
- exit(1);
- }
- E_fsconfig(fsfd, FSCONFIG_SET_STRING, "source", "#grand.central.org:root.cell.", 0);
- E_fsconfig(fsfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0);
- mfd = fsmount(fsfd, 0, MOUNT_ATTR_RDONLY);
- if (mfd < 0)
- mount_error(fsfd, "fsmount");
- E(close(fsfd));
- if (move_mount(mfd, "", AT_FDCWD, "/mnt", MOVE_MOUNT_F_EMPTY_PATH) < 0) {
- perror("move_mount");
- exit(1);
- }
- E(close(mfd));
- exit(0);
- }
|