| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: gpt.c,v 1.6.2.1 2019/08/05 04:34:54 msaitoh Exp $ */ | | 1 | /* $NetBSD: gpt.c,v 1.6.2.2 2019/08/05 04:37:44 msaitoh Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright 2018 The NetBSD Foundation, Inc. | | 4 | * Copyright 2018 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -218,31 +218,54 @@ gpt_add_info(struct gpt_part_entry *part | | | @@ -218,31 +218,54 @@ gpt_add_info(struct gpt_part_entry *part |
218 | | | 218 | |
219 | while ((n = strsep(&val, ", ")) != NULL) { | | 219 | while ((n = strsep(&val, ", ")) != NULL) { |
220 | if (*n == 0) | | 220 | if (*n == 0) |
221 | continue; | | 221 | continue; |
222 | for (const struct gpt_attr_desc *p = gpt_avail_attrs; | | 222 | for (const struct gpt_attr_desc *p = gpt_avail_attrs; |
223 | p->name != NULL; p++) { | | 223 | p->name != NULL; p++) { |
224 | if (strcmp(p->name, n) == 0) | | 224 | if (strcmp(p->name, n) == 0) |
225 | part->gp_attr |= p->flag; | | 225 | part->gp_attr |= p->flag; |
226 | } | | 226 | } |
227 | } | | 227 | } |
228 | } | | 228 | } |
229 | } | | 229 | } |
230 | | | 230 | |
| | | 231 | /* |
| | | 232 | * Find the partition matching this wedge info and record that we |
| | | 233 | * have a wedge already. |
| | | 234 | */ |
| | | 235 | static void |
| | | 236 | update_part_from_wedge_info(struct gpt_disk_partitions *parts, |
| | | 237 | const struct dkwedge_info *dkw) |
| | | 238 | { |
| | | 239 | for (struct gpt_part_entry *p = parts->partitions; p != NULL; |
| | | 240 | p = p->gp_next) { |
| | | 241 | if (p->gp_start != dkw->dkw_offset || |
| | | 242 | (uint64_t)p->gp_size != dkw->dkw_size) |
| | | 243 | continue; |
| | | 244 | p->gp_flags |= GPEF_WEDGE; |
| | | 245 | strlcpy(p->gp_dev_name, dkw->dkw_devname, |
| | | 246 | sizeof p->gp_dev_name); |
| | | 247 | return; |
| | | 248 | } |
| | | 249 | } |
| | | 250 | |
231 | static struct disk_partitions * | | 251 | static struct disk_partitions * |
232 | gpt_read_from_disk(const char *dev, daddr_t start, daddr_t len) | | 252 | gpt_read_from_disk(const char *dev, daddr_t start, daddr_t len) |
233 | { | | 253 | { |
234 | char diskpath[MAXPATHLEN]; | | 254 | char diskpath[MAXPATHLEN]; |
235 | int fd; | | 255 | int fd; |
| | | 256 | struct dkwedge_info *dkw; |
| | | 257 | struct dkwedge_list dkwl; |
| | | 258 | size_t bufsize, dk; |
236 | | | 259 | |
237 | assert(start == 0); | | 260 | assert(start == 0); |
238 | assert(have_gpt); | | 261 | assert(have_gpt); |
239 | | | 262 | |
240 | if (run_program(RUN_SILENT | RUN_ERROR_OK, | | 263 | if (run_program(RUN_SILENT | RUN_ERROR_OK, |
241 | "gpt -rq header %s", dev) != 0) | | 264 | "gpt -rq header %s", dev) != 0) |
242 | return NULL; | | 265 | return NULL; |
243 | | | 266 | |
244 | /* read the partitions */ | | 267 | /* read the partitions */ |
245 | int i; | | 268 | int i; |
246 | unsigned int p_index; | | 269 | unsigned int p_index; |
247 | daddr_t p_start = 0, p_size = 0, avail_start = 0, avail_size = 0, | | 270 | daddr_t p_start = 0, p_size = 0, avail_start = 0, avail_size = 0, |
248 | disk_size = 0; | | 271 | disk_size = 0; |
| @@ -374,26 +397,46 @@ gpt_read_from_disk(const char *dev, dadd | | | @@ -374,26 +397,46 @@ gpt_read_from_disk(const char *dev, dadd |
374 | p->fs_type = p->gp_type->default_fs_type; | | 397 | p->fs_type = p->gp_type->default_fs_type; |
375 | #ifdef DEFAULT_UFS2 | | 398 | #ifdef DEFAULT_UFS2 |
376 | fs_is_default = true; | | 399 | fs_is_default = true; |
377 | #endif | | 400 | #endif |
378 | } | | 401 | } |
379 | #ifdef DEFAULT_UFS2 | | 402 | #ifdef DEFAULT_UFS2 |
380 | if (fs_is_default && p->fs_type == FS_BSDFFS) | | 403 | if (fs_is_default && p->fs_type == FS_BSDFFS) |
381 | p->fs_sub_type = 2; | | 404 | p->fs_sub_type = 2; |
382 | #endif | | 405 | #endif |
383 | } | | 406 | } |
384 | | | 407 | |
385 | parts->dp.free_space -= p->gp_size; | | 408 | parts->dp.free_space -= p->gp_size; |
386 | } | | 409 | } |
| | | 410 | |
| | | 411 | /* |
| | | 412 | * Check if we have any (matching/auto-configured) wedges already |
| | | 413 | */ |
| | | 414 | dkw = NULL; |
| | | 415 | dkwl.dkwl_buf = dkw; |
| | | 416 | dkwl.dkwl_bufsize = 0; |
| | | 417 | if (ioctl(fd, DIOCLWEDGES, &dkwl) == 0) { |
| | | 418 | /* do not even try to deal with any races at this point */ |
| | | 419 | bufsize = dkwl.dkwl_nwedges * sizeof(*dkw); |
| | | 420 | dkw = malloc(bufsize); |
| | | 421 | dkwl.dkwl_buf = dkw; |
| | | 422 | dkwl.dkwl_bufsize = bufsize; |
| | | 423 | if (dkw != NULL && ioctl(fd, DIOCLWEDGES, &dkwl) == 0) { |
| | | 424 | for (dk = 0; dk < dkwl.dkwl_ncopied; dk++) |
| | | 425 | update_part_from_wedge_info(parts, &dkw[dk]); |
| | | 426 | } |
| | | 427 | free(dkw); |
| | | 428 | } |
| | | 429 | |
387 | close(fd); | | 430 | close(fd); |
388 | | | 431 | |
389 | return &parts->dp; | | 432 | return &parts->dp; |
390 | } | | 433 | } |
391 | | | 434 | |
392 | static struct disk_partitions * | | 435 | static struct disk_partitions * |
393 | gpt_create_new(const char *disk, daddr_t start, daddr_t len, daddr_t total, | | 436 | gpt_create_new(const char *disk, daddr_t start, daddr_t len, daddr_t total, |
394 | bool is_boot_drive) | | 437 | bool is_boot_drive) |
395 | { | | 438 | { |
396 | struct gpt_disk_partitions *parts; | | 439 | struct gpt_disk_partitions *parts; |
397 | | | 440 | |
398 | if (start != 0) { | | 441 | if (start != 0) { |
399 | assert(0); | | 442 | assert(0); |