]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/amd/amd/ops_lustre.c
MFC r308493, r308619: Update amd from am-utils 6.1.5 to 6.2.
[FreeBSD/stable/10.git] / contrib / amd / amd / ops_lustre.c
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 */
43 static char *lustre_match(am_opts *fo);
44 static int lustre_mount(am_node *am, mntfs *mf);
45 static int lustre_umount(am_node *am, mntfs *mf);
46
47 /*
48  * Ops structure
49  */
50 am_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  */
75 static char *
76 lustre_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
154 static int
155 lustre_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
196 static int
197 lustre_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