1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Cluster File Systems, Inc.
5 * Author: Robert Read <rread@clusterfs.com>
6 * Author: Nathan Rutman <nathan@clusterfs.com>
8 * This file is part of Lustre, http://www.lustre.org.
10 * Lustre is free software; you can redistribute it and/or
11 * modify it under the terms of version 2 of the GNU General Public
12 * License as published by the Free Software Foundation.
14 * Lustre is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with Lustre; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 #include <sys/mount.h>
36 #include <sys/utsname.h>
38 #include <linux/lustre_disk.h>
39 #include <portals/ptlctl.h>
46 static char *progname = NULL;
50 fprintf(out, "usage: %s <mdsnode>:/<mdsname>/<cfgname> <mountpt> "
51 "[-fhnv] [-o mntopt]\n", progname);
52 fprintf(out, "\t<mdsnode>: nid of MDS (config) node\n"
53 "\t<mdsname>: name of MDS service (e.g. mds1)\n"
54 "\t<cfgname>: name of client config (e.g. client)\n"
55 "\t<mountpt>: filesystem mountpoint (e.g. /mnt/lustre)\n"
56 "\t-f|--fake: fake mount (updates /etc/mtab)\n"
57 "\t--force: force mount even if already in /etc/mtab\n"
58 "\t-h|--help: print this usage message\n"
59 "\t-n|--nomtab: do not update /etc/mtab after mount\n"
60 "\t-v|--verbose: print verbose config settings\n");
66 static int version = 0;
72 fd = open("/proc/sys/kernel/osrelease", O_RDONLY);
74 fprintf(stderr, "Warning: Can't resolve kernel version,"
80 if (strncmp(release, "2.4.", 4) == 0)
88 static int load_module(char *module_name)
94 printf("loading %s\n", module_name);
95 sprintf(buf, "/sbin/modprobe %s", module_name);
98 fprintf(stderr, "%s: failed to modprobe %s: %s\n",
99 progname, module_name, strerror(errno));
100 fprintf(stderr, "Check /etc/modules.conf\n");
105 static int load_modules(struct lustre_mount_data *lmd)
109 if (lmd_is_client(lmd)) {
110 rc = load_module("lustre");
112 rc = load_module("mds");
114 rc = load_module("oss");
119 static int check_mtab_entry(char *spec, char *mtpt, char *type)
127 fp = setmntent(MOUNTED, "r");
131 while ((mnt = getmntent(fp)) != NULL) {
132 if (strcmp(mnt->mnt_fsname, spec) == 0 &&
133 strcmp(mnt->mnt_dir, mtpt) == 0 &&
134 strcmp(mnt->mnt_type, type) == 0) {
135 fprintf(stderr, "%s: according to %s %s is "
136 "already mounted on %s\n",
137 progname, MOUNTED, spec, mtpt);
138 return(1); /* or should we return an error? */
147 update_mtab_entry(char *spec, char *mtpt, char *type, char *opts,
148 int flags, int freq, int pass)
154 mnt.mnt_fsname = spec;
157 mnt.mnt_opts = opts ? opts : "";
159 mnt.mnt_passno = pass;
161 fp = setmntent(MOUNTED, "a+");
163 fprintf(stderr, "%s: setmntent(%s): %s:",
164 progname, MOUNTED, strerror (errno));
167 if ((addmntent(fp, &mnt)) == 1) {
168 fprintf(stderr, "%s: addmntent: %s:",
169 progname, strerror (errno));
179 init_options(struct lustre_mount_data *lmd)
181 memset(lmd, 0, sizeof(*lmd));
182 //gethostname(lmd->lmd_hostname, sizeof lmd->lmd_hostname);
183 //lmd->lmd_server_nid = PTL_NID_ANY;
184 //ptl_parse_nid(&lmd->lmd_nid, lmd->lmd_hostname);
185 //lmd->lmd_port = 988; /* XXX define LUSTRE_DEFAULT_PORT */
186 //lmd->lmd_nal = SOCKNAL;
187 //ptl_parse_ipaddr(&lmd->lmd_ipaddr, lmd->lmd_hostname);
188 lmd->lmd_magic = LMD_MAGIC;
189 lmd->lmd_flags = LMD_FLG_MNTCNF;
190 lmd->lmd_mgsnid.primary = PTL_NID_ANY;
191 lmd->lmd_mgsnid.backup = PTL_NID_ANY;
196 print_options(struct lustre_mount_data *lmd)
198 printf("mgmt primary nid: %s\n",
199 libcfs_nid2str(lmd->lmd_mgsnid.primary));
200 printf("mgmt backup nid: %s\n",
201 libcfs_nid2str(lmd->lmd_mgsnid.backup));
202 printf("device: %s\n", lmd->lmd_dev);
203 printf("mount point: %s\n", lmd->lmd_mtpt);
204 printf("options: %s\n", lmd->lmd_opts);
205 printf("flags: %x\n", lmd->lmd_flags);
206 if (lmd_is_client(lmd))
214 /*****************************************************************************
216 * This part was cribbed from util-linux/mount/mount.c. There was no clear
217 * license information, but many other files in the package are identified as
218 * GNU GPL, so it's a pretty safe bet that was their intent.
220 ****************************************************************************/
222 const char *opt; /* option name */
223 int skip; /* skip in mtab option string */
224 int inv; /* true if flag value should be inverted */
225 int mask; /* flag mask value */
228 static const struct opt_map opt_map[] = {
229 { "defaults", 0, 0, 0 }, /* default options */
230 { "rw", 1, 1, MS_RDONLY }, /* read-write */
231 { "ro", 0, 0, MS_RDONLY }, /* read-only */
232 { "exec", 0, 1, MS_NOEXEC }, /* permit execution of binaries */
233 { "noexec", 0, 0, MS_NOEXEC }, /* don't execute binaries */
234 { "suid", 0, 1, MS_NOSUID }, /* honor suid executables */
235 { "nosuid", 0, 0, MS_NOSUID }, /* don't honor suid executables */
236 { "dev", 0, 1, MS_NODEV }, /* interpret device files */
237 { "nodev", 0, 0, MS_NODEV }, /* don't interpret devices */
238 { "async", 0, 1, MS_SYNCHRONOUS}, /* asynchronous I/O */
239 { "auto", 0, 0, 0 }, /* Can be mounted using -a */
240 { "noauto", 0, 0, 0 }, /* Can only be mounted explicitly */
241 { "nousers", 0, 1, 0 }, /* Forbid ordinary user to mount */
242 { "nouser", 0, 1, 0 }, /* Forbid ordinary user to mount */
243 { "noowner", 0, 1, 0 }, /* Device owner has no special privs */
244 { "_netdev", 0, 0, 0 }, /* Device accessible only via network */
247 /****************************************************************************/
249 static int parse_one_option(const char *check, int *flagp)
251 const struct opt_map *opt;
253 for (opt = &opt_map[0]; opt->opt != NULL; opt++) {
254 if (strcmp(check, opt->opt) == 0) {
256 *flagp &= ~(opt->mask);
265 int parse_options(char *options, struct lustre_mount_data *lmd, int *flagp)
271 /* parsing ideas here taken from util-linux/mount/nfsmount.c */
272 for (opt = strtok(options, ","); opt; opt = strtok(NULL, ",")) {
273 if ((opteq = strchr(opt, '='))) {
274 val = atoi(opteq + 1);
277 /* All the network options have gone :)) */
279 fprintf(stderr, "%s: unknown option '%s'\n",
284 if (parse_one_option(opt, flagp))
287 fprintf(stderr, "%s: unknown option '%s'\n",
296 build_data(char *source, char *target, char *options,
297 struct lustre_mount_data *lmd, int *flagp)
301 char *devname = NULL;
305 if (lmd_bad_magic(lmd))
308 if (strlen(source) >= sizeof(buf)) {
309 fprintf(stderr, "%s: device name too long\n",
315 if ((s = strchr(buf, ':'))) {
319 lmd->lmd_flags |= LMD_FLG_CLIENT;
321 /* <mgsnid>[,<alt mgsnid>]:/fsname[/fsetname[/subdir/]]
322 nid=mgsnid, devname=fsname */
325 while (*++s == '/') /*spin*/;
326 devname = s; /* for clients, devname=fsname */
328 rc = parse_options(options, lmd, flagp);
332 if (lmd->lmd_mgsnid.primary != PTL_NID_ANY)
333 /* In case it was defined as -o mgmtnode= */
334 //FIXME set_nid_pair(&lmd->lmd_mgsnid, nid);
335 if (lmd->lmd_mgsnid.primary == PTL_NID_ANY) {
336 fprintf(stderr, "%s: can't parse nid '%s'\n",
347 /* We have to keep the loop= option in the mtab file
348 in order for umount to free the loop device. The strtok
349 in parse_options terminates the options list at the first
350 comma, so we're saving a local copy here. */
351 strcpy(buf, options);
352 rc = parse_options(options, lmd, flagp);
355 strcpy(options, buf);
357 // move into lustre: rc = read_mount_options(source, target, lmd);
360 if (strlen(devname) + 1 > sizeof(lmd->lmd_dev)) {
361 fprintf(stderr, "%s: device name too long\n", progname);
364 strcpy(lmd->lmd_dev, devname);
366 if (strlen(target) + 1 > sizeof(lmd->lmd_mtpt)) {
367 fprintf(stderr, "%s: mount point too long\n", progname);
370 strcpy(lmd->lmd_mtpt, target);
377 int main(int argc, char *const argv[])
379 char *source, *target, *options = "";
380 int i, nargs = 3, opt, rc, flags;
381 struct lustre_mount_data lmd;
382 static struct option long_opt[] = {
386 {"nomtab", 0, 0, 'n'},
387 {"options", 1, 0, 'o'},
388 {"verbose", 0, 0, 'v'},
392 progname = strrchr(argv[0], '/');
393 progname = progname ? progname + 1 : argv[0];
395 while ((opt = getopt_long(argc, argv, "fhno:v",
396 long_opt, NULL)) != EOF){
400 printf("force: %d\n", force);
405 printf("fake: %d\n", fake);
413 printf("nomtab: %d\n", nomtab);
422 printf("verbose: %d\n", verbose);
426 fprintf(stderr, "%s: unknown option '%c'\n",
433 if (optind + 2 > argc) {
434 fprintf(stderr, "%s: too few arguments\n", progname);
438 source = argv[optind];
439 target = argv[optind + 1];
442 for (i = 0; i < argc; i++)
443 printf("arg[%d] = %s\n", i, argv[i]);
444 printf("source = %s, target = %s\n", source, target);
447 if (!force && check_mtab_entry(source, target, "lustre"))
451 rc = build_data(source, target, options, &lmd, &flags);
456 rc = access(target, F_OK);
459 fprintf(stderr, "%s: %s inaccessible: %s\n", progname, target,
465 if ((rc = load_modules(&lmd))) {
470 /* flags and target get to lustre_get_sb, but not
471 lustre_fill_super. Lustre ignores the flags, but mount
473 rc = mount(source, target, "lustre", flags, (void *)&lmd);
475 fprintf(stderr, "%s: mount(%s, %s) failed: %s\n", source,
476 target, progname, strerror(errno));
478 fprintf(stderr, "Are the lustre modules loaded?\n"
479 "Check /etc/modules.conf and /proc/filesystems\n");
481 } else if (!nomtab) {
482 rc = update_mtab_entry(source, target, "lustre", options,0,0,0);