.BI nouser_fid2path
Disable FID to path translation by regular users. Root and process with
CAP_DAC_READ_SEARCH can still perform FID to path translation.
+.TP
+.BI skpath= file|directory
+Path to a file or directory with the keyfile(s) to load for this mount command.
+Keys are inserted into the KEY_SPEC_SESSION_KEYRING keyring with a description
+containing "lustre:" and a suffix which depends on whether the context of the
+mount command is for an MGS, MDT/OST, or client.
+This option is only available when built with --enable-gss.
.PP
In addition to the standard mount options and backing disk type
(e.g. ext3) options listed in
if GSS
SUBDIRS = gss
+GSSSRC = gss/sk_utils.c gss/sk_utils.h gss/err_util.c gss/err_util.h
+GSSLIB = -lcrypto -lssl -lkeyutils -lm
+else
+GSSSRC =
+GSSLIB =
endif
# mount only finds helpers in /sbin
mount_osd_ldiskfs_la_LIBADD := $(SELINUX)
endif # LDISKFS_ENABLED
-mount_lustre_SOURCES = mount_lustre.c mount_utils.c mount_utils.h
+mount_lustre_SOURCES = mount_lustre.c mount_utils.c mount_utils.h $(GSSSRC)
mount_lustre_CPPFLAGS := ${MNTMODCFLAGS}
mount_lustre_LDFLAGS := ${MNTMODLDFLAGS}
-mount_lustre_LDADD := $(LIBPTLCTL) $(SELINUX) $(LDLIBMOUNT)
+mount_lustre_LDADD := $(LIBPTLCTL) $(SELINUX) $(LDLIBMOUNT) $(GSSLIB)
mount_lustre_DEPENDENCIES := $(LIBPTLCTL)
-mkfs_lustre_SOURCES = mkfs_lustre.c mount_utils.c mount_utils.h
+mkfs_lustre_SOURCES = mkfs_lustre.c mount_utils.c mount_utils.h $(GSSSRC)
mkfs_lustre_CPPFLAGS := -UTUNEFS ${MNTMODCFLAGS}
mkfs_lustre_LDFLAGS := ${MNTMODLDFLAGS}
-mkfs_lustre_LDADD := $(LIBPTLCTL) $(LDLIBMOUNT)
+mkfs_lustre_LDADD := $(LIBPTLCTL) $(LDLIBMOUNT) $(GSSLIB)
mkfs_lustre_DEPENDENCIES := $(LIBPTLCTL)
-tunefs_lustre_SOURCES = mkfs_lustre.c mount_utils.c mount_utils.h
+tunefs_lustre_SOURCES = mkfs_lustre.c mount_utils.c mount_utils.h $(GSSSRC)
tunefs_lustre_CPPFLAGS := -DTUNEFS ${MNTMODCFLAGS}
tunefs_lustre_LDFLAGS := ${MNTMODLDFLAGS}
tunefs_lustre_LDADD := $(mkfs_lustre_LDADD)
"\t\tskip_lfsck: NOT auto resume the paused/crashed LFSCK\n"
"\t\texclude=<ostname>[:<ostname>] : colon-separated list of "
"inactive OSTs (e.g. lustre-OST0001)\n"
+#ifdef HAVE_GSS
+ "\t\tskpath=<file|directory>: Path to a file or directory of"
+ "key configuration files to load into the kernel keyring\n"
+#endif
"\t\tretry=<num>: number of times mount is retried by client\n"
"\t\tmd_stripe_cache_size=<num>: set the raid stripe cache "
"size for the underlying raid if present\n");
/* XXX special check for 'force' option */
++mop->mo_force;
printf("force: %d\n", mop->mo_force);
+#ifdef HAVE_GSS
+ } else if (val && strncmp(opt, "skpath=", 7) == 0) {
+ if (strlen(val) + 1 >= sizeof(mop->mo_skpath)) {
+ fprintf(stderr,
+ "%s: shared key path too long\n",
+ progname);
+ free(options);
+ return -1;
+ }
+ strncpy(mop->mo_skpath, val + 1, strlen(val + 1));
+#endif
} else if (parse_one_option(opt, flagp) == 0) {
/* pass this on as an option */
append_option(options, opt);
struct mount_opts mop;
char *options;
int i, rc, flags;
+ bool client;
progname = strrchr(argv[0], '/');
progname = progname ? progname + 1 : argv[0];
return rc;
}
- if (strstr(mop.mo_usource, ":/") == NULL) {
+ client = (strstr(mop.mo_usource, ":/") != NULL);
+ if (!client) {
rc = osd_init();
if (rc)
return rc;
printf("mounting device %s at %s, flags=%#x options=%s\n",
mop.mo_source, mop.mo_target, flags, options);
- if (strstr(mop.mo_usource, ":/") == NULL &&
- osd_tune_lustre(mop.mo_source, &mop)) {
+ if (!client && osd_tune_lustre(mop.mo_source, &mop)) {
if (verbose)
fprintf(stderr, "%s: unable to set tunables for %s"
" (may cause reduced IO performance)\n",
argv[0], mop.mo_source);
}
+#ifdef HAVE_GSS
+ if (mop.mo_skpath[0] != '\0') {
+ /* Treat shared key failures as fatal */
+ rc = load_shared_keys(&mop);
+ if (rc) {
+ fprintf(stderr,
+ "%s: Error loading shared keys: %s\n",
+ progname, strerror(rc));
+ return rc;
+ }
+ }
+#endif
+
if (!mop.mo_fake) {
/* flags and target get to lustre_get_sb(), but not
* lustre_fill_super(). Lustre ignores the flags, but mount
/* mo_usource should be freed, but we can rely on the kernel */
free(mop.mo_source);
- if (strstr(mop.mo_usource, ":/") == NULL)
+ if (!client)
osd_fini();
return rc;
#include <sys/stat.h>
#include <sys/utsname.h>
#include <linux/loop.h>
+#include <sys/types.h>
+#include <dirent.h>
#include <dlfcn.h>
+#ifdef HAVE_GSS
+#include <keyutils.h>
+#include <lustre/utils/gss/sk_utils.h>
+#endif
+
#include "mount_utils.h"
extern char *progname;
return 0;
}
+
+#ifdef HAVE_GSS
+int load_shared_keys(struct mount_opts *mop)
+{
+ DIR *dir;
+ struct dirent *dentry;
+ struct stat sbuf;
+ char fullpath[PATH_MAX];
+ char *path = mop->mo_skpath;
+ int type = 0;
+ int rc;
+
+ if (IS_SERVER(&mop->mo_ldd)) {
+ if (IS_MGS(&mop->mo_ldd))
+ type |= SK_TYPE_MGS;
+ if (IS_MDT(&mop->mo_ldd) || IS_OST(&mop->mo_ldd))
+ type |= SK_TYPE_SERVER | SK_TYPE_CLIENT;
+ } else {
+ type |= SK_TYPE_CLIENT;
+ }
+
+ /* init logging */
+ sk_init_logging(NULL, 1, 1);
+
+ rc = stat(path, &sbuf);
+ if (rc < 0) {
+ fprintf(stderr, "stat() failed for key %s: %s\n", path,
+ strerror(errno));
+ return -errno;
+ }
+
+ /* Load individual keys or a directory of them */
+ if (S_ISREG(sbuf.st_mode)) {
+ return sk_load_keyfile(path, type);
+ } else if (!S_ISDIR(sbuf.st_mode)) {
+ fprintf(stderr, "Invalid shared key path: %s\n", path);
+ return -ENOKEY;
+ }
+
+ dir = opendir(path);
+ if (dir == NULL) {
+ fprintf(stderr, "Unable to open shared key directory: %s\n",
+ path);
+ return -ENOENT;
+ }
+
+ /* Loop through the files in the directory attempting to load them.
+ * Any issue with loading the keyfile is treated as an error although
+ * the loop continues until all files have been attempted. This will
+ * allow all errors be reported at once rather then requiring
+ * incremental corrections to fix each one and try again. */
+ while ((dentry = readdir(dir)) != NULL) {
+ if (strcmp(".", dentry->d_name) == 0 ||
+ strcmp("..", dentry->d_name) == 0)
+ continue;
+
+ rc = snprintf(fullpath, PATH_MAX, "%s/%s", path,
+ dentry->d_name);
+ if (rc >= PATH_MAX) {
+ fprintf(stderr, "Path too long for %s/%s\n",
+ path, dentry->d_name);
+ rc = -ENAMETOOLONG;
+ continue;
+ }
+
+ rc = stat(fullpath, &sbuf);
+ if (rc < 0) {
+ fprintf(stderr, "Unable to stat %s: %s\n", fullpath,
+ strerror(errno));
+ rc = -errno;
+ continue;
+ }
+
+ if (!S_ISREG(sbuf.st_mode))
+ continue;
+
+ rc = sk_load_keyfile(fullpath, type);
+ if (rc) {
+ fprintf(stderr, "Failed to load key %s\n", fullpath);
+ }
+ }
+ closedir(dir);
+
+ return rc;
+}
+#endif
char *mo_usource; /* user-specified mount device */
char *mo_source; /* our mount device name */
char mo_target[PATH_MAX]; /* mount directory */
+#ifdef HAVE_GSS
+ char mo_skpath[PATH_MAX]; /* shared key file/directory */
+#endif
int mo_nomtab;
int mo_fake;
int mo_force;
#define IS_OST(data) ((data)->ldd_flags & LDD_F_SV_TYPE_OST)
#undef IS_MGS
#define IS_MGS(data) ((data)->ldd_flags & LDD_F_SV_TYPE_MGS)
+#undef IS_SERVER
+#define IS_SERVER(data) ((data)->ldd_flags & (LDD_F_SV_TYPE_MGS | \
+ LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST))
+
/* mkfs/mount helper functions */
void fatal(void);
struct module_backfs_ops *load_backfs_module(enum ldd_mount_type mount_type);
void unload_backfs_ops(struct module_backfs_ops *ops);
-
+int load_shared_keys(struct mount_opts *mop);
#endif