xref: /titanic_41/usr/src/lib/lvm/libsvm/common/metaconf.c (revision 835ee2195df075073d2670eb95a6eab413d6c789)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <stdio.h>
27 #include <ctype.h>
28 #include <sys/types.h>
29 #include <sys/mkdev.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <dirent.h>
33 #include <limits.h>
34 #include <string.h>
35 #include <libsvm.h>
36 #include <svm.h>
37 #include <errno.h>
38 
39 
40 #define	VERSION "1.0"
41 #define	DISK_DIR "/dev/rdsk"
42 
43 extern int _map_to_effective_dev();
44 
45 static int is_blank(char *);
46 
47 /*
48  * is_blank() returns 1 (true) if a line specified is composed of
49  * whitespace characters only. otherwise, it returns 0 (false).
50  *
51  * Note. the argument (line) must be null-terminated.
52  */
53 static int
54 is_blank(char *line)
55 {
56 	for (/* nothing */; *line != '\0'; line++)
57 		if (!isspace(*line))
58 			return (0);
59 	return (1);
60 }
61 
62 /*
63  * FUNCTION: write_targ_nm_table
64  *	creates a tuple table of <driver name, major number > in md.conf
65  * INPUT: rootpath
66  *
67  * RETURN VALUES:
68  *	RET_SUCCESS
69  *	RET_ERROR
70  */
71 
72 int
73 write_targ_nm_table(char *path)
74 {
75 	FILE	*targfp = NULL;
76 	FILE	*mdfp = NULL;
77 	char	buf[PATH_MAX], *cp;
78 	int	retval = RET_SUCCESS;
79 	int	first_entry = 1;
80 
81 	if ((mdfp = fopen(MD_CONF, "a")) == NULL)
82 		return (RET_ERROR);
83 
84 	(void) snprintf(buf, sizeof (buf), "%s%s", path, NAME_TO_MAJOR);
85 
86 	if ((targfp = fopen(buf, "r")) == NULL) {
87 		(void) fclose(mdfp);
88 		return (RET_ERROR);
89 	}
90 
91 	while (fgets(buf, PATH_MAX, targfp) != NULL &&
92 	    (retval == RET_SUCCESS)) {
93 		/* remove a new-line character for md_targ_nm_table */
94 		if ((cp = strchr(buf, '\n')) != NULL)
95 			*cp = 0;
96 		/* cut off comments starting with '#' */
97 		if ((cp = strchr(buf, '#')) != NULL)
98 			*cp = 0;
99 		/* ignore comment or blank lines */
100 		if (is_blank(buf))
101 			continue;
102 		if (first_entry) {
103 			if (fprintf(mdfp, "md_targ_nm_table=\"%s\"", buf) < 0)
104 				retval = RET_ERROR;
105 			first_entry = 0;
106 		} else {
107 			if (fprintf(mdfp, ",\"%s\"", buf) < 0)
108 					retval = RET_ERROR;
109 		}
110 	}
111 	if (!first_entry)
112 		if (fprintf(mdfp, ";\n") < 0)
113 			retval = RET_ERROR;
114 	(void) fclose(mdfp);
115 	(void) fclose(targfp);
116 	return (retval);
117 }
118 
119 /*
120  * FUNCTION: write_xlate_to_mdconf
121  *	creates a tuple table of <miniroot devt, target devt> in md.conf
122  * INPUT: rootpath
123  *
124  * RETURN VALUES:
125  *	RET_SUCCESS
126  *	RET_ERROR
127  */
128 
129 int
130 write_xlate_to_mdconf(char *path)
131 {
132 	FILE		*fptr = NULL;
133 	struct dirent	*dp;
134 	DIR		*dirp;
135 	struct stat	statb_dev;
136 	struct stat	statb_edev;
137 	char		*devname;
138 	char		edevname[PATH_MAX];
139 	char		targname[PATH_MAX];
140 	char		diskdir[PATH_MAX];
141 	char		linkpath[PATH_MAX];
142 	int		first_devid = 1;
143 	int		ret = RET_SUCCESS;
144 
145 	if ((fptr = fopen(MD_CONF, "a")) == NULL) {
146 		return (RET_ERROR);
147 	}
148 
149 
150 	(void) snprintf(diskdir, sizeof (diskdir), "%s%s", path, DISK_DIR);
151 	if ((dirp = opendir(diskdir)) == NULL) {
152 		(void) fclose(fptr);
153 		return (RET_ERROR);
154 	}
155 
156 	/* special case to write the first tuple in the table */
157 	while (((dp = readdir(dirp)) != (struct dirent *)0) &&
158 	    (ret != RET_ERROR)) {
159 		if ((strcmp(dp->d_name, ".") == 0) ||
160 		    (strcmp(dp->d_name, "..") == 0))
161 			continue;
162 
163 		if ((strlen(diskdir) + strlen(dp->d_name) + 2) > PATH_MAX) {
164 			continue;
165 		}
166 
167 		(void) snprintf(targname, sizeof (targname), "%s/%s",
168 		    diskdir, dp->d_name);
169 
170 		/*
171 		 * stat /devices to see if it's a devfs based file system
172 		 * On Solaris 10 and up, the devfs has been built on the
173 		 * fly for the mini-root. We need to adjust the path
174 		 * accordingly.
175 		 * If it's not devfs, just use the targname as it is.
176 		 */
177 
178 		if (stat("/devices", &statb_dev) != 0) {
179 			continue;
180 		}
181 
182 		if (strncmp("devfs", statb_dev.st_fstype, 5) == 0) {
183 			if (readlink(targname, linkpath,
184 			    sizeof (linkpath)) == -1) {
185 				continue;
186 			}
187 			/*
188 			 * turn ../../devices/<path> into /devices/<path>
189 			 * and stat that into statb_dev
190 			 */
191 			if (stat(strstr(linkpath, "/devices"),
192 			    &statb_dev) != 0) {
193 				continue;
194 			}
195 		} else {
196 			if (stat(targname, &statb_dev) != 0) {
197 				continue;
198 			}
199 		}
200 
201 		if ((devname = strstr(targname, DISK_DIR)) == NULL) {
202 			continue;
203 		}
204 
205 		if (_map_to_effective_dev((char *)devname, (char *)&edevname)
206 		    != 0) {
207 			continue;
208 		}
209 
210 		if (stat(edevname, &statb_edev) != 0) {
211 			continue;
212 		}
213 
214 		if (first_devid) {
215 			if (fprintf(fptr, "md_xlate_ver=\"%s\";\n"
216 			    "md_xlate=%lu,%lu", VERSION,
217 			    statb_edev.st_rdev, statb_dev.st_rdev) < 0)
218 				ret = RET_ERROR;
219 			first_devid = 0;
220 		}
221 		if (fprintf(fptr, ",%lu,%lu", statb_edev.st_rdev,
222 		    statb_dev.st_rdev) < 0)
223 			ret = RET_ERROR;
224 	} /* end while */
225 
226 	if (!first_devid)
227 		if (fprintf(fptr, ";\n") < 0)
228 			ret = RET_ERROR;
229 	(void) fclose(fptr);
230 	(void) closedir(dirp);
231 	return (ret);
232 }
233