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