7 #include "common/module.h"
8 #include "common/secret.h"
9 #include "include/addr_parsing.h"
12 # define MS_RELATIME (1<<21)
15 #define MAX_SECRET_LEN 1000
16 #define MAX_SECRET_OPTION_LEN (MAX_SECRET_LEN + 7)
19 int skip_mtab_flag = 0;
20 static const char * const EMPTY_STRING = "";
22 /* TODO duplicates logic from kernel */
23 #define CEPH_AUTH_NAME_DEFAULT "guest"
27 static void block_signals (int how)
32 sigdelset(&sigs, SIGTRAP);
33 sigdelset(&sigs, SIGSEGV);
34 sigprocmask (how, &sigs, (sigset_t *) 0);
37 static char *mount_resolve_src(const char *orig_str)
42 char *buf = strdup(orig_str);
44 mount_path = strstr(buf, ":/");
46 printf("source mount path was not specified\n");
50 if (mount_path == buf) {
51 printf("server address expected\n");
60 printf("incorrect source mount path\n");
65 src = resolve_addrs(buf);
72 pos = safe_cat(&src, &len, len, ":");
73 safe_cat(&src, &len, pos, mount_path);
80 * this one is partialy based on parse_options() from cifs.mount.c
82 static char *parse_options(const char *data, int *filesys_flags)
84 char * next_keyword = NULL;
91 char secret[MAX_SECRET_LEN];
92 char *saw_name = NULL;
93 char *saw_secret = NULL;
96 printf("parsing options: %s\n", data);
100 /* check if ends with trailing comma */
103 next_keyword = strchr(data,',');
105 /* temporarily null terminate end of keyword=value pair */
109 /* temporarily null terminate keyword to make keyword and value distinct */
110 if ((value = strchr(data, '=')) != NULL) {
117 if (strncmp(data, "ro", 2) == 0) {
118 *filesys_flags |= MS_RDONLY;
119 } else if (strncmp(data, "rw", 2) == 0) {
120 *filesys_flags &= ~MS_RDONLY;
121 } else if (strncmp(data, "nosuid", 6) == 0) {
122 *filesys_flags |= MS_NOSUID;
123 } else if (strncmp(data, "suid", 4) == 0) {
124 *filesys_flags &= ~MS_NOSUID;
125 } else if (strncmp(data, "dev", 3) == 0) {
126 *filesys_flags &= ~MS_NODEV;
127 } else if (strncmp(data, "nodev", 5) == 0) {
128 *filesys_flags |= MS_NODEV;
129 } else if (strncmp(data, "noexec", 6) == 0) {
130 *filesys_flags |= MS_NOEXEC;
131 } else if (strncmp(data, "exec", 4) == 0) {
132 *filesys_flags &= ~MS_NOEXEC;
133 } else if (strncmp(data, "sync", 4) == 0) {
134 *filesys_flags |= MS_SYNCHRONOUS;
135 } else if (strncmp(data, "remount", 7) == 0) {
136 *filesys_flags |= MS_REMOUNT;
137 } else if (strncmp(data, "mandlock", 8) == 0) {
138 *filesys_flags |= MS_MANDLOCK;
139 } else if ((strncmp(data, "nobrl", 5) == 0) ||
140 (strncmp(data, "nolock", 6) == 0)) {
141 *filesys_flags &= ~MS_MANDLOCK;
142 } else if (strncmp(data, "noatime", 7) == 0) {
143 *filesys_flags |= MS_NOATIME;
144 } else if (strncmp(data, "nodiratime", 10) == 0) {
145 *filesys_flags |= MS_NODIRATIME;
146 } else if (strncmp(data, "relatime", 8) == 0) {
147 *filesys_flags |= MS_RELATIME;
149 } else if (strncmp(data, "noauto", 6) == 0) {
150 skip = 1; /* ignore */
151 } else if (strncmp(data, "_netdev", 7) == 0) {
152 skip = 1; /* ignore */
154 } else if (strncmp(data, "secretfile", 10) == 0) {
155 if (!value || !*value) {
156 printf("keyword secretfile found, but no secret file specified\n");
161 if (read_secret_from_file(value, secret, sizeof(secret)) < 0) {
162 printf("error reading secret file\n");
166 /* see comment for "secret" */
169 } else if (strncmp(data, "secret", 6) == 0) {
170 if (!value || !*value) {
171 printf("mount option secret requires a value.\n");
176 /* secret is only added to kernel options as
177 backwards compatibility, if add_key doesn't
178 recognize our keytype; hence, it is skipped
179 here and appended to options on add_key
181 size_t len = sizeof(secret);
182 strncpy(secret, value, len-1);
183 secret[len-1] = '\0';
186 } else if (strncmp(data, "name", 4) == 0) {
187 if (!value || !*value) {
188 printf("mount option name requires a value.\n");
192 /* take a copy of the name, to be used for
193 naming the keys that we add to kernel; */
195 saw_name = strdup(value);
197 printf("out of memory.\n");
204 fprintf(stderr, "mount.ceph: unrecognized mount option \"%s\", "
205 "passing to kernel.\n", data);
209 /* Copy (possibly modified) option to out */
212 pos = safe_cat(&out, &out_len, pos, ",");
215 pos = safe_cat(&out, &out_len, pos, data);
216 pos = safe_cat(&out, &out_len, pos, "=");
217 pos = safe_cat(&out, &out_len, pos, value);
219 pos = safe_cat(&out, &out_len, pos, data);
226 name_pos = safe_cat(&name, &name_len, name_pos, "client.");
228 name_pos = safe_cat(&name, &name_len, name_pos, CEPH_AUTH_NAME_DEFAULT);
230 name_pos = safe_cat(&name, &name_len, name_pos, saw_name);
232 if (saw_secret || is_kernel_secret(name)) {
234 char secret_option[MAX_SECRET_OPTION_LEN];
235 ret = get_secret_option(saw_secret, name, secret_option, sizeof(secret_option));
241 pos = safe_cat(&out, &out_len, pos, ",");
243 pos = safe_cat(&out, &out_len, pos, secret_option);
249 return strdup(EMPTY_STRING);
254 static int parse_arguments(int argc, char *const *const argv,
255 const char **src, const char **node, const char **opts)
260 // There were no arguments. Just show the usage.
263 if ((!strcmp(argv[1], "-h")) || (!strcmp(argv[1], "--help"))) {
264 // The user asked for help.
268 // The first two arguments are positional
274 // Parse the remaining options
275 *opts = EMPTY_STRING;
276 for (i = 3; i < argc; ++i) {
277 if (!strcmp("-h", argv[i]))
279 else if (!strcmp("-n", argv[i]))
281 else if (!strcmp("-v", argv[i]))
283 else if (!strcmp("-o", argv[i])) {
286 printf("Option -o requires an argument.\n\n");
292 printf("Can't understand option: '%s'\n\n", argv[i]);
299 /* modprobe failing doesn't necessarily prevent from working, so this
301 static void modprobe(void)
305 r = module_load("ceph", NULL);
307 printf("failed to load ceph kernel module (%d)\n", r);
310 static void usage(const char *prog_name)
312 printf("usage: %s [src] [mount-point] [-n] [-v] [-o ceph-options]\n",
314 printf("options:\n");
315 printf("\t-h: Print this help\n");
316 printf("\t-n: Do not update /etc/mtab\n");
317 printf("\t-v: Verbose\n");
318 printf("\tceph-options: refer to mount.ceph(8)\n");
322 int main(int argc, char *argv[])
324 const char *src, *node, *opts;
330 retval = parse_arguments(argc, argv, &src, &node, &opts);
333 exit((retval > 0) ? EXIT_SUCCESS : EXIT_FAILURE);
336 rsrc = mount_resolve_src(src);
338 printf("failed to resolve source\n");
344 popts = parse_options(opts, &flags);
346 printf("failed to parse ceph_options\n");
350 block_signals(SIG_BLOCK);
352 if (mount(rsrc, node, "ceph", flags, popts)) {
356 printf("mount error: ceph filesystem not supported by the system\n");
359 printf("mount error %d = %s\n",errno,strerror(errno));
362 if (!skip_mtab_flag) {
363 update_mtab_entry(rsrc, node, "ceph", popts, flags, 0, 0);
367 block_signals(SIG_UNBLOCK);