Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sbin/gpt - handle a GPT that isn't an exact multiple of a se...
details: https://anonhg.NetBSD.org/src/rev/cb44fade183e
branches: trunk
changeset: 332519:cb44fade183e
user: jnemeth <jnemeth%NetBSD.org@localhost>
date: Fri Sep 26 08:56:34 2014 +0000
description:
- handle a GPT that isn't an exact multiple of a sector
- adjust PMBR size, in case new disk is a different size
- don't leak as much memory
- clean up error handling somewhat
diffstat:
sbin/gpt/restore.c | 107 +++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 79 insertions(+), 28 deletions(-)
diffs (180 lines):
diff -r fde3108128c3 -r cb44fade183e sbin/gpt/restore.c
--- a/sbin/gpt/restore.c Fri Sep 26 08:05:00 2014 +0000
+++ b/sbin/gpt/restore.c Fri Sep 26 08:56:34 2014 +0000
@@ -29,7 +29,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/create.c,v 1.11 2005/08/31 01:47:19 marcel Exp $");
#endif
#ifdef __RCSID
-__RCSID("$NetBSD: restore.c,v 1.2 2014/09/20 22:11:27 jnemeth Exp $");
+__RCSID("$NetBSD: restore.c,v 1.3 2014/09/26 08:56:34 jnemeth Exp $");
#endif
#include <sys/types.h>
@@ -101,13 +101,15 @@
warnx("%s: error: device contains a MBR", device_name);
return;
}
-
/* Nuke the MBR in our internal map. */
map->map_type = MAP_TYPE_UNUSED;
}
props = prop_dictionary_internalize_from_file("/dev/stdin");
- PROP_ERR(props);
+ if (props == NULL) {
+ warnx("error: unable to read/parse backup file");
+ return;
+ }
propnum = prop_dictionary_get(props, "sector_size");
PROP_ERR(propnum);
@@ -133,6 +135,10 @@
propnum = prop_dictionary_get(gpt_dict, "entries");
PROP_ERR(propnum);
entries = prop_number_integer_value(propnum);
+ gpt_size = entries * sizeof(struct gpt_ent) / secsz;
+ if (gpt_size * sizeof(struct gpt_ent) % secsz)
+ gpt_size++;
+
propstr = prop_dictionary_get(gpt_dict, "guid");
PROP_ERR(propstr);
s = prop_string_cstring_nocopy(propstr);
@@ -143,7 +149,6 @@
}
le_uuid_enc(&gpt_guid, &uuid);
- gpt_size = entries * sizeof(struct gpt_ent) / secsz;
firstdata = gpt_size + 2; /* PMBR and GPT header */
lastdata = last - gpt_size - 1; /* alt. GPT table and header */
@@ -187,12 +192,27 @@
warnx("not enough memory to create a sector buffer");
return;
}
- lseek(fd, 0LL, SEEK_SET);
- for (i = 0; i < firstdata; i++)
- write(fd, secbuf, secsz);
- lseek(fd, (lastdata + 1) * secsz, SEEK_SET);
- for (i = lastdata + 1; i <= last; i++)
- write(fd, secbuf, secsz);
+
+ if (lseek(fd, 0LL, SEEK_SET) == -1) {
+ warnx("%s: error: can't seek to beginning", device_name);
+ return;
+ }
+ for (i = 0; i < firstdata; i++) {
+ if (write(fd, secbuf, secsz) == -1) {
+ warnx("%s: error: can't write", device_name);
+ return;
+ }
+ }
+ if (lseek(fd, (lastdata + 1) * secsz, SEEK_SET) == -1) {
+ warnx("%s: error: can't seek to end", device_name);
+ return;
+ }
+ for (i = lastdata + 1; i <= last; i++) {
+ if (write(fd, secbuf, secsz) == -1) {
+ warnx("%s: error: can't write", device_name);
+ return;
+ }
+ }
mbr = (struct mbr *)secbuf;
type_dict = prop_dictionary_get(props, "MBR");
@@ -249,19 +269,35 @@
PROP_ERR(propnum);
mbr->mbr_part[i].part_start_hi =
htole16(prop_number_unsigned_integer_value(propnum));
- propnum = prop_dictionary_get(mbr_dict, "lba_size_low");
- PROP_ERR(propnum);
- mbr->mbr_part[i].part_size_lo =
- htole16(prop_number_unsigned_integer_value(propnum));
- propnum = prop_dictionary_get(mbr_dict, "lba_size_high");
- PROP_ERR(propnum);
- mbr->mbr_part[i].part_size_hi =
- htole16(prop_number_unsigned_integer_value(propnum));
+ /* adjust PMBR size to size of device */
+ if (mbr->mbr_part[i].part_typ == MBR_PTYPE_PMBR) {
+ if (last > 0xffffffff) {
+ mbr->mbr_part[0].part_size_lo = htole16(0xffff);
+ mbr->mbr_part[0].part_size_hi = htole16(0xffff);
+ } else {
+ mbr->mbr_part[0].part_size_lo = htole16(last);
+ mbr->mbr_part[0].part_size_hi =
+ htole16(last >> 16);
+ }
+ } else {
+ propnum = prop_dictionary_get(mbr_dict, "lba_size_low");
+ PROP_ERR(propnum);
+ mbr->mbr_part[i].part_size_lo =
+ htole16(prop_number_unsigned_integer_value(propnum));
+ propnum =
+ prop_dictionary_get(mbr_dict, "lba_size_high");
+ PROP_ERR(propnum);
+ mbr->mbr_part[i].part_size_hi =
+ htole16(prop_number_unsigned_integer_value(propnum));
+ }
}
prop_object_iterator_release(propiter);
mbr->mbr_sig = htole16(MBR_SIG);
- lseek(fd, 0LL, SEEK_SET);
- write(fd, mbr, secsz);
+ if (lseek(fd, 0LL, SEEK_SET) == -1 ||
+ write(fd, mbr, secsz) == -1) {
+ warnx("%s: error: unable to write MBR", device_name);
+ return;
+ }
propiter = prop_array_iterator(gpt_array);
PROP_ERR(propiter);
@@ -309,10 +345,16 @@
sizeof(ent));
}
prop_object_iterator_release(propiter);
- lseek(fd, 2 * secsz, SEEK_SET);
- write(fd, (char *)secbuf + 1 * secsz, gpt_size * secsz);
- lseek(fd, (lastdata + 1) * secsz, SEEK_SET);
- write(fd, (char *)secbuf + 1 * secsz, gpt_size * secsz);
+ if (lseek(fd, 2 * secsz, SEEK_SET) == -1 ||
+ write(fd, (char *)secbuf + 1 * secsz, gpt_size * secsz) == -1) {
+ warnx("%s: error: unable to write primary GPT", device_name);
+ return;
+ }
+ if (lseek(fd, (lastdata + 1) * secsz, SEEK_SET) == -1 ||
+ write(fd, (char *)secbuf + 1 * secsz, gpt_size * secsz) == -1) {
+ warnx("%s: error: unable to write secondary GPT", device_name);
+ return;
+ }
memset(secbuf, 0, secsz);
hdr = (struct gpt_hdr *)secbuf;
@@ -330,16 +372,25 @@
hdr->hdr_crc_table =
htole32(crc32((char *)secbuf + 1 * secsz, gpt_size * secsz));
hdr->hdr_crc_self = htole32(crc32(hdr, GPT_HDR_SIZE));
- lseek(fd, 1 * secsz, SEEK_SET);
- write(fd, hdr, secsz);
+ if (lseek(fd, 1 * secsz, SEEK_SET) == -1 ||
+ write(fd, hdr, secsz) == -1) {
+ warnx("%s: error: unable to write primary header", device_name);
+ return;
+ }
+
hdr->hdr_lba_self = htole64(last);
hdr->hdr_lba_alt = htole64(GPT_HDR_BLKNO);
hdr->hdr_lba_table = htole64(lastdata + 1);
hdr->hdr_crc_self = 0;
hdr->hdr_crc_self = htole32(crc32(hdr, GPT_HDR_SIZE));
- lseek(fd, last * secsz, SEEK_SET);
- write(fd, hdr, secsz);
+ if (lseek(fd, last * secsz, SEEK_SET) == -1 ||
+ write(fd, hdr, secsz) == -1) {
+ warnx("%s: error: unable to write secondary header",
+ device_name);
+ return;
+ }
+ prop_object_release(props);
return;
}
Home |
Main Index |
Thread Index |
Old Index