diff options
Diffstat (limited to 'usr.sbin/amd/amd/restart.c')
-rw-r--r-- | usr.sbin/amd/amd/restart.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/usr.sbin/amd/amd/restart.c b/usr.sbin/amd/amd/restart.c new file mode 100644 index 0000000..52a9c87 --- /dev/null +++ b/usr.sbin/amd/amd/restart.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: restart.c,v 5.2.2.1 1992/02/09 15:08:59 jsp beta $ + * + */ + +#ifndef lint +static char sccsid[] = "@(#)restart.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "am.h" + +/* + * Handle an amd restart. + * + * Scan through the mount list finding all "interesting" mount points. + * Next hack up partial data structures and add the mounted file + * system to the list of known filesystems. This will leave a + * dangling reference to that filesystems, so when the filesystem is + * finally inherited, an extra "free" must be done on it. + * + * This module relies on internal details of other components. If + * you change something else make *sure* restart() still works. + */ +void restart() +{ + /* + * Read the existing mount table + */ + mntlist *ml, *mlp; + + /* + * For each entry, find nfs, ufs or auto mounts + * and create a partial am_node to represent it. + */ + for (mlp = ml = read_mtab("restart"); mlp; mlp = mlp->mnext) { + struct mntent *me = mlp->mnt; + am_ops *fs_ops = 0; + if (STREQ(me->mnt_type, MTAB_TYPE_UFS)) { + /* + * UFS entry + */ + fs_ops = &ufs_ops; + } else if (STREQ(me->mnt_type, MTAB_TYPE_NFS)) { + /* + * NFS entry, or possibly an Amd entry... + */ + int au_pid; + char *colon = strchr(me->mnt_fsname, ':'); + if (colon && sscanf(colon, ":(pid%d)", &au_pid) == 1) { + plog(XLOG_WARNING, "%s is an existing automount point", me->mnt_dir); + fs_ops = &sfs_ops; + } else { + fs_ops = &nfs_ops; + } +#ifdef MTAB_TYPE_MFS + } else if (STREQ(me->mnt_type, MTAB_TYPE_MFS)) { + /* + * MFS entry. Fake with a symlink. + */ + fs_ops = &sfs_ops; +#endif /* MTAB_TYPE_MFS */ + } else { + /* + * Catch everything else with symlinks to + * avoid recursive mounts. This is debatable... + */ + fs_ops = &sfs_ops; + } + + /* + * If we found something to do + */ + if (fs_ops) { + mntfs *mf; + am_opts mo; + char *cp; + cp = strchr(me->mnt_fsname, ':'); + /* + * Partially fake up an opts structure + */ + mo.opt_rhost = 0; + mo.opt_rfs = 0; + if (cp) { + *cp = '\0'; + mo.opt_rhost = strdup(me->mnt_fsname); + mo.opt_rfs = strdup(cp+1); + *cp = ':'; + } else if (fs_ops->ffserver == find_nfs_srvr) { + /* + * Prototype 4.4 BSD used to end up here - + * might as well keep the workaround for now + */ + plog(XLOG_WARNING, "NFS server entry assumed to be %s:/", me->mnt_fsname); + mo.opt_rhost = strdup(me->mnt_fsname); + mo.opt_rfs = strdup("/"); + me->mnt_fsname = str3cat(me->mnt_fsname, mo.opt_rhost, ":", "/"); + } + mo.opt_fs = me->mnt_dir; + mo.opt_opts = me->mnt_opts; + + /* + * Make a new mounted filesystem + */ + mf = find_mntfs(fs_ops, &mo, me->mnt_dir, + me->mnt_fsname, "", me->mnt_opts, ""); + if (mf->mf_refc == 1) { + mf->mf_flags |= MFF_RESTART|MFF_MOUNTED; + mf->mf_error = 0; /* Already mounted correctly */ + mf->mf_fo = 0; + /* + * If the restarted type is a link then + * don't time out. + */ + if (fs_ops == &sfs_ops || fs_ops == &ufs_ops) + mf->mf_flags |= MFF_RSTKEEP; + if (fs_ops->fs_init) { + /* + * Don't care whether this worked since + * it is checked again when the fs is + * inherited. + */ + (void) (*fs_ops->fs_init)(mf); + } + + plog(XLOG_INFO, "%s restarted fstype %s on %s", + me->mnt_fsname, fs_ops->fs_type, me->mnt_dir); + } else { + /* Something strange happened - two mounts at the same place! */ + free_mntfs(mf); + } + /* + * Clean up mo + */ + if (mo.opt_rhost) + free(mo.opt_rhost); + if (mo.opt_rfs) + free(mo.opt_rfs); + } + } + + /* + * Free the mount list + */ + free_mntlist(ml); +} |