File Remove-references-to-diskdump-private-data-from-flat.patch of Package libkdumpfile.36085
From: Petr Tesarik <petr@tesarici.cz>
Date: Thu, 26 Sep 2024 11:17:33 +0200
Subject: Remove references to diskdump private data from flatmap handling
References: bsc#1223399
Upstream: merged
Git-commit: b1f95a8e4cd596eafc5fc8d2553bb0f677d18103
Move all necessary data into struct flattened_map to remove all
dependencies on struct disk_dump_priv from the implementation. That way,
the functions can support flattened files in other formats than diskdump.
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
---
src/kdumpfile/diskdump.c | 137 +++++++++++++++++++++++++++++++----------------
1 file changed, 92 insertions(+), 45 deletions(-)
--- a/src/kdumpfile/diskdump.c
+++ b/src/kdumpfile/diskdump.c
@@ -179,6 +179,15 @@ struct flattened_file_map {
off_t *offs;
};
+/** Offset mappings for a set of flattened files. */
+struct flattened_map {
+ /** File cache. */
+ struct fcache *fcache;
+
+ /** Mappings for individual files. */
+ struct flattened_file_map fmap;
+};
+
/** PFN region mapping. */
struct pfn_rgn {
kdump_pfn_t pfn; /**< Starting PFN. */
@@ -196,7 +205,7 @@ struct disk_dump_priv {
size_t pfn_rgn_num; /**< Number of elements in the map. */
/** File offset mappings for flattened files. */
- struct flattened_file_map *flatmap;
+ struct flattened_map *flatmap;
};
struct setup_data {
@@ -220,7 +229,7 @@ struct setup_data {
static void diskdump_cleanup(struct kdump_shared *shared);
/** Read buffer from a flattened dump file.
- * @param ctx Dump file object.
+ * @param map Flattened format mapping to be initialized.
* @param buf Target I/O buffer.
* @param len Length of data.
* @param pos File position.
@@ -230,14 +239,14 @@ static void diskdump_cleanup(struct kdum
* at position @p pos after rearrangement.
*/
static kdump_status
-flattened_pread(kdump_ctx_t *ctx, void *buf, size_t len, off_t pos)
+flatmap_pread(struct flattened_map *map, void *buf, size_t len, off_t pos)
{
- struct disk_dump_priv *ddp = ctx->shared->fmtdata;
+ struct flattened_file_map *fmap = &map->fmap;
const addrxlat_range_t *range, *end;
off_t off;
- range = addrxlat_map_ranges(ddp->flatmap->map);
- end = range + addrxlat_map_len(ddp->flatmap->map);
+ range = addrxlat_map_ranges(fmap->map);
+ end = range + addrxlat_map_len(fmap->map);
for (off = pos; range < end && off > range->endoff; ++range)
off -= range->endoff + 1;
while (range < end && len) {
@@ -248,11 +257,11 @@ flattened_pread(kdump_ctx_t *ctx, void *
seglen = len;
if (range->meth != ADDRXLAT_SYS_METH_NONE) {
- off_t *flatoffs = ddp->flatmap->offs;
+ off_t *flatoffs = fmap->offs;
unsigned segidx = range->meth;
kdump_status ret;
- ret = fcache_pread(ctx->shared->fcache, buf, seglen,
+ ret = fcache_pread(map->fcache, buf, seglen,
pos + flatoffs[segidx]);
if (ret != KDUMP_OK)
return ret;
@@ -287,12 +296,12 @@ diskdump_pread(kdump_ctx_t *ctx, void *b
struct disk_dump_priv *ddp = ctx->shared->fmtdata;
return ddp->flatmap
- ? flattened_pread(ctx, buf, len, pos)
+ ? flatmap_pread(ddp->flatmap, buf, len, pos)
: fcache_pread(ctx->shared->fcache, buf, len, pos);
}
/** Get a contiguous data chunk from a flattened dump file.
- * @param ctx Dump file object.
+ * @param map Flattened format mapping to be initialized.
* @param fch File cache chunk, updated on success.
* @param len Length of data.
* @param pos File position.
@@ -301,27 +310,27 @@ diskdump_pread(kdump_ctx_t *ctx, void *b
* Get a contiguous data chunk from a flattened dump file.
*/
static inline kdump_status
-flattened_get_chunk(kdump_ctx_t *ctx, struct fcache_chunk *fch,
- size_t len, off_t pos)
+flatmap_get_chunk(struct flattened_map *map, struct fcache_chunk *fch,
+ size_t len, off_t pos)
{
- struct disk_dump_priv *ddp = ctx->shared->fmtdata;
+ struct flattened_file_map *fmap = &map->fmap;
const addrxlat_range_t *range, *end;
off_t off;
- range = addrxlat_map_ranges(ddp->flatmap->map);
- end = range + addrxlat_map_len(ddp->flatmap->map);
+ range = addrxlat_map_ranges(fmap->map);
+ end = range + addrxlat_map_len(fmap->map);
for (off = pos; range < end && off > range->endoff; ++range)
off -= range->endoff + 1;
if (len <= range->endoff + 1 - off) {
- pos += ddp->flatmap->offs[range->meth];
- return fcache_get_chunk(ctx->shared->fcache, fch, len, pos);
+ pos += fmap->offs[range->meth];
+ return fcache_get_chunk(map->fcache, fch, len, pos);
}
fch->data = malloc(len);
if (!fch->data)
return KDUMP_ERR_SYSTEM;
fch->nent = 0;
- return flattened_pread(ctx, fch->data, len, pos);
+ return flatmap_pread(map, fch->data, len, pos);
}
/** Get a contiguous data chunk from a diskdump file.
@@ -341,7 +350,7 @@ diskdump_get_chunk(kdump_ctx_t *ctx, str
struct disk_dump_priv *ddp = ctx->shared->fmtdata;
return ddp->flatmap
- ? flattened_get_chunk(ctx, fch, len, pos)
+ ? flatmap_get_chunk(ddp->flatmap, fch, len, pos)
: fcache_get_chunk(ctx->shared->fcache, fch, len, pos);
}
@@ -1066,16 +1075,22 @@ open_common(kdump_ctx_t *ctx, void *hdr)
#define FLATOFFS_ALLOC_INC 32
/** Initialize flattened dump maps for one file.
+ * @param fmap Flattened format mapping to be initialized.
* @param ctx Dump file object.
* @returns Error status.
*
* Read all flattened segment headers and initialize
- * @p flatmap and @p flatoffs.
+ * @p fmap.
+ *
+ * Note that the mapping may be already partially initialized when this
+ * function fails with an error status, so you should always release the
+ * associated resources with @ref flatmap_file_cleanup(). As a consequence,
+ * the mapping must be initialized to all zeroes prior to calling
+ * flatmap_file_init().
*/
static kdump_status
-init_flattened_file(kdump_ctx_t *ctx)
+flatmap_file_init(struct flattened_file_map *fmap, kdump_ctx_t *ctx)
{
- struct disk_dump_priv *ddp = ctx->shared->fmtdata;
struct makedumpfile_data_header hdr;
addrxlat_range_t range;
int64_t pos, size;
@@ -1083,8 +1098,8 @@ init_flattened_file(kdump_ctx_t *ctx)
off_t flatpos;
kdump_status status;
- ddp->flatmap->map = addrxlat_map_new();
- if (!ddp->flatmap->map)
+ fmap->map = addrxlat_map_new();
+ if (!fmap->map)
return set_error(ctx, KDUMP_ERR_SYSTEM,
"Cannot allocate %s", "flattened map");
@@ -1116,20 +1131,20 @@ init_flattened_file(kdump_ctx_t *ctx)
unsigned newlen = segidx + FLATOFFS_ALLOC_INC;
off_t *newbuf;
- newbuf = realloc(ddp->flatmap->offs,
- sizeof(*ddp->flatmap->offs) * newlen);
+ newbuf = realloc(fmap->offs,
+ sizeof(*fmap->offs) * newlen);
if (!newbuf)
return set_error(ctx, KDUMP_ERR_SYSTEM,
"Cannot allocate %s",
"flattened offset array");
- ddp->flatmap->offs = newbuf;
+ fmap->offs = newbuf;
}
flatpos += sizeof(hdr);
- ddp->flatmap->offs[segidx] = flatpos - pos;
+ fmap->offs[segidx] = flatpos - pos;
range.endoff = size - 1;
range.meth = segidx;
- if (addrxlat_map_set(ddp->flatmap->map, pos, &range) != ADDRXLAT_OK)
+ if (addrxlat_map_set(fmap->map, pos, &range) != ADDRXLAT_OK)
return set_error(ctx, KDUMP_ERR_SYSTEM,
"Cannot allocate %s",
"flattened map entry");
@@ -1140,24 +1155,43 @@ init_flattened_file(kdump_ctx_t *ctx)
return KDUMP_OK;
}
+static void
+flatmap_file_cleanup(struct flattened_file_map *fmap)
+{
+ if (fmap->map)
+ addrxlat_map_decref(fmap->map);
+ if (fmap->offs)
+ free(fmap->offs);
+}
+
+/** Allocate a flattened dump map.
+ * @returns Flattened offset map, or @c NULL on error.
+ */
+static struct flattened_map*
+flatmap_alloc(void)
+{
+ struct flattened_map *map;
+
+ map = calloc(1, sizeof(*map));
+ return map;
+}
+
/** Initialize flattened dump maps for all files.
+ * @param map Flattened offset map.
* @param ctx Dump file object.
* @returns Error status.
*
* Initialize flattened dump maps for all files.
*/
static kdump_status
-init_flattened_maps(kdump_ctx_t *ctx)
+flatmap_init(struct flattened_map *map, kdump_ctx_t *ctx)
{
- struct disk_dump_priv *ddp = ctx->shared->fmtdata;
kdump_status status;
- ddp->flatmap = calloc(1, sizeof(*ddp->flatmap));
- if (!ddp->flatmap)
- return set_error(ctx, KDUMP_ERR_SYSTEM,
- "Cannot allocate %s", "flatmap array");
+ map->fcache = ctx->shared->fcache;
+ fcache_incref(map->fcache);
- status = init_flattened_file(ctx);
+ status = flatmap_file_init(&map->fmap, ctx);
if (status != KDUMP_OK)
return set_error(ctx, status,
"Cannot rearrange file");
@@ -1165,6 +1199,17 @@ init_flattened_maps(kdump_ctx_t *ctx)
return KDUMP_OK;
}
+static void
+flatmap_free(struct flattened_map *map)
+{
+ if (!map)
+ return;
+ flatmap_file_cleanup(&map->fmap);
+ if (map->fcache)
+ fcache_decref(map->fcache);
+ free(map);
+}
+
static kdump_status
diskdump_probe(kdump_ctx_t *ctx)
{
@@ -1185,6 +1230,7 @@ diskdump_probe(kdump_ctx_t *ctx)
if (!memcmp(hdr, magic_flattened, sizeof magic_flattened)) {
struct makedumpfile_header *flathdr =
(struct makedumpfile_header*) hdr;
+ struct disk_dump_priv *ddp;
if (be64toh(flathdr->type) != MDF_TYPE_FLAT_HEADER)
return set_error(ctx, KDUMP_ERR_NOTIMPL,
@@ -1199,11 +1245,18 @@ diskdump_probe(kdump_ctx_t *ctx)
if (status != KDUMP_OK)
return status;
- status = init_flattened_maps(ctx);
+ ddp = ctx->shared->fmtdata;
+ ddp->flatmap = flatmap_alloc();
+ if (!ddp->flatmap)
+ return set_error(ctx, KDUMP_ERR_SYSTEM,
+ "Cannot allocate %s",
+ "flattened dump maps");
+
+ status = flatmap_init(ddp->flatmap, ctx);
if (status != KDUMP_OK)
return status;
- status = flattened_pread(ctx, &hdr, sizeof hdr, 0);
+ status = flatmap_pread(ddp->flatmap, &hdr, sizeof hdr, 0);
if (status != KDUMP_OK)
return set_error(ctx, status, "Cannot read dump header");
strcpy(desc, "Flattened ");
@@ -1244,13 +1297,7 @@ diskdump_cleanup(struct kdump_shared *sh
if (ddp) {
if (ddp->pfn_rgn)
free(ddp->pfn_rgn);
- if (ddp->flatmap) {
- if (ddp->flatmap->map)
- addrxlat_map_decref(ddp->flatmap->map);
- if (ddp->flatmap->offs)
- free(ddp->flatmap->offs);
- free(ddp->flatmap);
- }
+ flatmap_free(ddp->flatmap);
free(ddp);
shared->fmtdata = NULL;
}