Print this page
4846 HAL partition names don't match real partition names
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/hal/utils/fsutils.c
+++ new/usr/src/cmd/hal/utils/fsutils.c
1 1 /*
2 2 *
3 3 * fsutils.c : filesystem utilities
4 4 *
5 5 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
6 6 * Use is subject to license terms.
7 7 *
8 + * Copyright 2014 Andrew Stormont.
9 + *
8 10 * Licensed under the Academic Free License version 2.1
9 11 *
10 12 */
11 13
12 14 #ifdef HAVE_CONFIG_H
13 15 #include <config.h>
14 16 #endif
15 17
16 18 #include <stdio.h>
17 19 #include <sys/types.h>
18 20 #include <sys/scsi/impl/uscsi.h>
19 21 #include <string.h>
20 22 #include <strings.h>
21 23 #include <ctype.h>
22 24 #include <unistd.h>
23 25 #include <stdlib.h>
24 26 #include <errno.h>
25 27 #include <fcntl.h>
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
26 28 #include <sys/dkio.h>
27 29 #include <libintl.h>
28 30 #include <sys/dktp/fdisk.h>
29 31 #include <sys/fs/pc_label.h>
30 32
31 33 #include <libhal.h>
32 34 #include "fsutils.h"
33 35
34 36 /*
35 37 * Separates dos notation device spec into device and drive number
38 + * pN partition names are rewritten to point to p0
39 + * :N partition names are dropped
36 40 */
37 41 boolean_t
38 42 dos_to_dev(char *path, char **devpath, int *num)
39 43 {
40 - char *p;
44 + int i;
45 + char *buf;
46 + boolean_t found = B_FALSE;
41 47
42 - if ((p = strrchr(path, ':')) == NULL) {
43 - return (B_FALSE);
48 + for (i = strlen(path); i > 0; i--) {
49 + if (path[i] == 'p' || path[i] == ':') {
50 + found = B_TRUE;
51 + break;
52 + }
44 53 }
45 - if ((*num = atoi(p + 1)) == 0) {
54 +
55 + if (found == B_FALSE || (*num = atoi(path + i + 1)) == 0 ||
56 + (buf = strdup(path)) == NULL) {
46 57 return (B_FALSE);
47 58 }
48 - p[0] = '\0';
49 - *devpath = strdup(path);
50 - p[0] = ':';
51 - return (*devpath != NULL);
59 +
60 + (void) strcpy(buf + i, path[i] == 'p' ? "p0" : "");
61 + *devpath = buf;
62 + return (B_TRUE);
52 63 }
53 64
54 65 char *
55 66 get_slice_name(char *devlink)
56 67 {
57 68 char *part, *slice, *disk;
58 69 char *s = NULL;
59 70 char *p;
60 71
61 72 if ((p = strstr(devlink, "/lofi/")) != 0) {
62 73 return (p + sizeof ("/lofi/") - 1);
63 74 }
64 75
65 76 part = strrchr(devlink, 'p');
66 77 slice = strrchr(devlink, 's');
67 78 disk = strrchr(devlink, 'd');
68 79
69 80 if ((part != NULL) && (part > slice) && (part > disk)) {
70 81 s = part;
71 82 } else if ((slice != NULL) && (slice > disk)) {
72 83 s = slice;
73 84 } else {
74 85 s = disk;
75 86 }
76 87 if ((s != NULL) && isdigit(s[1])) {
77 88 return (s);
78 89 } else {
79 90 return ("");
80 91 }
81 92 }
82 93
83 94 boolean_t
84 95 is_dos_drive(uchar_t type)
85 96 {
86 97 return ((type == DOSOS12) || (type == DOSOS16) ||
87 98 (type == DOSHUGE) || (type == FDISK_WINDOWS) ||
88 99 (type == FDISK_EXT_WIN) || (type == FDISK_FAT95) ||
89 100 (type == DIAGPART));
90 101 }
91 102
92 103 boolean_t
93 104 is_dos_extended(uchar_t id)
94 105 {
95 106 return ((id == EXTDOS) || (id == FDISK_EXTLBA));
96 107 }
97 108
98 109 struct part_find_s {
99 110 int num;
100 111 int count;
101 112 int systid;
102 113 int r_systid;
103 114 uint_t r_relsect;
104 115 uint_t r_numsect;
105 116 };
106 117
107 118 enum { WALK_CONTINUE, WALK_TERMINATE };
108 119
109 120 /*
110 121 * Walk partition tables and invoke a callback for each.
111 122 */
112 123 static void
113 124 walk_partitions(int fd, int startsec, uint_t secsz,
114 125 int (*f)(void *, int, uint_t, uint_t), void *arg)
115 126 {
116 127 uint32_t buf[1024/4];
117 128 int bufsize = 1024;
118 129 struct mboot *mboot = (struct mboot *)&buf[0];
119 130 struct ipart ipart[FD_NUMPART];
120 131 uint_t sec = startsec;
121 132 uint_t lastsec = sec + 1;
122 133 uint_t relsect;
123 134 int ext = 0;
124 135 int systid;
125 136 boolean_t valid;
126 137 int i;
127 138
128 139 while (sec != lastsec) {
129 140 if (pread(fd, buf, bufsize, (off_t)sec * secsz) != bufsize) {
130 141 break;
131 142 }
132 143 lastsec = sec;
133 144 if (ltohs(mboot->signature) != MBB_MAGIC) {
134 145 break;
135 146 }
136 147 bcopy(mboot->parts, ipart, FD_NUMPART * sizeof (struct ipart));
137 148
138 149 for (i = 0; i < FD_NUMPART; i++) {
139 150 systid = ipart[i].systid;
140 151 relsect = sec + ltohi(ipart[i].relsect);
141 152 if (systid == 0) {
142 153 continue;
143 154 }
144 155 valid = B_TRUE;
145 156 if (is_dos_extended(systid) && (sec == lastsec)) {
146 157 sec = startsec + ltohi(ipart[i].relsect);
147 158 if (ext++ == 0) {
148 159 relsect = startsec = sec;
149 160 } else {
150 161 valid = B_FALSE;
151 162 }
152 163 }
153 164 if (valid && f(arg, ipart[i].systid, relsect,
154 165 ltohi(ipart[i].numsect)) == WALK_TERMINATE) {
155 166 return;
156 167 }
157 168 }
158 169 }
159 170 }
160 171
161 172 static int
162 173 find_dos_drive_cb(void *arg, int systid, uint_t relsect, uint_t numsect)
163 174 {
164 175 struct part_find_s *p = arg;
165 176
166 177 if (is_dos_drive(systid)) {
167 178 if (++p->count == p->num) {
168 179 p->r_relsect = relsect;
169 180 p->r_numsect = numsect;
170 181 p->r_systid = systid;
171 182 return (WALK_TERMINATE);
172 183 }
173 184 }
174 185
175 186 return (WALK_CONTINUE);
176 187 }
177 188
178 189 /*
179 190 * Given a dos drive number, return its relative sector number,
180 191 * number of sectors in partition and the system id.
181 192 */
182 193 boolean_t
183 194 find_dos_drive(int fd, int num, uint_t secsz, off_t *offset)
184 195 {
185 196 struct part_find_s p = { 0, 0, 0, 0, 0, 0 };
186 197
187 198 p.num = num;
188 199
189 200 if (num > 0) {
190 201 walk_partitions(fd, 0, secsz, find_dos_drive_cb, &p);
191 202 if (p.count == num) {
192 203 *offset = (off_t)p.r_relsect * secsz;
193 204 return (B_TRUE);
194 205 }
195 206 }
196 207
197 208 return (B_FALSE);
198 209 }
199 210
200 211 static int
201 212 get_num_dos_drives_cb(void *arg, int systid, uint_t relsect, uint_t numsect)
202 213 {
203 214 if (is_dos_drive(systid)) {
204 215 (*(int *)arg)++;
205 216 }
206 217 return (WALK_CONTINUE);
207 218 }
208 219
209 220 int
210 221 get_num_dos_drives(int fd, uint_t secsz)
211 222 {
212 223 int count = 0;
213 224
214 225 walk_partitions(fd, 0, secsz, get_num_dos_drives_cb, &count);
215 226
216 227 return (count);
217 228 }
218 229
219 230 /*
220 231 * Return true if all non-empty slices in vtoc have identical start/size and
221 232 * are tagged backup/entire disk.
222 233 */
223 234 boolean_t
224 235 vtoc_one_slice_entire_disk(struct extvtoc *vtoc)
225 236 {
226 237 int i;
227 238 struct extpartition *p;
228 239 diskaddr_t prev_start;
229 240 diskaddr_t prev_size;
230 241
231 242 for (i = 0; i < vtoc->v_nparts; i++) {
232 243 p = &vtoc->v_part[i];
233 244 if (p->p_size == 0) {
234 245 continue;
235 246 }
236 247 if ((p->p_tag != V_BACKUP) && ((p->p_tag != V_UNASSIGNED))) {
237 248 return (B_FALSE);
238 249 }
239 250 if ((i > 0) &&
240 251 ((p->p_start != prev_start) || (p->p_size != prev_size))) {
241 252 return (B_FALSE);
242 253 }
243 254 prev_start = p->p_start;
244 255 prev_size = p->p_size;
245 256 }
246 257
247 258 return (B_TRUE);
248 259 }
↓ open down ↓ |
187 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX