1 /* 2 * $Id: restart.c,v 5.2 90/06/23 22:19:55 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 * @(#)restart.c 5.1 (Berkeley) 06/29/90 15 */ 16 17 #include "am.h" 18 19 /* 20 * Handle an amd restart. 21 * 22 * Scan through the mount list finding all "interesting" mount points. 23 * Next hack up partial data structures and add the mounted file 24 * system to the list of known filesystems. This will leave a 25 * dangling reference to that filesystems, so when the filesystem is 26 * finally inherited, an extra "free" must be done on it. 27 * 28 * This module relies on internal details of other components. If 29 * you change something else make *sure* restart() still works. 30 */ 31 void restart() 32 { 33 /* 34 * Read the existing mount table 35 */ 36 mntlist *ml, *mlp; 37 38 /* 39 * For each entry, find nfs, ufs or auto mounts 40 * and create a partial am_node to represent it. 41 */ 42 for (mlp = ml = read_mtab("restart"); mlp; mlp = mlp->mnext) { 43 struct mntent *me = mlp->mnt; 44 am_ops *fs_ops = 0; 45 if (STREQ(me->mnt_type, MTAB_TYPE_UFS)) { 46 /* 47 * UFS entry 48 */ 49 fs_ops = &ufs_ops; 50 } else if (STREQ(me->mnt_type, MTAB_TYPE_NFS)) { 51 /* 52 * NFS entry, or possibly an Amd entry... 53 */ 54 int au_pid; 55 char *colon = strchr(me->mnt_fsname, ':'); 56 if (colon && sscanf(colon, ":(pid%d)", &au_pid) == 1) { 57 plog(XLOG_WARNING, "%s is an existing automount point", me->mnt_dir); 58 fs_ops = &sfs_ops; 59 } else { 60 fs_ops = &nfs_ops; 61 } 62 #ifdef MTAB_TYPE_MFS 63 } else if (STREQ(me->mnt_type, MTAB_TYPE_MFS)) { 64 /* 65 * MFS entry. Fake with a symlink. 66 */ 67 fs_ops = &sfs_ops; 68 #endif /* MTAB_TYPE_MFS */ 69 } else { 70 /* 71 * Catch everything else with symlinks to 72 * avoid recursive mounts. This is debatable... 73 */ 74 fs_ops = &sfs_ops; 75 } 76 77 /* 78 * If we found something to do 79 */ 80 if (fs_ops) { 81 mntfs *mf; 82 am_opts mo; 83 char *cp; 84 cp = strchr(me->mnt_fsname, ':'); 85 /* 86 * Partially fake up an opts structure 87 */ 88 mo.opt_rhost = 0; 89 mo.opt_rfs = 0; 90 if (cp) { 91 *cp = '\0'; 92 mo.opt_rhost = strdup(me->mnt_fsname); 93 mo.opt_rfs = strdup(cp+1); 94 *cp = ':'; 95 } else if (fs_ops->ffserver == find_nfs_srvr) { 96 /* 97 * Prototype 4.4 BSD used to end up here - 98 * might as well keep the workaround for now 99 */ 100 plog(XLOG_WARNING, "NFS server entry assumed to be %s:/", me->mnt_fsname); 101 mo.opt_rhost = strdup(me->mnt_fsname); 102 mo.opt_rfs = strdup("/"); 103 me->mnt_fsname = str3cat(me->mnt_fsname, mo.opt_rhost, ":", "/"); 104 } 105 mo.opt_fs = me->mnt_dir; 106 107 /* 108 * Make a new mounted filesystem 109 */ 110 mf = find_mntfs(fs_ops, &mo, me->mnt_dir, 111 me->mnt_fsname, me->mnt_opts); 112 if (mf->mf_refc == 1) { 113 mf->mf_flags |= MFF_RESTART|MFF_MOUNTED; 114 mf->mf_error = 0; /* Already mounted correctly */ 115 /* 116 * If the restarted type is a link then 117 * don't time out. 118 */ 119 if (fs_ops == &sfs_ops) 120 mf->mf_flags |= MFF_RSTKEEP; 121 if (fs_ops->fs_init) { 122 /* 123 * Don't care whether this worked since 124 * it is checked again when the fs is 125 * inherited. 126 */ 127 (void) (*fs_ops->fs_init)(mf); 128 } 129 130 plog(XLOG_INFO, "%s restarted fstype %s on %s", 131 me->mnt_fsname, fs_ops->fs_type, me->mnt_dir); 132 } else { 133 /* Something strange happened - two mounts at the same place! */ 134 free_mntfs(mf); 135 } 136 /* 137 * Clean up mo 138 */ 139 if (mo.opt_rhost) 140 free(mo.opt_rhost); 141 if (mo.opt_rfs) 142 free(mo.opt_rfs); 143 } 144 } 145 146 /* 147 * Free the mount list 148 */ 149 free_mntlist(ml); 150 } 151