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