xref: /netbsd-src/external/bsd/am-utils/dist/conf/mount/mount_aix3.c (revision 93bf6008f8b7982c1d1a9486e4a4a0e687fe36eb)
1 /*	$NetBSD: mount_aix3.c,v 1.1.1.2 2009/03/20 20:26:50 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 1997-2009 Erez Zadok
5  * Copyright (c) 1990 Jan-Simon Pendry
6  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
7  * Copyright (c) 1990 The Regents of the University of California.
8  * All rights reserved.
9  *
10  * This code is derived from software contributed to Berkeley by
11  * Jan-Simon Pendry at Imperial College, London.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. All advertising materials mentioning features or use of this software
22  *    must display the following acknowledgment:
23  *      This product includes software developed by the University of
24  *      California, Berkeley and its contributors.
25  * 4. Neither the name of the University nor the names of its contributors
26  *    may be used to endorse or promote products derived from this software
27  *    without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39  * SUCH DAMAGE.
40  *
41  *
42  * File: am-utils/conf/mount/mount_aix3.c
43  *
44  */
45 
46 /*
47  * AIX 3.x/4.x Mount helper
48  */
49 
50 #ifdef HAVE_CONFIG_H
51 # include <config.h>
52 #endif /* HAVE_CONFIG_H */
53 #include <am_defs.h>
54 #include <amu.h>
55 
56 #define	VMT_ROUNDUP(len) (4 * ((len + 3) / 4))
57 #define VMT_ASSIGN(vp, idx, data, size) \
58 	vp->vmt_data[idx].vmt_off = p - (char *) vp; \
59 	vp->vmt_data[idx].vmt_size = size; \
60 	memmove(p, data, size); \
61 	p += VMT_ROUNDUP(size);
62 
63 /* missing external definitions from AIX's headers */
64 extern int vmount(struct vmount *vmount, int size);
65 
66 
67 static int
68 aix3_mkvp(char *p, int gfstype, int flags, char *object, char *stub, char *host, char *info, int info_size, char *args)
69 {
70   struct vmount *vp = (struct vmount *) p;
71 
72   memset((voidp) vp, 0, sizeof(*vp));
73   /*
74    * Fill in standard fields
75    */
76   vp->vmt_revision = VMT_REVISION;
77   vp->vmt_flags = flags;
78   vp->vmt_gfstype = gfstype;
79 
80   /*
81    * Fill in all variable length data
82    */
83   p += sizeof(*vp);
84 
85   VMT_ASSIGN(vp, VMT_OBJECT, object, strlen(object) + 1);
86   VMT_ASSIGN(vp, VMT_STUB, stub, strlen(stub) + 1);
87   VMT_ASSIGN(vp, VMT_HOST, host, strlen(host) + 1);
88   VMT_ASSIGN(vp, VMT_HOSTNAME, host, strlen(host) + 1);
89   VMT_ASSIGN(vp, VMT_INFO, info, info_size);
90   VMT_ASSIGN(vp, VMT_ARGS, args, strlen(args) + 1);
91 
92   /*
93    * Return length
94    */
95   return vp->vmt_length = p - (char *) vp;
96 }
97 
98 
99 /*
100  * Map from conventional mount arguments
101  * to AIX 3-style arguments.
102  */
103 int
104 mount_aix3(char *fsname, char *dir, int flags, int type, void *data, char *mnt_opts)
105 {
106   char buf[4096];
107   int size, ret;
108   int real_size = sizeof(nfs_args_t); /* size passed to aix3_mkvp() */
109   char *real_args = data;	/* args passed to aix3_mkvp() */
110   char *host, *rfs, *idx;
111   int aix_type = type;
112 #ifdef HAVE_FS_NFS3
113   struct nfs_args v2args;
114   nfs_args_t *v3args = (nfs_args_t *) data;
115 #ifdef MOUNT_TYPE_NFS3_BIS
116   struct aix4_nfs_args_bis v3args_bis;
117 #endif /* MOUNT_TYPE_NFS3_BIS */
118 #endif /* HAVE_FS_NFS3 */
119 
120 #ifdef DEBUG
121   dlog("mount_aix3: fsname %s, dir %s, type %d", fsname, dir, type);
122 #endif /* DEBUG */
123 
124 #ifdef MOUNT_TYPE_NFS3_BIS
125  retry_ibm_buggy_service_pack:
126 #endif /* MOUNT_TYPE_NFS3_BIS */
127   switch (aix_type) {
128 
129   case MOUNT_TYPE_NFS:
130 
131 #ifdef HAVE_FS_NFS3
132     /*
133      * This is tricky.  If we have v3 support, but this nfs mount is v2,
134      * then I must copy the arguments from the v3 nfs_args to the v2 one.
135      */
136     memmove((voidp) &v2args.addr, (voidp) &v3args->addr, sizeof(struct sockaddr_in));
137     v2args.hostname = v3args->hostname;
138     v2args.netname = v3args->netname;
139     memmove((voidp) v2args.fh, v3args->fh, FHSIZE);
140     v2args.flags = v3args->flags;
141     v2args.wsize = v3args->wsize;
142     v2args.rsize = v3args->rsize;
143     v2args.timeo = v3args->timeo;
144     v2args.retrans = v3args->retrans;
145     v2args.acregmin = v3args->acregmin;
146     v2args.acregmax = v3args->acregmax;
147     v2args.acdirmin = v3args->acdirmin;
148     v2args.acdirmax = v3args->acdirmax;
149     v2args.pathconf = v3args->pathconf;
150 
151     /* now set real_* stuff */
152     real_size = sizeof(v2args);
153     real_args = (char *) &v2args;
154 
155   case MOUNT_TYPE_NFS3:
156 #ifdef MOUNT_TYPE_NFS3_BIS
157   case MOUNT_TYPE_NFS3_BIS:
158     /* just fall through */
159     if (aix_type == MOUNT_TYPE_NFS3_BIS) {
160       dlog("mount_aix3: creating alternate nfs3_args structure");
161       memmove((voidp) &v3args_bis.addr, (voidp) &v3args->addr, sizeof(struct sockaddr_in));
162       v3args_bis.syncaddr = v3args->syncaddr;
163       v3args_bis.proto = v3args->proto;
164       v3args_bis.hostname = v3args->hostname;
165       v3args_bis.netname = v3args->netname;
166       v3args_bis.fh = v3args->fh;
167       v3args_bis.flags = v3args->flags;
168       v3args_bis.wsize = v3args->wsize;
169       v3args_bis.rsize = v3args->rsize;
170       v3args_bis.timeo = v3args->timeo;
171       v3args_bis.retrans = v3args->retrans;
172       v3args_bis.acregmin = v3args->acregmin;
173       v3args_bis.acregmax = v3args->acregmax;
174       v3args_bis.acdirmin = v3args->acdirmin;
175       v3args_bis.acdirmax = v3args->acdirmax;
176       v3args_bis.pathconf = v3args->pathconf;
177       v3args_bis.biods = v3args->biods;
178       v3args_bis.numclust = v3args->numclust;
179       /* now set real_* stuff */
180       real_size = sizeof(v3args_bis);
181       real_args = (char *) &v3args_bis;
182     }
183 #endif /* MOUNT_TYPE_NFS3_BIS */
184 #endif /* HAVE_FS_NFS3 */
185 
186     idx = strchr(fsname, ':');
187     if (idx) {
188       *idx = '\0';
189       rfs = strdup(idx + 1);
190       host = strdup(fsname);
191       *idx = ':';
192     } else {
193       rfs = strdup(fsname);
194       host = strdup(am_get_hostname());
195     }
196 
197     size = aix3_mkvp(buf, type, flags, rfs, dir, host,
198 		     real_args, real_size, mnt_opts);
199     XFREE(rfs);
200     XFREE(host);
201     break;
202 
203   case MOUNT_TYPE_UFS:
204     /* Need to open block device and extract log device info from sblk. */
205     return EINVAL;
206 
207   default:
208     return EINVAL;
209   }
210 
211   /*
212    * XXX: Warning, if vmount() hangs your amd in AIX 5.1, it
213    * is because of a kernel bug in the NFS code.  Get a patch from IBM
214    * or upgrade to 5.2.
215    */
216   ret = vmount((struct vmount *)buf, size);
217   if (ret < 0) {
218     plog(XLOG_ERROR, "mount_aix3: vmount failed with errno %d", errno);
219     perror ("vmount");
220 #ifdef MOUNT_TYPE_NFS3_BIS
221     if (aix_type == MOUNT_TYPE_NFS3 && errno == EINVAL) {
222       aix_type = MOUNT_TYPE_NFS3_BIS;
223 #ifdef DEBUG
224       dlog("mount_aix3: retrying with alternate nfs3_args structure");
225 #endif /* DEBUG */
226       goto retry_ibm_buggy_service_pack;
227     }
228 #endif /* MOUNT_TYPE_NFS3_BIS */
229   }
230   return ret;
231 }
232