xref: /illumos-gate/usr/src/cmd/fs.d/autofs/automount.c (revision 30699046)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
56012a713Spetede  * Common Development and Distribution License (the "License").
66012a713Spetede  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
227c478bd9Sstevel@tonic-gate  *	automount.c
237c478bd9Sstevel@tonic-gate  *
24dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <ctype.h>
297c478bd9Sstevel@tonic-gate #include <stdio.h>
307c478bd9Sstevel@tonic-gate #include <unistd.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include <locale.h>
337c478bd9Sstevel@tonic-gate #include <stdarg.h>
347c478bd9Sstevel@tonic-gate #include <errno.h>
357c478bd9Sstevel@tonic-gate #include <string.h>
367c478bd9Sstevel@tonic-gate #include <dirent.h>
377c478bd9Sstevel@tonic-gate #include <signal.h>
387c478bd9Sstevel@tonic-gate #include <syslog.h>
39dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States #include <libshare.h>
40dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States #include <libscf.h>
417c478bd9Sstevel@tonic-gate #include <sys/param.h>
427c478bd9Sstevel@tonic-gate #include <sys/time.h>
437c478bd9Sstevel@tonic-gate #include <sys/vfs.h>
447c478bd9Sstevel@tonic-gate #include <sys/types.h>
457c478bd9Sstevel@tonic-gate #include <sys/stat.h>
467c478bd9Sstevel@tonic-gate #include <sys/mnttab.h>
477c478bd9Sstevel@tonic-gate #include <sys/mntent.h>
487c478bd9Sstevel@tonic-gate #include <sys/mount.h>
497c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
507c478bd9Sstevel@tonic-gate #include <sys/tiuser.h>
517c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
527c478bd9Sstevel@tonic-gate #include <rpcsvc/nfs_prot.h>
537c478bd9Sstevel@tonic-gate #include <nsswitch.h>
547c478bd9Sstevel@tonic-gate #include <deflt.h>
557c478bd9Sstevel@tonic-gate #include <rpcsvc/daemon_utils.h>
567c478bd9Sstevel@tonic-gate #include "automount.h"
57dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States #include "smfcfg.h"
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate static int mkdir_r(char *);
607c478bd9Sstevel@tonic-gate struct autodir *dir_head;
617c478bd9Sstevel@tonic-gate struct autodir *dir_tail;
627c478bd9Sstevel@tonic-gate static struct extmnttab *find_mount();
637c478bd9Sstevel@tonic-gate int verbose = 0;
647c478bd9Sstevel@tonic-gate int trace = 0;
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate static void usage();
677c478bd9Sstevel@tonic-gate static int compare_opts(char *, char *);
687c478bd9Sstevel@tonic-gate static void do_unmounts();
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate static int mount_timeout = AUTOFS_MOUNT_TIMEOUT;
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate static char	*service_list[] = { AUTOMOUNTD, NULL };
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate /*
757c478bd9Sstevel@tonic-gate  * XXX
767c478bd9Sstevel@tonic-gate  * The following are needed because they're used in auto_subr.c and
777c478bd9Sstevel@tonic-gate  * we link with it. Should avoid this.
787c478bd9Sstevel@tonic-gate  */
797c478bd9Sstevel@tonic-gate mutex_t cleanup_lock;
807c478bd9Sstevel@tonic-gate cond_t cleanup_start_cv;
817c478bd9Sstevel@tonic-gate cond_t cleanup_done_cv;
827c478bd9Sstevel@tonic-gate 
8311606941Sjwahlig int
main(int argc,char * argv[])8411606941Sjwahlig main(int argc, char *argv[])
857c478bd9Sstevel@tonic-gate {
867c478bd9Sstevel@tonic-gate 	int c;
877c478bd9Sstevel@tonic-gate 	struct autofs_args ai;
887c478bd9Sstevel@tonic-gate 	struct utsname utsname;
897c478bd9Sstevel@tonic-gate 	char autofs_addr[MAXADDRLEN];
907c478bd9Sstevel@tonic-gate 	struct autodir *dir, *d;
917c478bd9Sstevel@tonic-gate 	struct stat stbuf;
927c478bd9Sstevel@tonic-gate 	char *master_map = "auto_master";
937c478bd9Sstevel@tonic-gate 	int null;
947c478bd9Sstevel@tonic-gate 	struct extmnttab mnt, *mntp;
957c478bd9Sstevel@tonic-gate 	struct mnttab *omntp;
967c478bd9Sstevel@tonic-gate 	char mntopts[MAX_MNTOPT_STR];
977c478bd9Sstevel@tonic-gate 	int mntflgs;
987c478bd9Sstevel@tonic-gate 	int count = 0;
997c478bd9Sstevel@tonic-gate 	char *stack[STACKSIZ];
1007c478bd9Sstevel@tonic-gate 	char **stkptr;
1017c478bd9Sstevel@tonic-gate 	char *defval;
1027c478bd9Sstevel@tonic-gate 	struct sigaction sigintact;
103dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 	int ret = 0, bufsz = 0;
104dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 	char valbuf[6];
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate 	/*
1077c478bd9Sstevel@tonic-gate 	 * protect this command from session termination when run in background
1087c478bd9Sstevel@tonic-gate 	 * we test background by whether SIGINT is ignored
1097c478bd9Sstevel@tonic-gate 	 */
1107c478bd9Sstevel@tonic-gate 	(void) sigaction(SIGINT, NULL, &sigintact);
111*30699046SRichard Lowe 	if (sigintact.sa_handler == SIG_IGN) {
1127c478bd9Sstevel@tonic-gate 		(void) signal(SIGHUP, SIG_IGN);
1137c478bd9Sstevel@tonic-gate 		(void) setsid();
1147c478bd9Sstevel@tonic-gate 	}
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate 	/*
117dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 	 * Read in the values from SMF first before we check
118dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 	 * commandline options so the options override the SMF values.
1197c478bd9Sstevel@tonic-gate 	 */
120dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 	bufsz = 6;
121dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 	ret = autofs_smf_get_prop("timeout", valbuf, DEFAULT_INSTANCE,
122dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 	    SCF_TYPE_INTEGER, AUTOMOUNTD, &bufsz);
123dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 	if (ret == SA_OK)
124dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 		/*
125dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 		 * Ignore errno.  In event of failure, mount_timeout is
126dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 		 * already initialized to the correct value.
127dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 		 */
128dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 		mount_timeout = strtol(valbuf, (char **)NULL, 10);
129dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 
130dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 	bufsz = 6;
131dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 	ret = autofs_smf_get_prop("automount_verbose", valbuf, DEFAULT_INSTANCE,
132dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 	    SCF_TYPE_BOOLEAN, AUTOMOUNTD, &bufsz);
133dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 	if (ret == SA_OK) {
134dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 		if (strncasecmp("true", valbuf, 4) == 0)
135dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 			verbose = TRUE;
1367c478bd9Sstevel@tonic-gate 	}
1377c478bd9Sstevel@tonic-gate 
138dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 	put_automountd_env();
139dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 
1407c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "mM:D:f:t:v?")) != EOF) {
1417c478bd9Sstevel@tonic-gate 		switch (c) {
1427c478bd9Sstevel@tonic-gate 		case 'm':
1437c478bd9Sstevel@tonic-gate 			pr_msg("Warning: -m option not supported");
1447c478bd9Sstevel@tonic-gate 			break;
1457c478bd9Sstevel@tonic-gate 		case 'M':
1467c478bd9Sstevel@tonic-gate 			pr_msg("Warning: -M option not supported");
1477c478bd9Sstevel@tonic-gate 			break;
1487c478bd9Sstevel@tonic-gate 		case 'D':
1497c478bd9Sstevel@tonic-gate 			pr_msg("Warning: -D option not supported");
1507c478bd9Sstevel@tonic-gate 			break;
1517c478bd9Sstevel@tonic-gate 		case 'f':
1527c478bd9Sstevel@tonic-gate 			pr_msg("Error: -f option no longer supported");
1537c478bd9Sstevel@tonic-gate 			usage();
1547c478bd9Sstevel@tonic-gate 			break;
1557c478bd9Sstevel@tonic-gate 		case 't':
1567c478bd9Sstevel@tonic-gate 			if (strchr(optarg, '=')) {
1577c478bd9Sstevel@tonic-gate 				pr_msg("Error: invalid value for -t");
1587c478bd9Sstevel@tonic-gate 				usage();
1597c478bd9Sstevel@tonic-gate 			}
1607c478bd9Sstevel@tonic-gate 			mount_timeout = atoi(optarg);
1617c478bd9Sstevel@tonic-gate 			break;
1627c478bd9Sstevel@tonic-gate 		case 'v':
1637c478bd9Sstevel@tonic-gate 			verbose++;
1647c478bd9Sstevel@tonic-gate 			break;
1657c478bd9Sstevel@tonic-gate 		default:
1667c478bd9Sstevel@tonic-gate 			usage();
1677c478bd9Sstevel@tonic-gate 			break;
1687c478bd9Sstevel@tonic-gate 		}
1697c478bd9Sstevel@tonic-gate 	}
1707c478bd9Sstevel@tonic-gate 
1717c478bd9Sstevel@tonic-gate 	if (optind < argc) {
1727c478bd9Sstevel@tonic-gate 		pr_msg("%s: command line mountpoints/maps "
173dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 		    "no longer supported", argv[optind]);
1747c478bd9Sstevel@tonic-gate 		usage();
1757c478bd9Sstevel@tonic-gate 	}
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	current_mounts = getmntlist();
1787c478bd9Sstevel@tonic-gate 	if (current_mounts == NULL) {
1797c478bd9Sstevel@tonic-gate 		pr_msg("Couldn't establish current mounts");
1807c478bd9Sstevel@tonic-gate 		exit(1);
1817c478bd9Sstevel@tonic-gate 	}
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	(void) umask(0);
1847c478bd9Sstevel@tonic-gate 	ns_setup(stack, &stkptr);
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 	openlog("automount", LOG_PID, LOG_DAEMON);
1877c478bd9Sstevel@tonic-gate 	(void) loadmaster_map(master_map, "", stack, &stkptr);
1887c478bd9Sstevel@tonic-gate 	if (dir_head != NULL) {
1897c478bd9Sstevel@tonic-gate 		/*
1907c478bd9Sstevel@tonic-gate 		 * automount maps found. enable services as needed.
1917c478bd9Sstevel@tonic-gate 		 */
1927c478bd9Sstevel@tonic-gate 		_check_services(service_list);
1937c478bd9Sstevel@tonic-gate 	}
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 	closelog();
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 	if (uname(&utsname) < 0) {
1987c478bd9Sstevel@tonic-gate 		pr_msg("uname: %m");
1997c478bd9Sstevel@tonic-gate 		exit(1);
2007c478bd9Sstevel@tonic-gate 	}
2017c478bd9Sstevel@tonic-gate 	(void) strcpy(autofs_addr, utsname.nodename);
2027c478bd9Sstevel@tonic-gate 	(void) strcat(autofs_addr, ".autofs");
2037c478bd9Sstevel@tonic-gate 	ai.addr.buf	= autofs_addr;
2047c478bd9Sstevel@tonic-gate 	ai.addr.len	= strlen(ai.addr.buf);
2057c478bd9Sstevel@tonic-gate 	ai.addr.maxlen	= ai.addr.len;
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	ai.mount_to	= mount_timeout;
2087c478bd9Sstevel@tonic-gate 	ai.rpc_to	= AUTOFS_RPC_TIMEOUT;
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 	/*
2117c478bd9Sstevel@tonic-gate 	 * Mount the daemon at its mount points.
2127c478bd9Sstevel@tonic-gate 	 */
2137c478bd9Sstevel@tonic-gate 	for (dir = dir_head; dir; dir = dir->dir_next) {
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 		/*
2167c478bd9Sstevel@tonic-gate 		 * Skip null entries
2177c478bd9Sstevel@tonic-gate 		 */
2187c478bd9Sstevel@tonic-gate 		if (strcmp(dir->dir_map, "-null") == 0)
2197c478bd9Sstevel@tonic-gate 			continue;
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate 		/*
2227c478bd9Sstevel@tonic-gate 		 * Skip null'ed entries
2237c478bd9Sstevel@tonic-gate 		 */
2247c478bd9Sstevel@tonic-gate 		null = 0;
2257c478bd9Sstevel@tonic-gate 		for (d = dir->dir_prev; d; d = d->dir_prev) {
2267c478bd9Sstevel@tonic-gate 			if (strcmp(dir->dir_name, d->dir_name) == 0)
2277c478bd9Sstevel@tonic-gate 				null = 1;
2287c478bd9Sstevel@tonic-gate 		}
2297c478bd9Sstevel@tonic-gate 		if (null)
2307c478bd9Sstevel@tonic-gate 			continue;
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 		/*
2337c478bd9Sstevel@tonic-gate 		 * Check whether there's already an entry
2347c478bd9Sstevel@tonic-gate 		 * in the mnttab for this mountpoint.
2357c478bd9Sstevel@tonic-gate 		 */
2367c478bd9Sstevel@tonic-gate 		if (mntp = find_mount(dir->dir_name, 1)) {
2377c478bd9Sstevel@tonic-gate 			/*
2387c478bd9Sstevel@tonic-gate 			 * If it's not an autofs mount - don't
2397c478bd9Sstevel@tonic-gate 			 * mount over it.
2407c478bd9Sstevel@tonic-gate 			 */
2417c478bd9Sstevel@tonic-gate 			if (strcmp(mntp->mnt_fstype, MNTTYPE_AUTOFS) != 0) {
2427c478bd9Sstevel@tonic-gate 				pr_msg("%s: already mounted",
243dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 				    mntp->mnt_mountp);
2447c478bd9Sstevel@tonic-gate 				continue;
2457c478bd9Sstevel@tonic-gate 			}
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 			/*
2487c478bd9Sstevel@tonic-gate 			 * Compare the mnttab entry with the master map
2497c478bd9Sstevel@tonic-gate 			 * entry.  If the map or mount options are
2507c478bd9Sstevel@tonic-gate 			 * different, then update this information
2517c478bd9Sstevel@tonic-gate 			 * with a remount.
2527c478bd9Sstevel@tonic-gate 			 */
2537c478bd9Sstevel@tonic-gate 			if (strcmp(mntp->mnt_special, dir->dir_map) == 0 &&
254dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 			    compare_opts(dir->dir_opts,
255dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 			    mntp->mnt_mntopts) == 0) {
2567c478bd9Sstevel@tonic-gate 				continue;	/* no change */
2577c478bd9Sstevel@tonic-gate 			}
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate 			/*
2607c478bd9Sstevel@tonic-gate 			 * Check for an overlaid direct autofs mount.
2617c478bd9Sstevel@tonic-gate 			 * Cannot remount since it's inaccessible.
2627c478bd9Sstevel@tonic-gate 			 */
2637c478bd9Sstevel@tonic-gate 			omntp = (struct mnttab *)mntp;
2647c478bd9Sstevel@tonic-gate 			if (hasmntopt(omntp, "direct") != NULL) {
2657c478bd9Sstevel@tonic-gate 				mntp = find_mount(dir->dir_name, 0);
2667c478bd9Sstevel@tonic-gate 				omntp = (struct mnttab *)mntp;
2677c478bd9Sstevel@tonic-gate 				if (hasmntopt(omntp, "direct") == NULL) {
2687c478bd9Sstevel@tonic-gate 					if (verbose)
2697c478bd9Sstevel@tonic-gate 						pr_msg("%s: cannot remount",
270dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 						    dir->dir_name);
2717c478bd9Sstevel@tonic-gate 					continue;
2727c478bd9Sstevel@tonic-gate 				}
2737c478bd9Sstevel@tonic-gate 			}
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 			dir->dir_remount = 1;
2767c478bd9Sstevel@tonic-gate 		}
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate 		/*
2797c478bd9Sstevel@tonic-gate 		 * Create a mount point if necessary
2807c478bd9Sstevel@tonic-gate 		 * If the path refers to an existing symbolic
2817c478bd9Sstevel@tonic-gate 		 * link, refuse to mount on it.  This avoids
2827c478bd9Sstevel@tonic-gate 		 * future problems.
2837c478bd9Sstevel@tonic-gate 		 */
2847c478bd9Sstevel@tonic-gate 		if (lstat(dir->dir_name, &stbuf) == 0) {
2857c478bd9Sstevel@tonic-gate 			if ((stbuf.st_mode & S_IFMT) != S_IFDIR) {
2867c478bd9Sstevel@tonic-gate 				pr_msg("%s: Not a directory", dir->dir_name);
2877c478bd9Sstevel@tonic-gate 				continue;
2887c478bd9Sstevel@tonic-gate 			}
2897c478bd9Sstevel@tonic-gate 		} else {
2907c478bd9Sstevel@tonic-gate 			if (mkdir_r(dir->dir_name)) {
2917c478bd9Sstevel@tonic-gate 				pr_msg("%s: %m", dir->dir_name);
2927c478bd9Sstevel@tonic-gate 				continue;
2937c478bd9Sstevel@tonic-gate 			}
2947c478bd9Sstevel@tonic-gate 		}
2957c478bd9Sstevel@tonic-gate 
296*30699046SRichard Lowe 		ai.path		= dir->dir_name;
2977c478bd9Sstevel@tonic-gate 		ai.opts		= dir->dir_opts;
2987c478bd9Sstevel@tonic-gate 		ai.map		= dir->dir_map;
2997c478bd9Sstevel@tonic-gate 		ai.subdir	= "";
300*30699046SRichard Lowe 		ai.direct	= dir->dir_direct;
3017c478bd9Sstevel@tonic-gate 		if (dir->dir_direct)
3027c478bd9Sstevel@tonic-gate 			ai.key = dir->dir_name;
3037c478bd9Sstevel@tonic-gate 		else
3047c478bd9Sstevel@tonic-gate 			ai.key = "";
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate 		(void) sprintf(mntopts, "ignore,%s",
307dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 		    dir->dir_direct  ? "direct" : "indirect");
3087c478bd9Sstevel@tonic-gate 		if (dir->dir_opts && *dir->dir_opts) {
3097c478bd9Sstevel@tonic-gate 			(void) strcat(mntopts, ",");
3107c478bd9Sstevel@tonic-gate 			(void) strcat(mntopts, dir->dir_opts);
3117c478bd9Sstevel@tonic-gate 		}
3127c478bd9Sstevel@tonic-gate 		mntflgs = MS_OPTIONSTR | (dir->dir_remount ? MS_REMOUNT : 0);
3137c478bd9Sstevel@tonic-gate 		if (mount(dir->dir_map, dir->dir_name, MS_DATA | mntflgs,
314dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 		    MNTTYPE_AUTOFS, &ai, sizeof (ai), mntopts,
315dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 		    MAX_MNTOPT_STR) < 0) {
3167c478bd9Sstevel@tonic-gate 			pr_msg("mount %s: %m", dir->dir_name);
3177c478bd9Sstevel@tonic-gate 			continue;
3187c478bd9Sstevel@tonic-gate 		}
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate 		count++;
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 		if (verbose) {
3237c478bd9Sstevel@tonic-gate 			if (dir->dir_remount)
3247c478bd9Sstevel@tonic-gate 				pr_msg("%s remounted", dir->dir_name);
3257c478bd9Sstevel@tonic-gate 			else
3267c478bd9Sstevel@tonic-gate 				pr_msg("%s mounted", dir->dir_name);
3277c478bd9Sstevel@tonic-gate 		}
3287c478bd9Sstevel@tonic-gate 	}
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 	if (verbose && count == 0)
3317c478bd9Sstevel@tonic-gate 		pr_msg("no mounts");
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 	/*
3347c478bd9Sstevel@tonic-gate 	 * Now compare the /etc/mnttab with the master
3357c478bd9Sstevel@tonic-gate 	 * map.  Any autofs mounts in the /etc/mnttab
3367c478bd9Sstevel@tonic-gate 	 * that are not in the master map must be
3377c478bd9Sstevel@tonic-gate 	 * unmounted
3387c478bd9Sstevel@tonic-gate 	 */
3397c478bd9Sstevel@tonic-gate 	do_unmounts();
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 	return (0);
3427c478bd9Sstevel@tonic-gate }
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate /*
3457c478bd9Sstevel@tonic-gate  * Find a mount entry given
3467c478bd9Sstevel@tonic-gate  * the mountpoint path.
3477c478bd9Sstevel@tonic-gate  * Optionally return the first
3487c478bd9Sstevel@tonic-gate  * or last entry.
3497c478bd9Sstevel@tonic-gate  */
3507c478bd9Sstevel@tonic-gate static struct extmnttab *
find_mount(mntpnt,first)3517c478bd9Sstevel@tonic-gate find_mount(mntpnt, first)
3527c478bd9Sstevel@tonic-gate 	char *mntpnt;
3537c478bd9Sstevel@tonic-gate 	int first;
3547c478bd9Sstevel@tonic-gate {
3557c478bd9Sstevel@tonic-gate 	struct mntlist *mntl;
3567c478bd9Sstevel@tonic-gate 	struct extmnttab *found = NULL;
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 	for (mntl = current_mounts; mntl; mntl = mntl->mntl_next) {
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate 		if (strcmp(mntpnt, mntl->mntl_mnt->mnt_mountp) == 0) {
3617c478bd9Sstevel@tonic-gate 			found = mntl->mntl_mnt;
3627c478bd9Sstevel@tonic-gate 			if (first)
3637c478bd9Sstevel@tonic-gate 				break;
3647c478bd9Sstevel@tonic-gate 		}
3657c478bd9Sstevel@tonic-gate 	}
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 	return (found);
3687c478bd9Sstevel@tonic-gate }
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate static char *ignore_opts[] = {"ignore", "direct", "indirect", "dev", NULL};
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate /*
3737c478bd9Sstevel@tonic-gate  * Compare mount options
3747c478bd9Sstevel@tonic-gate  * ignoring "ignore", "direct", "indirect"
3757c478bd9Sstevel@tonic-gate  * and "dev=".
3767c478bd9Sstevel@tonic-gate  */
3777c478bd9Sstevel@tonic-gate static int
compare_opts(opts,mntopts)3787c478bd9Sstevel@tonic-gate compare_opts(opts, mntopts)
3797c478bd9Sstevel@tonic-gate 	char *opts, *mntopts;
3807c478bd9Sstevel@tonic-gate {
3817c478bd9Sstevel@tonic-gate 	char optbuf1[MAX_MNTOPT_STR], *s = optbuf1;
3827c478bd9Sstevel@tonic-gate 	char optbuf2[MAX_MNTOPT_STR];
3837c478bd9Sstevel@tonic-gate 	char **opttbl1, **opttbl2;
3847c478bd9Sstevel@tonic-gate 	int nopts1, nopts2;
3857c478bd9Sstevel@tonic-gate 	char *ostart, *optr, *valp;
3867c478bd9Sstevel@tonic-gate 	int j, i, notsame;
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate 	opttbl1 = opttbl2 = NULL;
3897c478bd9Sstevel@tonic-gate 	/*
3907c478bd9Sstevel@tonic-gate 	 * Parse the two option strings to split them both into
3917c478bd9Sstevel@tonic-gate 	 * lists of individual options.
3927c478bd9Sstevel@tonic-gate 	 */
3937c478bd9Sstevel@tonic-gate 	if (mntopts != NULL)
3947c478bd9Sstevel@tonic-gate 		(void) strcpy(s, mntopts);
3957c478bd9Sstevel@tonic-gate 	else
3967c478bd9Sstevel@tonic-gate 		*s = '\0';
3977c478bd9Sstevel@tonic-gate 	if (*s != '\0')
3987c478bd9Sstevel@tonic-gate 		nopts1 = 1;
3997c478bd9Sstevel@tonic-gate 	else
4007c478bd9Sstevel@tonic-gate 		nopts1 = 0;
4017c478bd9Sstevel@tonic-gate 	for (s = strchr(s, ','); s != NULL; s = strchr(s, ',')) {
4027c478bd9Sstevel@tonic-gate 		nopts1++;
4037c478bd9Sstevel@tonic-gate 		s++;
4047c478bd9Sstevel@tonic-gate 	}
4057c478bd9Sstevel@tonic-gate 	if (nopts1)
4067c478bd9Sstevel@tonic-gate 		if ((opttbl1 = memalign(sizeof (char *),
4077c478bd9Sstevel@tonic-gate 			nopts1 * sizeof (char *))) == NULL)
4087c478bd9Sstevel@tonic-gate 			return (1);
4097c478bd9Sstevel@tonic-gate 	nopts1 = 0;
4107c478bd9Sstevel@tonic-gate 	s = optbuf1;
4117c478bd9Sstevel@tonic-gate 	for (ostart = optr = s; *optr != '\0'; ostart = optr) {
4127c478bd9Sstevel@tonic-gate 		if (getsubopt(&optr, ignore_opts, &valp) == -1) {
4137c478bd9Sstevel@tonic-gate 			opttbl1[nopts1++] = ostart;
4147c478bd9Sstevel@tonic-gate 		}
4157c478bd9Sstevel@tonic-gate 	}
4167c478bd9Sstevel@tonic-gate 	s = optbuf2;
4177c478bd9Sstevel@tonic-gate 	if (opts != NULL)
4187c478bd9Sstevel@tonic-gate 		(void) strcpy(s, opts);
4197c478bd9Sstevel@tonic-gate 	else
4207c478bd9Sstevel@tonic-gate 		*s = '\0';
4217c478bd9Sstevel@tonic-gate 	if (*s != '\0')
4227c478bd9Sstevel@tonic-gate 		nopts2 = 1;
4237c478bd9Sstevel@tonic-gate 	else
4247c478bd9Sstevel@tonic-gate 		nopts2 = 0;
4257c478bd9Sstevel@tonic-gate 	for (s = strchr(s, ','); s != NULL; s = strchr(s, ',')) {
4267c478bd9Sstevel@tonic-gate 		nopts2++;
4277c478bd9Sstevel@tonic-gate 		s++;
4287c478bd9Sstevel@tonic-gate 	}
4297c478bd9Sstevel@tonic-gate 	if (nopts2)
4307c478bd9Sstevel@tonic-gate 		if ((opttbl2 = memalign(sizeof (char *),
4317c478bd9Sstevel@tonic-gate 			nopts2 * sizeof (char *))) == NULL) {
4327c478bd9Sstevel@tonic-gate 			notsame = 1;
4337c478bd9Sstevel@tonic-gate 			goto done;
4347c478bd9Sstevel@tonic-gate 		}
4357c478bd9Sstevel@tonic-gate 	nopts2 = 0;
4367c478bd9Sstevel@tonic-gate 	s = optbuf2;
4377c478bd9Sstevel@tonic-gate 	for (ostart = optr = s; *optr != '\0'; ostart = optr) {
4387c478bd9Sstevel@tonic-gate 		if (getsubopt(&optr, ignore_opts, &valp) == -1) {
4397c478bd9Sstevel@tonic-gate 			opttbl2[nopts2++] = ostart;
4407c478bd9Sstevel@tonic-gate 		}
4417c478bd9Sstevel@tonic-gate 	}
4427c478bd9Sstevel@tonic-gate 	if (nopts2 != nopts1) {
4437c478bd9Sstevel@tonic-gate 		notsame = 1;
4447c478bd9Sstevel@tonic-gate 		goto done;
4457c478bd9Sstevel@tonic-gate 	}
4467c478bd9Sstevel@tonic-gate 	notsame = 0;
4477c478bd9Sstevel@tonic-gate 	for (i = 0; i < nopts1; i++) {
4487c478bd9Sstevel@tonic-gate 		notsame = 1;
4497c478bd9Sstevel@tonic-gate 		for (j = 0; j < nopts2; j++) {
4507c478bd9Sstevel@tonic-gate 			if (strcmp(opttbl1[i], opttbl2[j]) == 0) {
4517c478bd9Sstevel@tonic-gate 				notsame = 0;
4527c478bd9Sstevel@tonic-gate 				break;
4537c478bd9Sstevel@tonic-gate 			}
4547c478bd9Sstevel@tonic-gate 		}
4557c478bd9Sstevel@tonic-gate 		if (notsame)
4567c478bd9Sstevel@tonic-gate 			break;
4577c478bd9Sstevel@tonic-gate 	}
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate done:
4607c478bd9Sstevel@tonic-gate 	if (opttbl1 != NULL)
4617c478bd9Sstevel@tonic-gate 		free(opttbl1);
4627c478bd9Sstevel@tonic-gate 	if (opttbl2 != NULL)
4637c478bd9Sstevel@tonic-gate 		free(opttbl2);
4647c478bd9Sstevel@tonic-gate 	return (notsame);
4657c478bd9Sstevel@tonic-gate }
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate static void
usage()4687c478bd9Sstevel@tonic-gate usage()
4697c478bd9Sstevel@tonic-gate {
4707c478bd9Sstevel@tonic-gate 	pr_msg("Usage: automount  [ -v ]  [ -t duration ]");
4717c478bd9Sstevel@tonic-gate 	exit(1);
4727c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
4737c478bd9Sstevel@tonic-gate }
4747c478bd9Sstevel@tonic-gate 
4757c478bd9Sstevel@tonic-gate /*
4767c478bd9Sstevel@tonic-gate  * Unmount any autofs mounts that
4777c478bd9Sstevel@tonic-gate  * aren't in the master map
4787c478bd9Sstevel@tonic-gate  */
4797c478bd9Sstevel@tonic-gate static void
do_unmounts()4807c478bd9Sstevel@tonic-gate do_unmounts()
4817c478bd9Sstevel@tonic-gate {
4827c478bd9Sstevel@tonic-gate 	struct mntlist *mntl;
4837c478bd9Sstevel@tonic-gate 	struct extmnttab *mnt;
4847c478bd9Sstevel@tonic-gate 	struct mnttab *omnt;
4857c478bd9Sstevel@tonic-gate 	struct autodir *dir;
4867c478bd9Sstevel@tonic-gate 	int current;
4877c478bd9Sstevel@tonic-gate 	int count = 0;
4887c478bd9Sstevel@tonic-gate 	struct zone_summary *zsp;
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate 	zsp = fs_get_zone_summaries();
4917c478bd9Sstevel@tonic-gate 	if (zsp == NULL) {
4927c478bd9Sstevel@tonic-gate 		pr_msg("Couldn't establish active zones");
4937c478bd9Sstevel@tonic-gate 		exit(1);
4947c478bd9Sstevel@tonic-gate 	}
4957c478bd9Sstevel@tonic-gate 	for (mntl = current_mounts; mntl; mntl = mntl->mntl_next) {
4967c478bd9Sstevel@tonic-gate 		mnt = mntl->mntl_mnt;
4977c478bd9Sstevel@tonic-gate 		omnt = (struct mnttab *)mnt;
4987c478bd9Sstevel@tonic-gate 		if (strcmp(mnt->mnt_fstype, MNTTYPE_AUTOFS) != 0)
4997c478bd9Sstevel@tonic-gate 			continue;
5007c478bd9Sstevel@tonic-gate 		if (fs_mount_in_other_zone(zsp, mnt->mnt_mountp))
5017c478bd9Sstevel@tonic-gate 			continue;
5027c478bd9Sstevel@tonic-gate 		/*
5037c478bd9Sstevel@tonic-gate 		 * Don't unmount autofs mounts done
5047c478bd9Sstevel@tonic-gate 		 * from the autofs mount command.
5057c478bd9Sstevel@tonic-gate 		 * How do we tell them apart ?
5067c478bd9Sstevel@tonic-gate 		 * Autofs mounts not eligible for auto-unmount
5077c478bd9Sstevel@tonic-gate 		 * have the "nest" pseudo-option.
5087c478bd9Sstevel@tonic-gate 		 */
5097c478bd9Sstevel@tonic-gate 		if (hasmntopt(omnt, "nest") != NULL)
5107c478bd9Sstevel@tonic-gate 			continue;
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate 		current = 0;
5137c478bd9Sstevel@tonic-gate 		for (dir = dir_head; dir; dir = dir->dir_next) {
5147c478bd9Sstevel@tonic-gate 			if (strcmp(dir->dir_name, mnt->mnt_mountp) == 0) {
5157c478bd9Sstevel@tonic-gate 				current = strcmp(dir->dir_map, "-null");
5167c478bd9Sstevel@tonic-gate 				break;
5177c478bd9Sstevel@tonic-gate 			}
5187c478bd9Sstevel@tonic-gate 		}
5197c478bd9Sstevel@tonic-gate 		if (current)
5207c478bd9Sstevel@tonic-gate 			continue;
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate 		if (umount(mnt->mnt_mountp) == 0) {
5247c478bd9Sstevel@tonic-gate 			if (verbose) {
5257c478bd9Sstevel@tonic-gate 				pr_msg("%s unmounted",
526dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States 				    mnt->mnt_mountp);
5277c478bd9Sstevel@tonic-gate 			}
5287c478bd9Sstevel@tonic-gate 			count++;
5297c478bd9Sstevel@tonic-gate 		}
5307c478bd9Sstevel@tonic-gate 	}
5317c478bd9Sstevel@tonic-gate 	if (verbose && count == 0)
5327c478bd9Sstevel@tonic-gate 		pr_msg("no unmounts");
5337c478bd9Sstevel@tonic-gate }
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate static int
mkdir_r(dir)5367c478bd9Sstevel@tonic-gate mkdir_r(dir)
5377c478bd9Sstevel@tonic-gate 	char *dir;
5387c478bd9Sstevel@tonic-gate {
5397c478bd9Sstevel@tonic-gate 	int err;
5407c478bd9Sstevel@tonic-gate 	char *slash;
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate 	if (mkdir(dir, 0555) == 0 || errno == EEXIST)
5437c478bd9Sstevel@tonic-gate 		return (0);
5447c478bd9Sstevel@tonic-gate 	if (errno != ENOENT)
5457c478bd9Sstevel@tonic-gate 		return (-1);
5467c478bd9Sstevel@tonic-gate 	slash = strrchr(dir, '/');
5477c478bd9Sstevel@tonic-gate 	if (slash == NULL)
5487c478bd9Sstevel@tonic-gate 		return (-1);
5497c478bd9Sstevel@tonic-gate 	*slash = '\0';
5507c478bd9Sstevel@tonic-gate 	err = mkdir_r(dir);
5517c478bd9Sstevel@tonic-gate 	*slash++ = '/';
5527c478bd9Sstevel@tonic-gate 	if (err || !*slash)
5537c478bd9Sstevel@tonic-gate 		return (err);
5547c478bd9Sstevel@tonic-gate 	return (mkdir(dir, 0555));
5557c478bd9Sstevel@tonic-gate }
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate /*
5587c478bd9Sstevel@tonic-gate  * Print an error.
5597c478bd9Sstevel@tonic-gate  * Works like printf (fmt string and variable args)
5607c478bd9Sstevel@tonic-gate  * except that it will subsititute an error message
5617c478bd9Sstevel@tonic-gate  * for a "%m" string (like syslog).
5627c478bd9Sstevel@tonic-gate  */
5637c478bd9Sstevel@tonic-gate /* VARARGS1 */
5647c478bd9Sstevel@tonic-gate void
pr_msg(const char * fmt,...)5657c478bd9Sstevel@tonic-gate pr_msg(const char *fmt, ...)
5667c478bd9Sstevel@tonic-gate {
5677c478bd9Sstevel@tonic-gate 	va_list ap;
5687c478bd9Sstevel@tonic-gate 	char buf[BUFSIZ], *p2;
5697c478bd9Sstevel@tonic-gate 	char *p1;
5707c478bd9Sstevel@tonic-gate 	char *nfmt;
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate 	(void) strcpy(buf, "automount: ");
5737c478bd9Sstevel@tonic-gate 	p2 = buf + strlen(buf);
5747c478bd9Sstevel@tonic-gate 
5757c478bd9Sstevel@tonic-gate 	nfmt = gettext(fmt);
5767c478bd9Sstevel@tonic-gate 
5777c478bd9Sstevel@tonic-gate 	for (p1 = nfmt; *p1; p1++) {
5787c478bd9Sstevel@tonic-gate 		if (*p1 == '%' && *(p1+1) == 'm') {
579ace1a5f1Sdp 			(void) strcpy(p2, strerror(errno));
580ace1a5f1Sdp 			p2 += strlen(p2);
5817c478bd9Sstevel@tonic-gate 			p1++;
5827c478bd9Sstevel@tonic-gate 		} else {
5837c478bd9Sstevel@tonic-gate 			*p2++ = *p1;
5847c478bd9Sstevel@tonic-gate 		}
5857c478bd9Sstevel@tonic-gate 	}
5867c478bd9Sstevel@tonic-gate 	if (p2 > buf && *(p2-1) != '\n')
5877c478bd9Sstevel@tonic-gate 		*p2++ = '\n';
5887c478bd9Sstevel@tonic-gate 	*p2 = '\0';
5897c478bd9Sstevel@tonic-gate 
5907c478bd9Sstevel@tonic-gate 	va_start(ap, fmt);
5917c478bd9Sstevel@tonic-gate 	(void) vfprintf(stderr, buf, ap);
5927c478bd9Sstevel@tonic-gate 	va_end(ap);
5937c478bd9Sstevel@tonic-gate }
594