|
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 |
|