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