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