File diskdump-Support-partially-rearranged-file-sets.patch of Package libkdumpfile.36085

From: Petr Tesarik <petr@tesarici.cz>
Date: Thu, 26 Sep 2024 12:43:22 +0200
Subject: diskdump: Support partially rearranged file sets
References: bsc#1223399
Upstream: merged
Git-commit: da6d91e818613447f31586e894615c2bc578f363

Move the flattened header handling to flatmap.c and run it separately on
every file.

When probing for a diskdump file set, always initialize the flattened map,
even if the first file is not flattened.

[ ptesarik: This patch does no longer do what the subject says, but
  it is a pre-requisite to allow flattened ELF. Other parts removed. ]
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
---
 src/kdumpfile/diskdump.c |   60 +++++++++++++----------------------------------
 src/kdumpfile/flatmap.c  |   36 ++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 43 deletions(-)
 create mode 100755 tests/diskdump-split-mixed

--- a/src/kdumpfile/diskdump.c
+++ b/src/kdumpfile/diskdump.c
@@ -47,18 +47,6 @@
 
 /** @cond TARGET_ABI */
 
-#define MDF_SIGNATURE		"makedumpfile"
-#define MDF_SIG_LEN		16
-#define MDF_TYPE_FLAT_HEADER	1
-#define MDF_VERSION_FLAT_HEADER	1
-
-/* Flattened format header. */
-struct makedumpfile_header {
-	char	signature[MDF_SIG_LEN];
-	int64_t	type;
-	int64_t	version;
-} __attribute__((packed));
-
 /* The header is architecture-dependent, unfortunately */
 struct disk_dump_header_32 {
 	char			signature[SIG_LEN];	/* = "DISKDUMP" */
@@ -907,7 +895,7 @@ init_private(kdump_ctx_t *ctx)
 				 "Cannot allocate %s",
 				 "flattened dump maps");
 
-	return KDUMP_OK;
+	return flatmap_init(ddp->flatmap, ctx);
 }
 
 static kdump_status
@@ -966,10 +954,20 @@ open_common(kdump_ctx_t *ctx, void *hdr)
 	return ret;
 }
 
+static void
+init_desc(kdump_ctx_t *ctx, char *desc)
+{
+	struct disk_dump_priv *ddp = ctx->shared->fmtdata;
+
+	if (flatmap_isflattened(ddp->flatmap))
+		strcpy(desc, "Flattened ");
+	else
+		desc[0] = '\0';
+}
+
 static kdump_status
 diskdump_probe(kdump_ctx_t *ctx)
 {
-	static const char magic_flattened[MDF_SIG_LEN] = MDF_SIGNATURE;
 	static const char magic_diskdump[] =
 		{ 'D', 'I', 'S', 'K', 'D', 'U', 'M', 'P' };
 	static const char magic_kdump[] =
@@ -979,39 +977,15 @@ diskdump_probe(kdump_ctx_t *ctx)
 	char desc[32];
 	kdump_status status;
 
-	status = fcache_pread(ctx->shared->fcache, hdr, sizeof hdr, 0);
-	if (status != KDUMP_OK)
-		return set_error(ctx, status, "Cannot read dump header");
-
 	status = init_private(ctx);
 	if (status != KDUMP_OK)
 		return status;
 
-	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,
-					 "Unknown flattened %s: %" PRId64 "\n",
-					 "type", be64toh(flathdr->type));
-		if (be64toh(flathdr->version) != MDF_VERSION_FLAT_HEADER)
-			return set_error(ctx, KDUMP_ERR_NOTIMPL,
-					 "Unknown flattened %s: %" PRId64 "\n",
-					 "version", be64toh(flathdr->version));
-
-		ddp = ctx->shared->fmtdata;
-		status = flatmap_init(ddp->flatmap, ctx);
-		if (status != KDUMP_OK)
-			return status;
-
-		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 ");
-	} else
-		desc[0] = '\0';
+	status = diskdump_pread(ctx, hdr, sizeof hdr, 0);
+	if (status != KDUMP_OK)
+		return set_error(ctx, status, "Cannot read dump header");
+
+	init_desc(ctx, desc);
 
 	if (!memcmp(hdr, magic_diskdump, sizeof magic_diskdump))
 		strcat(desc, "Diskdump");
--- a/src/kdumpfile/flatmap.c
+++ b/src/kdumpfile/flatmap.c
@@ -34,9 +34,21 @@
 
 #include <stdlib.h>
 
+#define MDF_SIGNATURE		"makedumpfile"
+#define MDF_SIG_LEN		16
+#define MDF_TYPE_FLAT_HEADER	1
+#define MDF_VERSION_FLAT_HEADER	1
+
 #define MDF_HEADER_SIZE		4096
 #define MDF_OFFSET_END_FLAG	(-(int64_t)1)
 
+/* Flattened format header. */
+struct makedumpfile_header {
+	char	signature[MDF_SIG_LEN];
+	int64_t	type;
+	int64_t	version;
+} __attribute__((packed));
+
 /* Flattened segment header */
 struct makedumpfile_data_header {
         int64_t offset;
@@ -147,6 +159,13 @@ flatmap_alloc(void)
 	return map;
 }
 
+static inline kdump_status
+err_notimpl(kdump_ctx_t *ctx, const char *what, int_fast64_t value)
+{
+	return set_error(ctx, KDUMP_ERR_NOTIMPL,
+			 "Unknown flattened %s: %" PRId64 "\n", what, value);
+}
+
 /** Initialize flattened dump maps for all files.
  * @param map  Flattened offset map.
  * @param ctx  Dump file object.
@@ -157,11 +176,28 @@ flatmap_alloc(void)
 kdump_status
 flatmap_init(struct flattened_map *map, kdump_ctx_t *ctx)
 {
+	static const char magic[MDF_SIG_LEN] = MDF_SIGNATURE;
+
+	struct makedumpfile_header hdr;
 	kdump_status status;
 
 	map->fcache = ctx->shared->fcache;
 	fcache_incref(map->fcache);
 
+	status = fcache_pread(map->fcache, &hdr, sizeof(hdr), 0);
+	if (status != KDUMP_OK)
+		return set_error(ctx, status, "Cannot read file");
+
+	if (memcmp(hdr.signature, magic, sizeof magic))
+		return KDUMP_OK;
+
+	if (be64toh(hdr.type) != MDF_TYPE_FLAT_HEADER)
+		return err_notimpl(ctx, "type",
+				   be64toh(hdr.type));
+	if (be64toh(hdr.version) != MDF_VERSION_FLAT_HEADER)
+		return err_notimpl(ctx, "version",
+				   be64toh(hdr.version));
+
 	status = flatmap_file_init(&map->fmap, ctx);
 	if (status != KDUMP_OK)
 		return set_error(ctx, status,
openSUSE Build Service is sponsored by