⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nfsx_ops.c

📁 早期freebsd实现
💻 C
字号:
/* * 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. * *	@(#)nfsx_ops.c	8.1 (Berkeley) 6/6/93 * * $Id: nfsx_ops.c,v 5.2.2.3 1992/05/31 16:13:07 jsp Exp $ * */#include "am.h"#ifdef HAS_NFSX/* * NFS hierarchical mounts * * TODO: Re-implement. *//* * The rfs field contains a list of mounts to be done from * the remote host. */typedef struct nfsx_mnt {	mntfs *n_mnt;	int n_error;} nfsx_mnt;struct nfsx {	int nx_c;		/* Number of elements in nx_v */	nfsx_mnt *nx_v;		/* Underlying mounts */	nfsx_mnt *nx_try;};static int nfsx_fmount P((mntfs*));static char *nfsx_match(fo)am_opts *fo;{	char *xmtab;	char *ptr;	int len;	if (!fo->opt_rfs) {		plog(XLOG_USER, "nfsx: no remote filesystem specified");		return FALSE;	}	if (!fo->opt_rhost) {		plog(XLOG_USER, "nfsx: no remote host specified");		return FALSE;	}#ifdef notdef	/* fiddle sublink, must be last... */	if (fo->opt_sublink) {		plog(XLOG_WARNING, "nfsx: sublink %s ignored", fo->opt_sublink);		free((voidp) fo->opt_sublink);		fo->opt_sublink = 0;	}#endif	/* set default sublink */	if (fo->opt_sublink == 0) {		ptr = strchr(fo->opt_rfs, ',');		if (ptr && ptr != (fo->opt_rfs + 1))			fo->opt_sublink = strnsave(fo->opt_rfs + 1, ptr - fo->opt_rfs - 1);	}	/*	 * Remove trailing ",..." from ${fs}	 * After deslashifying, overwrite the end of ${fs} with "/"	 * to make sure it is unique.	 */	if (ptr = strchr(fo->opt_fs, ','))		*ptr = '\0';	deslashify(fo->opt_fs);	/*	 * Bump string length to allow trailing /	 */	len = strlen(fo->opt_fs);	fo->opt_fs = xrealloc(fo->opt_fs, len + 1 + 1);	ptr = fo->opt_fs + len;	/*	 * Make unique...	 */	*ptr++ = '/';	*ptr = '\0';	/*	 * Determine magic cookie to put in mtab	 */	xmtab = str3cat((char *) 0, fo->opt_rhost, ":", fo->opt_rfs);#ifdef DEBUG	dlog("NFS: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"",		fo->opt_rhost, fo->opt_rfs, fo->opt_fs);#endif /* DEBUG */	return xmtab;}static void nfsx_prfree P((voidp vp));static void nfsx_prfree(vp)voidp vp;{	struct nfsx *nx = (struct nfsx *) vp;	int i;	for (i = 0; i < nx->nx_c; i++) {		mntfs *m = nx->nx_v[i].n_mnt;		if (m)			free_mntfs(m);	}	free((voidp) nx->nx_v);	free((voidp) nx);}static int nfsx_init(mf)mntfs *mf;{	/*	 * mf_info has the form:	 *   host:/prefix/path,sub,sub,sub	 */	int i;	int glob_error;	struct nfsx *nx;	int asked_for_wakeup = 0;	nx = (struct nfsx *) mf->mf_private;	if (nx == 0) {		char **ivec;		char *info = 0;		char *host;		char *pref;		int error = 0;		info = strdup(mf->mf_info);		host = strchr(info, ':');		if (!host) {			error = EINVAL;			goto errexit;		}		pref = host+1;		host = info;		/*		 * Split the prefix off from the suffices		 */		ivec = strsplit(pref, ',', '\'');		/*		 * Count array size		 */		for (i = 0; ivec[i]; i++)			;		nx = ALLOC(nfsx);		mf->mf_private = (voidp) nx;		mf->mf_prfree = nfsx_prfree;		nx->nx_c = i - 1;	/* i-1 because we don't want the prefix */		nx->nx_v = (nfsx_mnt *) xmalloc(nx->nx_c * sizeof(nfsx_mnt));		{ char *mp = 0;		  char *xinfo = 0;		  char *fs = mf->mf_fo->opt_fs;		  char *rfs = 0;		  for (i = 0; i < nx->nx_c; i++) {		  	char *path = ivec[i+1];			rfs = str3cat(rfs, pref, "/", path);		  	/*			 * Determine the mount point.			 * If this is the root, then don't remove			 * the trailing slash to avoid mntfs name clashes.			 */			mp = str3cat(mp, fs, "/", rfs);			normalize_slash(mp);			deslashify(mp);			/*			 * Determine the mount info			 */			xinfo = str3cat(xinfo, host, *path == '/' ? "" : "/", path);			normalize_slash(xinfo);			if (pref[1] != '\0')				deslashify(xinfo);#ifdef DEBUG			dlog("nfsx: init mount for %s on %s", xinfo, mp);#endif			nx->nx_v[i].n_error = -1;			nx->nx_v[i].n_mnt = find_mntfs(&nfs_ops, mf->mf_fo, mp, xinfo, "", mf->mf_mopts, mf->mf_remopts);		  }		  if (rfs) free(rfs);		  if (mp) free(mp);		  if (xinfo) free(xinfo);		}		free((voidp) ivec);errexit:		if (info)			free(info);		if (error)			return error;	}	/*	 * Iterate through the mntfs's and call	 * the underlying init routine on each	 */	glob_error = 0;	for (i = 0; i < nx->nx_c; i++) {		nfsx_mnt *n = &nx->nx_v[i];		mntfs *m = n->n_mnt;		int error = (*m->mf_ops->fs_init)(m);		/*		 * If HARD_NFSX_ERRORS is defined, make any		 * initialisation failure a hard error and		 * fail the entire group.  Otherwise only fail		 * if none of the group is mountable (see nfsx_fmount).		 */#ifdef HARD_NFSX_ERRORS		if (error > 0)			return error;#else		if (error > 0)			n->n_error = error;#endif		else if (error < 0) {			glob_error = -1;			if (!asked_for_wakeup) {				asked_for_wakeup = 1;				sched_task(wakeup_task, (voidp) mf, (voidp) m);			}		}	}	return glob_error;}static void nfsx_cont P((int rc, int term, voidp closure));static void nfsx_cont(rc, term, closure)int rc;int term;voidp closure;{	mntfs *mf = (mntfs *) closure;	struct nfsx *nx = (struct nfsx *) mf->mf_private;	nfsx_mnt *n = nx->nx_try;	n->n_mnt->mf_flags &= ~(MFF_ERROR|MFF_MOUNTING);	mf->mf_flags &= ~MFF_ERROR;	/*	 * Wakeup anything waiting for this mount	 */	wakeup((voidp) n->n_mnt);	if (rc || term) {		if (term) {			/*			 * Not sure what to do for an error code.			 */			plog(XLOG_ERROR, "mount for %s got signal %d", n->n_mnt->mf_mount, term);			n->n_error = EIO;		} else {			/*			 * Check for exit status			 */			errno = rc;	/* XXX */			plog(XLOG_ERROR, "%s: mount (nfsx_cont): %m", n->n_mnt->mf_mount);			n->n_error = rc;		}		free_mntfs(n->n_mnt);		n->n_mnt = new_mntfs();		n->n_mnt->mf_error = n->n_error;		n->n_mnt->mf_flags |= MFF_ERROR;	} else {		/*		 * The mount worked.		 */		mf_mounted(n->n_mnt);		n->n_error = 0;	}	/*	 * Do the remaining bits	 */	if (nfsx_fmount(mf) >= 0) {		wakeup((voidp) mf);		mf->mf_flags &= ~MFF_MOUNTING;		mf_mounted(mf);	}}static int try_nfsx_mount P((voidp mv));static int try_nfsx_mount(mv)voidp mv;{	mntfs *mf = (mntfs *) mv;	int error;	mf->mf_flags |= MFF_MOUNTING;	error = (*mf->mf_ops->fmount_fs)(mf);	mf->mf_flags &= ~MFF_MOUNTING;	return error;}static int nfsx_remount P((mntfs *mf, int fg));static int nfsx_remount(mf, fg)mntfs *mf;int fg;{	struct nfsx *nx = (struct nfsx *) mf->mf_private;	nfsx_mnt *n;	int glob_error = -1;	for (n = nx->nx_v; n < nx->nx_v + nx->nx_c; n++) {		mntfs *m = n->n_mnt;		if (n->n_error < 0) {			if (!(m->mf_flags & MFF_MKMNT) && m->mf_ops->fs_flags & FS_MKMNT) {				int error = mkdirs(m->mf_mount, 0555);				if (!error)					m->mf_flags |= MFF_MKMNT;			}		}	}	/*	 * Iterate through the mntfs's and mount each filesystem	 * which is not yet mounted.	 */	for (n = nx->nx_v; n < nx->nx_v + nx->nx_c; n++) {		mntfs *m = n->n_mnt;		if (n->n_error < 0) {			/*			 * Check fmount entry pt. exists			 * and then mount...			 */			if (!m->mf_ops->fmount_fs) {				n->n_error = EINVAL;			} else {#ifdef DEBUG				dlog("calling underlying fmount on %s", m->mf_mount);#endif				if (!fg && foreground && (m->mf_ops->fs_flags & FS_MBACKGROUND)) {					m->mf_flags |= MFF_MOUNTING;	/* XXX */#ifdef DEBUG					dlog("backgrounding mount of \"%s\"", m->mf_info);#endif					nx->nx_try = n;					run_task(try_nfsx_mount, (voidp) m, nfsx_cont, (voidp) mf);					n->n_error = -1;					return -1;				} else {#ifdef DEBUG					dlog("foreground mount of \"%s\" ...", mf->mf_info);#endif					n->n_error = (*m->mf_ops->fmount_fs)(m);				}			}#ifdef DEBUG			if (n->n_error > 0) {				errno = n->n_error;	/* XXX */				dlog("underlying fmount of %s failed: %m", m->mf_mount);			}#endif			if (n->n_error == 0) {				glob_error = 0;			} else if (glob_error < 0) {				glob_error = n->n_error;			}		}	}	return glob_error < 0 ? 0 : glob_error;}static int nfsx_fmount P((mntfs *mf));static int nfsx_fmount(mf)mntfs *mf;{	return nfsx_remount(mf, FALSE);}/* * Unmount an NFS hierarchy. * Note that this is called in the foreground * and so may hang under extremely rare conditions. */static int nfsx_fumount(mf)mntfs *mf;{	struct nfsx *nx = (struct nfsx *) mf->mf_private;	nfsx_mnt *n;	int glob_error = 0;	/*	 * Iterate in reverse through the mntfs's and unmount each filesystem	 * which is mounted.	 */	for (n = nx->nx_v + nx->nx_c - 1; n >= nx->nx_v; --n) {		mntfs *m = n->n_mnt;		/*		 * If this node has not been messed with		 * and there has been no error so far		 * then try and unmount.		 * If an error had occured then zero		 * the error code so that the remount		 * only tries to unmount those nodes		 * which had been successfully unmounted.		 */		if (n->n_error == 0) {#ifdef DEBUG			dlog("calling underlying fumount on %s", m->mf_mount);#endif			n->n_error = (*m->mf_ops->fumount_fs)(m);			if (n->n_error) {				glob_error = n->n_error;				n->n_error = 0;			} else {				/*				 * Make sure remount gets this node				 */				n->n_error = -1;			}		}	}	/*	 * If any unmounts failed then remount the	 * whole lot...	 */	if (glob_error) {		glob_error = nfsx_remount(mf, TRUE);		if (glob_error) {			errno = glob_error; /* XXX */			plog(XLOG_USER, "nfsx: remount of %s failed: %m", mf->mf_mount);		}		glob_error = EBUSY;	} else {		/*		 * Remove all the mount points		 */		for (n = nx->nx_v; n < nx->nx_v + nx->nx_c; n++) {			mntfs *m = n->n_mnt;			if (n->n_error < 0) {				if (m->mf_ops->fs_flags & FS_MKMNT) {					(void) rmdirs(m->mf_mount);					m->mf_flags &= ~MFF_MKMNT;				}			}			free_mntfs(m);			n->n_mnt = 0;			n->n_error = -1;		}	}	return glob_error;}/* * Ops structure */am_ops nfsx_ops = {	"nfsx",	nfsx_match,	nfsx_init,	auto_fmount,	nfsx_fmount,	auto_fumount,	nfsx_fumount,	efs_lookuppn,	efs_readdir,	0, /* nfsx_readlink */	0, /* nfsx_mounted */	0, /* nfsx_umounted */	find_nfs_srvr,			/* XXX */	/*FS_UBACKGROUND|*/FS_AMQINFO};#endif /* HAS_NFSX */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -