usr/src/cmd/fs.d/switchout.c
changeset 767 0aa24dfb5d87
parent 0 68f95e015346
child 821 ef17b74dd690
equal deleted inserted replaced
766:c521de78a32f 767:0aa24dfb5d87
    22 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
    22 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
    23 /*	  All Rights Reserved  	*/
    23 /*	  All Rights Reserved  	*/
    24 
    24 
    25 
    25 
    26 /*
    26 /*
    27  * Copyright 1996-2003 Sun Microsystems, Inc.  All rights reserved.
    27  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
    28  * Use is subject to license terms.
    28  * Use is subject to license terms.
    29  */
    29  */
    30 
    30 
    31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
    31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
    32 
    32 
    39 #include	<sys/vfstab.h>
    39 #include	<sys/vfstab.h>
    40 #include	<sys/types.h>
    40 #include	<sys/types.h>
    41 #include	<sys/stat.h>
    41 #include	<sys/stat.h>
    42 #include	<fcntl.h>
    42 #include	<fcntl.h>
    43 #include	<string.h>
    43 #include	<string.h>
       
    44 #include	<libdiskmgt.h>
       
    45 #include	"fslib.h"
       
    46 
       
    47 
       
    48 static int match(char **opts, char *s);
    44 
    49 
    45 #define	FSTYPE_MAX	8
    50 #define	FSTYPE_MAX	8
    46 #define	ARGV_MAX	1024
    51 #define	ARGV_MAX	1024
    47 #define	VFS_PATH	"/usr/lib/fs"
    52 #define	VFS_PATH	"/usr/lib/fs"
    48 #define	ALT_PATH	"/etc/fs"
    53 #define	ALT_PATH	"/etc/fs"
   115 	register char *ptr;
   120 	register char *ptr;
   116 	char	full_path[PATH_MAX];
   121 	char	full_path[PATH_MAX];
   117 	char	*vfs_path = VFS_PATH;
   122 	char	*vfs_path = VFS_PATH;
   118 	char	*alt_path = ALT_PATH;
   123 	char	*alt_path = ALT_PATH;
   119 	int	i;
   124 	int	i;
       
   125 	int	j;
   120 	int	verbose = 0;		/* set if -V is specified */
   126 	int	verbose = 0;		/* set if -V is specified */
   121 	int	F_flg = 0;
   127 	int	F_flg = 0;
   122 	int	mflag = 0;
   128 	int	mflag = 0;
       
   129 	int	Nflag = 0;
   123 	char	*oopts = NULL;
   130 	char	*oopts = NULL;
       
   131 	char	*tmpopts = NULL;	/* used for in use checking */
   124 	int	iflag = 0;
   132 	int	iflag = 0;
   125 	int	usgflag = 0;
   133 	int	usgflag = 0;
   126 	int	arg;			/* argument from getopt() */
   134 	int	arg;			/* argument from getopt() */
       
   135 	char	*msg;
       
   136 	int	error;
   127 	extern	char *optarg;		/* getopt specific */
   137 	extern	char *optarg;		/* getopt specific */
   128 	extern	int optind;
   138 	extern	int optind;
   129 	extern	int opterr;
   139 	extern	int opterr;
   130 
   140 
   131 	(void) setlocale(LC_ALL, "");
   141 	(void) setlocale(LC_ALL, "");
   165 				break;
   175 				break;
   166 			case 'o':	/* FSType specific arguments */
   176 			case 'o':	/* FSType specific arguments */
   167 				newargv[newargc++] = "-o";
   177 				newargv[newargc++] = "-o";
   168 				newargv[newargc++] = optarg;
   178 				newargv[newargc++] = optarg;
   169 				oopts = optarg;
   179 				oopts = optarg;
       
   180 				if (!Nflag) {
       
   181 					tmpopts = optarg;
       
   182 					Nflag = has_Nflag(tmpopts);
       
   183 				}
   170 				break;
   184 				break;
   171 			case '?':	/* print usage message */
   185 			case '?':	/* print usage message */
   172 				newargv[newargc++] = "-?";
   186 				newargv[newargc++] = "-?";
   173 				usgflag = 1;
   187 				usgflag = 1;
   174 				break;
   188 				break;
   190 				break;
   204 				break;
   191 			}
   205 			}
   192 			optarg = NULL;
   206 			optarg = NULL;
   193 	}
   207 	}
   194 	if (F_flg > 1) {
   208 	if (F_flg > 1) {
   195 		fprintf(stderr, gettext("%s: more than one FSType specified\n"),
   209 		(void) fprintf(stderr,
   196 			cbasename);
   210 		    gettext("%s: more than one FSType specified\n"),
       
   211 		    cbasename);
   197 		usage(cbasename, c_ptr->c_usgstr);
   212 		usage(cbasename, c_ptr->c_usgstr);
   198 		exit(2);
   213 		exit(2);
   199 	}
   214 	}
   200 	if (fstype != NULL) {
   215 	if (fstype != NULL) {
   201 		if (strlen(fstype) > FSTYPE_MAX) {
   216 		if (strlen(fstype) > FSTYPE_MAX) {
   202 			fprintf(stderr,
   217 			(void) fprintf(stderr,
   203 			    gettext("%s: FSType %s exceeds %d characters\n"),
   218 			    gettext("%s: FSType %s exceeds %d characters\n"),
   204 			    cbasename, fstype, FSTYPE_MAX);
   219 			    cbasename, fstype, FSTYPE_MAX);
   205 			exit(2);
   220 			exit(2);
   206 		}
   221 		}
   207 	}
   222 	}
   222 		stat_snap(cbasename, diff == 0 ? argv[argc-1] : NULL, oopts);
   237 		stat_snap(cbasename, diff == 0 ? argv[argc-1] : NULL, oopts);
   223 		exit(0);
   238 		exit(0);
   224 	}
   239 	}
   225 
   240 
   226 	if ((special == NULL) && (!usgflag)) {
   241 	if ((special == NULL) && (!usgflag)) {
   227 		fprintf(stderr, gettext("%s: special not specified\n"),
   242 		(void) fprintf(stderr, gettext("%s: special not specified\n"),
   228 		    cbasename);
   243 		    cbasename);
   229 		usage(cbasename, c_ptr->c_usgstr);
   244 		usage(cbasename, c_ptr->c_usgstr);
   230 		exit(2);
   245 		exit(2);
   231 	}
   246 	}
       
   247 
   232 	if ((fstype == NULL) && (usgflag))
   248 	if ((fstype == NULL) && (usgflag))
   233 		usage(cbasename, c_ptr->c_usgstr);
   249 		usage(cbasename, c_ptr->c_usgstr);
   234 	if (fstype == NULL)
   250 	if (fstype == NULL)
   235 		lookup();
   251 		lookup();
   236 	if (fstype == NULL) {
   252 	if (fstype == NULL) {
   237 		fprintf(stderr, gettext("%s: FSType cannot be identified\n"),
   253 		(void) fprintf(stderr,
   238 			cbasename);
   254 		    gettext("%s: FSType cannot be identified\n"), cbasename);
   239 		usage(cbasename, c_ptr->c_usgstr);
   255 		usage(cbasename, c_ptr->c_usgstr);
   240 		exit(2);
   256 		exit(2);
   241 	}
   257 	}
   242 	newargv[newargc++] = special;
   258 	newargv[newargc++] = special;
   243 	for (; optind < argc; optind++)
   259 	for (; optind < argc; optind++)
   252 		printf("%s -F %s ", cbasename, fstype);
   268 		printf("%s -F %s ", cbasename, fstype);
   253 		for (i = 2; newargv[i]; i++)
   269 		for (i = 2; newargv[i]; i++)
   254 			printf("%s ", newargv[i]);
   270 			printf("%s ", newargv[i]);
   255 		printf("\n");
   271 		printf("\n");
   256 		exit(0);
   272 		exit(0);
       
   273 	}
       
   274 
       
   275 	/*
       
   276 	 * Prior to executing the command for mkfs check for device in use.
       
   277 	 * If the mflag is set, user wants to see command that created
       
   278 	 * an already existing filesystem. Do not check for in use in this
       
   279 	 * case. If Nflag is set user wants to see what the parameters
       
   280 	 * would be to create the filesystem. Do not check for in use in
       
   281 	 * this case.
       
   282 	 */
       
   283 	if (strcmp(cbasename, "mkfs") == 0 && !mflag && !Nflag) {
       
   284 		if (dm_inuse(special, &msg, DM_WHO_MKFS, &error) ||
       
   285 		    error) {
       
   286 			if (error != 0) {
       
   287 				(void) fprintf(stderr, gettext("Error occurred"
       
   288 				    " with device in use checking: %s\n"),
       
   289 				    strerror(error));
       
   290 			} else {
       
   291 				(void) fprintf(stderr, "%s", msg);
       
   292 				free(msg);
       
   293 				exit(2);
       
   294 			}
       
   295 		}
   257 	}
   296 	}
   258 
   297 
   259 	/*
   298 	/*
   260 	 *  Execute the FSType specific command.
   299 	 *  Execute the FSType specific command.
   261 	 */
   300 	 */
   277 		newargv[1] = full_path;
   316 		newargv[1] = full_path;
   278 		execv("/sbin/sh", &newargv[0]);
   317 		execv("/sbin/sh", &newargv[0]);
   279 	}
   318 	}
   280 	if (errno != ENOENT) {
   319 	if (errno != ENOENT) {
   281 		perror(cbasename);
   320 		perror(cbasename);
   282 		fprintf(stderr, gettext("%s: cannot execute %s\n"), cbasename,
   321 		(void) fprintf(stderr, gettext("%s: cannot execute %s\n"),
   283 		    full_path);
   322 		    cbasename, full_path);
   284 		exit(2);
   323 		exit(2);
   285 	}
   324 	}
   286 
   325 
   287 	if (sysfs(GETFSIND, fstype) == (-1)) {
   326 	if (sysfs(GETFSIND, fstype) == (-1)) {
   288 		fprintf(stderr,
   327 		(void) fprintf(stderr,
   289 		    gettext("%s: FSType %s not installed in the kernel\n"),
   328 		    gettext("%s: FSType %s not installed in the kernel\n"),
   290 		    cbasename, fstype);
   329 		    cbasename, fstype);
   291 		exit(2);
   330 		exit(2);
   292 	}
   331 	}
   293 	fprintf(stderr,
   332 	(void) fprintf(stderr,
   294 	    gettext("%s: Operation not applicable for FSType %s \n"),
   333 	    gettext("%s: Operation not applicable for FSType %s \n"),
   295 	    cbasename, fstype);
   334 	    cbasename, fstype);
   296 	exit(2);
   335 	exit(2);
   297 }
   336 }
   298 
   337 
   299 usage(cmd, usg)
   338 usage(cmd, usg)
   300 char *cmd;
   339 char *cmd;
   301 char **usg;
   340 char **usg;
   302 {
   341 {
   303 	int i;
   342 	int i;
   304 	fprintf(stderr, gettext("Usage:\n"));
   343 	(void) fprintf(stderr, gettext("Usage:\n"));
   305 	for (i = 0; usg[i] != NULL; i++)
   344 	for (i = 0; usg[i] != NULL; i++)
   306 		fprintf(stderr, "%s %s\n", gettext(cmd), gettext(usg[i]));
   345 		(void) fprintf(stderr, "%s %s\n", gettext(cmd),
       
   346 		    gettext(usg[i]));
   307 	exit(2);
   347 	exit(2);
   308 }
   348 }
   309 
   349 
   310 
   350 
   311 /*
   351 /*
   321 	FILE	*fd;
   361 	FILE	*fd;
   322 	int	ret;
   362 	int	ret;
   323 	struct vfstab	vget, vref;
   363 	struct vfstab	vget, vref;
   324 
   364 
   325 	if ((fd = fopen(vfstab, "r")) == NULL) {
   365 	if ((fd = fopen(vfstab, "r")) == NULL) {
   326 		fprintf(stderr, gettext("%s: cannot open vfstab\n"), cbasename);
   366 		(void) fprintf(stderr, gettext("%s: cannot open vfstab\n"),
       
   367 		    cbasename);
   327 		exit(1);
   368 		exit(1);
   328 	}
   369 	}
   329 	vfsnull(&vref);
   370 	vfsnull(&vref);
   330 	vref.vfs_special = special;
   371 	vref.vfs_special = special;
   331 	ret = getvfsany(fd, &vget, &vref);
   372 	ret = getvfsany(fd, &vget, &vref);
   343 		break;
   384 		break;
   344 	case 0:
   385 	case 0:
   345 		fstype = vget.vfs_fstype;
   386 		fstype = vget.vfs_fstype;
   346 		break;
   387 		break;
   347 	case VFS_TOOLONG:
   388 	case VFS_TOOLONG:
   348 		fprintf(stderr,
   389 		(void) fprintf(stderr,
   349 		    gettext("%s: line in vfstab exceeds %d characters\n"),
   390 		    gettext("%s: line in vfstab exceeds %d characters\n"),
   350 		    cbasename, VFS_LINE_MAX-2);
   391 		    cbasename, VFS_LINE_MAX-2);
   351 		exit(1);
   392 		exit(1);
   352 		break;
   393 		break;
   353 	case VFS_TOOFEW:
   394 	case VFS_TOOFEW:
   354 		fprintf(stderr,
   395 		(void) fprintf(stderr,
   355 		    gettext("%s: line in vfstab has too few entries\n"),
   396 		    gettext("%s: line in vfstab has too few entries\n"),
   356 		    cbasename);
   397 		    cbasename);
   357 		exit(1);
   398 		exit(1);
   358 		break;
   399 		break;
   359 	}
   400 	}
   374 			en = errno;
   415 			en = errno;
   375 			errstr = strerror(errno);
   416 			errstr = strerror(errno);
   376 			if (errstr == NULL)
   417 			if (errstr == NULL)
   377 				errstr = gettext("Unknown error");
   418 				errstr = gettext("Unknown error");
   378 
   419 
   379 			fprintf(stderr, gettext("%s: %s: error %d: %s\n"),
   420 			(void) fprintf(stderr,
   380 				cmd, mountpoint, en, errstr);
   421 			    gettext("%s: %s: error %d: %s\n"),
       
   422 			    cmd, mountpoint, en, errstr);
   381 
   423 
   382 			exit(2);
   424 			exit(2);
   383 		}
   425 		}
   384 		close(fd);
   426 		close(fd);
   385 	}
   427 	}
   386 	fssnap_show_status(mountpoint, opts, 1, (opts ? 0 : 1));
   428 	fssnap_show_status(mountpoint, opts, 1, (opts ? 0 : 1));
   387 }
   429 }
       
   430 static int
       
   431 has_Nflag(char *opts)
       
   432 {
       
   433 	while (opts != NULL && *opts != '\0') {
       
   434 		if (match(&opts, "N")) {
       
   435 			return (1);
       
   436 		}
       
   437 		if (!opts)
       
   438 			break;
       
   439 		if (*opts == ',')
       
   440 			opts ++;
       
   441 		if (*opts == ' ')
       
   442 			opts ++;
       
   443 	}
       
   444 	return (0);
       
   445 }
       
   446 /*
       
   447  * Parses the -o [fs specific options string] to search for the UFS -N flag.
       
   448  * Return the opts string pointing to the next position in the string if
       
   449  * match is not found. A delimiter of , or ' ' can be used depending on the
       
   450  * caller, newfs or mkfs.
       
   451  */
       
   452 static int
       
   453 match(char **opts, char *s)
       
   454 {
       
   455 	char *cs;
       
   456 	char *tmp_str;
       
   457 
       
   458 	cs = *opts;
       
   459 
       
   460 	while (*cs++ == *s) {
       
   461 		if (*s++ == '\0') {
       
   462 			goto true;
       
   463 		}
       
   464 	}
       
   465 	if (*s != '\0') {
       
   466 		/*
       
   467 		 * If we cannot find the delimiter it means we
       
   468 		 * have hit the end of the string.
       
   469 		 */
       
   470 		tmp_str = strchr(*opts, ',');
       
   471 		if (!tmp_str)
       
   472 			tmp_str = strchr(*opts, ' ');
       
   473 
       
   474 		*opts = tmp_str;
       
   475 		return (0);
       
   476 	}
       
   477 true:
       
   478 	cs--;
       
   479 	*opts = cs;
       
   480 	return (1);
       
   481 }