xref: /original-bsd/usr.sbin/amd/amd/restart.c (revision 95a66346)
1 /*
2  * $Id: restart.c,v 5.2.1.2 90/11/04 23:17:27 jsp Exp $
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.2 (Berkeley) 03/17/91
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 			mo.opt_opts = me->mnt_opts;
107 
108 			/*
109 			 * Make a new mounted filesystem
110 			 */
111 			mf = find_mntfs(fs_ops, &mo, me->mnt_dir,
112 				me->mnt_fsname, "", me->mnt_opts);
113 			if (mf->mf_refc == 1) {
114 				mf->mf_flags |= MFF_RESTART|MFF_MOUNTED;
115 				mf->mf_error = 0;	/* Already mounted correctly */
116 				mf->mf_fo = 0;
117 				/*
118 				 * If the restarted type is a link then
119 				 * don't time out.
120 				 */
121 				if (fs_ops == &sfs_ops || fs_ops == &ufs_ops)
122 					mf->mf_flags |= MFF_RSTKEEP;
123 				if (fs_ops->fs_init) {
124 					/*
125 					 * Don't care whether this worked since
126 					 * it is checked again when the fs is
127 					 * inherited.
128 					 */
129 					(void) (*fs_ops->fs_init)(mf);
130 				}
131 
132 				plog(XLOG_INFO, "%s restarted fstype %s on %s",
133 					me->mnt_fsname, fs_ops->fs_type, me->mnt_dir);
134 			} else {
135 				/* Something strange happened - two mounts at the same place! */
136 				free_mntfs(mf);
137 			}
138 			/*
139 			 * Clean up mo
140 			 */
141 			if (mo.opt_rhost)
142 				free(mo.opt_rhost);
143 			if (mo.opt_rfs)
144 				free(mo.opt_rfs);
145 		}
146 	}
147 
148 	/*
149 	 * Free the mount list
150 	 */
151 	free_mntlist(ml);
152 }
153