netmount, localmount, halt.sh and net scripts now check OS specific flags to see if a mount is network mounted (linux = fstab, *bsd = "local" in mount options) or not, #192772.
This commit is contained in:
		| @@ -3,6 +3,9 @@ | ||||
|  | ||||
|   09 Oct 2007; Roy Marples <uberlord@gentoo.org>: | ||||
|  | ||||
|     netmount, localmount, halt.sh and net scripts now check OS specific flags | ||||
|     to see if a mount is network mounted (linux = fstab, *bsd = "local" in | ||||
|     mount options) or not, #192772. | ||||
|     txqueuelen_eth0= now works, #190538. | ||||
|  | ||||
|   03 Oct 2007; Roy Marples <uberlord@gentoo.org>: | ||||
|   | ||||
| @@ -72,7 +72,9 @@ if [ "${RC_UNAME}" = "Linux" ] ; then | ||||
| 		fs="${fs}${fs:+|}${x}" | ||||
| 	done | ||||
| 	[ -n "${fs}" ] && fs="^(${fs})$" | ||||
| 	do_unmount "mount -n -o remount,ro" "^(/dev|/dev/.*|/proc|/proc/.*|/sys|/sys/.*)$" "" "" "${fs}" | ||||
| 	do_unmount "mount -n -o remount,ro" \ | ||||
| 		--skip-point-regex "^(/dev|/dev/.*|/proc|/proc/.*|/sys|/sys/.*)$" \ | ||||
| 		${fs:+--skip-fstype-regex} ${fs} --nonetdev | ||||
| 	eoutdent | ||||
| 	eend $? | ||||
| 	unmounted=$? | ||||
|   | ||||
| @@ -203,7 +203,8 @@ stop() { | ||||
| 	# Umount loopback devices | ||||
| 	einfo "Unmounting loopback devices" | ||||
| 	eindent | ||||
| 	do_unmount "umount -d" "${no_umounts}" "^/dev/loop" | ||||
| 	do_unmount "umount -d" --skip-point-regex "${no_umounts}" \ | ||||
| 		--node-regex "^/dev/loop" | ||||
| 	eoutdent | ||||
|  | ||||
| 	# Now everything else, except network filesystems as the | ||||
| @@ -215,7 +216,8 @@ stop() { | ||||
| 		fs="${fs}${fs:+|}${x}" | ||||
| 	done | ||||
| 	[ -n "${fs}" ] && fs="^(${fs})$" | ||||
| 	do_unmount "umount" "${no_umounts}" "" "" "${fs}" | ||||
| 	do_unmount "umount" --skip-point-regex "${no_umounts}" \ | ||||
| 		${fs:+--skip-fstype-regex} ${fs} --nonetdev | ||||
| 	eoutdent | ||||
|  | ||||
| 	return 0 | ||||
|   | ||||
| @@ -21,7 +21,7 @@ depend() { | ||||
| 	# Only have portmap as a dependency if there is a nfs mount in fstab that | ||||
| 	# is set to mount at boot | ||||
| 	local pmap="" | ||||
| 	if need_portmap ; then | ||||
| 	if need_portmap; then | ||||
| 		[ -x /etc/init.d/rpcbind ] \ | ||||
| 			&& pmap="rpcbind" \ | ||||
| 			|| pmap="portmap" | ||||
| @@ -37,7 +37,7 @@ start() { | ||||
| 	[ -x /etc/init.d/rpcbind ] && pmap="rpcbind" | ||||
|  | ||||
| 	local x= fs= | ||||
| 	for x in ${RC_NET_FS_LIST} ; do | ||||
| 	for x in ${RC_NET_FS_LIST}; do | ||||
| 		case "${x}" in | ||||
| 			nfs|nfs4) | ||||
|     			# If the nfsmount script took care of the nfs filesystems, | ||||
| @@ -47,7 +47,7 @@ start() { | ||||
|         		# Only try to mount NFS filesystems if portmap was started. | ||||
| 		        # This is to fix "hang" problems for new users who do not | ||||
| 				# add portmap to the default runlevel. | ||||
| 				if need_portmap && ! service_started "${pmap}" ; then | ||||
| 				if need_portmap && ! service_started "${pmap}"; then | ||||
| 					continue | ||||
| 				fi | ||||
| 				;; | ||||
| @@ -63,28 +63,28 @@ start() { | ||||
|  | ||||
| stop() { | ||||
| 	local x= fs= | ||||
|  | ||||
| 	ebegin "Unmounting network filesystems" | ||||
| 	. "${RC_LIBDIR}/sh/rc-mount.sh" | ||||
|  | ||||
| 	for x in ${RC_NET_FS_LIST} ; do | ||||
| 		fs="${fs}${fs:+,}${x}" | ||||
| 	done | ||||
|  | ||||
| 	ebegin "Unmounting network filesystems" | ||||
| 	umount -at ${fs} | ||||
| 	local retval=$? | ||||
| 	eend ${retval} "Failed to simply unmount filesystems" | ||||
|  | ||||
| 	if [ ${retval} -ne 0 ] ; then | ||||
| 		. "${RC_LIBDIR}/sh/rc-mount.sh" | ||||
| 		eindent | ||||
| 		fs= | ||||
| 		for x in ${RC_NET_FS_LIST} ; do | ||||
| 			fs="${fs:+|}${x}" | ||||
| 		done | ||||
| 		do_unmount "umount" "" "" "^(${fs})$" | ||||
| 		retval=$? | ||||
| 		eoutdent | ||||
| 	if [ -n "${fs}" ]; then | ||||
| 		umount -at ${fs} ||	eerror "Failed to simply unmount filesystems" | ||||
| 	fi | ||||
|  | ||||
| 	return ${retval} | ||||
| 	eindent | ||||
| 	fs= | ||||
| 	for x in ${RC_NET_FS_LIST}; do | ||||
| 		fs="${fs}${fs:+|}${x}" | ||||
| 	done | ||||
| 	[ -n "${fs}" ] && fs="^(${fs})$" | ||||
| 	do_unmount "umount" ${fs:+--fstype-regex} ${fs} --netdev | ||||
| 	retval=$? | ||||
|  | ||||
| 	eoutdent | ||||
| 	eend ${retval} "Failed to unmount network filesystems" | ||||
| } | ||||
|  | ||||
| # vim: set ts=4 : | ||||
|   | ||||
| @@ -26,6 +26,11 @@ stop_addon() { | ||||
| is_net_fs() { | ||||
| 	[ -z "$1" ] && return 1 | ||||
|  | ||||
| 	# Check OS specific flags to see if we're local or net mounted | ||||
| 	mountinfo --quiet --netdev "$1"  && return 0 | ||||
| 	mountinfo --quiet --nonetdev "$1" && return 1 | ||||
|  | ||||
| 	# Fall back on fs types | ||||
| 	local t=$(mountinfo --fstype "$1") | ||||
| 	for x in ${RC_NET_FS_LIST}; do | ||||
| 		[ "${x}" = "${t}" ] && return 0 | ||||
|   | ||||
| @@ -12,8 +12,8 @@ do_unmount() { | ||||
| 		f_kill="-" | ||||
| 	fi | ||||
|  | ||||
| 	mountinfo ${2:+--skip-point-regex} $2 ${3:+--node-regex} $3 ${4:+--fstype-regex} $4 ${5:+--skip-fstype-regex} $5 | \ | ||||
| 	while read mnt; do | ||||
| 	shift | ||||
| 	mountinfo "$@" | while read mnt; do | ||||
| 		case "${cmd}" in | ||||
| 			umount*) | ||||
| 				# If we're using the mount (probably /usr) then don't unmount us | ||||
|   | ||||
| @@ -15,6 +15,8 @@ | ||||
| #include <sys/param.h> | ||||
| #include <sys/ucred.h> | ||||
| #include <sys/mount.h> | ||||
| #elif defined (__linux__) | ||||
| #include <mntent.h> | ||||
| #endif | ||||
|  | ||||
| #include <errno.h> | ||||
| @@ -38,6 +40,12 @@ typedef enum { | ||||
| 	mount_options | ||||
| } mount_type; | ||||
|  | ||||
| typedef enum { | ||||
| 	net_ignore, | ||||
| 	net_yes, | ||||
| 	net_no | ||||
| } net_opts; | ||||
|  | ||||
| struct args { | ||||
| 	regex_t *node_regex; | ||||
| 	regex_t *skip_node_regex; | ||||
| @@ -47,10 +55,12 @@ struct args { | ||||
| 	regex_t *skip_options_regex; | ||||
| 	char **mounts; | ||||
| 	mount_type mount_type; | ||||
| 	net_opts netdev; | ||||
| }; | ||||
|  | ||||
| static int process_mount (char ***list, struct args *args, | ||||
| 						  char *from, char *to, char *fstype, char *options) | ||||
| 						  char *from, char *to, char *fstype, char *options, | ||||
| 						  int netdev) | ||||
| { | ||||
| 	char *p; | ||||
|  | ||||
| @@ -62,26 +72,34 @@ static int process_mount (char ***list, struct args *args, | ||||
| 		return (-1); | ||||
| #endif | ||||
|  | ||||
| 	if (args->node_regex && | ||||
| 		regexec (args->node_regex, from, 0, NULL, 0) != 0) | ||||
| 		return (1); | ||||
| 	if (args->skip_node_regex && | ||||
| 		regexec (args->skip_node_regex, from, 0, NULL, 0) == 0) | ||||
| 		return (1); | ||||
| 	if (args->netdev == net_yes && netdev != -1) { | ||||
| 		if (netdev != 0) | ||||
| 			return (1); | ||||
| 	} else if (args->netdev == net_no && netdev != -1) { | ||||
| 		if (netdev != 1) | ||||
| 			return (1); | ||||
| 	} else { | ||||
| 		if (args->node_regex && | ||||
| 			regexec (args->node_regex, from, 0, NULL, 0) != 0) | ||||
| 			return (1); | ||||
| 		if (args->skip_node_regex && | ||||
| 			regexec (args->skip_node_regex, from, 0, NULL, 0) == 0) | ||||
| 			return (1); | ||||
|  | ||||
| 	if (args->fstype_regex && | ||||
| 		regexec (args->fstype_regex, fstype, 0, NULL, 0) != 0) | ||||
| 		return (-1); | ||||
| 	if (args->skip_fstype_regex && | ||||
| 		regexec (args->skip_fstype_regex, fstype, 0, NULL, 0) == 0) | ||||
| 		return (-1); | ||||
| 		if (args->fstype_regex && | ||||
| 			regexec (args->fstype_regex, fstype, 0, NULL, 0) != 0) | ||||
| 			return (-1); | ||||
| 		if (args->skip_fstype_regex && | ||||
| 			regexec (args->skip_fstype_regex, fstype, 0, NULL, 0) == 0) | ||||
| 			return (-1); | ||||
|  | ||||
| 	if (args->options_regex && | ||||
| 		regexec (args->options_regex, options, 0, NULL, 0) != 0) | ||||
| 		return (-1); | ||||
| 	if (args->skip_options_regex && | ||||
| 		regexec (args->skip_options_regex, options, 0, NULL, 0) == 0) | ||||
| 		return (-1); | ||||
| 		if (args->options_regex && | ||||
| 			regexec (args->options_regex, options, 0, NULL, 0) != 0) | ||||
| 			return (-1); | ||||
| 		if (args->skip_options_regex && | ||||
| 			regexec (args->skip_options_regex, options, 0, NULL, 0) == 0) | ||||
| 			return (-1); | ||||
| 	} | ||||
|  | ||||
| 	if (args->mounts) { | ||||
| 		bool found = false; | ||||
| @@ -169,9 +187,12 @@ static char **find_mounts (struct args *args) | ||||
| 		eerrorx ("getmntinfo: %s", strerror (errno)); | ||||
|  | ||||
| 	for (i = 0; i < nmnts; i++) { | ||||
| 		int netdev = 0; | ||||
| 		flags = mnts[i].f_flags & MNT_VISFLAGMASK; | ||||
| 		for (o = optnames; flags && o->o_opt; o++) { | ||||
| 			if (flags & o->o_opt) { | ||||
| 				if (o->o_opt == MNT_LOCAL) | ||||
| 					netdev = 1; | ||||
| 				if (! options) | ||||
| 					options = xstrdup (o->o_name); | ||||
| 				else { | ||||
| @@ -188,7 +209,8 @@ static char **find_mounts (struct args *args) | ||||
| 					   mnts[i].f_mntfromname, | ||||
| 					   mnts[i].f_mntonname, | ||||
| 					   mnts[i].f_fstypename, | ||||
| 					   options); | ||||
| 					   options, | ||||
| 					   netdev); | ||||
|  | ||||
| 		free (options); | ||||
| 		options = NULL; | ||||
| @@ -198,6 +220,20 @@ static char **find_mounts (struct args *args) | ||||
| } | ||||
|  | ||||
| #elif defined (__linux__) | ||||
| static struct mntent *getmntfile (const char *file) | ||||
| { | ||||
| 	struct mntent *ent = NULL; | ||||
| 	FILE *fp; | ||||
|  | ||||
| 	fp = setmntent ("/etc/fstab", "r"); | ||||
| 	while ((ent = getmntent (fp))) | ||||
| 		if (strcmp (file, ent->mnt_dir) == 0) | ||||
| 			break; | ||||
| 	endmntent (fp); | ||||
| 	 | ||||
| 	return (ent); | ||||
| } | ||||
|  | ||||
| static char **find_mounts (struct args *args) | ||||
| { | ||||
| 	FILE *fp; | ||||
| @@ -208,18 +244,26 @@ static char **find_mounts (struct args *args) | ||||
| 	char *fst; | ||||
| 	char *opts; | ||||
| 	char **list = NULL; | ||||
| 	struct mntent *ent; | ||||
| 	int netdev; | ||||
|  | ||||
| 	if ((fp = fopen ("/proc/mounts", "r")) == NULL) | ||||
| 		eerrorx ("getmntinfo: %s", strerror (errno)); | ||||
|  | ||||
| 	while (fgets (buffer, sizeof (buffer), fp)) { | ||||
| 		netdev = -1; | ||||
| 		p = buffer; | ||||
| 		from = strsep (&p, " "); | ||||
| 		to = strsep (&p, " "); | ||||
| 		fst = strsep (&p, " "); | ||||
| 		opts = strsep (&p, " "); | ||||
|  | ||||
| 		process_mount (&list, args, from, to, fst, opts); | ||||
| 		if ((ent = getmntfile (to))) { | ||||
| 			if (strstr (ent->mnt_opts, "_netdev")) | ||||
| 				netdev = 0; | ||||
| 		} | ||||
|  | ||||
| 		process_mount (&list, args, from, to, fst, opts, netdev); | ||||
| 	} | ||||
| 	fclose (fp); | ||||
|  | ||||
| @@ -260,6 +304,8 @@ static struct option longopts[] = { | ||||
| 	{ "options",             0, NULL, 'i'}, | ||||
| 	{ "fstype",              0, NULL, 's'}, | ||||
| 	{ "node",                0, NULL, 't'}, | ||||
| 	{ "netdev",				 0, NULL, 'e'}, | ||||
| 	{ "nonetdev",            0, NULL, 'E'}, | ||||
| 	longopts_COMMON | ||||
| 	{ NULL,             0, NULL, 0} | ||||
| }; | ||||
| @@ -298,11 +344,18 @@ int mountinfo (int argc, char **argv) | ||||
|  | ||||
| 	memset (&args, 0, sizeof (struct args)); | ||||
| 	args.mount_type = mount_to; | ||||
| 	args.netdev = net_ignore; | ||||
|  | ||||
| 	while ((opt = getopt_long (argc, argv, getoptstring, | ||||
| 							   longopts, (int *) 0)) != -1) | ||||
| 	{ | ||||
| 		switch (opt) { | ||||
| 			case 'e': | ||||
| 				args.netdev = net_yes; | ||||
| 				break; | ||||
| 			case 'E': | ||||
| 				args.netdev = net_no; | ||||
| 				break; | ||||
| 			case 'f': | ||||
| 				DO_REG (args.fstype_regex); | ||||
| 				break; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user