Путеводитель по Руководству Linux

  User  |  Syst  |  Libr  |  Device  |  Files  |  Other  |  Admin  |  Head  |



   mount_setattr    ( 2 )

изменить свойства монтирования или дерева монтирования (change properties of a mount or mount tree)

  Name  |  Synopsis  |  Description  |  Return value  |  Error  |  Versions  |  Conforming to  |  Note  |    Examples    |  See also  |

Примеры (Examples)

/*
        * This program allows the caller to create a new detached mount
        * and set various properties on it.
        */
       #define _GNU_SOURCE
       #include <errno.h>
       #include <fcntl.h>
       #include <getopt.h>
       #include <linux/mount.h>
       #include <linux/types.h>
       #include <stdbool.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <sys/syscall.h>
       #include <unistd.h>

static inline int mount_setattr(int dirfd, const char *pathname, unsigned int flags, struct mount_attr *attr, size_t size) { return syscall(SYS_mount_setattr, dirfd, pathname, flags, attr, size); }

static inline int open_tree(int dirfd, const char *filename, unsigned int flags) { return syscall(SYS_open_tree, dirfd, filename, flags); }

static inline int move_mount(int from_dirfd, const char *from_pathname, int to_dirfd, const char *to_pathname, unsigned int flags) { return syscall(SYS_move_mount, from_dirfd, from_pathname, to_dirfd, to_pathname, flags); }

static const struct option longopts[] = { {"map-mount", required_argument, NULL, 'a'}, {"recursive", no_argument, NULL, 'b'}, {"read-only", no_argument, NULL, 'c'}, {"block-setid", no_argument, NULL, 'd'}, {"block-devices", no_argument, NULL, 'e'}, {"block-exec", no_argument, NULL, 'f'}, {"no-access-time", no_argument, NULL, 'g'}, { NULL, 0, NULL, 0 }, };

#define exit_log(format, ...) do \ { \ fprintf(stderr, format, ##__VA_ARGS__); \ exit(EXIT_FAILURE); \ } while (0)

int main(int argc, char *argv[]) { struct mount_attr *attr = &(struct mount_attr){}; int fd_userns = -1; bool recursive = false; int index = 0; int ret;

while ((ret = getopt_long_only(argc, argv, "", longopts, &index)) != -1) { switch (ret) { case 'a': fd_userns = open(optarg, O_RDONLY | O_CLOEXEC); if (fd_userns == -1) exit_log("%m - Failed top open %s\n", optarg); break; case 'b': recursive = true; break; case 'c': attr->attr_set |= MOUNT_ATTR_RDONLY; break; case 'd': attr->attr_set |= MOUNT_ATTR_NOSUID; break; case 'e': attr->attr_set |= MOUNT_ATTR_NODEV; break; case 'f': attr->attr_set |= MOUNT_ATTR_NOEXEC; break; case 'g': attr->attr_set |= MOUNT_ATTR_NOATIME; attr->attr_clr |= MOUNT_ATTR__ATIME; break; default: exit_log("Invalid argument specified"); } }

if ((argc - optind) < 2) exit_log("Missing source or target mount point\n");

const char *source = argv[optind]; const char *target = argv[optind + 1];

/* In the following, -1 as the 'dirfd' argument ensures that open_tree() fails if 'source' is not an absolute pathname. */

int fd_tree = open_tree(-1, source, OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC | AT_EMPTY_PATH | (recursive ? AT_RECURSIVE : 0)); if (fd_tree == -1) exit_log("%m - Failed to open %s\n", source);

if (fd_userns >= 0) { attr->attr_set |= MOUNT_ATTR_IDMAP; attr->userns_fd = fd_userns; }

ret = mount_setattr(fd_tree, "", AT_EMPTY_PATH | (recursive ? AT_RECURSIVE : 0), attr, sizeof(struct mount_attr)); if (ret == -1) exit_log("%m - Failed to change mount attributes\n");

close(fd_userns);

/* In the following, -1 as the 'to_dirfd' argument ensures that open_tree() fails if 'target' is not an absolute pathname. */

ret = move_mount(fd_tree, "", -1, target, MOVE_MOUNT_F_EMPTY_PATH); if (ret == -1) exit_log("%m - Failed to attach mount to %s\n", target);

close(fd_tree);

exit(EXIT_SUCCESS); }