File flatmap-Initialize-flatmap-offsets-only-once.patch of Package libkdumpfile.36085
From: Petr Tesarik <petr@tesarici.cz>
Date: Mon, 30 Sep 2024 08:48:54 +0200
Subject: flatmap: Initialize flatmap offsets only once
References: bsc#1223399
Upstream: merged
Git-commit: 24e53ed7bf7c24f338471bb0ce495b605d2068ee
The flattened offset mappings is initialized when probing for a format that
can be flattened. The downside is that for a flattened diskdump, the
initialization is done twice: first when probing for ELF dump (just to find
out it is not an ELF dump, so the mappings are immediately discarded) and
then again when probing for diskdump.
To fix it, move the flatmap object to struct kdump_shared and initialize it
before probing for format.
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
---
src/kdumpfile/context.c | 1
src/kdumpfile/diskdump.c | 38 ++++++++-------------------
src/kdumpfile/elfdump.c | 56 ++++++++++++++++++-----------------------
src/kdumpfile/kdumpfile-priv.h | 3 ++
src/kdumpfile/open.c | 10 +++++++
5 files changed, 50 insertions(+), 58 deletions(-)
--- a/src/kdumpfile/context.c
+++ b/src/kdumpfile/context.c
@@ -104,6 +104,7 @@ shared_free(struct kdump_shared *shared)
shared->arch_ops->cleanup(shared);
if (shared->cache)
cache_free(shared->cache);
+ flatmap_free(shared->flatmap);
if (shared->fcache)
fcache_decref(shared->fcache);
mutex_destroy(&shared->cache_lock);
--- a/src/kdumpfile/diskdump.c
+++ b/src/kdumpfile/diskdump.c
@@ -164,9 +164,6 @@ struct pfn_rgn {
struct disk_dump_priv {
struct pfn_rgn *pfn_rgn; /**< PFN region map. */
size_t pfn_rgn_num; /**< Number of elements in the map. */
-
- /** File offset mappings for flattened files. */
- struct flattened_map *flatmap;
};
struct setup_data {
@@ -381,7 +378,7 @@ diskdump_read_page(kdump_ctx_t *ctx, str
}
mutex_lock(&ctx->shared->cache_lock);
- ret = flatmap_pread(ddp->flatmap, &pd, sizeof pd, pd_pos);
+ ret = flatmap_pread(ctx->shared->flatmap, &pd, sizeof pd, pd_pos);
mutex_unlock(&ctx->shared->cache_lock);
if (ret != KDUMP_OK)
return set_error(ctx, ret,
@@ -400,7 +397,7 @@ diskdump_read_page(kdump_ctx_t *ctx, str
"Wrong compressed size: %lu",
(unsigned long)pd.size);
mutex_lock(&ctx->shared->cache_lock);
- ret = flatmap_get_chunk(ddp->flatmap, &fch, pd.size, pd.offset);
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch, pd.size, pd.offset);
mutex_unlock(&ctx->shared->cache_lock);
} else {
if (pd.size != get_page_size(ctx))
@@ -408,7 +405,7 @@ diskdump_read_page(kdump_ctx_t *ctx, str
"Wrong page size: %lu",
(unsigned long)pd.size);
mutex_lock(&ctx->shared->cache_lock);
- ret = flatmap_pread(ddp->flatmap, pio->chunk.data, pd.size, pd.offset);
+ ret = flatmap_pread(ctx->shared->flatmap, pio->chunk.data, pd.size, pd.offset);
mutex_unlock(&ctx->shared->cache_lock);
}
@@ -477,12 +474,11 @@ 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 = flatmap_get_chunk(ddp->flatmap, &fch, size, off);
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch, size, off);
if (ret != KDUMP_OK)
return set_error(ctx, ret,
"Cannot read %zu VMCOREINFO bytes at %llu",
@@ -505,11 +501,10 @@ 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 = flatmap_get_chunk(ddp->flatmap, &fch, size, off);
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch, size, off);
if (ret != KDUMP_OK)
return set_error(ctx, ret,
"Cannot read %zu note bytes at %llu",
@@ -607,7 +602,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 = flatmap_get_chunk(ddp->flatmap, &fch, bitmapsize, off);
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch, bitmapsize, off);
if (ret != KDUMP_OK)
return set_error(ctx, ret,
"Cannot read %zu bytes of page bitmap"
@@ -671,7 +666,6 @@ 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;
@@ -683,7 +677,7 @@ read_sub_hdr_32(struct setup_data *sdp,
if (header_version < 1)
return KDUMP_OK;
- ret = flatmap_pread(ddp->flatmap, &subhdr, sizeof subhdr,
+ ret = flatmap_pread(ctx->shared->flatmap, &subhdr, sizeof subhdr,
get_page_size(ctx));
if (ret != KDUMP_OK)
return set_error(ctx, ret,
@@ -755,7 +749,6 @@ 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;
@@ -767,7 +760,7 @@ read_sub_hdr_64(struct setup_data *sdp,
if (header_version < 1)
return KDUMP_OK;
- ret = flatmap_pread(ddp->flatmap, &subhdr, sizeof subhdr,
+ ret = flatmap_pread(ctx->shared->flatmap, &subhdr, sizeof subhdr,
get_page_size(ctx));
if (ret != KDUMP_OK)
return set_error(ctx, ret,
@@ -853,13 +846,7 @@ init_private(kdump_ctx_t *ctx)
"Cannot allocate diskdump private data");
ctx->shared->fmtdata = ddp;
- ddp->flatmap = flatmap_alloc();
- if (!ddp->flatmap)
- return set_error(ctx, KDUMP_ERR_SYSTEM,
- "Cannot allocate %s",
- "flattened dump maps");
-
- return flatmap_init(ddp->flatmap, ctx);
+ return KDUMP_OK;
}
static kdump_status
@@ -923,7 +910,7 @@ init_desc(kdump_ctx_t *ctx, char *desc)
{
struct disk_dump_priv *ddp = ctx->shared->fmtdata;
- if (flatmap_isflattened(ddp->flatmap))
+ if (flatmap_isflattened(ctx->shared->flatmap))
strcpy(desc, "Flattened ");
else
desc[0] = '\0';
@@ -938,7 +925,6 @@ 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;
@@ -946,8 +932,7 @@ diskdump_probe(kdump_ctx_t *ctx)
if (status != KDUMP_OK)
return status;
- ddp = ctx->shared->fmtdata;
- status = flatmap_pread(ddp->flatmap, hdr, sizeof hdr, 0);
+ status = flatmap_pread(ctx->shared->flatmap, hdr, sizeof hdr, 0);
if (status != KDUMP_OK)
return set_error(ctx, status, "Cannot read dump header");
@@ -981,7 +966,6 @@ diskdump_cleanup(struct kdump_shared *sh
if (ddp) {
if (ddp->pfn_rgn)
free(ddp->pfn_rgn);
- flatmap_free(ddp->flatmap);
free(ddp);
shared->fmtdata = NULL;
}
--- a/src/kdumpfile/elfdump.c
+++ b/src/kdumpfile/elfdump.c
@@ -138,9 +138,6 @@ struct elfdump_priv {
/** File offset of Xen page map (xc_core) */
off_t xen_map_offset;
-
- /** File offset mappings for flattened files. */
- struct flattened_map *flatmap;
};
static void elf_cleanup(struct kdump_shared *shared);
@@ -263,7 +260,8 @@ elf_read_page(kdump_ctx_t *ctx, struct p
if (size > loadaddr + pls->filesz - addr)
size = loadaddr + pls->filesz - addr;
- status = flatmap_pread(edp->flatmap, p, size, pos);
+ status = flatmap_pread(ctx->shared->flatmap, p, size,
+ pos);
if (status != KDUMP_OK)
goto err_read;
p += size;
@@ -336,7 +334,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 = flatmap_get_chunk(edp->flatmap, &pio->chunk, sz,
+ status = flatmap_get_chunk(ctx->shared->flatmap, &pio->chunk, sz,
pls->file_offset + addr - loadaddr);
mutex_unlock(&ctx->shared->cache_lock);
return status;
@@ -747,7 +745,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 = flatmap_pread(edp->flatmap, &p2m, sizeof p2m, pos);
+ status = flatmap_pread(shared->flatmap, &p2m, sizeof p2m, pos);
mutex_unlock(&shared->cache_lock);
if (status != KDUMP_OK)
return addrxlat_ctx_err(step->ctx, ADDRXLAT_ERR_NODATA,
@@ -785,7 +783,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 = flatmap_pread(edp->flatmap, &p2m, sizeof p2m, pos);
+ status = flatmap_pread(shared->flatmap, &p2m, sizeof p2m, pos);
mutex_unlock(&shared->cache_lock);
if (status != KDUMP_OK)
return addrxlat_ctx_err(step->ctx, ADDRXLAT_ERR_NODATA,
@@ -889,7 +887,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 = flatmap_get_chunk(edp->flatmap, &pio->chunk,
+ status = flatmap_get_chunk(ctx->shared->flatmap, &pio->chunk,
get_page_size(ctx), offset);
mutex_unlock(&ctx->shared->cache_lock);
return status;
@@ -990,7 +988,7 @@ init_strtab(kdump_ctx_t *ctx, unsigned s
if (!edp->strtab)
return KDUMP_ERR_SYSTEM;
- status = flatmap_pread(edp->flatmap, edp->strtab, ps->size,
+ status = flatmap_pread(ctx->shared->flatmap, edp->strtab, ps->size,
ps->file_offset);
if (status != KDUMP_OK) {
free(edp->strtab);
@@ -1029,7 +1027,7 @@ init_elf32(kdump_ctx_t *ctx, Elf32_Ehdr
if (offset != 0 && (shnum == 0 || phnum == PN_XNUM)) {
Elf32_Shdr *sect;
- ret = flatmap_get_chunk(edp->flatmap, &fch,
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch,
dump16toh(ctx, ehdr->e_shentsize),
offset);
if (ret != KDUMP_OK)
@@ -1061,7 +1059,8 @@ init_elf32(kdump_ctx_t *ctx, Elf32_Ehdr
Elf32_Phdr *prog;
struct load_segment *pls;
- ret = flatmap_get_chunk(edp->flatmap, &fch, entsz, offset);
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch, entsz,
+ offset);
if (ret != KDUMP_OK)
return set_error(ctx, ret,
"Cannot read ELF %s #%" PRIu32 " at %llu",
@@ -1088,7 +1087,8 @@ init_elf32(kdump_ctx_t *ctx, Elf32_Ehdr
for (i = 0; i < shnum; ++i) {
Elf32_Shdr *sect;
- ret = flatmap_get_chunk(edp->flatmap, &fch, entsz, offset);
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch, entsz,
+ offset);
if (ret != KDUMP_OK)
return set_error(ctx, ret,
"Cannot read ELF %s #%" PRIu32 " at %llu",
@@ -1129,7 +1129,7 @@ init_elf64(kdump_ctx_t *ctx, Elf64_Ehdr
if (offset != 0 && (shnum == 0 || phnum == PN_XNUM)) {
Elf64_Shdr *sect;
- ret = flatmap_get_chunk(edp->flatmap, &fch,
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch,
dump16toh(ctx, ehdr->e_shentsize),
offset);
if (ret != KDUMP_OK)
@@ -1161,7 +1161,8 @@ init_elf64(kdump_ctx_t *ctx, Elf64_Ehdr
Elf64_Phdr *prog;
struct load_segment *pls;
- ret = flatmap_get_chunk(edp->flatmap, &fch, entsz, offset);
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch, entsz,
+ offset);
if (ret != KDUMP_OK)
return set_error(ctx, ret,
"Cannot read ELF %s #%" PRIu64 " at %llu",
@@ -1188,7 +1189,8 @@ init_elf64(kdump_ctx_t *ctx, Elf64_Ehdr
for (i = 0; i < shnum; ++i) {
Elf64_Shdr *sect;
- ret = flatmap_get_chunk(edp->flatmap, &fch, entsz, offset);
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch, entsz,
+ offset);
if (ret != KDUMP_OK)
return set_error(ctx, ret,
"Cannot read ELF %s #%" PRIu64 " at %llu",
@@ -1224,8 +1226,8 @@ 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 = flatmap_get_chunk(edp->flatmap, &fch, seg->filesz,
- seg->file_offset);
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch,
+ seg->filesz, seg->file_offset);
if (ret != KDUMP_OK)
return set_error(ctx, ret,
"Cannot read ELF notes at %llu",
@@ -1367,7 +1369,8 @@ open_common(kdump_ctx_t *ctx)
return set_error(ctx, ret,
"Cannot create Xen PFN map");
} else if (!strcmp(name, ".note.Xen")) {
- ret = flatmap_get_chunk(edp->flatmap, &fch, sect->size,
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch,
+ sect->size,
sect->file_offset);
if (ret != KDUMP_OK)
return set_error(ctx, ret,
@@ -1378,7 +1381,8 @@ open_common(kdump_ctx_t *ctx)
return set_error(ctx, ret,
"Cannot process Xen notes");
} else if (!strcmp(name, ".xen_prstatus")) {
- ret = flatmap_get_chunk(edp->flatmap, &fch, sect->size,
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch,
+ sect->size,
sect->file_offset);
if (ret != KDUMP_OK)
return set_error(ctx, ret,
@@ -1464,17 +1468,8 @@ elf_probe(kdump_ctx_t *ctx)
"Cannot allocate ELF dump private data");
ctx->shared->fmtdata = edp;
- edp->flatmap = flatmap_alloc();
- if (!edp->flatmap)
- return set_error(ctx, KDUMP_ERR_SYSTEM,
- "Cannot allocate %s",
- "flattened dump maps");
-
- ret = flatmap_init(edp->flatmap, ctx);
- if (ret != KDUMP_OK)
- return ret;
-
- ret = flatmap_get_chunk(edp->flatmap, &fch, sizeof(Elf64_Ehdr), 0);
+ ret = flatmap_get_chunk(ctx->shared->flatmap, &fch, sizeof(Elf64_Ehdr),
+ 0);
if (ret != KDUMP_OK)
return set_error(ctx, ret, "Cannot read dump header");
@@ -1506,7 +1501,6 @@ elf_cleanup(struct kdump_shared *shared)
free(edp->strtab);
pfn2idx_map_free(&edp->xen_pfnmap);
pfn2idx_map_free(&edp->xen_mfnmap);
- flatmap_free(edp->flatmap);
free(edp);
shared->fmtdata = NULL;
}
--- a/src/kdumpfile/kdumpfile-priv.h
+++ b/src/kdumpfile/kdumpfile-priv.h
@@ -575,6 +575,9 @@ struct kdump_shared {
struct fcache *fcache; /**< File cache. */
mutex_t cache_lock; /**< Cache access lock. */
+ /** File offset mappings for flattened files. */
+ struct flattened_map *flatmap;
+
/** Static attributes. */
#define ATTR(dir, key, field, type, ctype, ...) \
kdump_attr_value_t field;
--- a/src/kdumpfile/open.c
+++ b/src/kdumpfile/open.c
@@ -93,6 +93,7 @@ file_fd_post_hook(kdump_ctx_t *ctx, stru
kdump_status ret;
int i;
+ flatmap_free(ctx->shared->flatmap);
if (ctx->shared->fcache) {
for (i = 0; i < ARRAY_SIZE(fcache_attrs); ++i)
attr_embed_value(gattr(ctx, fcache_attrs[i]));
@@ -116,6 +117,15 @@ file_fd_post_hook(kdump_ctx_t *ctx, stru
gattr(ctx, GKI_read_cache_hits),
gattr(ctx, GKI_read_cache_misses));
+ ctx->shared->flatmap = flatmap_alloc();
+ if (!ctx->shared->flatmap)
+ return set_error(ctx, KDUMP_ERR_SYSTEM,
+ "Cannot allocate %s", "flattened dump maps");
+
+ ret = flatmap_init(ctx->shared->flatmap, ctx);
+ if (ret != KDUMP_OK)
+ return ret;
+
ctx->xlat->dirty = true;
for (i = 0; i < ARRAY_SIZE(formats); ++i) {