Deleted Added
full compact
gpt.c (263537) gpt.c (263653)
1/*-
2 * Copyright (c) 2014 Juniper Networks, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2014 Juniper Networks, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: user/marcel/mkimg/gpt.c 263537 2014-03-21 19:40:05Z marcel $");
28__FBSDID("$FreeBSD: user/marcel/mkimg/gpt.c 263653 2014-03-23 01:10:05Z marcel $");
29
30#include <sys/types.h>
31#include <sys/diskmbr.h>
32#include <sys/endian.h>
33#include <sys/errno.h>
34#include <sys/gpt.h>
35#include <stddef.h>
36#include <stdint.h>

--- 82 unchanged lines hidden (view full) ---

119 uint32_t crc = ~0U;
120
121 while (sz--)
122 crc = crc32_tab[(crc ^ *p++) & 0xff] ^ (crc >> 8);
123 return (crc ^ ~0U);
124}
125
126static u_int
29
30#include <sys/types.h>
31#include <sys/diskmbr.h>
32#include <sys/endian.h>
33#include <sys/errno.h>
34#include <sys/gpt.h>
35#include <stddef.h>
36#include <stdint.h>

--- 82 unchanged lines hidden (view full) ---

119 uint32_t crc = ~0U;
120
121 while (sz--)
122 crc = crc32_tab[(crc ^ *p++) & 0xff] ^ (crc >> 8);
123 return (crc ^ ~0U);
124}
125
126static u_int
127gpt_tblsz(u_int parts, u_int secsz)
127gpt_tblsz()
128{
129 u_int ents;
130
131 ents = secsz / sizeof(struct gpt_ent);
128{
129 u_int ents;
130
131 ents = secsz / sizeof(struct gpt_ent);
132 return ((parts + ents - 1) / ents);
132 return ((nparts + ents - 1) / ents);
133}
134
135static u_int
133}
134
135static u_int
136gpt_metadata(u_int where, u_int parts, u_int secsz)
136gpt_metadata(u_int where)
137{
138 u_int secs;
139
140 if (where != SCHEME_META_IMG_START && where != SCHEME_META_IMG_END)
141 return (0);
142
137{
138 u_int secs;
139
140 if (where != SCHEME_META_IMG_START && where != SCHEME_META_IMG_END)
141 return (0);
142
143 secs = gpt_tblsz(parts, secsz);
143 secs = gpt_tblsz();
144 secs += (where == SCHEME_META_IMG_START) ? 2 : 1;
145 return (secs);
146}
147
148static int
144 secs += (where == SCHEME_META_IMG_START) ? 2 : 1;
145 return (secs);
146}
147
148static int
149gpt_filewrite(int fd, off_t ofs, void *buf, ssize_t bufsz)
149gpt_filewrite(int fd, lba_t blk, void *buf, ssize_t bufsz)
150{
150{
151 int error;
151
152
152 if (lseek(fd, ofs, SEEK_SET) != ofs)
153 return (errno);
154 if (write(fd, buf, bufsz) != bufsz)
155 return (errno);
156 return (0);
153 error = mkimg_seek(fd, blk);
154 if (error == 0) {
155 if (write(fd, buf, bufsz) != bufsz)
156 error = errno;
157 }
158 return (error);
157}
158
159static int
159}
160
161static int
160gpt_write_pmbr(int fd, off_t nblocks, u_int secsz, void *bootcode)
162gpt_write_pmbr(int fd, lba_t blks, void *bootcode)
161{
162 u_char *pmbr;
163 uint32_t secs;
164 int error;
165
163{
164 u_char *pmbr;
165 uint32_t secs;
166 int error;
167
166 secs = (nblocks > UINT32_MAX) ? UINT32_MAX : nblocks;
168 secs = (blks > UINT32_MAX) ? UINT32_MAX : (uint32_t)blks;
167
168 pmbr = malloc(secsz);
169 if (pmbr == NULL)
170 return (errno);
171 if (bootcode != NULL) {
172 memcpy(pmbr, bootcode, DOSPARTOFF);
173 memset(pmbr + DOSPARTOFF, 0, secsz - DOSPARTOFF);
174 } else

--- 7 unchanged lines hidden (view full) ---

182 le32enc(pmbr + DOSPARTOFF + 12, secs);
183 le16enc(pmbr + DOSMAGICOFFSET, DOSMAGIC);
184 error = gpt_filewrite(fd, 0, pmbr, secsz);
185 free(pmbr);
186 return (error);
187}
188
189static struct gpt_ent *
169
170 pmbr = malloc(secsz);
171 if (pmbr == NULL)
172 return (errno);
173 if (bootcode != NULL) {
174 memcpy(pmbr, bootcode, DOSPARTOFF);
175 memset(pmbr + DOSPARTOFF, 0, secsz - DOSPARTOFF);
176 } else

--- 7 unchanged lines hidden (view full) ---

184 le32enc(pmbr + DOSPARTOFF + 12, secs);
185 le16enc(pmbr + DOSMAGICOFFSET, DOSMAGIC);
186 error = gpt_filewrite(fd, 0, pmbr, secsz);
187 free(pmbr);
188 return (error);
189}
190
191static struct gpt_ent *
190gpt_mktbl(u_int tblsz, u_int secsz)
192gpt_mktbl(u_int tblsz)
191{
192 uuid_t uuid;
193 struct gpt_ent *tbl, *ent;
194 struct part *part;
193{
194 uuid_t uuid;
195 struct gpt_ent *tbl, *ent;
196 struct part *part;
195 uint64_t limit;
196 int c, idx;
197
198 tbl = calloc(tblsz, secsz);
199 if (tbl == NULL)
200 return (NULL);
201
202 STAILQ_FOREACH(part, &partlist, link) {
203 ent = tbl + part->index;
204 uuid_enc_le(&ent->ent_type, ALIAS_TYPE2PTR(part->type));
205 uuidgen(&uuid, 1);
206 uuid_enc_le(&ent->ent_uuid, &uuid);
197 int c, idx;
198
199 tbl = calloc(tblsz, secsz);
200 if (tbl == NULL)
201 return (NULL);
202
203 STAILQ_FOREACH(part, &partlist, link) {
204 ent = tbl + part->index;
205 uuid_enc_le(&ent->ent_type, ALIAS_TYPE2PTR(part->type));
206 uuidgen(&uuid, 1);
207 uuid_enc_le(&ent->ent_uuid, &uuid);
207 le64enc(&ent->ent_lba_start, part->offset / secsz);
208 limit = (part->offset + part->size) / secsz;
209 le64enc(&ent->ent_lba_end, limit - 1);
208 le64enc(&ent->ent_lba_start, part->block);
209 le64enc(&ent->ent_lba_end, part->block + part->size - 1);
210 if (part->label != NULL) {
211 idx = 0;
212 while ((c = part->label[idx]) != '\0') {
213 le16enc(ent->ent_name + idx, c);
214 idx++;
215 }
216 }
217 }
218 return (tbl);
219}
220
221static int
222gpt_write_hdr(int fd, struct gpt_hdr *hdr, uint64_t self, uint64_t alt,
210 if (part->label != NULL) {
211 idx = 0;
212 while ((c = part->label[idx]) != '\0') {
213 le16enc(ent->ent_name + idx, c);
214 idx++;
215 }
216 }
217 }
218 return (tbl);
219}
220
221static int
222gpt_write_hdr(int fd, struct gpt_hdr *hdr, uint64_t self, uint64_t alt,
223 uint64_t tbl, u_int secsz)
223 uint64_t tbl)
224{
225 uint32_t crc;
226
227 le64enc(&hdr->hdr_lba_self, self);
228 le64enc(&hdr->hdr_lba_alt, alt);
229 le64enc(&hdr->hdr_lba_table, tbl);
230 hdr->hdr_crc_self = 0;
231 crc = crc32(hdr, offsetof(struct gpt_hdr, padding));
232 le64enc(&hdr->hdr_crc_self, crc);
224{
225 uint32_t crc;
226
227 le64enc(&hdr->hdr_lba_self, self);
228 le64enc(&hdr->hdr_lba_alt, alt);
229 le64enc(&hdr->hdr_lba_table, tbl);
230 hdr->hdr_crc_self = 0;
231 crc = crc32(hdr, offsetof(struct gpt_hdr, padding));
232 le64enc(&hdr->hdr_crc_self, crc);
233 return (gpt_filewrite(fd, self * secsz, hdr, secsz));
233 return (gpt_filewrite(fd, self, hdr, secsz));
234}
235
236static int
234}
235
236static int
237gpt_write(int fd, off_t imgsz, u_int parts, u_int secsz, void *bootcode)
237gpt_write(int fd, lba_t imgsz, void *bootcode)
238{
239 uuid_t uuid;
240 struct gpt_ent *tbl;
241 struct gpt_hdr *hdr;
238{
239 uuid_t uuid;
240 struct gpt_ent *tbl;
241 struct gpt_hdr *hdr;
242 off_t nblocks;
243 uint32_t crc;
244 u_int tblsz;
245 int error;
246
242 uint32_t crc;
243 u_int tblsz;
244 int error;
245
247 nblocks = imgsz / secsz;
248
249 /* PMBR */
246 /* PMBR */
250 error = gpt_write_pmbr(fd, nblocks, secsz, bootcode);
247 error = gpt_write_pmbr(fd, imgsz, bootcode);
251 if (error)
252 return (error);
253
254 /* GPT table(s) */
248 if (error)
249 return (error);
250
251 /* GPT table(s) */
255 tblsz = gpt_tblsz(parts, secsz);
256 tbl = gpt_mktbl(tblsz, secsz);
252 tblsz = gpt_tblsz();
253 tbl = gpt_mktbl(tblsz);
257 if (tbl == NULL)
258 return (errno);
254 if (tbl == NULL)
255 return (errno);
259 error = gpt_filewrite(fd, 2 * secsz, tbl, tblsz * secsz);
256 error = gpt_filewrite(fd, 2, tbl, tblsz * secsz);
260 if (error)
261 goto out;
257 if (error)
258 goto out;
262 error = gpt_filewrite(fd, imgsz - (tblsz + 1) * secsz, tbl,
263 tblsz * secsz);
259 error = gpt_filewrite(fd, imgsz - (tblsz + 1), tbl, tblsz * secsz);
264 if (error)
265 goto out;
266
267 /* GPT header(s) */
268 hdr = malloc(secsz);
269 if (hdr == NULL) {
270 error = errno;
271 goto out;
272 }
273 memset(hdr, 0, secsz);
274 memcpy(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig));
275 le32enc(&hdr->hdr_revision, GPT_HDR_REVISION);
276 le32enc(&hdr->hdr_size, offsetof(struct gpt_hdr, padding));
277 le64enc(&hdr->hdr_lba_start, 2 + tblsz);
260 if (error)
261 goto out;
262
263 /* GPT header(s) */
264 hdr = malloc(secsz);
265 if (hdr == NULL) {
266 error = errno;
267 goto out;
268 }
269 memset(hdr, 0, secsz);
270 memcpy(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig));
271 le32enc(&hdr->hdr_revision, GPT_HDR_REVISION);
272 le32enc(&hdr->hdr_size, offsetof(struct gpt_hdr, padding));
273 le64enc(&hdr->hdr_lba_start, 2 + tblsz);
278 le64enc(&hdr->hdr_lba_end, nblocks - tblsz - 2);
274 le64enc(&hdr->hdr_lba_end, imgsz - tblsz - 2);
279 uuidgen(&uuid, 1);
280 uuid_enc_le(&hdr->hdr_uuid, &uuid);
275 uuidgen(&uuid, 1);
276 uuid_enc_le(&hdr->hdr_uuid, &uuid);
281 le32enc(&hdr->hdr_entries, parts);
277 le32enc(&hdr->hdr_entries, nparts);
282 le32enc(&hdr->hdr_entsz, sizeof(struct gpt_ent));
278 le32enc(&hdr->hdr_entsz, sizeof(struct gpt_ent));
283 crc = crc32(tbl, parts * sizeof(struct gpt_ent));
279 crc = crc32(tbl, nparts * sizeof(struct gpt_ent));
284 le32enc(&hdr->hdr_crc_table, crc);
280 le32enc(&hdr->hdr_crc_table, crc);
285 error = gpt_write_hdr(fd, hdr, 1, nblocks - 1, 2, secsz);
281 error = gpt_write_hdr(fd, hdr, 1, imgsz - 1, 2);
286 if (!error)
282 if (!error)
287 error = gpt_write_hdr(fd, hdr, nblocks - 1, 1,
288 nblocks - tblsz - 1, secsz);
283 error = gpt_write_hdr(fd, hdr, imgsz - 1, 1, imgsz - tblsz - 1);
289 free(hdr);
290
291 out:
292 free(tbl);
293 return (error);
294}
295
296static struct mkimg_scheme gpt_scheme = {
297 .name = "gpt",
298 .description = "GUID Partition Table",
299 .aliases = gpt_aliases,
300 .metadata = gpt_metadata,
301 .write = gpt_write,
302 .nparts = 4096,
303 .labellen = 36,
304 .bootcode = 512
305};
306
307SCHEME_DEFINE(gpt_scheme);
284 free(hdr);
285
286 out:
287 free(tbl);
288 return (error);
289}
290
291static struct mkimg_scheme gpt_scheme = {
292 .name = "gpt",
293 .description = "GUID Partition Table",
294 .aliases = gpt_aliases,
295 .metadata = gpt_metadata,
296 .write = gpt_write,
297 .nparts = 4096,
298 .labellen = 36,
299 .bootcode = 512
300};
301
302SCHEME_DEFINE(gpt_scheme);