1 1.37 abs /* $NetBSD: disklabel.c,v 1.37 2012/06/25 22:32:43 abs Exp $ */ 2 1.7 cgd 3 1.1 cgd /* 4 1.7 cgd * Copyright (c) 1983, 1987, 1993 5 1.7 cgd * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.30 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 cgd * may be used to endorse or promote products derived from this software 17 1.1 cgd * without specific prior written permission. 18 1.1 cgd * 19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 cgd * SUCH DAMAGE. 30 1.1 cgd */ 31 1.1 cgd 32 1.32 dyoung #if HAVE_NBTOOL_CONFIG_H 33 1.32 dyoung #include "nbtool_config.h" 34 1.32 dyoung #endif 35 1.32 dyoung 36 1.14 christos #include <sys/cdefs.h> 37 1.9 cgd #if defined(LIBC_SCCS) && !defined(lint) 38 1.7 cgd #if 0 39 1.16 perry static char sccsid[] = "@(#)disklabel.c 8.2 (Berkeley) 5/3/95"; 40 1.7 cgd #else 41 1.37 abs __RCSID("$NetBSD: disklabel.c,v 1.37 2012/06/25 22:32:43 abs Exp $"); 42 1.7 cgd #endif 43 1.9 cgd #endif /* LIBC_SCCS and not lint */ 44 1.1 cgd 45 1.15 jtc #include "namespace.h" 46 1.1 cgd #include <sys/param.h> 47 1.1 cgd #define DKTYPENAMES 48 1.22 christos #define FSTYPENAMES 49 1.16 perry #include <ufs/ufs/dinode.h> 50 1.7 cgd #include <ufs/ffs/fs.h> 51 1.7 cgd 52 1.32 dyoung #if HAVE_NBTOOL_CONFIG_H 53 1.33 he #include <nbinclude/sys/disklabel.h> 54 1.33 he #include <nbinclude/disktab.h> 55 1.32 dyoung #else 56 1.32 dyoung #include <sys/disklabel.h> 57 1.32 dyoung #include <disktab.h> 58 1.32 dyoung #endif /* HAVE_NBTOOL_CONFIG_H */ 59 1.32 dyoung 60 1.24 lukem #include <assert.h> 61 1.10 jtc #include <ctype.h> 62 1.7 cgd #include <errno.h> 63 1.7 cgd #include <fcntl.h> 64 1.1 cgd #include <stdio.h> 65 1.7 cgd #include <stdlib.h> 66 1.1 cgd #include <string.h> 67 1.1 cgd #include <unistd.h> 68 1.15 jtc 69 1.15 jtc #ifdef __weak_alias 70 1.26 mycroft __weak_alias(getdiskbyname,_getdiskbyname) 71 1.15 jtc #endif 72 1.1 cgd 73 1.14 christos #if 0 74 1.36 matt static void error(int); 75 1.14 christos #endif 76 1.36 matt static int gettype(char *, const char *const *); 77 1.1 cgd 78 1.31 christos static const char *db_array[2] = { _PATH_DISKTAB, 0 }; 79 1.23 abs 80 1.23 abs int 81 1.37 abs setdisktab(const char *name) 82 1.23 abs { 83 1.23 abs if (!name || !*name) 84 1.23 abs return -1; 85 1.23 abs 86 1.23 abs db_array[0] = name; 87 1.23 abs return 0; 88 1.23 abs } 89 1.23 abs 90 1.23 abs 91 1.1 cgd struct disklabel * 92 1.37 abs getdiskbyname(const char *name) 93 1.1 cgd { 94 1.1 cgd static struct disklabel disk; 95 1.17 perry struct disklabel *dp = &disk; 96 1.17 perry struct partition *pp; 97 1.7 cgd char *buf; 98 1.17 perry char *cp, *cq; /* can't be */ 99 1.1 cgd char p, max, psize[3], pbsize[3], 100 1.1 cgd pfsize[3], poffset[3], ptype[3]; 101 1.8 cgd u_int32_t *dx; 102 1.22 christos long f; 103 1.7 cgd 104 1.24 lukem _DIAGASSERT(name != NULL); 105 1.24 lukem 106 1.22 christos if (cgetent(&buf, db_array, name) < 0) 107 1.7 cgd return NULL; 108 1.1 cgd 109 1.21 perry memset(&disk, 0, sizeof(disk)); 110 1.1 cgd /* 111 1.1 cgd * typename 112 1.1 cgd */ 113 1.1 cgd cq = dp->d_typename; 114 1.1 cgd cp = buf; 115 1.1 cgd while (cq < dp->d_typename + sizeof(dp->d_typename) - 1 && 116 1.1 cgd (*cq = *cp) && *cq != '|' && *cq != ':') 117 1.1 cgd cq++, cp++; 118 1.1 cgd *cq = '\0'; 119 1.1 cgd /* 120 1.1 cgd * boot name (optional) xxboot, bootxx 121 1.1 cgd */ 122 1.7 cgd cgetstr(buf, "b0", &dp->d_boot0); 123 1.7 cgd cgetstr(buf, "b1", &dp->d_boot1); 124 1.7 cgd 125 1.34 christos if (cgetstr(buf, "ty", &cq) >= 0) { 126 1.34 christos if (strcmp(cq, "removable") == 0) 127 1.34 christos dp->d_flags |= D_REMOVABLE; 128 1.34 christos else if (strcmp(cq, "simulated") == 0) 129 1.34 christos dp->d_flags |= D_RAMDISK; 130 1.34 christos free(cq); 131 1.34 christos } 132 1.7 cgd if (cgetcap(buf, "sf", ':') != NULL) 133 1.1 cgd dp->d_flags |= D_BADSECT; 134 1.1 cgd 135 1.1 cgd #define getnumdflt(field, dname, dflt) \ 136 1.28 thorpej (field) = ((cgetnum(buf, dname, &f) == -1) ? (dflt) : (u_int32_t) f) 137 1.11 cgd #define getnum(field, dname) \ 138 1.22 christos if (cgetnum(buf, dname, &f) != -1) field = (u_int32_t)f 139 1.1 cgd 140 1.1 cgd getnumdflt(dp->d_secsize, "se", DEV_BSIZE); 141 1.11 cgd getnum(dp->d_ntracks, "nt"); 142 1.11 cgd getnum(dp->d_nsectors, "ns"); 143 1.11 cgd getnum(dp->d_ncylinders, "nc"); 144 1.7 cgd 145 1.34 christos if (cgetstr(buf, "dt", &cq) >= 0) { 146 1.1 cgd dp->d_type = gettype(cq, dktypenames); 147 1.34 christos free(cq); 148 1.34 christos } else 149 1.1 cgd getnumdflt(dp->d_type, "dt", 0); 150 1.1 cgd getnumdflt(dp->d_secpercyl, "sc", dp->d_nsectors * dp->d_ntracks); 151 1.1 cgd getnumdflt(dp->d_secperunit, "su", dp->d_secpercyl * dp->d_ncylinders); 152 1.1 cgd getnumdflt(dp->d_rpm, "rm", 3600); 153 1.1 cgd getnumdflt(dp->d_interleave, "il", 1); 154 1.1 cgd getnumdflt(dp->d_trackskew, "sk", 0); 155 1.1 cgd getnumdflt(dp->d_cylskew, "cs", 0); 156 1.1 cgd getnumdflt(dp->d_headswitch, "hs", 0); 157 1.1 cgd getnumdflt(dp->d_trkseek, "ts", 0); 158 1.1 cgd getnumdflt(dp->d_bbsize, "bs", BBSIZE); 159 1.29 fvdl getnumdflt(dp->d_sbsize, "sb", SBLOCKSIZE); 160 1.13 scottr strcpy(psize, "px"); /* XXX: strcpy is safe */ 161 1.13 scottr strcpy(pbsize, "bx"); /* XXX: strcpy is safe */ 162 1.13 scottr strcpy(pfsize, "fx"); /* XXX: strcpy is safe */ 163 1.13 scottr strcpy(poffset, "ox"); /* XXX: strcpy is safe */ 164 1.13 scottr strcpy(ptype, "tx"); /* XXX: strcpy is safe */ 165 1.1 cgd max = 'a' - 1; 166 1.1 cgd pp = &dp->d_partitions[0]; 167 1.1 cgd for (p = 'a'; p < 'a' + MAXPARTITIONS; p++, pp++) { 168 1.22 christos long ff; 169 1.11 cgd 170 1.1 cgd psize[1] = pbsize[1] = pfsize[1] = poffset[1] = ptype[1] = p; 171 1.22 christos if (cgetnum(buf, psize, &ff) == -1) 172 1.1 cgd pp->p_size = 0; 173 1.1 cgd else { 174 1.22 christos pp->p_size = (u_int32_t)ff; 175 1.11 cgd getnum(pp->p_offset, poffset); 176 1.1 cgd getnumdflt(pp->p_fsize, pfsize, 0); 177 1.7 cgd if (pp->p_fsize) { 178 1.7 cgd long bsize; 179 1.7 cgd 180 1.22 christos if (cgetnum(buf, pbsize, &bsize) == -1) 181 1.22 christos pp->p_frag = 8; 182 1.7 cgd else 183 1.22 christos pp->p_frag = 184 1.22 christos (u_int8_t)(bsize / pp->p_fsize); 185 1.7 cgd } 186 1.1 cgd getnumdflt(pp->p_fstype, ptype, 0); 187 1.34 christos if (pp->p_fstype == 0) 188 1.34 christos if (cgetstr(buf, ptype, &cq) >= 0) { 189 1.34 christos pp->p_fstype = gettype(cq, fstypenames); 190 1.34 christos free(cq); 191 1.34 christos } 192 1.1 cgd max = p; 193 1.1 cgd } 194 1.1 cgd } 195 1.1 cgd dp->d_npartitions = max + 1 - 'a'; 196 1.13 scottr strcpy(psize, "dx"); /* XXX: strcpy is safe */ 197 1.1 cgd dx = dp->d_drivedata; 198 1.1 cgd for (p = '0'; p < '0' + NDDATA; p++, dx++) { 199 1.1 cgd psize[1] = p; 200 1.1 cgd getnumdflt(*dx, psize, 0); 201 1.1 cgd } 202 1.1 cgd dp->d_magic = DISKMAGIC; 203 1.1 cgd dp->d_magic2 = DISKMAGIC; 204 1.7 cgd free(buf); 205 1.1 cgd return (dp); 206 1.1 cgd } 207 1.1 cgd 208 1.4 jtc static int 209 1.36 matt gettype(char *t, const char *const *names) 210 1.1 cgd { 211 1.20 mycroft const char *const *nm; 212 1.24 lukem 213 1.24 lukem _DIAGASSERT(t != NULL); 214 1.24 lukem _DIAGASSERT(names != NULL); 215 1.1 cgd 216 1.1 cgd for (nm = names; *nm; nm++) 217 1.1 cgd if (strcasecmp(t, *nm) == 0) 218 1.35 christos return (int)(nm - names); 219 1.27 itohy if (isdigit((unsigned char) *t)) 220 1.1 cgd return (atoi(t)); 221 1.1 cgd return (0); 222 1.1 cgd } 223 1.1 cgd 224 1.14 christos #if 0 225 1.4 jtc static void 226 1.1 cgd error(err) 227 1.1 cgd int err; 228 1.1 cgd { 229 1.1 cgd char *p; 230 1.1 cgd 231 1.1 cgd (void)write(STDERR_FILENO, "disktab: ", 9); 232 1.1 cgd (void)write(STDERR_FILENO, _PATH_DISKTAB, sizeof(_PATH_DISKTAB) - 1); 233 1.7 cgd (void)write(STDERR_FILENO, ": ", 2); 234 1.1 cgd p = strerror(err); 235 1.1 cgd (void)write(STDERR_FILENO, p, strlen(p)); 236 1.1 cgd (void)write(STDERR_FILENO, "\n", 1); 237 1.1 cgd } 238 1.14 christos #endif 239