Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.5:Update
libkdumpfile.36085
flatmap-Allow-to-use-the-flatmap-API-with-non-f...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File flatmap-Allow-to-use-the-flatmap-API-with-non-flatte.patch of Package libkdumpfile.36085
From: Petr Tesarik <petr@tesarici.cz> Date: Sun, 29 Sep 2024 18:01:50 +0200 Subject: flatmap: Allow to use the flatmap API with non-flattened files References: bsc#1223399 Upstream: merged Git-commit: bc14a715bbcc7698b25064e4b3dbafaa1ea86bcf The flatmap API now gets enough information to know if a file is flattened and (where appropriate) read directly from a non-flattened file. In fact, this is what elfdump_pread() and elfdump_get_chunk() already do. Moreover, the check adds only little overhead (especially if the function is inline), so rename the original functions (which can read only flattened files) by adding a _flat suffix to them and make the API usable with non-flattened files. Remove the format-specific diskdump and elfdump functions, which do essentially the same job as flatmap_pread() and flatmap_get_chunk() after this change. Signed-off-by: Petr Tesarik <ptesarik@suse.com> --- src/kdumpfile/diskdump.c | 70 ++++++++++------------------------------- src/kdumpfile/elfdump.c | 70 +++++++++-------------------------------- src/kdumpfile/flatmap.c | 8 ++-- src/kdumpfile/kdumpfile-priv.h | 43 ++++++++++++++++++++++++- 4 files changed, 79 insertions(+), 112 deletions(-) --- a/src/kdumpfile/diskdump.c +++ b/src/kdumpfile/diskdump.c @@ -189,47 +189,6 @@ struct setup_data { static void diskdump_cleanup(struct kdump_shared *shared); -/** Read buffer from a diskdump file. - * @param ctx Dump file object. - * @param buf Target I/O buffer. - * @param len Length of data. - * @param pos File position. - * @returns Error status. - * - * Read data from a diskdump file. If the file is flattened, interpret - * @p pos as if it was already rearranged. - */ -static inline kdump_status -diskdump_pread(kdump_ctx_t *ctx, void *buf, size_t len, off_t pos) -{ - struct disk_dump_priv *ddp = ctx->shared->fmtdata; - - return flatmap_isflattened(ddp->flatmap) - ? flatmap_pread(ddp->flatmap, buf, len, pos) - : fcache_pread(ctx->shared->fcache, buf, len, pos); -} - -/** Get a contiguous data chunk from a diskdump file. - * @param ctx Dump file object. - * @param fch File cache chunk, updated on success. - * @param len Length of data. - * @param pos File position. - * @returns Error status. - * - * Get a contiguous data chunk from a diskdump file. If the file is - * flattened, interpret @p pos as if it was already rearranged. - */ -static inline kdump_status -diskdump_get_chunk(kdump_ctx_t *ctx, struct fcache_chunk *fch, - size_t len, off_t pos) -{ - struct disk_dump_priv *ddp = ctx->shared->fmtdata; - - return flatmap_isflattened(ddp->flatmap) - ? flatmap_get_chunk(ddp->flatmap, fch, len, pos) - : fcache_get_chunk(ctx->shared->fcache, fch, len, pos); -} - /** Add a new PFN region. * @param ctx Dump file context. * @param rgn PFN region. @@ -422,7 +381,7 @@ diskdump_read_page(kdump_ctx_t *ctx, str } mutex_lock(&ctx->shared->cache_lock); - ret = diskdump_pread(ctx, &pd, sizeof pd, pd_pos); + ret = flatmap_pread(ddp->flatmap, &pd, sizeof pd, pd_pos); mutex_unlock(&ctx->shared->cache_lock); if (ret != KDUMP_OK) return set_error(ctx, ret, @@ -441,7 +400,7 @@ diskdump_read_page(kdump_ctx_t *ctx, str "Wrong compressed size: %lu", (unsigned long)pd.size); mutex_lock(&ctx->shared->cache_lock); - ret = diskdump_get_chunk(ctx, &fch, pd.size, pd.offset); + ret = flatmap_get_chunk(ddp->flatmap, &fch, pd.size, pd.offset); mutex_unlock(&ctx->shared->cache_lock); } else { if (pd.size != get_page_size(ctx)) @@ -449,7 +408,7 @@ diskdump_read_page(kdump_ctx_t *ctx, str "Wrong page size: %lu", (unsigned long)pd.size); mutex_lock(&ctx->shared->cache_lock); - ret = diskdump_pread(ctx, pio->chunk.data, pd.size, pd.offset); + ret = flatmap_pread(ddp->flatmap, pio->chunk.data, pd.size, pd.offset); mutex_unlock(&ctx->shared->cache_lock); } @@ -518,11 +477,12 @@ diskdump_get_page(kdump_ctx_t *ctx, stru static kdump_status read_vmcoreinfo(kdump_ctx_t *ctx, off_t off, size_t size) { + struct disk_dump_priv *ddp = ctx->shared->fmtdata; struct fcache_chunk fch; kdump_attr_value_t val; kdump_status ret; - ret = diskdump_get_chunk(ctx, &fch, size, off); + ret = flatmap_get_chunk(ddp->flatmap, &fch, size, off); if (ret != KDUMP_OK) return set_error(ctx, ret, "Cannot read %zu VMCOREINFO bytes at %llu", @@ -545,10 +505,11 @@ read_vmcoreinfo(kdump_ctx_t *ctx, off_t static kdump_status read_notes(kdump_ctx_t *ctx, off_t off, size_t size) { + struct disk_dump_priv *ddp = ctx->shared->fmtdata; struct fcache_chunk fch; kdump_status ret; - ret = diskdump_get_chunk(ctx, &fch, size, off); + ret = flatmap_get_chunk(ddp->flatmap, &fch, size, off); if (ret != KDUMP_OK) return set_error(ctx, ret, "Cannot read %zu note bytes at %llu", @@ -621,6 +582,7 @@ static kdump_status read_bitmap(kdump_ctx_t *ctx, int32_t sub_hdr_size, int32_t bitmap_blocks) { + struct disk_dump_priv *ddp = ctx->shared->fmtdata; off_t off = (1 + sub_hdr_size) * get_page_size(ctx); off_t descoff; size_t bitmapsize; @@ -645,7 +607,7 @@ read_bitmap(kdump_ctx_t *ctx, int32_t su if (get_max_pfn(ctx) > max_bitmap_pfn) set_max_pfn(ctx, max_bitmap_pfn); - ret = diskdump_get_chunk(ctx, &fch, bitmapsize, off); + ret = flatmap_get_chunk(ddp->flatmap, &fch, bitmapsize, off); if (ret != KDUMP_OK) return set_error(ctx, ret, "Cannot read %zu bytes of page bitmap" @@ -709,6 +671,7 @@ static kdump_status read_sub_hdr_32(struct setup_data *sdp, int32_t header_version) { kdump_ctx_t *ctx = sdp->ctx; + struct disk_dump_priv *ddp = ctx->shared->fmtdata; struct kdump_sub_header_32 subhdr; kdump_status ret; @@ -720,8 +683,8 @@ read_sub_hdr_32(struct setup_data *sdp, if (header_version < 1) return KDUMP_OK; - ret = diskdump_pread(ctx, &subhdr, sizeof subhdr, - get_page_size(ctx)); + ret = flatmap_pread(ddp->flatmap, &subhdr, sizeof subhdr, + get_page_size(ctx)); if (ret != KDUMP_OK) return set_error(ctx, ret, "Cannot read subheader"); @@ -792,6 +755,7 @@ static kdump_status read_sub_hdr_64(struct setup_data *sdp, int32_t header_version) { kdump_ctx_t *ctx = sdp->ctx; + struct disk_dump_priv *ddp = ctx->shared->fmtdata; struct kdump_sub_header_64 subhdr; kdump_status ret; @@ -803,8 +767,8 @@ read_sub_hdr_64(struct setup_data *sdp, if (header_version < 1) return KDUMP_OK; - ret = diskdump_pread(ctx, &subhdr, sizeof subhdr, - get_page_size(ctx)); + ret = flatmap_pread(ddp->flatmap, &subhdr, sizeof subhdr, + get_page_size(ctx)); if (ret != KDUMP_OK) return set_error(ctx, ret, "Cannot read subheader"); @@ -974,6 +938,7 @@ diskdump_probe(kdump_ctx_t *ctx) { 'K', 'D', 'U', 'M', 'P', ' ', ' ', ' ' }; char hdr[sizeof(struct disk_dump_header_64)]; + struct disk_dump_priv *ddp; char desc[32]; kdump_status status; @@ -981,7 +946,8 @@ diskdump_probe(kdump_ctx_t *ctx) if (status != KDUMP_OK) return status; - status = diskdump_pread(ctx, hdr, sizeof hdr, 0); + ddp = ctx->shared->fmtdata; + status = flatmap_pread(ddp->flatmap, hdr, sizeof hdr, 0); if (status != KDUMP_OK) return set_error(ctx, status, "Cannot read dump header"); --- a/src/kdumpfile/elfdump.c +++ b/src/kdumpfile/elfdump.c @@ -168,44 +168,6 @@ mach2arch(unsigned mach, int elfclass) } } -/** Read buffer from an ELF dump file. - * @param flatmap Flattened offset map. - * @param buf Target I/O buffer. - * @param len Length of data. - * @param pos File position. - * @returns Error status. - * - * Read data from an ELF dump file. If the file is flattened, interpret - * @p pos as if it was already rearranged. - */ -static inline kdump_status -elfdump_pread(struct flattened_map *flatmap, void *buf, size_t len, - off_t pos) -{ - return flatmap_isflattened(flatmap) - ? flatmap_pread(flatmap, buf, len, pos) - : fcache_pread(flatmap->fcache, buf, len, pos); -} - -/** Get a contiguous data chunk from an ELF dump file. - * @param flatmap Flattened offset map. - * @param fch File cache chunk, updated on success. - * @param len Length of data. - * @param pos File position. - * @returns Error status. - * - * Get a contiguous data chunk from an ELF dump file. If the file is - * flattened, interpret @p pos as if it was already rearranged. - */ -static inline kdump_status -elfdump_get_chunk(struct flattened_map *flatmap, struct fcache_chunk *fch, - size_t len, off_t pos) -{ - return flatmap_isflattened(flatmap) - ? flatmap_get_chunk(flatmap, fch, len, pos) - : fcache_get_chunk(flatmap->fcache, fch, len, pos); -} - /** Find the LOAD segment that is closest to a physical address. * @param edp ELF dump private data. * @param paddr Requested physical address. @@ -301,7 +263,7 @@ elf_read_page(kdump_ctx_t *ctx, struct p if (size > loadaddr + pls->filesz - addr) size = loadaddr + pls->filesz - addr; - status = elfdump_pread(edp->flatmap, p, size, pos); + status = flatmap_pread(edp->flatmap, p, size, pos); if (status != KDUMP_OK) goto err_read; p += size; @@ -374,7 +336,7 @@ elf_get_page(kdump_ctx_t *ctx, struct pa return cache_get_page(ctx, pio, elf_read_page); mutex_lock(&ctx->shared->cache_lock); - status = elfdump_get_chunk(edp->flatmap, &pio->chunk, sz, + status = flatmap_get_chunk(edp->flatmap, &pio->chunk, sz, pls->file_offset + addr - loadaddr); mutex_unlock(&ctx->shared->cache_lock); return status; @@ -785,7 +747,7 @@ xc_p2m_first_step(addrxlat_step_t *step, pos = edp->xen_map_offset + idx * sizeof(struct xen_p2m); mutex_lock(&shared->cache_lock); - status = elfdump_pread(edp->flatmap, &p2m, sizeof p2m, pos); + status = flatmap_pread(edp->flatmap, &p2m, sizeof p2m, pos); mutex_unlock(&shared->cache_lock); if (status != KDUMP_OK) return addrxlat_ctx_err(step->ctx, ADDRXLAT_ERR_NODATA, @@ -823,7 +785,7 @@ xc_m2p_first_step(addrxlat_step_t *step, pos = edp->xen_map_offset + idx * sizeof(struct xen_p2m); mutex_lock(&shared->cache_lock); - status = elfdump_pread(edp->flatmap, &p2m, sizeof p2m, pos); + status = flatmap_pread(edp->flatmap, &p2m, sizeof p2m, pos); mutex_unlock(&shared->cache_lock); if (status != KDUMP_OK) return addrxlat_ctx_err(step->ctx, ADDRXLAT_ERR_NODATA, @@ -927,7 +889,7 @@ xc_get_page(kdump_ctx_t *ctx, struct pag offset = edp->xen_pages_offset + ((off_t)idx << get_page_shift(ctx)); mutex_lock(&ctx->shared->cache_lock); - status = elfdump_get_chunk(edp->flatmap, &pio->chunk, + status = flatmap_get_chunk(edp->flatmap, &pio->chunk, get_page_size(ctx), offset); mutex_unlock(&ctx->shared->cache_lock); return status; @@ -1028,7 +990,7 @@ init_strtab(kdump_ctx_t *ctx, unsigned s if (!edp->strtab) return KDUMP_ERR_SYSTEM; - status = elfdump_pread(edp->flatmap, edp->strtab, ps->size, + status = flatmap_pread(edp->flatmap, edp->strtab, ps->size, ps->file_offset); if (status != KDUMP_OK) { free(edp->strtab); @@ -1067,7 +1029,7 @@ init_elf32(kdump_ctx_t *ctx, Elf32_Ehdr if (offset != 0 && (shnum == 0 || phnum == PN_XNUM)) { Elf32_Shdr *sect; - ret = elfdump_get_chunk(edp->flatmap, &fch, + ret = flatmap_get_chunk(edp->flatmap, &fch, dump16toh(ctx, ehdr->e_shentsize), offset); if (ret != KDUMP_OK) @@ -1099,7 +1061,7 @@ init_elf32(kdump_ctx_t *ctx, Elf32_Ehdr Elf32_Phdr *prog; struct load_segment *pls; - ret = elfdump_get_chunk(edp->flatmap, &fch, entsz, offset); + ret = flatmap_get_chunk(edp->flatmap, &fch, entsz, offset); if (ret != KDUMP_OK) return set_error(ctx, ret, "Cannot read ELF %s #%" PRIu32 " at %llu", @@ -1126,7 +1088,7 @@ init_elf32(kdump_ctx_t *ctx, Elf32_Ehdr for (i = 0; i < shnum; ++i) { Elf32_Shdr *sect; - ret = elfdump_get_chunk(edp->flatmap, &fch, entsz, offset); + ret = flatmap_get_chunk(edp->flatmap, &fch, entsz, offset); if (ret != KDUMP_OK) return set_error(ctx, ret, "Cannot read ELF %s #%" PRIu32 " at %llu", @@ -1167,7 +1129,7 @@ init_elf64(kdump_ctx_t *ctx, Elf64_Ehdr if (offset != 0 && (shnum == 0 || phnum == PN_XNUM)) { Elf64_Shdr *sect; - ret = elfdump_get_chunk(edp->flatmap, &fch, + ret = flatmap_get_chunk(edp->flatmap, &fch, dump16toh(ctx, ehdr->e_shentsize), offset); if (ret != KDUMP_OK) @@ -1199,7 +1161,7 @@ init_elf64(kdump_ctx_t *ctx, Elf64_Ehdr Elf64_Phdr *prog; struct load_segment *pls; - ret = elfdump_get_chunk(edp->flatmap, &fch, entsz, offset); + ret = flatmap_get_chunk(edp->flatmap, &fch, entsz, offset); if (ret != KDUMP_OK) return set_error(ctx, ret, "Cannot read ELF %s #%" PRIu64 " at %llu", @@ -1226,7 +1188,7 @@ init_elf64(kdump_ctx_t *ctx, Elf64_Ehdr for (i = 0; i < shnum; ++i) { Elf64_Shdr *sect; - ret = elfdump_get_chunk(edp->flatmap, &fch, entsz, offset); + ret = flatmap_get_chunk(edp->flatmap, &fch, entsz, offset); if (ret != KDUMP_OK) return set_error(ctx, ret, "Cannot read ELF %s #%" PRIu64 " at %llu", @@ -1262,7 +1224,7 @@ walk_elf_notes(kdump_ctx_t *ctx, walk_no for (i = 0; i < edp->num_note_segments; ++i) { struct load_segment *seg = edp->note_segments + i; - ret = elfdump_get_chunk(edp->flatmap, &fch, seg->filesz, + ret = flatmap_get_chunk(edp->flatmap, &fch, seg->filesz, seg->file_offset); if (ret != KDUMP_OK) return set_error(ctx, ret, @@ -1405,7 +1367,7 @@ open_common(kdump_ctx_t *ctx) return set_error(ctx, ret, "Cannot create Xen PFN map"); } else if (!strcmp(name, ".note.Xen")) { - ret = elfdump_get_chunk(edp->flatmap, &fch, sect->size, + ret = flatmap_get_chunk(edp->flatmap, &fch, sect->size, sect->file_offset); if (ret != KDUMP_OK) return set_error(ctx, ret, @@ -1416,7 +1378,7 @@ open_common(kdump_ctx_t *ctx) return set_error(ctx, ret, "Cannot process Xen notes"); } else if (!strcmp(name, ".xen_prstatus")) { - ret = elfdump_get_chunk(edp->flatmap, &fch, sect->size, + ret = flatmap_get_chunk(edp->flatmap, &fch, sect->size, sect->file_offset); if (ret != KDUMP_OK) return set_error(ctx, ret, @@ -1512,7 +1474,7 @@ elf_probe(kdump_ctx_t *ctx) if (ret != KDUMP_OK) return ret; - ret = elfdump_get_chunk(edp->flatmap, &fch, sizeof(Elf64_Ehdr), 0); + ret = flatmap_get_chunk(edp->flatmap, &fch, sizeof(Elf64_Ehdr), 0); if (ret != KDUMP_OK) return set_error(ctx, ret, "Cannot read dump header"); --- a/src/kdumpfile/flatmap.c +++ b/src/kdumpfile/flatmap.c @@ -231,8 +231,8 @@ flatmap_free(struct flattened_map *map) * at position @p pos after rearrangement. */ kdump_status -flatmap_pread(struct flattened_map *map, void *buf, size_t len, - off_t pos) +flatmap_pread_flat(struct flattened_map *map, void *buf, size_t len, + off_t pos) { struct flattened_file_map *fmap = &map->fmap; const addrxlat_range_t *range, *end; @@ -283,8 +283,8 @@ flatmap_pread(struct flattened_map *map, * Get a contiguous data chunk from a flattened dump file. */ kdump_status -flatmap_get_chunk(struct flattened_map *map, struct fcache_chunk *fch, - size_t len, off_t pos) +flatmap_get_chunk_flat(struct flattened_map *map, struct fcache_chunk *fch, + size_t len, off_t pos) { struct flattened_file_map *fmap = &map->fmap; const addrxlat_range_t *range, *end; --- a/src/kdumpfile/kdumpfile-priv.h +++ b/src/kdumpfile/kdumpfile-priv.h @@ -1531,10 +1531,10 @@ INTERNAL_DECL(kdump_status, flatmap_init (struct flattened_map *map, kdump_ctx_t *ctx)); INTERNAL_DECL(void, flatmap_free, (struct flattened_map *map)); -INTERNAL_DECL(kdump_status, flatmap_pread, +INTERNAL_DECL(kdump_status, flatmap_pread_flat, (struct flattened_map *map, void *buf, size_t len, off_t pos)); -INTERNAL_DECL(kdump_status, flatmap_get_chunk, +INTERNAL_DECL(kdump_status, flatmap_get_chunk_flat, (struct flattened_map *map, struct fcache_chunk *fch, size_t len, off_t pos)); @@ -1548,6 +1548,45 @@ flatmap_isflattened(struct flattened_map return map->fmap.map; } +/** Read buffer from a possibly flattened dump file. + * @param flatmap Flattened offset map. + * @param buf Target I/O buffer. + * @param len Length of data. + * @param pos File position. + * @returns Error status. + * + * Read data from an ELF dump file. If the file is flattened, interpret + * @p pos as if it was already rearranged. + */ +static inline kdump_status +flatmap_pread(struct flattened_map *flatmap, void *buf, size_t len, + off_t pos) +{ + return flatmap_isflattened(flatmap) + ? flatmap_pread_flat(flatmap, buf, len, pos) + : fcache_pread(flatmap->fcache, buf, len, pos); +} + +/** Get a contiguous data chunk from a possibly flattend dump file. + * @param flatmap Flattened offset map. + * @param fch File cache chunk, updated on success. + * @param len Length of data. + * @param pos File position. + * @returns Error status. + * + * Get a contiguous data chunk from an ELF dump file. If the file is + * flattened, interpret @p pos as if it was already rearranged. + */ +static inline kdump_status +flatmap_get_chunk(struct flattened_map *flatmap, struct fcache_chunk *fch, + size_t len, off_t pos) +{ + return flatmap_isflattened(flatmap) + ? flatmap_get_chunk_flat(flatmap, fch, len, pos) + : fcache_get_chunk(flatmap->fcache, fch, len, pos); +} + + /** Check if a character is a POSIX white space. * @param c Character to check. *
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor