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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 29 #include <stdio.h> 30 #include <ctype.h> 31 #include <sys/types.h> 32 #include <sys/mkdev.h> 33 #include <sys/stat.h> 34 #include <unistd.h> 35 #include <dirent.h> 36 #include <limits.h> 37 #include <string.h> 38 #include <libsvm.h> 39 #include <svm.h> 40 #include <errno.h> 41 42 43 #define VERSION "1.0" 44 #define DISK_DIR "/dev/rdsk" 45 46 extern int _map_to_effective_dev(); 47 48 static int is_blank(char *); 49 50 /* 51 * is_blank() returns 1 (true) if a line specified is composed of 52 * whitespace characters only. otherwise, it returns 0 (false). 53 * 54 * Note. the argument (line) must be null-terminated. 55 */ 56 static int 57 is_blank(char *line) 58 { 59 for (/* nothing */; *line != '\0'; line++) 60 if (!isspace(*line)) 61 return (0); 62 return (1); 63 } 64 65 /* 66 * FUNCTION: write_targ_nm_table 67 * creates a tuple table of <driver name, major number > in md.conf 68 * INPUT: rootpath 69 * 70 * RETURN VALUES: 71 * RET_SUCCESS 72 * RET_ERROR 73 */ 74 75 int 76 write_targ_nm_table(char *path) 77 { 78 FILE *targfp = NULL; 79 FILE *mdfp = NULL; 80 char buf[PATH_MAX], *cp; 81 int retval = RET_SUCCESS; 82 int first_entry = 1; 83 84 if ((mdfp = fopen(MD_CONF, "a")) == NULL) 85 return (RET_ERROR); 86 87 (void) snprintf(buf, sizeof (buf), "%s%s", path, NAME_TO_MAJOR); 88 89 if ((targfp = fopen(buf, "r")) == NULL) { 90 (void) fclose(mdfp); 91 return (RET_ERROR); 92 } 93 94 while (fgets(buf, PATH_MAX, targfp) != NULL && 95 (retval == RET_SUCCESS)) { 96 /* remove a new-line character for md_targ_nm_table */ 97 if ((cp = strchr(buf, '\n')) != NULL) 98 *cp = 0; 99 /* cut off comments starting with '#' */ 100 if ((cp = strchr(buf, '#')) != NULL) 101 *cp = 0; 102 /* ignore comment or blank lines */ 103 if (is_blank(buf)) 104 continue; 105 if (first_entry) { 106 if (fprintf(mdfp, "md_targ_nm_table=\"%s\"", buf) < 0) 107 retval = RET_ERROR; 108 first_entry = 0; 109 } else { 110 if (fprintf(mdfp, ",\"%s\"", buf) < 0) 111 retval = RET_ERROR; 112 } 113 } 114 if (!first_entry) 115 if (fprintf(mdfp, ";\n") < 0) 116 retval = RET_ERROR; 117 (void) fclose(mdfp); 118 (void) fclose(targfp); 119 return (retval); 120 } 121 122 /* 123 * FUNCTION: write_xlate_to_mdconf 124 * creates a tuple table of <miniroot devt, target devt> in md.conf 125 * INPUT: rootpath 126 * 127 * RETURN VALUES: 128 * RET_SUCCESS 129 * RET_ERROR 130 */ 131 132 int 133 write_xlate_to_mdconf(char *path) 134 { 135 FILE *fptr = NULL; 136 struct dirent *dp; 137 DIR *dirp; 138 struct stat statb_dev; 139 struct stat statb_edev; 140 char *devname; 141 char edevname[PATH_MAX]; 142 char targname[PATH_MAX]; 143 char diskdir[PATH_MAX]; 144 int first_devid = 1; 145 int ret = RET_SUCCESS; 146 147 if ((fptr = fopen(MD_CONF, "a")) == NULL) { 148 return (RET_ERROR); 149 } 150 151 152 (void) snprintf(diskdir, sizeof (diskdir), "%s%s", path, DISK_DIR); 153 if ((dirp = opendir(diskdir)) == NULL) { 154 (void) fclose(fptr); 155 return (RET_ERROR); 156 } 157 158 /* special case to write the first tuple in the table */ 159 while (((dp = readdir(dirp)) != (struct dirent *)0) && 160 (ret != RET_ERROR)) { 161 if ((strcmp(dp->d_name, ".") == 0) || 162 (strcmp(dp->d_name, "..") == 0)) 163 continue; 164 165 if ((strlen(diskdir) + strlen(dp->d_name) + 2) > PATH_MAX) { 166 continue; 167 } 168 169 (void) snprintf(targname, sizeof (targname), "%s/%s", 170 diskdir, dp->d_name); 171 172 if (stat(targname, &statb_dev) != 0) { 173 continue; 174 } 175 176 if ((devname = strstr(targname, DISK_DIR)) == NULL) { 177 continue; 178 } 179 180 if (_map_to_effective_dev((char *)devname, (char *)&edevname) 181 != 0) { 182 continue; 183 } 184 185 if (stat(edevname, &statb_edev) != 0) { 186 continue; 187 } 188 189 if (first_devid) { 190 if (fprintf(fptr, "md_xlate_ver=\"%s\";\n" 191 "md_xlate=%lu,%lu", VERSION, 192 statb_edev.st_rdev, statb_dev.st_rdev) < 0) 193 ret = RET_ERROR; 194 first_devid = 0; 195 } 196 if (fprintf(fptr, ",%lu,%lu", statb_edev.st_rdev, 197 statb_dev.st_rdev) < 0) 198 ret = RET_ERROR; 199 } /* end while */ 200 201 if (!first_devid) 202 if (fprintf(fptr, ";\n") < 0) 203 ret = RET_ERROR; 204 (void) fclose(fptr); 205 (void) closedir(dirp); 206 return (ret); 207 } 208