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 */
restart()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