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 *
lustre_match(am_opts * fo)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
lustre_mount(am_node * am,mntfs * mf)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
lustre_umount(am_node * am,mntfs * mf)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