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