]>
git.proxmox.com Git - ceph.git/blob - ceph/src/mount/mount.ceph.c
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
);