void write_stats(int what) { StatsEntry stats = STATS_ENTRY__INIT; DumpStatsEntry ds_entry = DUMP_STATS_ENTRY__INIT; RestoreStatsEntry rs_entry = RESTORE_STATS_ENTRY__INIT; char *name; struct cr_img *img; pr_info("Writing stats\n"); if (what == DUMP_STATS) { stats.dump = &ds_entry; encode_time(TIME_FREEZING, &ds_entry.freezing_time); encode_time(TIME_FROZEN, &ds_entry.frozen_time); encode_time(TIME_MEMDUMP, &ds_entry.memdump_time); encode_time(TIME_MEMWRITE, &ds_entry.memwrite_time); ds_entry.has_irmap_resolve = true; encode_time(TIME_IRMAP_RESOLVE, &ds_entry.irmap_resolve); ds_entry.pages_scanned = dstats->counts[CNT_PAGES_SCANNED]; ds_entry.pages_skipped_parent = dstats->counts[CNT_PAGES_SKIPPED_PARENT]; ds_entry.pages_written = dstats->counts[CNT_PAGES_WRITTEN]; ds_entry.pages_zero = dstats->counts[CNT_PAGES_ZERO]; ds_entry.pages_lazy = dstats->counts[CNT_PAGES_LAZY]; name = "dump"; } else if (what == RESTORE_STATS) { stats.restore = &rs_entry; rs_entry.pages_compared = atomic_read(&rstats->counts[CNT_PAGES_COMPARED]); rs_entry.pages_skipped_cow = atomic_read(&rstats->counts[CNT_PAGES_SKIPPED_COW]); rs_entry.has_pages_restored = true; rs_entry.pages_restored = atomic_read(&rstats->counts[CNT_PAGES_RESTORED]); encode_time(TIME_FORK, &rs_entry.forking_time); encode_time(TIME_RESTORE, &rs_entry.restore_time); name = "restore"; } else return; img = open_image_at(AT_FDCWD, CR_FD_STATS, O_DUMP, name); if (img) { pb_write_one(img, &stats, PB_STATS); close_image(img); } }
struct cr_img *open_pages_image_at(int dfd, unsigned long flags, struct cr_img *pmi, u32 *id) { if (flags == O_RDONLY || flags == O_RDWR) { PagemapHead *h; if (pb_read_one(pmi, &h, PB_PAGEMAP_HEAD) < 0) return NULL; *id = h->pages_id; pagemap_head__free_unpacked(h, NULL); } else { PagemapHead h = PAGEMAP_HEAD__INIT; *id = h.pages_id = page_ids++; if (pb_write_one(pmi, &h, PB_PAGEMAP_HEAD) < 0) return NULL; } return open_image_at(dfd, CR_FD_PAGES, flags, *id); }
int open_pages_image_at(int dfd, unsigned long flags, int pm_fd) { unsigned id; if (flags == O_RDONLY || flags == O_RDWR) { PagemapHead *h; if (pb_read_one(pm_fd, &h, PB_PAGEMAP_HEAD) < 0) return -1; id = h->pages_id; pagemap_head__free_unpacked(h, NULL); } else { PagemapHead h = PAGEMAP_HEAD__INIT; id = h.pages_id = page_ids++; if (pb_write_one(pm_fd, &h, PB_PAGEMAP_HEAD) < 0) return -1; } return open_image_at(dfd, CR_FD_PAGES, flags, id); }
InventoryEntry *get_parent_inventory(void) { struct cr_img *img; InventoryEntry *ie; int dir; dir = openat(get_service_fd(IMG_FD_OFF), CR_PARENT_LINK, O_RDONLY); if (dir == -1) { pr_warn("Failed to open parent directory\n"); return NULL; } img = open_image_at(dir, CR_FD_INVENTORY, O_RSTR); if (!img) { pr_warn("Failed to open parent pre-dump inventory image\n"); close(dir); return NULL; } if (pb_read_one(img, &ie, PB_INVENTORY) < 0) { pr_warn("Failed to read parent pre-dump inventory entry\n"); close_image(img); close(dir); return NULL; } if (!ie->has_dump_uptime) { pr_warn("Parent pre-dump inventory has no uptime\n"); inventory_entry__free_unpacked(ie, NULL); ie = NULL; } close_image(img); close(dir); return ie; }