#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
+#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/mount.h>
#include <mntent.h>
#define _GNU_SOURCE
#include <getopt.h>
+#include <sys/utsname.h>
+#include <pwd.h>
+#include <grp.h>
#include "obdctl.h"
#include <portals/ptlctl.h>
+#include <linux/lustre_idl.h>
int debug;
int verbose;
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;
+ strncpy(lmd->lmd_security, "null", sizeof(lmd->lmd_security));
return 0;
}
printf("mds: %s\n", lmd->lmd_mds);
printf("profile: %s\n", lmd->lmd_profile);
+ printf("sec_flavor: %s\n", lmd->lmd_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: 0x%llx : 0x%llx - 0x%llx\n",
+ printf("route: "LPX64" : "LPX64" - "LPX64"\n",
routes[i].gw, routes[i].lo, routes[i].hi);
return 0;
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;
*opteq = '\0';
if (!strcmp(opt, "nettype")) {
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 "
lmd->lmd_server_nid = nid;
} else if (!strcmp(opt, "port")) {
lmd->lmd_port = val;
+ } else if (!strcmp(opt, "sec")) {
+ strncpy(lmd->lmd_security, opteq + 1,
+ sizeof(lmd->lmd_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 if (!strcmp(opt, "clone")) {
- lmd->lmd_clone_index = val;
- }
} 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 {
+ val = 1;
+ if (!strncmp(opt, "no", 2)) {
+ val = 0;
+ opt += 2;
+ }
+ if (!strcmp(opt, "debug")) {
+ debug = val;
+ }
}
}
}
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, "%s: can't get local buf: %d\n",
- progname, 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",
return -1;
}
+ break;
+ }
+#endif
}
if (ptl_parse_nid (&nid, buf) != 0) {
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, "%s: can't parse NID %s\n",
progname, hostname);
- return (-1);
+ return (1);
}
lmd->lmd_server_nid = nid;
}
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, "%s: can't get elan id from host %s\n",
return (-1);
}
lmd->lmd_server_nid = nid;
- }
-
+ break;
+ }
+#endif
+ }
return 0;
}
int rc;
if (lmd_bad_magic(lmd))
- return -EINVAL;
+ return 4;
if (strlen(source) > sizeof(buf) + 1) {
fprintf(stderr, "%s: host:/mds/profile argument too long\n",
progname);
- return -EINVAL;
+ return 1;
}
strcpy(buf, source);
if ((s = strchr(buf, ':'))) {
fprintf(stderr, "%s: directory to mount not in "
"host:/mds/profile format\n",
progname);
- return(-1);
+ return(1);
}
} else {
fprintf(stderr, "%s: "
"directory to mount not in host:/mds/profile format\n",
progname);
- return(-1);
+ return(1);
}
rc = parse_options(options, lmd);
return rc;
if (strlen(mds) > sizeof(lmd->lmd_mds) + 1) {
fprintf(stderr, "%s: mds name too long\n", progname);
- return(-1);
+ return(1);
}
strcpy(lmd->lmd_mds, mds);
if (strlen(profile) > sizeof(lmd->lmd_profile) + 1) {
fprintf(stderr, "%s: profile name too long\n", progname);
- return(-1);
+ return(1);
}
strcpy(lmd->lmd_profile, profile);
rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
if (rc != 0) {
fprintf(stderr, "%s: Unable to add route "
- "0x%llx : 0x%llx - 0x%llx\n[%d] %s\n",
- progname, routes[i].gw, routes[i].lo,
- routes[i].hi, errno, strerror(errno));
+ LPX64" : "LPX64" - "LPX64"\n[%d] %s\n",
+ progname, routes[i].gw, routes[i].lo,
+ routes[i].hi, errno, strerror(errno));
err = -1;
break;
}
init_options(&lmd);
rc = build_data(source, options, &lmd);
if (rc) {
- exit(1);
+ exit(rc);
}
rc = set_routes(&lmd);
if (rc) {
- exit(1);
+ exit(rc);
}
if (debug) {
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]);
+ 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");
- } else {
- update_mtab_entry(source, target, "lustre", options, 0, 0, 0);
+ return 2;
}
- return rc;
+ update_mtab_entry(source, target, "lustre", options, 0, 0, 0);
+ return 0;
}