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