Lines 312-317
Link Here
|
312 |
return (0); |
312 |
return (0); |
313 |
} |
313 |
} |
314 |
|
314 |
|
|
|
315 |
static uint64_t |
316 |
gpt_recover(struct dsk *dskp, struct gpt_hdr *hdr_prim, |
317 |
const struct gpt_hdr *hdr_back) |
318 |
{ |
319 |
printf("%s: trying to recover GPT...\n", BOOTPROG); |
320 |
const int head_prim_lba = 1; |
321 |
const int table_prim_lba = 2; |
322 |
|
323 |
/* Copy partition table backup -> primary */ |
324 |
int n_sect = DEV_BSIZE / hdr_back->hdr_entsz; |
325 |
n_sect = hdr_back->hdr_entries / n_sect; |
326 |
|
327 |
/* Copy sector by sector because no assumption is |
328 |
* made about n_sect value and secbuf size */ |
329 |
for (int i = 0; i < n_sect; i++) { |
330 |
if (drvread(dskp, secbuf, hdr_back->hdr_lba_table + i, 1)) |
331 |
goto recover_failed; |
332 |
if (drvwrite(dskp, secbuf, table_prim_lba + i, 1)) |
333 |
goto recover_failed; |
334 |
} |
335 |
|
336 |
/* Set GPT primary header with backup header */ |
337 |
*hdr_prim = *hdr_back; |
338 |
hdr_prim->hdr_crc_self = 0; |
339 |
hdr_prim->hdr_lba_self = head_prim_lba; |
340 |
hdr_prim->hdr_lba_alt = hdr_back->hdr_lba_self; |
341 |
hdr_prim->hdr_lba_table = table_prim_lba; |
342 |
hdr_prim->hdr_crc_self = crc32(hdr_prim, hdr_prim->hdr_size); |
343 |
bzero(secbuf, DEV_BSIZE); |
344 |
bcopy(hdr_prim, secbuf, hdr_prim->hdr_size); |
345 |
if (drvwrite(dskp, secbuf, hdr_prim->hdr_lba_self, 1)) |
346 |
goto recover_failed; |
347 |
|
348 |
printf("%s: GPT recovering -> SUCCESS\n", BOOTPROG); |
349 |
return (hdr_prim->hdr_lba_self); |
350 |
|
351 |
recover_failed: |
352 |
printf("%s: GPT recovering -> FAILED\n", BOOTPROG); |
353 |
return (0); |
354 |
} |
355 |
|
315 |
int |
356 |
int |
316 |
gptread(const uuid_t *uuid, struct dsk *dskp, char *buf) |
357 |
gptread(const uuid_t *uuid, struct dsk *dskp, char *buf) |
317 |
{ |
358 |
{ |
Lines 352-361
Link Here
|
352 |
gptread_table("backup", uuid, dskp, &hdr_backup, |
393 |
gptread_table("backup", uuid, dskp, &hdr_backup, |
353 |
table_backup) == 0) { |
394 |
table_backup) == 0) { |
354 |
hdr_backup_lba = hdr_backup.hdr_lba_self; |
395 |
hdr_backup_lba = hdr_backup.hdr_lba_self; |
|
|
396 |
|
397 |
/* If primary GPT is dammaged but backup GPT is ok |
398 |
* we try to recover primary GPT */ |
355 |
if (hdr_primary_lba == 0) { |
399 |
if (hdr_primary_lba == 0) { |
356 |
gpthdr = &hdr_backup; |
400 |
gpthdr = &hdr_backup; |
357 |
gpttable = table_backup; |
401 |
gpttable = table_backup; |
358 |
printf("%s: using backup GPT\n", BOOTPROG); |
402 |
hdr_primary_lba = gpt_recover(dskp, &hdr_primary, |
|
|
403 |
&hdr_backup); |
404 |
if (hdr_primary_lba == 0) { |
405 |
printf("%s: using backup GPT\n", BOOTPROG); |
406 |
} else { |
407 |
if (!gptread_table("primary", uuid, dskp, |
408 |
&hdr_primary, table_primary)) { |
409 |
gpthdr = &hdr_primary; |
410 |
gpttable = table_primary; |
411 |
} |
412 |
} |
359 |
} |
413 |
} |
360 |
} |
414 |
} |
361 |
|
415 |
|