mount_puffs.c revision 1.5 1 1.5 pho /* $NetBSD: mount_puffs.c,v 1.5 2016/11/23 14:33:29 pho Exp $ */
2 1.1 pooka
3 1.1 pooka /*
4 1.1 pooka * Copyright (c) 2010 Antti Kantee. All Rights Reserved.
5 1.1 pooka *
6 1.1 pooka * Redistribution and use in source and binary forms, with or without
7 1.1 pooka * modification, are permitted provided that the following conditions
8 1.1 pooka * are met:
9 1.1 pooka * 1. Redistributions of source code must retain the above copyright
10 1.1 pooka * notice, this list of conditions and the following disclaimer.
11 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright
12 1.1 pooka * notice, this list of conditions and the following disclaimer in the
13 1.1 pooka * documentation and/or other materials provided with the distribution.
14 1.1 pooka *
15 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16 1.1 pooka * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 1.1 pooka * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 1.1 pooka * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 1.1 pooka * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 1.1 pooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 1.1 pooka * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 1.1 pooka * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 1.1 pooka * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 1.1 pooka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 1.1 pooka * SUCH DAMAGE.
26 1.1 pooka */
27 1.1 pooka
28 1.1 pooka /*
29 1.5 pho * This is to support -o getargs without having to replicate it in
30 1.5 pho * every file server. It also allows puffs filesystems to be mounted
31 1.5 pho * via "mount -a".
32 1.1 pooka */
33 1.1 pooka
34 1.1 pooka #include <sys/cdefs.h>
35 1.1 pooka #ifndef lint
36 1.5 pho __RCSID("$NetBSD: mount_puffs.c,v 1.5 2016/11/23 14:33:29 pho Exp $");
37 1.1 pooka #endif /* !lint */
38 1.1 pooka
39 1.1 pooka #include <sys/param.h>
40 1.1 pooka #include <sys/mount.h>
41 1.1 pooka
42 1.1 pooka #include <fs/puffs/puffs_msgif.h>
43 1.1 pooka
44 1.1 pooka #include <err.h>
45 1.1 pooka #include <stdio.h>
46 1.1 pooka #include <stdlib.h>
47 1.5 pho #include <string.h>
48 1.5 pho #include <sys/cdefs.h>
49 1.1 pooka #include <unistd.h>
50 1.5 pho #include <util.h>
51 1.1 pooka
52 1.5 pho static int
53 1.1 pooka usage(void)
54 1.1 pooka {
55 1.1 pooka
56 1.5 pho fprintf(stderr, "usage: %s [-o options] program[#source] mountpoint\n", getprogname());
57 1.5 pho return 1;
58 1.1 pooka }
59 1.1 pooka
60 1.5 pho static int show_puffs_mount_args(const char *mountpoint)
61 1.1 pooka {
62 1.1 pooka const char *vtypes[] = { VNODE_TYPES };
63 1.1 pooka struct puffs_kargs kargs;
64 1.1 pooka
65 1.5 pho if (mount(MOUNT_PUFFS, mountpoint, MNT_GETARGS, &kargs, sizeof(kargs)) == -1)
66 1.5 pho err(1, "mount");
67 1.1 pooka
68 1.3 pooka printf("version=%d, ", kargs.pa_vers);
69 1.1 pooka printf("flags=0x%x, ", kargs.pa_flags);
70 1.1 pooka
71 1.1 pooka printf("root cookie=%p, ", kargs.pa_root_cookie);
72 1.1 pooka printf("root type=%s", vtypes[kargs.pa_root_vtype]);
73 1.1 pooka
74 1.1 pooka if (kargs.pa_root_vtype != VDIR)
75 1.1 pooka printf(", root size=%llu",
76 1.1 pooka (unsigned long long)kargs.pa_root_vsize);
77 1.1 pooka if (kargs.pa_root_vtype == VCHR || kargs.pa_root_vtype == VBLK)
78 1.1 pooka printf(", root rdev=0x%" PRIx64, (uint64_t)kargs.pa_root_rdev);
79 1.1 pooka printf("\n");
80 1.2 pooka
81 1.2 pooka return 0;
82 1.1 pooka }
83 1.5 pho
84 1.5 pho static int
85 1.5 pho mount_puffs_filesystem(const char *program, const char *opts,
86 1.5 pho const char *source, const char *mountpoint)
87 1.5 pho {
88 1.5 pho int argc = 0;
89 1.5 pho const char **argv;
90 1.5 pho int rv = 0;
91 1.5 pho
92 1.5 pho /* Construct an argument vector:
93 1.5 pho * program [-o opts] [source] mountpoint */
94 1.5 pho argv = ecalloc(1 + 2 + 1 + 1, sizeof(*argv));
95 1.5 pho argv[argc++] = program;
96 1.5 pho if (opts != NULL) {
97 1.5 pho argv[argc++] = "-o";
98 1.5 pho argv[argc++] = opts;
99 1.5 pho }
100 1.5 pho if (source != NULL) {
101 1.5 pho argv[argc++] = source;
102 1.5 pho }
103 1.5 pho argv[argc++] = mountpoint;
104 1.5 pho argv[argc] = NULL;
105 1.5 pho
106 1.5 pho /* We intentionally use execvp(3) here because the program can
107 1.5 pho * actually be a basename. */
108 1.5 pho if (execvp(program, __UNCONST(argv)) == -1) {
109 1.5 pho warn("Cannot execute %s", program);
110 1.5 pho rv = 1;
111 1.5 pho }
112 1.5 pho
113 1.5 pho free(argv);
114 1.5 pho return rv;
115 1.5 pho }
116 1.5 pho
117 1.5 pho static void add_opt(char **opts, const char *opt)
118 1.5 pho {
119 1.5 pho const size_t orig_len = *opts == NULL ? 0 : strlen(*opts);
120 1.5 pho
121 1.5 pho *opts = erealloc(*opts, orig_len + 1 + strlen(opt) + 1);
122 1.5 pho
123 1.5 pho if (orig_len == 0) {
124 1.5 pho strcpy(*opts, opt);
125 1.5 pho }
126 1.5 pho else {
127 1.5 pho strcat(*opts, ",");
128 1.5 pho strcat(*opts, opt);
129 1.5 pho }
130 1.5 pho }
131 1.5 pho
132 1.5 pho int
133 1.5 pho main(int argc, char *argv[])
134 1.5 pho {
135 1.5 pho int mntflags = 0;
136 1.5 pho int ch;
137 1.5 pho char *opts = NULL;
138 1.5 pho int rv = 0;
139 1.5 pho
140 1.5 pho while ((ch = getopt(argc, argv, "o:")) != -1) {
141 1.5 pho switch (ch) {
142 1.5 pho case 'o':
143 1.5 pho for (char *opt = optarg; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
144 1.5 pho if (strcmp(opt, "getargs") == 0) {
145 1.5 pho mntflags |= MNT_GETARGS;
146 1.5 pho break; /* No need to parse it any further. */
147 1.5 pho }
148 1.5 pho else {
149 1.5 pho add_opt(&opts, opt);
150 1.5 pho }
151 1.5 pho }
152 1.5 pho break;
153 1.5 pho default:
154 1.5 pho rv = usage();
155 1.5 pho goto free_opts;
156 1.5 pho }
157 1.5 pho }
158 1.5 pho argc -= optind;
159 1.5 pho argv += optind;
160 1.5 pho
161 1.5 pho if (argc != 2) {
162 1.5 pho rv = usage();
163 1.5 pho goto free_opts;
164 1.5 pho }
165 1.5 pho
166 1.5 pho if (mntflags & MNT_GETARGS) {
167 1.5 pho /* Special case for -o getargs: retrieve kernel arguments for
168 1.5 pho * an already mounted filesystem. */
169 1.5 pho rv = show_puffs_mount_args(argv[1]);
170 1.5 pho }
171 1.5 pho else {
172 1.5 pho /* Split the program name and source. This is to allow
173 1.5 pho * filesystems to be mounted via "mount -a" i.e. /etc/fstab */
174 1.5 pho char *source = argv[0];
175 1.5 pho char *program = strsep(&source, "#");
176 1.5 pho
177 1.5 pho rv = mount_puffs_filesystem(program, opts, source, argv[1]);
178 1.5 pho }
179 1.5 pho
180 1.5 pho free_opts:
181 1.5 pho free(opts);
182 1.5 pho return rv;
183 1.5 pho }
184