aboutsummaryrefslogtreecommitdiff
path: root/amd/ops_lustre.c
diff options
context:
space:
mode:
Diffstat (limited to 'amd/ops_lustre.c')
-rw-r--r--amd/ops_lustre.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/amd/ops_lustre.c b/amd/ops_lustre.c
new file mode 100644
index 000000000000..1b321ce4e8c4
--- /dev/null
+++ b/amd/ops_lustre.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2011 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *
+ * File: am-utils/amd/ops_lustre.c
+ *
+ */
+
+/*
+ * Lustre file system
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+#ifdef HAVE_FS_LUSTRE
+#include <am_defs.h>
+#include <amd.h>
+
+/* forward declarations */
+static char *lustre_match(am_opts *fo);
+static int lustre_mount(am_node *am, mntfs *mf);
+static int lustre_umount(am_node *am, mntfs *mf);
+
+/*
+ * Ops structure
+ */
+am_ops lustre_ops =
+{
+ "lustre",
+ lustre_match,
+ 0, /* lustre_init */
+ lustre_mount,
+ lustre_umount,
+ amfs_error_lookup_child,
+ amfs_error_mount_child,
+ amfs_error_readdir,
+ 0, /* lustre_readlink */
+ 0, /* lustre_mounted */
+ 0, /* lustre_umounted */
+ amfs_generic_find_srvr,
+ 0, /* lustre_get_wchan */
+ FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
+#ifdef HAVE_FS_AUTOFS
+ AUTOFS_LUSTRE_FS_FLAGS,
+#endif /* HAVE_FS_AUTOFS */
+};
+
+
+/*
+ * Lustre needs remote filesystem and host.
+ */
+static char *
+lustre_match(am_opts *fo)
+{
+ char *xmtab, *cp;
+ size_t l;
+ char *rhost, *ptr, *remhost;
+ struct in_addr addr;
+
+ if (fo->opt_fs && !fo->opt_rfs)
+ fo->opt_rfs = fo->opt_fs;
+ if (!fo->opt_rfs) {
+ plog(XLOG_USER, "lustre: no remote filesystem specified");
+ return NULL;
+ }
+ if (!fo->opt_rhost) {
+ plog(XLOG_USER, "lustre: no remote host specified");
+ return NULL;
+ }
+
+ /*
+ * Determine magic cookie to put in mtab
+ */
+ rhost = xstrdup(fo->opt_rhost);
+ remhost = NULL;
+ for (ptr = strtok(rhost, ":"); ptr; ptr = strtok(NULL, ":")) {
+ char *at = strchr(ptr, '@');
+ if (at == NULL) {
+ plog(XLOG_USER, "lustre: missing protocol in host `%s'", ptr);
+ XFREE(rhost);
+ return NULL;
+ }
+ *at = '\0';
+ /*
+ * Convert symbolic addresses to numbers that the kernel likes
+ */
+ if (inet_aton(ptr, &addr) == 0) {
+ struct hostent *hp;
+ if ((hp = gethostbyname(ptr)) == NULL) {
+ plog(XLOG_USER, "lustre: unknown host `%s'", ptr);
+ XFREE(rhost);
+ return NULL;
+ }
+ if (hp->h_length != sizeof(addr.s_addr)) {
+ plog(XLOG_USER, "lustre: bad address length %zu != %d for %s",
+ sizeof(addr), hp->h_length, ptr);
+ XFREE(rhost);
+ return NULL;
+ }
+ memcpy(&addr.s_addr, hp->h_addr, sizeof(addr));
+ }
+ *at = '@';
+
+ cp = remhost;
+ if (remhost)
+ remhost = strvcat(cp, ":", inet_ntoa(addr), at, NULL);
+ else
+ remhost = strvcat(inet_ntoa(addr), at, NULL);
+ XFREE(cp);
+ }
+ if (remhost == NULL) {
+ plog(XLOG_USER, "lustre: empty host");
+ XFREE(rhost);
+ return NULL;
+ }
+
+ XFREE(rhost);
+ XFREE(fo->opt_rhost);
+ fo->opt_rhost = remhost;
+
+ l = strlen(fo->opt_rhost) + strlen(fo->opt_rfs) + 2;
+ xmtab = xmalloc(l);
+ xsnprintf(xmtab, l, "%s:%s", fo->opt_rhost, fo->opt_rfs);
+ dlog("lustre: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"",
+ fo->opt_rhost, fo->opt_rfs, fo->opt_fs);
+
+
+ return xmtab;
+}
+
+static int
+lustre_mount(am_node *am, mntfs *mf)
+{
+ mntent_t mnt;
+ int genflags, error;
+ int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
+
+ /*
+ * Figure out the name of the file system type.
+ */
+ MTYPE_TYPE type = MOUNT_TYPE_LUSTRE;
+
+ /*
+ * Fill in the mount structure
+ */
+ memset(&mnt, 0, sizeof(mnt));
+ mnt.mnt_dir = mf->mf_mount;
+ mnt.mnt_fsname = mf->mf_info;
+ mnt.mnt_type = MNTTAB_TYPE_LUSTRE;
+ mnt.mnt_opts = mf->mf_mopts;
+
+ genflags = compute_mount_flags(&mnt);
+#ifdef HAVE_FS_AUTOFS
+ if (on_autofs)
+ genflags |= autofs_compute_mount_flags(&mnt);
+#endif /* HAVE_FS_AUTOFS */
+
+ /*
+ * Call generic mount routine
+ */
+ error = mount_fs(&mnt, genflags, NULL, 0, type, 0,
+ NULL, mnttab_file_name, on_autofs);
+ if (error) {
+ errno = error;
+ plog(XLOG_ERROR, "mount_lustre: %m");
+ return error;
+ }
+
+ return 0;
+}
+
+
+static int
+lustre_umount(am_node *am, mntfs *mf)
+{
+ int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
+
+ return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
+}
+#endif