X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Fllmount.c;h=bc8d4f69ff6916c53bab8e6e013c20809b09c41b;hb=272294dfa235dac803ed2d2b2ee8e0bd402622bb;hp=ce28e09ff8dfd55cf106cccff491310b597abd02;hpb=ff17cc7e0282d9b1522810e0c5d12171c4d46a2d;p=fs%2Flustre-release.git diff --git a/lustre/utils/llmount.c b/lustre/utils/llmount.c index ce28e09..bc8d4f69 100644 --- a/lustre/utils/llmount.c +++ b/lustre/utils/llmount.c @@ -25,27 +25,72 @@ #include #include #include +#include #include #include #include #include +#define _GNU_SOURCE +#include +#include +#include +#include #include "obdctl.h" #include - -int debug = 0; -int verbose = 0; -int nomtab = 0; +#include + +int debug; +int verbose; +int nomtab; +int force; +static char *progname = NULL; + +typedef struct { + ptl_nid_t gw; + ptl_nid_t lo; + ptl_nid_t hi; +} llmount_route_t; + +#define MAX_ROUTES 1024 +int route_index; +ptl_nid_t lmd_cluster_id = 0; +llmount_route_t routes[MAX_ROUTES]; + +static int check_mtab_entry(char *spec, char *mtpt, char *type) +{ + FILE *fp; + struct mntent *mnt; + + if (!force) { + fp = setmntent(MOUNTED, "r"); + if (fp == NULL) + return(0); + + while ((mnt = getmntent(fp)) != NULL) { + if (strcmp(mnt->mnt_fsname, spec) == 0 && + strcmp(mnt->mnt_dir, mtpt) == 0 && + strcmp(mnt->mnt_type, type) == 0) { + fprintf(stderr, "%s: according to %s %s is " + "already mounted on %s\n", + progname, MOUNTED, spec, mtpt); + return(1); /* or should we return an error? */ + } + } + endmntent(fp); + } + return(0); +} static void -update_mtab_entry(char *spec, char *node, char *type, char *opts, - int flags, int freq, int pass) +update_mtab_entry(char *spec, char *mtpt, char *type, char *opts, + int flags, int freq, int pass) { FILE *fp; struct mntent mnt; mnt.mnt_fsname = spec; - mnt.mnt_dir = node; + mnt.mnt_dir = mtpt; mnt.mnt_type = type; mnt.mnt_opts = opts ? opts : ""; mnt.mnt_freq = freq; @@ -54,12 +99,12 @@ update_mtab_entry(char *spec, char *node, char *type, char *opts, if (!nomtab) { fp = setmntent(MOUNTED, "a+"); if (fp == NULL) { - fprintf(stderr, "setmntent(%s): %s:", MOUNTED, - strerror (errno)); + fprintf(stderr, "%s: setmntent(%s): %s:", + progname, MOUNTED, strerror (errno)); } else { if ((addmntent (fp, &mnt)) == 1) { - fprintf(stderr, "addmntent: %s:", - strerror (errno)); + fprintf(stderr, "%s: addmntent: %s:", + progname, strerror (errno)); } endmntent(fp); } @@ -69,36 +114,174 @@ update_mtab_entry(char *spec, char *node, char *type, char *opts, int init_options(struct lustre_mount_data *lmd) { - memset(lmd, 0, sizeof(lmd)); + memset(lmd, 0, sizeof(*lmd)); lmd->lmd_magic = LMD_MAGIC; lmd->lmd_server_nid = PTL_NID_ANY; lmd->lmd_local_nid = PTL_NID_ANY; lmd->lmd_port = 988; /* XXX define LUSTRE_DEFAULT_PORT */ lmd->lmd_nal = SOCKNAL; + lmd->lmd_async = 0; + lmd->lmd_remote_flag = 0; + lmd->lmd_nllu = NOBODY_UID; + lmd->lmd_nllg = NOBODY_GID; + lmd->lmd_pag = 0; + strncpy(lmd->lmd_mds_security, "null", sizeof(lmd->lmd_mds_security)); + strncpy(lmd->lmd_oss_security, "null", sizeof(lmd->lmd_oss_security)); return 0; } int print_options(struct lustre_mount_data *lmd) { + int i; + printf("mds: %s\n", lmd->lmd_mds); printf("profile: %s\n", lmd->lmd_profile); + printf("mds_sec_flavor: %s\n", lmd->lmd_mds_security); + printf("oss_sec_flavor: %s\n", lmd->lmd_oss_security); printf("server_nid: "LPX64"\n", lmd->lmd_server_nid); - printf("local_nid: "LPX64"\n", lmd->lmd_local_nid); - printf("nal: %d\n", lmd->lmd_nal); - printf("server_ipaddr: 0x%x\n", lmd->lmd_server_ipaddr); - printf("port: %d\n", lmd->lmd_port); +#ifdef CRAY_PORTALS + if (lmd->lmd_nal != CRAY_KB_SSNAL) { +#endif + printf("local_nid: "LPX64"\n", lmd->lmd_local_nid); +#ifdef CRAY_PORTALS + } +#endif + printf("nal: %x\n", lmd->lmd_nal); +#ifdef CRAY_PORTALS + if (lmd->lmd_nal != CRAY_KB_SSNAL) { +#endif + printf("server_ipaddr: 0x%x\n", lmd->lmd_server_ipaddr); + printf("port: %d\n", lmd->lmd_port); +#ifdef CRAY_PORTALS + } +#endif + + for (i = 0; i < route_index; i++) + printf("route: "LPX64" : "LPX64" - "LPX64"\n", + routes[i].gw, routes[i].lo, routes[i].hi); return 0; } -int -parse_options(char * options, struct lustre_mount_data *lmd) +static int parse_route(char *opteq, char *opttgts) { - ptl_nid_t nid = 0; + char *gw_lo_ptr, *gw_hi_ptr, *tgt_lo_ptr, *tgt_hi_ptr; + ptl_nid_t gw_lo, gw_hi, tgt_lo, tgt_hi; + + opttgts[0] = '\0'; + gw_lo_ptr = opteq + 1; + if (!(gw_hi_ptr = strchr(gw_lo_ptr, '-'))) { + gw_hi_ptr = gw_lo_ptr; + } else { + gw_hi_ptr[0] = '\0'; + gw_hi_ptr++; + } + + if (ptl_parse_nid(&gw_lo, gw_lo_ptr) != 0) { + fprintf(stderr, "%s: can't parse NID %s\n", progname,gw_lo_ptr); + return(-1); + } + + if (ptl_parse_nid(&gw_hi, gw_hi_ptr) != 0) { + fprintf(stderr, "%s: can't parse NID %s\n", progname,gw_hi_ptr); + return(-1); + } + + tgt_lo_ptr = opttgts + 1; + if (!(tgt_hi_ptr = strchr(tgt_lo_ptr, '-'))) { + tgt_hi_ptr = tgt_lo_ptr; + } else { + tgt_hi_ptr[0] = '\0'; + tgt_hi_ptr++; + } + + if (ptl_parse_nid(&tgt_lo, tgt_lo_ptr) != 0) { + fprintf(stderr, "%s: can't parse NID %s\n",progname,tgt_lo_ptr); + return(-1); + } + + if (ptl_parse_nid(&tgt_hi, tgt_hi_ptr) != 0) { + fprintf(stderr, "%s: can't parse NID %s\n",progname,tgt_hi_ptr); + return(-1); + } + + while (gw_lo <= gw_hi) { + if (route_index >= MAX_ROUTES) { + fprintf(stderr, "%s: to many routes %d\n", + progname, MAX_ROUTES); + return(-1); + } + + routes[route_index].gw = gw_lo; + routes[route_index].lo = tgt_lo; + routes[route_index].hi = tgt_hi; + route_index++; + gw_lo++; + } + + return(0); +} + +/* + * here all what we do is gurantee the result is exactly + * what user intend to get, no ambiguous. maybe there have + * simpler library call could do the same job for us? + */ +static int parse_u32(char *str, uint32_t *res) +{ + unsigned long id; + char *endptr = NULL; + + id = strtol(str, &endptr, 0); + if (endptr && *endptr != 0) + return -1; + + if (id == LONG_MAX || id == LONG_MIN) + return -1; + + if ((uint32_t)id != id) + return -1; + + *res = (uint32_t) id; + return 0; +} + +static int parse_nllu(struct lustre_mount_data *lmd, char *str_nllu) +{ + struct passwd *pass; + + if (parse_u32(str_nllu, &lmd->lmd_nllu) == 0) + return 0; + + pass = getpwnam(str_nllu); + if (pass == NULL) + return -1; + + lmd->lmd_nllu = pass->pw_uid; + return 0; +} + +static int parse_nllg(struct lustre_mount_data *lmd, char *str_nllg) +{ + struct group *grp; + + if (parse_u32(str_nllg, &lmd->lmd_nllg) == 0) + return 0; + + grp = getgrnam(str_nllg); + if (grp == NULL) + return -1; + + lmd->lmd_nllg = grp->gr_gid; + return 0; +} + +int parse_options(char * options, struct lustre_mount_data *lmd) +{ + ptl_nid_t nid = 0, cluster_id = 0; int val; - char *opt; - char * opteq; + char *opt, *opteq, *opttgts; /* parsing ideas here taken from util-linux/mount/nfsmount.c */ for (opt = strtok(options, ","); opt; opt = strtok(NULL, ",")) { @@ -106,34 +289,86 @@ parse_options(char * options, struct lustre_mount_data *lmd) val = atoi(opteq + 1); *opteq = '\0'; if (!strcmp(opt, "nettype")) { - lmd->lmd_nal = ptl_name2nal(opteq+1); - } else if(!strcmp(opt, "local_nid")) { - if (ptl_parse_nid(&nid, opteq+1) != 0) { - fprintf (stderr, "mount: " + lmd->lmd_nal = ptl_name2nal(opteq + 1); + if (lmd->lmd_nal < 0) { + fprintf(stderr, "%s: can't parse NET " + "%s\n", progname, opteq + 1); + return (-1); + } + } else if(!strcmp(opt, "cluster_id")) { + if (ptl_parse_nid(&cluster_id, opteq+1) != 0) { + fprintf (stderr, "%s: can't parse NID " + "%s\n", progname, opteq+1); + return (-1); + } + lmd_cluster_id = cluster_id; + } else if(!strcmp(opt, "route")) { + if (!(opttgts = strchr(opteq + 1, ':'))) { + fprintf(stderr, "%s: Route must be " + "of the form: route=" + "[-]:[-]\n", + progname); + return(-1); + } + parse_route(opteq, opttgts); + } else if (!strcmp(opt, "local_nid")) { + if (ptl_parse_nid(&nid, opteq + 1) != 0) { + fprintf (stderr, "%s: " "can't parse NID %s\n", + progname, opteq+1); return (-1); } lmd->lmd_local_nid = nid; - } else if(!strcmp(opt, "server_nid")) { - if (ptl_parse_nid(&nid, opteq+1) != 0) { - fprintf (stderr, "mount: " + } else if (!strcmp(opt, "server_nid")) { + if (ptl_parse_nid(&nid, opteq + 1) != 0) { + fprintf (stderr, "%s: " "can't parse NID %s\n", - opteq+1); + progname, opteq + 1); return (-1); } lmd->lmd_server_nid = nid; } else if (!strcmp(opt, "port")) { lmd->lmd_port = val; + } else if (!strcmp(opt, "mds_sec")) { + strncpy(lmd->lmd_mds_security, opteq + 1, + sizeof(lmd->lmd_mds_security)); + } else if (!strcmp(opt, "oss_sec")) { + strncpy(lmd->lmd_oss_security, opteq + 1, + sizeof(lmd->lmd_oss_security)); + } else if (!strcmp(opt, "nllu")) { + if (parse_nllu(lmd, opteq + 1)) { + fprintf(stderr, "%s: " + "can't parse user: %s\n", + progname, opteq + 1); + return (-1); + } + } else if (!strcmp(opt, "nllg")) { + if (parse_nllg(lmd, opteq + 1)) { + fprintf(stderr, "%s: " + "can't parse group: %s\n", + progname, opteq + 1); + return (-1); + } } } else { - val = 1; - if (!strncmp(opt, "no", 2)) { - val = 0; - opt += 2; - } - if (!strcmp(opt, "debug")) { - debug = val; + if (!strcmp(opt, "remote")) { + lmd->lmd_remote_flag = OBD_CONNECT_REMOTE; + } else if (!strcmp(opt, "local")) { + lmd->lmd_remote_flag = OBD_CONNECT_LOCAL; + } else if (!strcmp(opt, "async")) { + lmd->lmd_async = 1; + } else if (!strcmp(opt, "pag")) { + lmd->lmd_pag = 1; + } else { + val = 1; + if (!strncmp(opt, "no", 2)) { + val = 0; + opt += 2; + } + if (!strcmp(opt, "debug")) { + debug = val; + } } } } @@ -171,14 +406,67 @@ set_local(struct lustre_mount_data *lmd) memset(buf, 0, sizeof(buf)); - if (lmd->lmd_nal == SOCKNAL || lmd->lmd_nal == TCPNAL) { + switch (lmd->lmd_nal) { + default: + fprintf(stderr, "%s: Unknown network type: %d\n", + progname, lmd->lmd_nal); + return 1; + +#if CRAY_PORTALS + case CRAY_KB_SSNAL: + return 0; + + case CRAY_KB_ERNAL: +#else + case SOCKNAL: + case TCPNAL: + case OPENIBNAL: + case IIBNAL: + case VIBNAL: + case RANAL: +#endif + { + struct utsname uts; + rc = gethostname(buf, sizeof(buf) - 1); if (rc) { - fprintf (stderr, "mount: can't get local buf:" - "%d\n", rc); + fprintf(stderr, "%s: can't get hostname: %s\n", + progname, strerror(rc)); return rc; } - } else if (lmd->lmd_nal == QSWNAL) { + + rc = uname(&uts); + /* for 2.6 kernels, reserve at least 8MB free, or we will + * go OOM during heavy read load */ + if (rc == 0 && strncmp(uts.release, "2.6", 3) == 0) { + int f, minfree = 32768; + char name[40], val[40]; + FILE *meminfo; + + meminfo = fopen("/proc/meminfo", "r"); + if (meminfo != NULL) { + while (fscanf(meminfo, "%s %s %*s\n", name, val) != EOF) { + if (strcmp(name, "MemTotal:") == 0) { + f = strtol(val, NULL, 0); + if (f > 0 && f < 8 * minfree) + minfree = f / 16; + break; + } + } + fclose(meminfo); + } + f = open("/proc/sys/vm/min_free_kbytes", O_WRONLY); + if (f >= 0) { + sprintf(val, "%d", minfree); + write(f, val, strlen(val)); + close(f); + } + } + break; + } +#if !CRAY_PORTALS + case QSWNAL: + { char *pfiles[] = {"/proc/qsnet/elan3/device0/position", "/proc/qsnet/elan4/device0/position", "/proc/elan/device0/position", @@ -190,18 +478,22 @@ set_local(struct lustre_mount_data *lmd) } while (rc != 0 && pfiles[++i] != NULL); if (rc != 0) { - fprintf(stderr, - "mount: can't read Elan ID from /proc\n"); + fprintf(stderr, "%s: can't read Elan ID from /proc\n", + progname); + return -1; } + break; + } +#endif } if (ptl_parse_nid (&nid, buf) != 0) { - fprintf (stderr, "mount: can't parse NID %s\n", buf); + fprintf (stderr, "%s: can't parse NID %s\n", progname, buf); return (-1); } - lmd->lmd_local_nid = nid; + lmd->lmd_local_nid = nid + lmd_cluster_id; return 0; } @@ -211,62 +503,97 @@ set_peer(char *hostname, struct lustre_mount_data *lmd) ptl_nid_t nid = 0; int rc; - if (lmd->lmd_nal == SOCKNAL || lmd->lmd_nal == TCPNAL) { + switch (lmd->lmd_nal) { + default: + fprintf(stderr, "%s: Unknown network type: %d\n", + progname, lmd->lmd_nal); + return 1; + +#if CRAY_PORTALS + case CRAY_KB_SSNAL: + lmd->lmd_server_nid = strtoll(hostname,0,0); + return 0; + + case CRAY_KB_ERNAL: +#else + case IIBNAL: + if (lmd->lmd_server_nid != PTL_NID_ANY) + break; + if (ptl_parse_nid (&nid, hostname) != 0) { + fprintf (stderr, "%s: can't parse NID %s\n", + progname, hostname); + return (1); + } + lmd->lmd_server_nid = nid; + break; + + case SOCKNAL: + case TCPNAL: + case OPENIBNAL: + case VIBNAL: + case RANAL: +#endif if (lmd->lmd_server_nid == PTL_NID_ANY) { if (ptl_parse_nid (&nid, hostname) != 0) { - fprintf (stderr, "mount: can't parse NID %s\n", - hostname); - return (-1); + fprintf (stderr, "%s: can't parse NID %s\n", + progname, hostname); + return (1); } lmd->lmd_server_nid = nid; } if (ptl_parse_ipaddr(&lmd->lmd_server_ipaddr, hostname) != 0) { - fprintf (stderr, "mount: can't parse host %s\n", - hostname); + fprintf (stderr, "%s: can't parse host %s\n", + progname, hostname); return (-1); } - } else if (lmd->lmd_nal == QSWNAL) { + + break; + +#if !CRAY_PORTALS + case QSWNAL: { char buf[64]; + if (lmd->lmd_server_nid != PTL_NID_ANY) + break; + rc = sscanf(hostname, "%*[^0-9]%63[0-9]", buf); if (rc != 1) { - fprintf (stderr, "mount: can't get elan id from host %s\n", - hostname); + fprintf (stderr, "%s: can't get elan id from host %s\n", + progname, hostname); return -1; } if (ptl_parse_nid (&nid, buf) != 0) { - fprintf (stderr, "mount: can't parse NID %s\n", - hostname); + fprintf (stderr, "%s: can't parse NID %s\n", + progname, hostname); return (-1); } lmd->lmd_server_nid = nid; - } - + break; + } +#endif + } return 0; } int build_data(char *source, char *options, struct lustre_mount_data *lmd) { - char target[1024]; - char *hostname = NULL; - char *mds = NULL; - char *profile = NULL; - char *s; + char buf[1024]; + char *hostname = NULL, *mds = NULL, *profile = NULL, *s; int rc; if (lmd_bad_magic(lmd)) - return -EINVAL; + return 4; - if (strlen(source) > sizeof(target) + 1) { - fprintf(stderr, "mount: " - "exessively long host:/mds/profile argument\n"); - return -EINVAL; + if (strlen(source) > sizeof(buf) + 1) { + fprintf(stderr, "%s: host:/mds/profile argument too long\n", + progname); + return 1; } - strcpy(target, source); - if ((s = strchr(target, ':'))) { - hostname = target; + strcpy(buf, source); + if ((s = strchr(buf, ':'))) { + hostname = buf; *s = '\0'; while (*++s == '/') @@ -276,19 +603,17 @@ build_data(char *source, char *options, struct lustre_mount_data *lmd) *s = '\0'; profile = s + 1; } else { - fprintf(stderr, "mount: " - "directory to mount not in " - "host:/mds/profile format\n"); - return(-1); + fprintf(stderr, "%s: directory to mount not in " + "host:/mds/profile format\n", + progname); + return(1); } } else { - fprintf(stderr, "mount: " - "directory to mount not in host:/mds/profile format\n"); - return(-1); + fprintf(stderr, "%s: " + "directory to mount not in host:/mds/profile format\n", + progname); + return(1); } - if (verbose) - printf("host: %s\nmds: %s\nprofile: %s\n", hostname, mds, - profile); rc = parse_options(options, lmd); if (rc) @@ -302,14 +627,14 @@ build_data(char *source, char *options, struct lustre_mount_data *lmd) if (rc) return rc; if (strlen(mds) > sizeof(lmd->lmd_mds) + 1) { - fprintf(stderr, "mount: mds name too long\n"); - return(-1); + fprintf(stderr, "%s: mds name too long\n", progname); + return(1); } strcpy(lmd->lmd_mds, mds); if (strlen(profile) > sizeof(lmd->lmd_profile) + 1) { - fprintf(stderr, "mount: profile name too long\n"); - return(-1); + fprintf(stderr, "%s: profile name too long\n", progname); + return(1); } strcpy(lmd->lmd_profile, profile); @@ -318,57 +643,179 @@ build_data(char *source, char *options, struct lustre_mount_data *lmd) return 0; } -int -main(int argc, char * const argv[]) -{ - char * source = argv[1]; - char * target = argv[2]; - char * options = ""; - int opt; - int i; - struct lustre_mount_data lmd; +static int set_routes(struct lustre_mount_data *lmd) { + struct portals_cfg pcfg; + struct portal_ioctl_data data; + int i, j, route_exists, rc, err = 0; + + register_ioc_dev(PORTALS_DEV_ID, PORTALS_DEV_PATH); + + for (i = 0; i < route_index; i++) { + + /* Check for existing routes so as not to add duplicates */ + for (j = 0; ; j++) { + PCFG_INIT(pcfg, NAL_CMD_GET_ROUTE); + pcfg.pcfg_nal = ROUTER; + pcfg.pcfg_count = j; + + PORTAL_IOC_INIT(data); + data.ioc_pbuf1 = (char*)&pcfg; + data.ioc_plen1 = sizeof(pcfg); + data.ioc_nid = pcfg.pcfg_nid; + + rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data); + if (rc != 0) { + route_exists = 0; + break; + } + + if ((pcfg.pcfg_gw_nal == lmd->lmd_nal) && + (pcfg.pcfg_nid == routes[i].gw) && + (pcfg.pcfg_nid2 == routes[i].lo) && + (pcfg.pcfg_nid3 == routes[i].hi)) { + route_exists = 1; + break; + } + } + + if (route_exists) + continue; + + PCFG_INIT(pcfg, NAL_CMD_ADD_ROUTE); + pcfg.pcfg_nid = routes[i].gw; + pcfg.pcfg_nal = ROUTER; + pcfg.pcfg_gw_nal = lmd->lmd_nal; + pcfg.pcfg_nid2 = MIN(routes[i].lo, routes[i].hi); + pcfg.pcfg_nid3 = MAX(routes[i].lo, routes[i].hi); + + PORTAL_IOC_INIT(data); + data.ioc_pbuf1 = (char*)&pcfg; + data.ioc_plen1 = sizeof(pcfg); + data.ioc_nid = pcfg.pcfg_nid; + + rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data); + if (rc != 0) { + fprintf(stderr, "%s: Unable to add route " + LPX64" : "LPX64" - "LPX64"\n[%d] %s\n", + progname, routes[i].gw, routes[i].lo, + routes[i].hi, errno, strerror(errno)); + err = -1; + break; + } + } + + unregister_ioc_dev(PORTALS_DEV_ID); + return err; +} - int rc; +void usage(FILE *out) +{ + fprintf(out, "usage: %s [-f] [-v] [-n] [-o mntopt]\n", + progname); + exit(out != stdout); +} - while ((opt = getopt(argc, argv, "vno:")) != EOF) { +int main(int argc, char *const argv[]) +{ + char *source, *target, *options = ""; + int i, nargs = 3, opt, rc; + struct lustre_mount_data lmd; + static struct option long_opt[] = { + {"force", 0, 0, 'f'}, + {"help", 0, 0, 'h'}, + {"nomtab", 0, 0, 'n'}, + {"options", 1, 0, 'o'}, + {"verbose", 0, 0, 'v'}, + {0, 0, 0, 0} + }; + + progname = strrchr(argv[0], '/'); + progname = progname ? progname + 1 : argv[0]; + + while ((opt = getopt_long(argc, argv, "fno:v", long_opt, NULL)) != EOF){ switch (opt) { - case 'v': - verbose = 1; - printf("verbose: %d\n", verbose); + case 'f': + ++force; + printf("force: %d\n", force); + nargs++; + break; + case 'h': + usage(stdout); break; case 'n': - nomtab = 1; + ++nomtab; printf("nomtab: %d\n", nomtab); + nargs++; break; case 'o': options = optarg; + nargs++; + break; + case 'v': + ++verbose; + printf("verbose: %d\n", verbose); + nargs++; break; default: + fprintf(stderr, "%s: unknown option '%c'\n", + progname, opt); + usage(stderr); break; } } - if (verbose) - for (i = 0; i < argc; i++) { + if (optind + 2 > argc) { + fprintf(stderr, "%s: too few arguments\n", progname); + usage(stderr); + } + + source = argv[optind]; + target = argv[optind + 1]; + + if (verbose) { + for (i = 0; i < argc; i++) printf("arg[%d] = %s\n", i, argv[i]); - } + printf("source = %s, target = %s\n", source, target); + } + + if (check_mtab_entry(source, target, "lustre")) + exit(32); init_options(&lmd); rc = build_data(source, options, &lmd); if (rc) { - exit(1); + exit(rc); + } + + rc = set_routes(&lmd); + if (rc) { + exit(rc); } if (debug) { - printf("mount: debug mode, not mounting\n"); + printf("%s: debug mode, not mounting\n", progname); exit(0); } + rc = access(target, F_OK); + if (rc) { + rc = errno; + fprintf(stderr, "%s: %s inaccessible: %s\n", progname, target, + strerror(errno)); + return rc; + } + rc = mount(source, target, "lustre", 0, (void *)&lmd); if (rc) { + rc = errno; perror(argv[0]); - } else { - update_mtab_entry(source, target, "lustre", options, 0, 0, 0); + fprintf(stderr, "%s: mount(%s, %s) failed: %s\n", source, + target, progname, strerror(errno)); + if (rc == ENODEV) + fprintf(stderr, "Are the lustre modules loaded?\n" + "Check /etc/modules.conf and /proc/filesystems\n"); + return 2; } - return rc; + update_mtab_entry(source, target, "lustre", options, 0, 0, 0); + return 0; }