1 /* $NetBSD: ops_lustre.c,v 1.1.1.1 2015/01/17 16:34:15 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2011 Christos Zoulas 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * 29 * File: am-utils/amd/ops_lustre.c 30 * 31 */ 32 33 /* 34 * Lustre file system 35 */ 36 37 #ifdef HAVE_CONFIG_H 38 # include <config.h> 39 #endif /* HAVE_CONFIG_H */ 40 #ifdef HAVE_FS_LUSTRE 41 #include <am_defs.h> 42 #include <amd.h> 43 44 /* forward declarations */ 45 static char *lustre_match(am_opts *fo); 46 static int lustre_mount(am_node *am, mntfs *mf); 47 static int lustre_umount(am_node *am, mntfs *mf); 48 49 /* 50 * Ops structure 51 */ 52 am_ops lustre_ops = 53 { 54 "lustre", 55 lustre_match, 56 0, /* lustre_init */ 57 lustre_mount, 58 lustre_umount, 59 amfs_error_lookup_child, 60 amfs_error_mount_child, 61 amfs_error_readdir, 62 0, /* lustre_readlink */ 63 0, /* lustre_mounted */ 64 0, /* lustre_umounted */ 65 amfs_generic_find_srvr, 66 0, /* lustre_get_wchan */ 67 FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */ 68 #ifdef HAVE_FS_AUTOFS 69 AUTOFS_LUSTRE_FS_FLAGS, 70 #endif /* HAVE_FS_AUTOFS */ 71 }; 72 73 74 /* 75 * Lustre needs remote filesystem and host. 76 */ 77 static char * 78 lustre_match(am_opts *fo) 79 { 80 char *xmtab, *cp; 81 size_t l; 82 char *rhost, *ptr, *remhost; 83 struct in_addr addr; 84 85 if (fo->opt_fs && !fo->opt_rfs) 86 fo->opt_rfs = fo->opt_fs; 87 if (!fo->opt_rfs) { 88 plog(XLOG_USER, "lustre: no remote filesystem specified"); 89 return NULL; 90 } 91 if (!fo->opt_rhost) { 92 plog(XLOG_USER, "lustre: no remote host specified"); 93 return NULL; 94 } 95 96 /* 97 * Determine magic cookie to put in mtab 98 */ 99 rhost = xstrdup(fo->opt_rhost); 100 remhost = NULL; 101 for (ptr = strtok(rhost, ":"); ptr; ptr = strtok(NULL, ":")) { 102 char *at = strchr(ptr, '@'); 103 if (at == NULL) { 104 plog(XLOG_USER, "lustre: missing protocol in host `%s'", ptr); 105 XFREE(rhost); 106 return NULL; 107 } 108 *at = '\0'; 109 /* 110 * Convert symbolic addresses to numbers that the kernel likes 111 */ 112 if (inet_aton(ptr, &addr) == 0) { 113 struct hostent *hp; 114 if ((hp = gethostbyname(ptr)) == NULL) { 115 plog(XLOG_USER, "lustre: unknown host `%s'", ptr); 116 XFREE(rhost); 117 return NULL; 118 } 119 if (hp->h_length != sizeof(addr.s_addr)) { 120 plog(XLOG_USER, "lustre: bad address length %zu != %d for %s", 121 sizeof(addr), hp->h_length, ptr); 122 XFREE(rhost); 123 return NULL; 124 } 125 memcpy(&addr.s_addr, hp->h_addr, sizeof(addr)); 126 } 127 *at = '@'; 128 129 cp = remhost; 130 if (remhost) 131 remhost = strvcat(cp, ":", inet_ntoa(addr), at, NULL); 132 else 133 remhost = strvcat(inet_ntoa(addr), at, NULL); 134 XFREE(cp); 135 } 136 if (remhost == NULL) { 137 plog(XLOG_USER, "lustre: empty host"); 138 XFREE(rhost); 139 return NULL; 140 } 141 142 XFREE(rhost); 143 XFREE(fo->opt_rhost); 144 fo->opt_rhost = remhost; 145 146 l = strlen(fo->opt_rhost) + strlen(fo->opt_rfs) + 2; 147 xmtab = xmalloc(l); 148 xsnprintf(xmtab, l, "%s:%s", fo->opt_rhost, fo->opt_rfs); 149 dlog("lustre: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"", 150 fo->opt_rhost, fo->opt_rfs, fo->opt_fs); 151 152 153 return xmtab; 154 } 155 156 static int 157 lustre_mount(am_node *am, mntfs *mf) 158 { 159 mntent_t mnt; 160 int genflags, error; 161 int on_autofs = mf->mf_flags & MFF_ON_AUTOFS; 162 163 /* 164 * Figure out the name of the file system type. 165 */ 166 MTYPE_TYPE type = MOUNT_TYPE_LUSTRE; 167 168 /* 169 * Fill in the mount structure 170 */ 171 memset(&mnt, 0, sizeof(mnt)); 172 mnt.mnt_dir = mf->mf_mount; 173 mnt.mnt_fsname = mf->mf_info; 174 mnt.mnt_type = MNTTAB_TYPE_LUSTRE; 175 mnt.mnt_opts = mf->mf_mopts; 176 177 genflags = compute_mount_flags(&mnt); 178 #ifdef HAVE_FS_AUTOFS 179 if (on_autofs) 180 genflags |= autofs_compute_mount_flags(&mnt); 181 #endif /* HAVE_FS_AUTOFS */ 182 183 /* 184 * Call generic mount routine 185 */ 186 error = mount_fs(&mnt, genflags, NULL, 0, type, 0, 187 NULL, mnttab_file_name, on_autofs); 188 if (error) { 189 errno = error; 190 plog(XLOG_ERROR, "mount_lustre: %m"); 191 return error; 192 } 193 194 return 0; 195 } 196 197 198 static int 199 lustre_umount(am_node *am, mntfs *mf) 200 { 201 int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0; 202 203 return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags); 204 } 205 #endif 206