xref: /original-bsd/usr.sbin/amd/amd/restart.c (revision 403c148d)
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