summaryrefslogtreecommitdiff
path: root/sys/src/cmd/disk
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-06-03 23:19:13 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2015-06-03 23:19:13 +0200
commit137a762eca0389d91a14f830cb1e29b1d483a112 (patch)
tree881ce22ee2dc50c3b8e63199013c01c2fa56eb94 /sys/src/cmd/disk
parent1a1863e5dc8913e47b16e44499a3cc735aead394 (diff)
disk/edisk: fix blank mode
there where two problems with blank (-b flag): we did not update the backup header when there was already a valid backup header in place. we always want to initialize a new backup header in blank mode! we now also check the backup header matches the primary (or the other way arround depending on which header could be read), reporting any mismatches and restoring the backup from the data of the primary. the protective mbr needs to start at sector 1 not 0 (apparently, this matters for ovmf).
Diffstat (limited to 'sys/src/cmd/disk')
-rw-r--r--sys/src/cmd/disk/prep/edisk.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/sys/src/cmd/disk/prep/edisk.c b/sys/src/cmd/disk/prep/edisk.c
index d8edc846a..cd2800815 100644
--- a/sys/src/cmd/disk/prep/edisk.c
+++ b/sys/src/cmd/disk/prep/edisk.c
@@ -610,6 +610,33 @@ readtab(Edit *edit, Header *hdr)
return 0;
}
+static char*
+checkhdr(Header *a, Header *b)
+{
+ if(memcmp(a->sig, b->sig, sizeof(a->sig)) != 0)
+ return "signature";
+ if(memcmp(a->rev, b->rev, sizeof(a->rev)) != 0)
+ return "revision";
+ if(memcmp(a->hdrsiz, b->hdrsiz, sizeof(a->hdrsiz)) != 0)
+ return "header size";
+ if(memcmp(a->selflba, b->backlba, sizeof(a->selflba)) != 0
+ || memcmp(a->backlba, b->selflba, sizeof(a->backlba)) != 0)
+ return "backup lba/self lba";
+ if(memcmp(a->firstlba, b->firstlba, sizeof(a->firstlba)) != 0)
+ return "first lba";
+ if(memcmp(a->lastlba, b->lastlba, sizeof(a->lastlba)) != 0)
+ return "last lba";
+ if(memcmp(a->devid, b->devid, sizeof(a->devid)) != 0)
+ return "device guid";
+ if(memcmp(a->entrycount, b->entrycount, sizeof(a->entrycount)) != 0)
+ return "entry count";
+ if(memcmp(a->entrysize, b->entrysize, sizeof(a->entrysize)) != 0)
+ return "entry size";
+ if(memcmp(a->tabcrc, b->tabcrc, sizeof(a->tabcrc)) != 0)
+ return "table checksum";
+ return nil;
+}
+
static Header*
getbakhdr(Edit *edit, Header *bhdr)
{
@@ -619,9 +646,17 @@ getbakhdr(Edit *edit, Header *bhdr)
siz = getle32(bhdr->hdrsiz);
lba = getle64(bhdr->backlba);
- hdr = readhdr(edit->disk, lba);
- if(hdr != nil)
- return hdr;
+
+ if(!blank){
+ char *mismatch;
+
+ mismatch = "data";
+ hdr = readhdr(edit->disk, lba);
+ if(hdr != nil && (mismatch = checkhdr(bhdr, hdr)) == nil)
+ return hdr;
+ fprint(2, "backup header at lba %lld has mismatching %s, restoring.\n",
+ lba, mismatch);
+ }
hdr = getblock(edit->disk, lba);
memmove(hdr, bhdr, siz);
@@ -756,13 +791,13 @@ initmbr(Disk *disk)
t->type = 0xEE;
t->active = 0;
- size = disk->secs > 0xFFFFFFFF ? 0xFFFFFFFF : disk->secs;
- putle32(t->lba, 0);
+ size = (disk->secs - 1) > 0xFFFFFFFF ? 0xFFFFFFFF : (disk->secs - 1);
+ putle32(t->lba, 1);
putle32(t->size, size);
t->starth = 0;
t->startc = 0;
- t->starts = 0;
+ t->starts = 1;
t->endh = disk->h-1;
t->ends = (disk->s & 0x3F) | (((disk->c-1)>>2) & 0xC0);
t->endc = disk->c-1;