10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*2805Seota  * Common Development and Distribution License (the "License").
6*2805Seota  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*2805Seota  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <stdio.h>
300Sstevel@tonic-gate #include <ctype.h>
310Sstevel@tonic-gate #include <sys/types.h>
320Sstevel@tonic-gate #include <sys/mkdev.h>
330Sstevel@tonic-gate #include <sys/stat.h>
340Sstevel@tonic-gate #include <unistd.h>
350Sstevel@tonic-gate #include <dirent.h>
360Sstevel@tonic-gate #include <limits.h>
370Sstevel@tonic-gate #include <string.h>
380Sstevel@tonic-gate #include <libsvm.h>
390Sstevel@tonic-gate #include <svm.h>
400Sstevel@tonic-gate #include <errno.h>
410Sstevel@tonic-gate 
420Sstevel@tonic-gate 
430Sstevel@tonic-gate #define	VERSION "1.0"
440Sstevel@tonic-gate #define	DISK_DIR "/dev/rdsk"
450Sstevel@tonic-gate 
460Sstevel@tonic-gate extern int _map_to_effective_dev();
470Sstevel@tonic-gate 
48*2805Seota static int is_blank(char *);
49*2805Seota 
50*2805Seota /*
51*2805Seota  * is_blank() returns 1 (true) if a line specified is composed of
52*2805Seota  * whitespace characters only. otherwise, it returns 0 (false).
53*2805Seota  *
54*2805Seota  * Note. the argument (line) must be null-terminated.
55*2805Seota  */
56*2805Seota static int
57*2805Seota is_blank(char *line)
580Sstevel@tonic-gate {
59*2805Seota 	for (/* nothing */; *line != '\0'; line++)
60*2805Seota 		if (!isspace(*line))
610Sstevel@tonic-gate 			return (0);
620Sstevel@tonic-gate 	return (1);
630Sstevel@tonic-gate }
640Sstevel@tonic-gate 
650Sstevel@tonic-gate /*
660Sstevel@tonic-gate  * FUNCTION: write_targ_nm_table
670Sstevel@tonic-gate  *	creates a tuple table of <driver name, major number > in md.conf
680Sstevel@tonic-gate  * INPUT: rootpath
690Sstevel@tonic-gate  *
700Sstevel@tonic-gate  * RETURN VALUES:
710Sstevel@tonic-gate  *	RET_SUCCESS
720Sstevel@tonic-gate  *	RET_ERROR
730Sstevel@tonic-gate  */
740Sstevel@tonic-gate 
750Sstevel@tonic-gate int
760Sstevel@tonic-gate write_targ_nm_table(char *path)
770Sstevel@tonic-gate {
780Sstevel@tonic-gate 	FILE	*targfp = NULL;
790Sstevel@tonic-gate 	FILE	*mdfp = NULL;
800Sstevel@tonic-gate 	char	buf[PATH_MAX], *cp;
810Sstevel@tonic-gate 	int	retval = RET_SUCCESS;
820Sstevel@tonic-gate 	int	first_entry = 1;
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	if ((mdfp = fopen(MD_CONF, "a")) == NULL)
850Sstevel@tonic-gate 		return (RET_ERROR);
860Sstevel@tonic-gate 
870Sstevel@tonic-gate 	(void) snprintf(buf, sizeof (buf), "%s%s", path, NAME_TO_MAJOR);
880Sstevel@tonic-gate 
890Sstevel@tonic-gate 	if ((targfp = fopen(buf, "r")) == NULL) {
900Sstevel@tonic-gate 		(void) fclose(mdfp);
910Sstevel@tonic-gate 		return (RET_ERROR);
920Sstevel@tonic-gate 	}
930Sstevel@tonic-gate 
940Sstevel@tonic-gate 	while (fgets(buf, PATH_MAX, targfp) != NULL &&
950Sstevel@tonic-gate 				(retval == RET_SUCCESS)) {
96*2805Seota 		/* cut off comments starting with '#' */
97*2805Seota 		if ((cp = strchr(buf, '#')) != NULL)
98*2805Seota 			*cp = 0;
99*2805Seota 		/* ignore comment or blank lines */
100*2805Seota 		if (is_blank(buf))
1010Sstevel@tonic-gate 			continue;
1020Sstevel@tonic-gate 		if (first_entry) {
1030Sstevel@tonic-gate 			if (fprintf(mdfp, "md_targ_nm_table=\"%s\"", buf) < 0)
1040Sstevel@tonic-gate 				retval = RET_ERROR;
1050Sstevel@tonic-gate 			first_entry = 0;
1060Sstevel@tonic-gate 		}
1070Sstevel@tonic-gate 		if (fprintf(mdfp, ",\"%s\"", buf) < 0)
1080Sstevel@tonic-gate 				retval = RET_ERROR;
1090Sstevel@tonic-gate 	}
1100Sstevel@tonic-gate 	if (!first_entry)
1110Sstevel@tonic-gate 		if (fprintf(mdfp, ";\n") < 0)
1120Sstevel@tonic-gate 			retval = RET_ERROR;
1130Sstevel@tonic-gate 	(void) fclose(mdfp);
1140Sstevel@tonic-gate 	(void) fclose(targfp);
1150Sstevel@tonic-gate 	return (retval);
1160Sstevel@tonic-gate }
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate /*
1190Sstevel@tonic-gate  * FUNCTION: write_xlate_to_mdconf
1200Sstevel@tonic-gate  *	creates a tuple table of <miniroot devt, target devt> in md.conf
1210Sstevel@tonic-gate  * INPUT: rootpath
1220Sstevel@tonic-gate  *
1230Sstevel@tonic-gate  * RETURN VALUES:
1240Sstevel@tonic-gate  *	RET_SUCCESS
1250Sstevel@tonic-gate  *	RET_ERROR
1260Sstevel@tonic-gate  */
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate int
1290Sstevel@tonic-gate write_xlate_to_mdconf(char *path)
1300Sstevel@tonic-gate {
1310Sstevel@tonic-gate 	FILE		*fptr = NULL;
1320Sstevel@tonic-gate 	struct dirent	*dp;
1330Sstevel@tonic-gate 	DIR		*dirp;
1340Sstevel@tonic-gate 	struct stat	statb_dev;
1350Sstevel@tonic-gate 	struct stat	statb_edev;
1360Sstevel@tonic-gate 	char		*devname;
1370Sstevel@tonic-gate 	char		edevname[PATH_MAX];
1380Sstevel@tonic-gate 	char		targname[PATH_MAX];
1390Sstevel@tonic-gate 	char		diskdir[PATH_MAX];
1400Sstevel@tonic-gate 	int		first_devid = 1;
1410Sstevel@tonic-gate 	int		ret = RET_SUCCESS;
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate 	if ((fptr = fopen(MD_CONF, "a")) == NULL) {
1440Sstevel@tonic-gate 		return (RET_ERROR);
1450Sstevel@tonic-gate 	}
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 	(void) snprintf(diskdir, sizeof (diskdir), "%s%s", path, DISK_DIR);
1490Sstevel@tonic-gate 	if ((dirp = opendir(diskdir)) == NULL) {
1500Sstevel@tonic-gate 		(void) fclose(fptr);
1510Sstevel@tonic-gate 		return (RET_ERROR);
1520Sstevel@tonic-gate 	}
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	/* special case to write the first tuple in the table */
1550Sstevel@tonic-gate 	while (((dp = readdir(dirp)) != (struct dirent *)0) &&
1560Sstevel@tonic-gate 						(ret != RET_ERROR)) {
1570Sstevel@tonic-gate 		if ((strcmp(dp->d_name, ".") == 0) ||
1580Sstevel@tonic-gate 		    (strcmp(dp->d_name, "..") == 0))
1590Sstevel@tonic-gate 			continue;
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate 		if ((strlen(diskdir) + strlen(dp->d_name) + 2) > PATH_MAX) {
1620Sstevel@tonic-gate 		    continue;
1630Sstevel@tonic-gate 		}
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 		(void) snprintf(targname, sizeof (targname), "%s/%s",
1660Sstevel@tonic-gate 		    diskdir, dp->d_name);
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate 		if (stat(targname, &statb_dev) != 0) {
1690Sstevel@tonic-gate 		    continue;
1700Sstevel@tonic-gate 		}
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate 		if ((devname = strstr(targname, DISK_DIR)) == NULL) {
1730Sstevel@tonic-gate 			continue;
1740Sstevel@tonic-gate 		}
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate 		if (_map_to_effective_dev((char *)devname, (char *)&edevname)
1770Sstevel@tonic-gate 		    != 0) {
1780Sstevel@tonic-gate 			continue;
1790Sstevel@tonic-gate 		}
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate 		if (stat(edevname, &statb_edev) != 0) {
1820Sstevel@tonic-gate 			continue;
1830Sstevel@tonic-gate 		}
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 		if (first_devid) {
1860Sstevel@tonic-gate 			if (fprintf(fptr, "md_xlate_ver=\"%s\";\n"
1870Sstevel@tonic-gate 				"md_xlate=%lu,%lu", VERSION,
1880Sstevel@tonic-gate 				statb_edev.st_rdev, statb_dev.st_rdev) < 0)
1890Sstevel@tonic-gate 				ret = RET_ERROR;
1900Sstevel@tonic-gate 			first_devid = 0;
1910Sstevel@tonic-gate 		}
1920Sstevel@tonic-gate 		if (fprintf(fptr, ",%lu,%lu", statb_edev.st_rdev,
1930Sstevel@tonic-gate 			statb_dev.st_rdev) < 0)
1940Sstevel@tonic-gate 			ret = RET_ERROR;
1950Sstevel@tonic-gate 	} /* end while */
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate 	if (!first_devid)
1980Sstevel@tonic-gate 		if (fprintf(fptr, ";\n") < 0)
1990Sstevel@tonic-gate 			ret = RET_ERROR;
2000Sstevel@tonic-gate 	(void) fclose(fptr);
2010Sstevel@tonic-gate 	(void) closedir(dirp);
2020Sstevel@tonic-gate 	return (ret);
2030Sstevel@tonic-gate }
204