static int vhd_print_headers(vhd_context_t *vhd, int hex) { int err; vhd_print_footer(&vhd->footer, hex); if (vhd_type_dynamic(vhd)) { vhd_print_header(vhd, &vhd->header, hex); if (vhd->footer.type == HD_TYPE_DIFF) vhd_print_parent_locators(vhd, hex); if (vhd_has_batmap(vhd)) { err = vhd_get_batmap(vhd); if (err) { printf("failed to get batmap header\n"); return err; } vhd_print_batmap_header(vhd, &vhd->batmap, hex); } } return 0; }
static int vhd_journal_add_metadata(vhd_journal_t *j) { int err; off_t eof; vhd_context_t *vhd; vhd = &j->vhd; err = vhd_journal_add_footer(j); if (err) return err; if (!vhd_type_dynamic(vhd)) return 0; err = vhd_journal_add_header(j); if (err) return err; err = vhd_journal_add_locators(j); if (err) return err; err = vhd_journal_add_bat(j); if (err) return err; if (vhd_has_batmap(vhd)) { err = vhd_journal_add_batmap(j); if (err) return err; } j->header.journal_data_offset = j->header.journal_eof; return vhd_journal_write_header(j, &j->header); }
static int vhd_journal_restore_metadata(vhd_journal_t *j) { off64_t off; char **locators; vhd_footer_t copy; vhd_context_t *vhd; int i, locs, hlocs, err; vhd = &j->vhd; locs = 0; hlocs = 0; locators = NULL; err = vhd_journal_seek(j, sizeof(vhd_journal_header_t), SEEK_SET); if (err) return err; err = vhd_journal_read_footer(j, &vhd->footer); if (err) return err; if (!vhd_type_dynamic(vhd)) goto restore; err = vhd_journal_read_footer_copy(j, ©); if (err) return err; err = vhd_journal_read_header(j, &vhd->header); if (err) return err; for (hlocs = 0, i = 0; i < vhd_parent_locator_count(vhd); i++) { if (vhd_validate_platform_code(vhd->header.loc[i].code)) return err; if (vhd->header.loc[i].code != PLAT_CODE_NONE) hlocs++; } if (hlocs) { err = vhd_journal_read_locators(j, &locators, &locs); if (err) return err; if (hlocs != locs) { err = -EINVAL; goto out; } } err = vhd_journal_read_bat(j, &vhd->bat); if (err) goto out; if (vhd_has_batmap(vhd)) { err = vhd_journal_read_batmap(j, &vhd->batmap); if (err) goto out; } restore: off = vhd_journal_position(j); if (off == (off64_t)-1) return -errno; if (j->header.journal_data_offset != off) return -EINVAL; err = vhd_journal_restore_footer(j, &vhd->footer); if (err) goto out; if (!vhd_type_dynamic(vhd)) goto out; err = vhd_journal_restore_footer_copy(j, ©); if (err) goto out; err = vhd_journal_restore_header(j, &vhd->header); if (err) goto out; if (locs) { err = vhd_journal_restore_locators(j, locators, locs); if (err) goto out; } err = vhd_journal_restore_bat(j, &vhd->bat); if (err) goto out; if (vhd_has_batmap(vhd)) { err = vhd_journal_restore_batmap(j, &vhd->batmap); if (err) goto out; } err = 0; out: if (locators) { for (i = 0; i < locs; i++) free(locators[i]); free(locators); } if (!err && !vhd->is_block) err = ftruncate(vhd->fd, j->header.vhd_footer_offset + sizeof(vhd_footer_t)); return err; }
int vhd_journal_create(vhd_journal_t *j, const char *file, const char *jfile) { int err; memset(j, 0, sizeof(vhd_journal_t)); j->jfd = -1; j->jname = strdup(jfile); if (j->jname == NULL) { err = -ENOMEM; goto fail1; } if (access(j->jname, F_OK) == 0) { err = vhd_test_file_fixed(j->jname, &j->is_block); if (err) goto fail1; if (!j->is_block) { err = -EEXIST; goto fail1; } } if (j->is_block) j->jfd = open(j->jname, O_LARGEFILE | O_RDWR, 0644); else j->jfd = open(j->jname, O_CREAT | O_TRUNC | O_LARGEFILE | O_RDWR, 0644); if (j->jfd == -1) { err = -errno; goto fail1; } err = vhd_open(&j->vhd, file, VHD_OPEN_RDWR | VHD_OPEN_STRICT); if (err) goto fail1; err = vhd_get_bat(&j->vhd); if (err) goto fail2; if (vhd_has_batmap(&j->vhd)) { err = vhd_get_batmap(&j->vhd); if (err) goto fail2; } err = vhd_journal_add_journal_header(j); if (err) goto fail2; err = vhd_journal_add_metadata(j); if (err) goto fail2; err = vhd_journal_disable_vhd(j); if (err) goto fail2; err = vhd_journal_sync(j); if (err) goto fail2; return 0; fail1: if (j->jfd != -1) { close(j->jfd); if (!j->is_block) unlink(j->jname); } free(j->jname); memset(j, 0, sizeof(vhd_journal_t)); return err; fail2: vhd_journal_remove(j); return err; }
int vhd_journal_open(vhd_journal_t *j, const char *file, const char *jfile) { int err; vhd_context_t *vhd; memset(j, 0, sizeof(vhd_journal_t)); j->jfd = -1; vhd = &j->vhd; j->jname = strdup(jfile); if (j->jname == NULL) return -ENOMEM; j->jfd = open(j->jname, O_LARGEFILE | O_RDWR); if (j->jfd == -1) { err = -errno; goto fail; } err = vhd_test_file_fixed(j->jname, &j->is_block); if (err) goto fail; vhd->fd = open(file, O_LARGEFILE | O_RDWR | O_DIRECT); if (vhd->fd == -1) { err = -errno; goto fail; } err = vhd_test_file_fixed(file, &vhd->is_block); if (err) goto fail; err = vhd_journal_read_journal_header(j, &j->header); if (err) goto fail; err = vhd_journal_restore_metadata(j); if (err) goto fail; close(vhd->fd); free(vhd->bat.bat); free(vhd->batmap.map); err = vhd_open(vhd, file, VHD_OPEN_RDWR); if (err) goto fail; err = vhd_get_bat(vhd); if (err) goto fail; if (vhd_has_batmap(vhd)) { err = vhd_get_batmap(vhd); if (err) goto fail; } err = vhd_journal_disable_vhd(j); if (err) goto fail; return 0; fail: vhd_journal_close(j); return err; }