1 /* 2 * $Id: mount_fs.c,v 5.2 90/06/23 22:19:42 jsp Rel $ 3 * 4 * Copyright (c) 1990 Jan-Simon Pendry 5 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 6 * Copyright (c) 1990 The Regents of the University of California. 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by 10 * Jan-Simon Pendry at Imperial College, London. 11 * 12 * %sccs.include.redist.c% 13 * 14 * @(#)mount_fs.c 5.1 (Berkeley) 06/29/90 15 */ 16 17 #include "am.h" 18 #ifdef NFS_3 19 typedef nfs_fh fhandle_t; 20 #endif /* NFS_3 */ 21 #include <sys/mount.h> 22 23 /* 24 * System Vr4 / SunOS 4.1 compatibility 25 * - put dev= in the options list 26 * 27 * From: Brent Callaghan <brent@eng.sun.com> 28 */ 29 #define MNTINFO_DEV "dev" 30 #include <sys/stat.h> 31 32 /* 33 * Standard mount flags 34 */ 35 #ifdef hpux 36 /* 37 * HP-UX has an annoying feature of printing 38 * error msgs on /dev/console 39 */ 40 #undef M_NOSUID 41 #endif /* hpux */ 42 43 struct opt_tab mnt_flags[] = { 44 { "ro", M_RDONLY }, 45 #ifdef M_CACHE 46 { "nocache", M_NOCACHE }, 47 #endif /* M_CACHE */ 48 #ifdef M_GRPID 49 { "grpid", M_GRPID }, 50 #endif /* M_GRPID */ 51 #ifdef M_MULTI 52 { "multi", M_MULTI }, 53 #endif /* M_MULTI */ 54 #ifdef M_NODEV 55 { "nodev", M_NODEV }, 56 #endif /* M_NODEV */ 57 #ifdef M_NOEXEC 58 { "noexec", M_NOEXEC }, 59 #endif /* M_NOEXEC */ 60 #ifdef M_NOSUB 61 { "nosub", M_NOSUB }, 62 #endif /* M_NOSUB */ 63 #ifdef M_NOSUID 64 { "nosuid", M_NOSUID }, 65 #endif /* M_NOSUID */ 66 #ifdef M_SYNC 67 { "sync", M_SYNC }, 68 #endif /* M_SYNC */ 69 { 0, 0 } 70 }; 71 72 int compute_mount_flags(mnt) 73 struct mntent *mnt; 74 { 75 struct opt_tab *opt; 76 int flags; 77 #ifdef NFS_4 78 flags = M_NEWTYPE; 79 #else 80 flags = 0; 81 #endif /* NFS_4 */ 82 83 /* 84 * Crack basic mount options 85 */ 86 for (opt = mnt_flags; opt->opt; opt++) 87 flags |= hasmntopt(mnt, opt->opt) ? opt->flag : 0; 88 89 return flags; 90 } 91 92 int mount_fs(mnt, flags, mnt_data, retry, type) 93 struct mntent *mnt; 94 int flags; 95 caddr_t mnt_data; 96 int retry; 97 MTYPE_TYPE type; 98 { 99 int error = 0; 100 int automount = 0; 101 #ifdef MNTINFO_DEV 102 struct stat stb; 103 char *xopts = 0; 104 #endif /* MNTINFO_DEV */ 105 106 #ifdef DEBUG 107 #ifdef NFS_4 108 dlog("%s fstype %s (%s) flags %#x (%s)", 109 mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts); 110 #else 111 dlog("%s fstype %d (%s) flags %#x (%s)", 112 mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts); 113 #endif /* NFS_4 */ 114 #endif /* DEBUG */ 115 116 /* 117 * Fake some mount table entries for the automounter 118 */ 119 if (STREQ(mnt->mnt_type, MNTTYPE_AUTO)) { 120 automount = 1; 121 mnt->mnt_fsname = pid_fsname; 122 /* 123 * Try it with the normal name 124 */ 125 #ifdef notdef 126 /* 127 * This is notdef'ed because some systems use 128 * the mount table in getwd() (esp. SunOS4) and 129 * if all the mount points are not marked it can 130 * cause major confusion. This can probably 131 * be changed when no-one is running SunOS 4.0 132 * any more. 133 */ 134 mnt->mnt_type = MNTTYPE_IGNORE; 135 #endif /* notdef */ 136 mnt->mnt_type = MNTTYPE_NFS; 137 /* 138 * Background the mount, so that the stat of the 139 * mountpoint is done in a background process. 140 */ 141 if (background()) 142 return 0; 143 } 144 145 again: 146 clock_valid = 0; 147 error = MOUNT_TRAP(type, mnt, flags, mnt_data); 148 if (error < 0) 149 plog(XLOG_ERROR, "%s: mount: %m", mnt->mnt_dir); 150 if (error < 0 && --retry > 0) { 151 sleep(1); 152 goto again; 153 } 154 if (error < 0) { 155 if (automount) 156 going_down(errno); 157 return errno; 158 } 159 160 #ifdef UPDATE_MTAB 161 #ifdef MNTINFO_DEV 162 /* 163 * Add the extra dev= field to the mount table. 164 */ 165 if (lstat(mnt->mnt_dir, &stb) == 0) { 166 char *zopts = (char *) xmalloc(strlen(mnt->mnt_opts) + 32); 167 xopts = mnt->mnt_opts; 168 if (sizeof(stb.st_dev) == 2) { 169 /* SunOS 4.1 */ 170 sprintf(zopts, "%s,%s=%04lx", xopts, MNTINFO_DEV, 171 (u_long) stb.st_dev & 0xffff); 172 } else { 173 /* System Vr4 */ 174 sprintf(zopts, "%s,%s=%08lx", xopts, MNTINFO_DEV, 175 (u_long) stb.st_dev); 176 } 177 mnt->mnt_opts = zopts; 178 } 179 #endif /* MNTINFO_DEV */ 180 181 #ifdef hpux 182 /* 183 * Yet another gratuitously incompatible change in HP-UX 184 */ 185 mnt->mnt_time = clocktime(); 186 #endif /* hpux */ 187 write_mntent(mnt); 188 #ifdef MNTINFO_DEV 189 if (xopts) { 190 free(mnt->mnt_opts); 191 mnt->mnt_opts = xopts; 192 } 193 #endif /* MNTINFO_DEV */ 194 #endif /* UPDATE_MTAB */ 195 196 /* 197 * Needed this way since mnt may contain a pointer 198 * to a local variable in this stack frame. 199 */ 200 if (automount) 201 going_down(0); 202 return 0; 203 } 204 205 #ifdef NEED_MNTOPT_PARSER 206 /* 207 * Some systems don't provide these to the user, 208 * but amd needs them, so... 209 * 210 * From: Piete Brooks <pb@cl.cam.ac.uk> 211 */ 212 213 #include <ctype.h> 214 215 static char *nextmntopt(p) 216 char **p; 217 { 218 char *cp = *p; 219 char *rp; 220 /* 221 * Skip past white space 222 */ 223 while (*cp && isspace(*cp)) 224 cp++; 225 /* 226 * Word starts here 227 */ 228 rp = cp; 229 /* 230 * Scan to send of string or separator 231 */ 232 while (*cp && *cp != ',') 233 cp++; 234 /* 235 * If separator found the overwrite with nul char. 236 */ 237 if (*cp) { 238 *cp = '\0'; 239 cp++; 240 } 241 /* 242 * Return value for next call 243 */ 244 *p = cp; 245 return rp; 246 } 247 248 char *hasmntopt(mnt, opt) 249 struct mntent *mnt; 250 char *opt; 251 { 252 char t[MNTMAXSTR]; 253 char *f; 254 char *o = t; 255 int l = strlen(opt); 256 strcpy(t, mnt->mnt_opts); 257 258 while (*(f = nextmntopt(&o))) 259 if (strncmp(opt, f, l) == 0) 260 return f - t + mnt->mnt_opts; 261 262 return 0; 263 } 264 #endif /* NEED_MNTOPT_PARSER */ 265 266 #ifdef MOUNT_AIX3 267 268 #include "aix3-nfs.h" 269 270 static int aix3_mkvp(p, gfstype, flags, object, stub, host, info, info_size, args) 271 char *p; 272 int gfstype; 273 int flags; 274 char *object; 275 char *stub; 276 char *host; 277 char *info; 278 int info_size; 279 char *args; 280 { 281 struct vmount *vp = (struct vmount *) p; 282 bzero((voidp) vp, sizeof(*vp)); 283 /* 284 * Fill in standard fields 285 */ 286 vp->vmt_revision = VMT_REVISION; 287 vp->vmt_flags = flags; 288 vp->vmt_gfstype = gfstype; 289 290 #define VMT_ROUNDUP(len) (4 * ((len + 3) / 4)) 291 #define VMT_ASSIGN(vp, idx, data, size) \ 292 vp->vmt_data[idx].vmt_off = p - (char *) vp; \ 293 vp->vmt_data[idx].vmt_size = size; \ 294 bcopy(data, p, size); \ 295 p += VMT_ROUNDUP(size); 296 297 /* 298 * Fill in all variable length data 299 */ 300 p += sizeof(*vp); 301 302 VMT_ASSIGN(vp, VMT_OBJECT, object, strlen(object) + 1); 303 VMT_ASSIGN(vp, VMT_STUB, stub, strlen(stub) + 1); 304 VMT_ASSIGN(vp, VMT_HOST, host, strlen(host) + 1); 305 VMT_ASSIGN(vp, VMT_HOSTNAME, host, strlen(host) + 1); 306 VMT_ASSIGN(vp, VMT_INFO, info, info_size); 307 VMT_ASSIGN(vp, VMT_ARGS, args, strlen(args) + 1); 308 309 #undef VMT_ASSIGN 310 #undef VMT_ROUNDUP 311 312 /* 313 * Return length 314 */ 315 return vp->vmt_length = p - (char *) vp; 316 } 317 318 /* 319 * Map from conventional mount arguments 320 * to AIX 3-style arguments. 321 */ 322 aix3_mount(fsname, dir, flags, type, data, args) 323 char *fsname; 324 char *dir; 325 int flags; 326 int type; 327 void *data; 328 char *args; 329 { 330 char buf[4096]; 331 int size; 332 333 #ifdef DEBUG 334 dlog("aix3_mount: fsname %s, dir %s, type %d", fsname, dir, type); 335 #endif /* DEBUG */ 336 337 /* aix3_mkvp(p, gfstype, flags, object, stub, host, info, info_size, args) */ 338 339 switch (type) { 340 341 case MOUNT_TYPE_NFS: { 342 char *host = strdup(fsname); 343 char *rfs = strchr(host, ':'); 344 *rfs++ = '\0'; 345 346 size = aix3_mkvp(buf, type, flags, rfs, dir, host, data, sizeof(struct nfs_args), args); 347 free(host); 348 349 } break; 350 351 case MOUNT_TYPE_UFS: 352 /* Need to open block device and extract log device info from sblk. */ 353 return EINVAL; 354 355 default: 356 return EINVAL; 357 } 358 #ifdef DEBUG 359 /*dlog("aix3_mkvp: flags %#x, size %d, args %s", flags, size, args);*/ 360 #endif /* DEBUG */ 361 362 return vmount(buf, size); 363 } 364 #endif /* MOUNT_AIX3 */ 365