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>
39 #include <portals/ptlctl.h>
40 #include <linux/lustre_disk.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 if (lmd->u.srv.disk_type & MDS_DISK_TYPE)
113 rc = load_module("mds");
115 if (lmd->u.srv.disk_type & OST_DISK_TYPE)
116 rc = load_module("oss");
121 static int check_mtab_entry(char *spec, char *mtpt, char *type)
129 fp = setmntent(MOUNTED, "r");
133 while ((mnt = getmntent(fp)) != NULL) {
134 if (strcmp(mnt->mnt_fsname, spec) == 0 &&
135 strcmp(mnt->mnt_dir, mtpt) == 0 &&
136 strcmp(mnt->mnt_type, type) == 0) {
137 fprintf(stderr, "%s: according to %s %s is "
138 "already mounted on %s\n",
139 progname, MOUNTED, spec, mtpt);
140 return(1); /* or should we return an error? */
149 update_mtab_entry(char *spec, char *mtpt, char *type, char *opts,
150 int flags, int freq, int pass)
156 mnt.mnt_fsname = spec;
159 mnt.mnt_opts = opts ? opts : "";
161 mnt.mnt_passno = pass;
163 fp = setmntent(MOUNTED, "a+");
165 fprintf(stderr, "%s: setmntent(%s): %s:",
166 progname, MOUNTED, strerror (errno));
169 if ((addmntent(fp, &mnt)) == 1) {
170 fprintf(stderr, "%s: addmntent: %s:",
171 progname, strerror (errno));
181 init_options(struct lustre_mount_data *lmd)
183 memset(lmd, 0, sizeof(*lmd));
184 //gethostname(lmd->lmd_hostname, sizeof lmd->lmd_hostname);
185 //lmd->lmd_server_nid = PTL_NID_ANY;
186 //ptl_parse_nid(&lmd->lmd_nid, lmd->lmd_hostname);
187 //lmd->lmd_port = 988; /* XXX define LUSTRE_DEFAULT_PORT */
188 //lmd->lmd_nal = SOCKNAL;
189 //ptl_parse_ipaddr(&lmd->lmd_ipaddr, lmd->lmd_hostname);
190 //lmd->u.cli.lmd_async = 0;
191 lmd->lmd_magic = LMD_MAGIC;
192 lmd->lmd_nid = PTL_NID_ANY;
197 print_options(struct lustre_mount_data *lmd)
199 printf("nid: %s\n", libcfs_nid2str(lmd->lmd_nid));
201 if (lmd_is_client(lmd)) {
203 printf("mds: %s\n", lmd->u.cli.lmd_mds);
204 printf("profile: %s\n", lmd->u.cli.lmd_profile);
207 printf("service type: %x\n", lmd->u.srv.disk_type);
208 printf("device: %s\n", lmd->u.srv.lmd_source);
209 printf("fs type: %s\n", lmd->u.srv.lmd_fstype);
210 printf("fs opts: %s\n", lmd->u.srv.lmd_fsopts);
216 /*****************************************************************************
218 * This part was cribbed from util-linux/mount/mount.c. There was no clear
219 * license information, but many other files in the package are identified as
220 * GNU GPL, so it's a pretty safe bet that was their intent.
222 ****************************************************************************/
224 const char *opt; /* option name */
225 int skip; /* skip in mtab option string */
226 int inv; /* true if flag value should be inverted */
227 int mask; /* flag mask value */
230 static const struct opt_map opt_map[] = {
231 { "defaults", 0, 0, 0 }, /* default options */
232 { "rw", 1, 1, MS_RDONLY }, /* read-write */
233 { "ro", 0, 0, MS_RDONLY }, /* read-only */
234 { "exec", 0, 1, MS_NOEXEC }, /* permit execution of binaries */
235 { "noexec", 0, 0, MS_NOEXEC }, /* don't execute binaries */
236 { "suid", 0, 1, MS_NOSUID }, /* honor suid executables */
237 { "nosuid", 0, 0, MS_NOSUID }, /* don't honor suid executables */
238 { "dev", 0, 1, MS_NODEV }, /* interpret device files */
239 { "nodev", 0, 0, MS_NODEV }, /* don't interpret devices */
240 { "async", 0, 1, MS_SYNCHRONOUS}, /* asynchronous I/O */
241 { "auto", 0, 0, 0 }, /* Can be mounted using -a */
242 { "noauto", 0, 0, 0 }, /* Can only be mounted explicitly */
243 { "nousers", 0, 1, 0 }, /* Forbid ordinary user to mount */
244 { "nouser", 0, 1, 0 }, /* Forbid ordinary user to mount */
245 { "noowner", 0, 1, 0 }, /* Device owner has no special privs */
246 { "_netdev", 0, 0, 0 }, /* Device accessible only via network */
249 /****************************************************************************/
251 static int parse_one_option(const char *check, int *flagp)
253 const struct opt_map *opt;
255 for (opt = &opt_map[0]; opt->opt != NULL; opt++) {
256 if (strcmp(check, opt->opt) == 0) {
258 *flagp &= ~(opt->mask);
267 int parse_options(char *options, struct lustre_mount_data *lmd, int *flagp)
273 /* parsing ideas here taken from util-linux/mount/nfsmount.c */
274 for (opt = strtok(options, ","); opt; opt = strtok(NULL, ",")) {
275 if ((opteq = strchr(opt, '='))) {
276 val = atoi(opteq + 1);
279 /* All the network options have gone :)) */
281 fprintf(stderr, "%s: unknown option '%s'\n",
286 if (parse_one_option(opt, flagp))
289 fprintf(stderr, "%s: unknown option '%s'\n",
297 int read_mount_options(char *source, char *target,
298 struct lustre_mount_data *lmd)
306 if ( strlen(lmd->u.srv.lmd_source) == 0) {
307 strcpy(lmd->u.srv.lmd_source, source);
308 sprintf(cmd, "mount -t ext3 %s %s", lmd->u.srv.lmd_source, target);
311 sprintf(cmd, "mount -o loop %s %s", lmd->u.srv.lmd_source, target);
315 fprintf(stderr, "Unable to mount %s\n", lmd->u.srv.lmd_source);
319 /* mounted, now read the options file */
320 sprintf(opfilenm, "%s/%s", target, MOUNTOPTS_FILE_NAME);
321 opfile = fopen(opfilenm, "r");
323 fprintf(stderr,"Unable to open options file %s: %s\n",
324 opfilenm, strerror(errno));
329 ret = fscanf(opfile, "%x\n", &lddmagic);
331 fprintf(stderr, "Can't read options file %s\n", opfilenm);
334 if (lddmagic != LDD_MAGIC) {
335 fprintf(stderr, "Bad magic in options file %s\n", opfilenm);
339 fscanf(opfile, "%s\n", lmd->u.srv.lmd_fstype);
340 fscanf(opfile, "%s\n", lmd->u.srv.lmd_fsopts);
341 fscanf(opfile, "%x\n", &lmd->u.srv.disk_type);
342 //fread(&data->mgt.host, sizeof(data->mgt.host), 1, opfile);
348 sprintf(cmd, "umount %s", target);
354 build_data(char *source, char *target, char *options,
355 struct lustre_mount_data *lmd, int *flagp)
363 if (lmd_bad_magic(lmd))
366 if (strlen(source) >= sizeof(buf)) {
367 fprintf(stderr, "%s: nid:/fsname argument too long\n",
373 if ((s = strchr(buf, ':'))) {
386 rc = parse_options(options, lmd, flagp);
390 lmd->lmd_nid = libcfs_str2nid(nid);
391 if (lmd->lmd_nid == PTL_NID_ANY) {
392 fprintf(stderr, "%s: can't parse nid '%s'\n",
393 progname, libcfs_nid2str(lmd->lmd_nid));
397 if (strlen(mgmt) + 4 > sizeof(lmd->lmd_mgmt)) {
398 fprintf(stderr, "%s: mgmt name too long\n", progname);
401 strcpy(lmd->lmd_mds, mgmt);
406 lmd->lmd_magic = LMD_SERVER_MAGIC;
408 if (strlen(source) + 1 > sizeof(lmd->u.srv.lmd_source)) {
409 fprintf(stderr, "%s: source name too long\n", progname);
413 /* We have to keep the loop= option in the mtab file
414 in order for umount to free the loop device. The strtok
415 in parse_options terminates the options list at the first
416 comma, so we're saving a local copy here. */
417 strcpy(buf, options);
418 rc = parse_options(options, lmd, flagp);
419 fprintf(stderr, "source = %s \n",lmd->u.srv.lmd_source);
423 strcpy(options, buf);
425 rc = read_mount_options(source, target, lmd);
435 int main(int argc, char *const argv[])
437 char *source, *target, *options = "";
438 int i, nargs = 3, opt, rc, flags;
439 struct lustre_mount_data lmd;
440 static struct option long_opt[] = {
444 {"nomtab", 0, 0, 'n'},
445 {"options", 1, 0, 'o'},
446 {"verbose", 0, 0, 'v'},
450 progname = strrchr(argv[0], '/');
451 progname = progname ? progname + 1 : argv[0];
453 while ((opt = getopt_long(argc, argv, "fhno:v",
454 long_opt, NULL)) != EOF){
458 printf("force: %d\n", force);
463 printf("fake: %d\n", fake);
471 printf("nomtab: %d\n", nomtab);
480 printf("verbose: %d\n", verbose);
484 fprintf(stderr, "%s: unknown option '%c'\n",
491 if (optind + 2 > argc) {
492 fprintf(stderr, "%s: too few arguments\n", progname);
496 source = argv[optind];
497 target = argv[optind + 1];
500 for (i = 0; i < argc; i++)
501 printf("arg[%d] = %s\n", i, argv[i]);
502 printf("source = %s, target = %s\n", source, target);
505 if (!force && check_mtab_entry(source, target, "lustre"))
509 rc = build_data(source, target, options, &lmd, &flags);
514 rc = access(target, F_OK);
517 fprintf(stderr, "%s: %s inaccessible: %s\n", progname, target,
522 if ((rc = load_modules(&lmd))) {
527 rc = mount(source, target, "lustre", flags, (void *)&lmd);
529 fprintf(stderr, "%s: mount(%s, %s) failed: %s\n", source,
530 target, progname, strerror(errno));
532 fprintf(stderr, "Are the lustre modules loaded?\n"
533 "Check /etc/modules.conf and /proc/filesystems\n");
535 } else if (!nomtab) {
536 rc = update_mtab_entry(source, target, "lustre", options,0,0,0);