Sun Nov 20 11:57:02 2022 UTC ()
Fix destroying and moving GPT header also for truncated/extended
images.


(mlelstv)
diff -r1.13 -r1.14 src/sbin/gpt/destroy.c
diff -r1.82 -r1.83 src/sbin/gpt/gpt.c
diff -r1.43 -r1.44 src/sbin/gpt/gpt.h
diff -r1.18 -r1.19 src/sbin/gpt/resizedisk.c

cvs diff -r1.13 -r1.14 src/sbin/gpt/destroy.c (expand / switch to unified diff)

--- src/sbin/gpt/destroy.c 2019/10/16 19:03:53 1.13
+++ src/sbin/gpt/destroy.c 2022/11/20 11:57:02 1.14
@@ -23,53 +23,53 @@ @@ -23,53 +23,53 @@
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27#if HAVE_NBTOOL_CONFIG_H 27#if HAVE_NBTOOL_CONFIG_H
28#include "nbtool_config.h" 28#include "nbtool_config.h"
29#endif 29#endif
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32#ifdef __FBSDID 32#ifdef __FBSDID
33__FBSDID("$FreeBSD: src/sbin/gpt/destroy.c,v 1.6 2005/08/31 01:47:19 marcel Exp $"); 33__FBSDID("$FreeBSD: src/sbin/gpt/destroy.c,v 1.6 2005/08/31 01:47:19 marcel Exp $");
34#endif 34#endif
35#ifdef __RCSID 35#ifdef __RCSID
36__RCSID("$NetBSD: destroy.c,v 1.13 2019/10/16 19:03:53 jnemeth Exp $"); 36__RCSID("$NetBSD: destroy.c,v 1.14 2022/11/20 11:57:02 mlelstv Exp $");
37#endif 37#endif
38 38
39#include <sys/types.h> 39#include <sys/types.h>
40 40
41#include <err.h> 41#include <err.h>
42#include <stddef.h> 42#include <stddef.h>
43#include <stdio.h> 43#include <stdio.h>
44#include <stdlib.h> 44#include <stdlib.h>
45#include <string.h> 45#include <string.h>
46#include <unistd.h> 46#include <unistd.h>
47 47
48#include "map.h" 48#include "map.h"
49#include "gpt.h" 49#include "gpt.h"
50#include "gpt_private.h" 50#include "gpt_private.h"
51 51
52static int cmd_destroy(gpt_t, int, char *[]); 52static int cmd_destroy(gpt_t, int, char *[]);
53 53
54static const char *destroyhelp[] = { 54static const char *destroyhelp[] = {
55 "[-r]", 55 "[-r]",
56}; 56};
57 57
58struct gpt_cmd c_destroy = { 58struct gpt_cmd c_destroy = {
59 "destroy", 59 "destroy",
60 cmd_destroy, 60 cmd_destroy,
61 destroyhelp, __arraycount(destroyhelp), 61 destroyhelp, __arraycount(destroyhelp),
62 GPT_SYNC, 62 GPT_OPTGPT | GPT_SYNC,
63}; 63};
64 64
65#define usage() gpt_usage(NULL, &c_destroy) 65#define usage() gpt_usage(NULL, &c_destroy)
66 66
67 67
68static int 68static int
69destroy(gpt_t gpt, int force, int recoverable) 69destroy(gpt_t gpt, int force, int recoverable)
70{ 70{
71 map_t pri_hdr, sec_hdr, pmbr; 71 map_t pri_hdr, sec_hdr, pmbr;
72 72
73 pri_hdr = map_find(gpt, MAP_TYPE_PRI_GPT_HDR); 73 pri_hdr = map_find(gpt, MAP_TYPE_PRI_GPT_HDR);
74 sec_hdr = map_find(gpt, MAP_TYPE_SEC_GPT_HDR); 74 sec_hdr = map_find(gpt, MAP_TYPE_SEC_GPT_HDR);
75 pmbr = map_find(gpt, MAP_TYPE_PMBR); 75 pmbr = map_find(gpt, MAP_TYPE_PMBR);

cvs diff -r1.82 -r1.83 src/sbin/gpt/gpt.c (expand / switch to unified diff)

--- src/sbin/gpt/gpt.c 2020/05/24 18:42:20 1.82
+++ src/sbin/gpt/gpt.c 2022/11/20 11:57:02 1.83
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * 25 *
26 * CRC32 code derived from work by Gary S. Brown. 26 * CRC32 code derived from work by Gary S. Brown.
27 */ 27 */
28 28
29#if HAVE_NBTOOL_CONFIG_H 29#if HAVE_NBTOOL_CONFIG_H
30#include "nbtool_config.h" 30#include "nbtool_config.h"
31#endif 31#endif
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34#ifdef __FBSDID 34#ifdef __FBSDID
35__FBSDID("$FreeBSD: src/sbin/gpt/gpt.c,v 1.16 2006/07/07 02:44:23 marcel Exp $"); 35__FBSDID("$FreeBSD: src/sbin/gpt/gpt.c,v 1.16 2006/07/07 02:44:23 marcel Exp $");
36#endif 36#endif
37#ifdef __RCSID 37#ifdef __RCSID
38__RCSID("$NetBSD: gpt.c,v 1.82 2020/05/24 18:42:20 jmcneill Exp $"); 38__RCSID("$NetBSD: gpt.c,v 1.83 2022/11/20 11:57:02 mlelstv Exp $");
39#endif 39#endif
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/types.h> 42#include <sys/types.h>
43#include <sys/stat.h> 43#include <sys/stat.h>
44#include <sys/ioctl.h> 44#include <sys/ioctl.h>
45#include <sys/bootblock.h> 45#include <sys/bootblock.h>
46 46
47#include <err.h> 47#include <err.h>
48#include <errno.h> 48#include <errno.h>
49#include <fcntl.h> 49#include <fcntl.h>
50#include <paths.h> 50#include <paths.h>
51#include <stddef.h> 51#include <stddef.h>
@@ -564,28 +564,45 @@ gpt_open(const char *dev, int flags, int @@ -564,28 +564,45 @@ gpt_open(const char *dev, int flags, int
564 if (gpt->verbose) { 564 if (gpt->verbose) {
565 gpt_msg(gpt, "mediasize=%ju; sectorsize=%u; blocks=%ju", 565 gpt_msg(gpt, "mediasize=%ju; sectorsize=%u; blocks=%ju",
566 (uintmax_t)gpt->mediasz, gpt->secsz, (uintmax_t)devsz); 566 (uintmax_t)gpt->mediasz, gpt->secsz, (uintmax_t)devsz);
567 } 567 }
568 568
569 if (map_init(gpt, devsz) == -1) 569 if (map_init(gpt, devsz) == -1)
570 goto close; 570 goto close;
571 571
572 index = 1; 572 index = 1;
573 if (gpt_mbr(gpt, 0LL, &index, 0U) == -1) 573 if (gpt_mbr(gpt, 0LL, &index, 0U) == -1)
574 goto close; 574 goto close;
575 if ((found = gpt_gpt(gpt, 1LL, 1)) == -1) 575 if ((found = gpt_gpt(gpt, 1LL, 1)) == -1)
576 goto close; 576 goto close;
577 if (gpt_gpt(gpt, devsz - 1LL, found) == -1) 577
578 goto close; 578 if (found) {
 579 struct map *map;
 580 struct gpt_hdr *hdr;
 581
 582 /*
 583 * read secondary GPT from position stored in primary header
 584 * when possible
 585 */
 586 map = map_find(gpt, MAP_TYPE_PRI_GPT_HDR);
 587 hdr = map ? map->map_data : NULL;
 588 if (hdr && hdr->hdr_lba_alt > 0 && hdr->hdr_lba_alt < (uint64_t)devsz) {
 589 if (gpt_gpt(gpt, (off_t)hdr->hdr_lba_alt, found) == -1)
 590 goto close;
 591 }
 592 } else {
 593 if (gpt_gpt(gpt, devsz - 1LL, found) == -1)
 594 goto close;
 595 }
579 596
580 return gpt; 597 return gpt;
581 598
582 close: 599 close:
583 if (gpt->fd != -1) 600 if (gpt->fd != -1)
584 close(gpt->fd); 601 close(gpt->fd);
585 free(gpt); 602 free(gpt);
586 return NULL; 603 return NULL;
587} 604}
588 605
589void 606void
590gpt_close(gpt_t gpt) 607gpt_close(gpt_t gpt)
591{ 608{

cvs diff -r1.43 -r1.44 src/sbin/gpt/gpt.h (expand / switch to unified diff)

--- src/sbin/gpt/gpt.h 2022/07/16 12:57:14 1.43
+++ src/sbin/gpt/gpt.h 2022/11/20 11:57:02 1.44
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: gpt.h,v 1.43 2022/07/16 12:57:14 mlelstv Exp $ */ 1/* $NetBSD: gpt.h,v 1.44 2022/11/20 11:57:02 mlelstv Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2002 Marcel Moolenaar 4 * Copyright (c) 2002 Marcel Moolenaar
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 * 10 *
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -75,26 +75,27 @@ struct gpt_cmd { @@ -75,26 +75,27 @@ struct gpt_cmd {
75 75
76uint32_t crc32(const void *, size_t); 76uint32_t crc32(const void *, size_t);
77void gpt_close(gpt_t); 77void gpt_close(gpt_t);
78int gpt_gpt(gpt_t, off_t, int); 78int gpt_gpt(gpt_t, off_t, int);
79gpt_t gpt_open(const char *, int, int, off_t, u_int, time_t); 79gpt_t gpt_open(const char *, int, int, off_t, u_int, time_t);
80#define GPT_READONLY 0x01 80#define GPT_READONLY 0x01
81#define GPT_MODIFIED 0x02 81#define GPT_MODIFIED 0x02
82#define GPT_QUIET 0x04 82#define GPT_QUIET 0x04
83#define GPT_NOSYNC 0x08 83#define GPT_NOSYNC 0x08
84#define GPT_FILE 0x10 84#define GPT_FILE 0x10
85#define GPT_TIMESTAMP 0x20 85#define GPT_TIMESTAMP 0x20
86#define GPT_SYNC 0x40 86#define GPT_SYNC 0x40
87#define GPT_HYBRID 0x80 87#define GPT_HYBRID 0x80
 88#define GPT_OPTGPT 0x4000
88#define GPT_OPTDEV 0x8000 89#define GPT_OPTDEV 0x8000
89 90
90void* gpt_read(gpt_t, off_t, size_t); 91void* gpt_read(gpt_t, off_t, size_t);
91off_t gpt_last(gpt_t); 92off_t gpt_last(gpt_t);
92off_t gpt_create(gpt_t, off_t, u_int, int); 93off_t gpt_create(gpt_t, off_t, u_int, int);
93int gpt_write(gpt_t, map_t); 94int gpt_write(gpt_t, map_t);
94int gpt_write_crc(gpt_t, map_t, map_t); 95int gpt_write_crc(gpt_t, map_t, map_t);
95int gpt_write_primary(gpt_t); 96int gpt_write_primary(gpt_t);
96int gpt_write_backup(gpt_t); 97int gpt_write_backup(gpt_t);
97struct gpt_hdr *gpt_hdr(gpt_t); 98struct gpt_hdr *gpt_hdr(gpt_t);
98void gpt_msg(gpt_t, const char *, ...) __printflike(2, 3); 99void gpt_msg(gpt_t, const char *, ...) __printflike(2, 3);
99void gpt_warn(gpt_t, const char *, ...) __printflike(2, 3); 100void gpt_warn(gpt_t, const char *, ...) __printflike(2, 3);
100void gpt_warnx(gpt_t, const char *, ...) __printflike(2, 3); 101void gpt_warnx(gpt_t, const char *, ...) __printflike(2, 3);

cvs diff -r1.18 -r1.19 src/sbin/gpt/resizedisk.c (expand / switch to unified diff)

--- src/sbin/gpt/resizedisk.c 2020/05/24 14:42:44 1.18
+++ src/sbin/gpt/resizedisk.c 2022/11/20 11:57:02 1.19
@@ -23,27 +23,27 @@ @@ -23,27 +23,27 @@
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27#if HAVE_NBTOOL_CONFIG_H 27#if HAVE_NBTOOL_CONFIG_H
28#include "nbtool_config.h" 28#include "nbtool_config.h"
29#endif 29#endif
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32#ifdef __FBSDID 32#ifdef __FBSDID
33__FBSDID("$FreeBSD: src/sbin/gpt/add.c,v 1.14 2006/06/22 22:05:28 marcel Exp $"); 33__FBSDID("$FreeBSD: src/sbin/gpt/add.c,v 1.14 2006/06/22 22:05:28 marcel Exp $");
34#endif 34#endif
35#ifdef __RCSID 35#ifdef __RCSID
36__RCSID("$NetBSD: resizedisk.c,v 1.18 2020/05/24 14:42:44 jmcneill Exp $"); 36__RCSID("$NetBSD: resizedisk.c,v 1.19 2022/11/20 11:57:02 mlelstv Exp $");
37#endif 37#endif
38 38
39#include <sys/bootblock.h> 39#include <sys/bootblock.h>
40#include <sys/types.h> 40#include <sys/types.h>
41 41
42#include <err.h> 42#include <err.h>
43#include <stdbool.h> 43#include <stdbool.h>
44#include <stddef.h> 44#include <stddef.h>
45#include <stdio.h> 45#include <stdio.h>
46#include <stdlib.h> 46#include <stdlib.h>
47#include <string.h> 47#include <string.h>
48#include <unistd.h> 48#include <unistd.h>
49 49
@@ -52,27 +52,27 @@ __RCSID("$NetBSD: resizedisk.c,v 1.18 20 @@ -52,27 +52,27 @@ __RCSID("$NetBSD: resizedisk.c,v 1.18 20
52#include "gpt_private.h" 52#include "gpt_private.h"
53 53
54 54
55static int cmd_resizedisk(gpt_t, int, char *[]); 55static int cmd_resizedisk(gpt_t, int, char *[]);
56 56
57static const char *resizediskhelp[] = { 57static const char *resizediskhelp[] = {
58 "[-s size] [-q]", 58 "[-s size] [-q]",
59}; 59};
60 60
61struct gpt_cmd c_resizedisk = { 61struct gpt_cmd c_resizedisk = {
62 "resizedisk", 62 "resizedisk",
63 cmd_resizedisk, 63 cmd_resizedisk,
64 resizediskhelp, __arraycount(resizediskhelp), 64 resizediskhelp, __arraycount(resizediskhelp),
65 0, 65 GPT_OPTGPT,
66}; 66};
67 67
68#define usage() gpt_usage(NULL, &c_resizedisk) 68#define usage() gpt_usage(NULL, &c_resizedisk)
69 69
70/* 70/*
71 * relocate the secondary GPT based on the following criteria: 71 * relocate the secondary GPT based on the following criteria:
72 * - size not specified 72 * - size not specified
73 * - disk has not changed size, do nothing 73 * - disk has not changed size, do nothing
74 * - disk has grown, relocate secondary 74 * - disk has grown, relocate secondary
75 * - disk has shrunk, create new secondary 75 * - disk has shrunk, create new secondary
76 * - size specified 76 * - size specified
77 * - size is larger then disk or same as current location, do nothing 77 * - size is larger then disk or same as current location, do nothing
78 * - relocate or create new secondary 78 * - relocate or create new secondary
@@ -113,57 +113,42 @@ resizedisk(gpt_t gpt, off_t sector, off_ @@ -113,57 +113,42 @@ resizedisk(gpt_t gpt, off_t sector, off_
113 } 113 }
114 114
115 gpt->tbl = map_find(gpt, MAP_TYPE_PRI_GPT_TBL); 115 gpt->tbl = map_find(gpt, MAP_TYPE_PRI_GPT_TBL);
116 if (gpt->tbl == NULL) { 116 if (gpt->tbl == NULL) {
117 gpt_warnx(gpt, "No primary GPT table; Run recover"); 117 gpt_warnx(gpt, "No primary GPT table; Run recover");
118 return -1; 118 return -1;
119 } 119 }
120 120
121 hdr = gpt->gpt->map_data; 121 hdr = gpt->gpt->map_data;
122 oldloc = (off_t)le64toh((uint64_t)hdr->hdr_lba_alt); 122 oldloc = (off_t)le64toh((uint64_t)hdr->hdr_lba_alt);
123 123
124 gpt->tpg = map_find(gpt, MAP_TYPE_SEC_GPT_HDR); 124 gpt->tpg = map_find(gpt, MAP_TYPE_SEC_GPT_HDR);
125 gpt->lbt = map_find(gpt, MAP_TYPE_SEC_GPT_TBL); 125 gpt->lbt = map_find(gpt, MAP_TYPE_SEC_GPT_TBL);
126 if (gpt->tpg == NULL || gpt->lbt == NULL) { 
127 if (gpt_gpt(gpt, oldloc, 1) == -1) { 
128 gpt_warnx(gpt, 
129 "Error reading backup GPT information at %#jx", 
130 oldloc); 
131 return -1; 
132 } 
133 } 
134 126
135 gpt->tpg = map_find(gpt, MAP_TYPE_SEC_GPT_HDR); 127 if (gpt->tpg == NULL || gpt->lbt == NULL)
136 if (gpt->tpg == NULL) { 128 gpt_warnx(gpt, "No secondary GPT table");
137 gpt_warnx(gpt, "No secondary GPT header; Run recover"); 
138 return -1; 
139 } 
140 gpt->lbt = map_find(gpt, MAP_TYPE_SEC_GPT_TBL); 
141 if (gpt->lbt == NULL) { 
142 gpt_warnx(gpt, "No secondary GPT table; Run recover"); 
143 return -1; 
144 } 
145 129
146 gpt_size = gpt->tbl->map_size; 130 gpt_size = gpt->tbl->map_size;
147 if (sector == oldloc) { 131 if (sector == oldloc) {
148 if (!quiet) 132 if (!quiet)
149 gpt_warnx(gpt, "Device is already the specified size"); 133 gpt_warnx(gpt, "Device is already the specified size");
150 return 0; 134 return 0;
151 } 135 }
152 136
153 if (sector == 0 && last == oldloc) { 137 if (sector == 0 && last == oldloc) {
154 if (!quiet) 138 if (!quiet)
155 gpt_warnx(gpt, "Device hasn't changed size"); 139 gpt_warnx(gpt, "Device hasn't changed size");
156 return 0; 140 if (gpt->tpg != NULL && gpt->lbt != NULL)
 141 return 0;
157 } 142 }
158 143
159 for (ent = gpt->tbl->map_data; ent < 144 for (ent = gpt->tbl->map_data; ent <
160 (struct gpt_ent *)((char *)gpt->tbl->map_data + 145 (struct gpt_ent *)((char *)gpt->tbl->map_data +
161 le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz)); ent++) { 146 le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz)); ent++) {
162 if (!gpt_uuid_is_nil(ent->ent_type) && 147 if (!gpt_uuid_is_nil(ent->ent_type) &&
163 ((off_t)le64toh(ent->ent_lba_end) > lastdata)) { 148 ((off_t)le64toh(ent->ent_lba_end) > lastdata)) {
164 lastdata = (off_t)le64toh((uint64_t)ent->ent_lba_end); 149 lastdata = (off_t)le64toh((uint64_t)ent->ent_lba_end);
165 } 150 }
166 } 151 }
167 152
168 if (sector - gpt_size <= lastdata) { 153 if (sector - gpt_size <= lastdata) {
169 gpt_warnx(gpt, "Not enough space at %" PRIu64 154 gpt_warnx(gpt, "Not enough space at %" PRIu64
@@ -173,38 +158,34 @@ resizedisk(gpt_t gpt, off_t sector, off_ @@ -173,38 +158,34 @@ resizedisk(gpt_t gpt, off_t sector, off_
173 158
174 if (last - gpt_size <= lastdata) { 159 if (last - gpt_size <= lastdata) {
175 gpt_warnx(gpt, "Not enough space for new secondary GPT table"); 160 gpt_warnx(gpt, "Not enough space for new secondary GPT table");
176 return -1; 161 return -1;
177 } 162 }
178 163
179 if (sector > oldloc) 164 if (sector > oldloc)
180 newloc = sector; 165 newloc = sector;
181 if (sector > 0 && sector < oldloc && last >= oldloc) 166 if (sector > 0 && sector < oldloc && last >= oldloc)
182 newloc = sector; 167 newloc = sector;
183 if (sector == 0 && last > oldloc) 168 if (sector == 0 && last > oldloc)
184 newloc = last; 169 newloc = last;
185 170
186 if (newloc > 0) { 171 if (newloc > 0 && gpt->tpg != NULL && gpt->lbt != NULL) {
187 if (gpt->tpg == NULL) { 172 if (!quiet)
188 gpt_warnx(gpt, "No secondary GPT header; run recover"); 173 gpt_msg(gpt, "Moving secondary GPT header");
189 return -1; 
190 } 
191 if (gpt->lbt == NULL) { 
192 gpt_warnx(gpt, "Run recover"); 
193 return -1; 
194 } 
195 gpt->tpg->map_start = newloc; 174 gpt->tpg->map_start = newloc;
196 gpt->lbt->map_start = newloc - gpt_size; 175 gpt->lbt->map_start = newloc - gpt_size;
197 } else { 176 } else {
 177 if (!quiet)
 178 gpt_msg(gpt, "Creating new secondary GPT header");
198 if (sector > 0) 179 if (sector > 0)
199 newloc = sector; 180 newloc = sector;
200 else 181 else
201 newloc = last; 182 newloc = last;
202 183
203 if (gpt_add_hdr(gpt, MAP_TYPE_SEC_GPT_HDR, newloc) == -1) 184 if (gpt_add_hdr(gpt, MAP_TYPE_SEC_GPT_HDR, newloc) == -1)
204 return -1; 185 return -1;
205 186
206 gpt->lbt = map_add(gpt, newloc - gpt_size, gpt_size, 187 gpt->lbt = map_add(gpt, newloc - gpt_size, gpt_size,
207 MAP_TYPE_SEC_GPT_TBL, gpt->tbl->map_data, 0); 188 MAP_TYPE_SEC_GPT_TBL, gpt->tbl->map_data, 0);
208 if (gpt->lbt == NULL) { 189 if (gpt->lbt == NULL) {
209 gpt_warn(gpt, "Error adding secondary GPT table"); 190 gpt_warn(gpt, "Error adding secondary GPT table");
210 return -1; 191 return -1;