Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP4:Update
libkdumpfile.36085
flatmap-Move-flatmap-routines-to-flatmap.c.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File flatmap-Move-flatmap-routines-to-flatmap.c.patch of Package libkdumpfile.36085
From: Petr Tesarik <petr@tesarici.cz> Date: Thu, 26 Sep 2024 11:32:30 +0200 Subject: flatmap: Move flatmap routines to flatmap.c References: bsc#1223399 Upstream: merged Git-commit: dacc72cc1d75adb31963894ca1e73271e1e28f33 Separate flattened format handling from diskdump and make the API available to other users. Signed-off-by: Petr Tesarik <ptesarik@suse.com> --- src/kdumpfile/Makefile.am | 1 src/kdumpfile/Makefile.in | 7 - src/kdumpfile/diskdump.c | 250 ------------------------------------- src/kdumpfile/flatmap.c | 271 +++++++++++++++++++++++++++++++++++++++++ src/kdumpfile/kdumpfile-priv.h | 33 ++++ 5 files changed, 310 insertions(+), 252 deletions(-) create mode 100644 src/kdumpfile/flatmap.c --- a/src/kdumpfile/Makefile.am +++ b/src/kdumpfile/Makefile.am @@ -37,6 +37,7 @@ libkdumpfile_la_SOURCES = \ diskdump.c \ elfdump.c \ fcache.c \ + flatmap.c \ ia32.c \ lkcd.c \ notes.c \ --- a/src/kdumpfile/diskdump.c +++ b/src/kdumpfile/diskdump.c @@ -51,7 +51,6 @@ #define MDF_SIG_LEN 16 #define MDF_TYPE_FLAT_HEADER 1 #define MDF_VERSION_FLAT_HEADER 1 -#define MDF_HEADER_SIZE 4096 /* Flattened format header. */ struct makedumpfile_header { @@ -60,14 +59,6 @@ struct makedumpfile_header { int64_t version; } __attribute__((packed)); -/* Flattened segment header */ -struct makedumpfile_data_header { - int64_t offset; - int64_t buf_size; -} __attribute__((packed)); - -#define MDF_OFFSET_END_FLAG (-(int64_t)1) - /* The header is architecture-dependent, unfortunately */ struct disk_dump_header_32 { char signature[SIG_LEN]; /* = "DISKDUMP" */ @@ -170,24 +161,6 @@ struct page_desc { uint64_t page_flags; /**< Page flags. */ }; -/** Offset mapping for a file in the flattened format. */ -struct flattened_file_map { - /** Map (rearranged) offset to an index in the offset arrray. */ - addrxlat_map_t *map; - - /** Differences between flattened and rearranged file offsets. */ - 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. */ @@ -228,58 +201,6 @@ struct setup_data { static void diskdump_cleanup(struct kdump_shared *shared); -/** Read buffer from a flattened dump file. - * @param map Flattened format mapping to be initialized. - * @param buf Target I/O buffer. - * @param len Length of data. - * @param pos File position. - * @returns Error status. - * - * Read data from the flattened segment(s) which contain(s) @p len bytes - * at position @p pos after rearrangement. - */ -static kdump_status -flatmap_pread(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; - off_t off; - - 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) { - size_t seglen; - - seglen = range->endoff + 1 - off; - if (seglen > len) - seglen = len; - - if (range->meth != ADDRXLAT_SYS_METH_NONE) { - off_t *flatoffs = fmap->offs; - unsigned segidx = range->meth; - kdump_status ret; - - ret = fcache_pread(map->fcache, buf, seglen, - pos + flatoffs[segidx]); - if (ret != KDUMP_OK) - return ret; - } else - memset(buf, 0, seglen); - - buf += seglen; - len -= seglen; - pos += seglen; - ++range; - off = 0; - } - - if (len) - memset(buf, 0, len); - return KDUMP_OK; -} - /** Read buffer from a diskdump file. * @param ctx Dump file object. * @param buf Target I/O buffer. @@ -300,39 +221,6 @@ diskdump_pread(kdump_ctx_t *ctx, void *b : fcache_pread(ctx->shared->fcache, buf, len, pos); } -/** Get a contiguous data chunk from a flattened dump file. - * @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. - * @returns Error status. - * - * Get a contiguous data chunk from a flattened dump file. - */ -static inline kdump_status -flatmap_get_chunk(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; - off_t off; - - 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 += 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 flatmap_pread(map, fch->data, len, pos); -} - /** Get a contiguous data chunk from a diskdump file. * @param ctx Dump file object. * @param fch File cache chunk, updated on success. @@ -1072,144 +960,6 @@ open_common(kdump_ctx_t *ctx, void *hdr) return ret; } -#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 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 -flatmap_file_init(struct flattened_file_map *fmap, kdump_ctx_t *ctx) -{ - struct makedumpfile_data_header hdr; - addrxlat_range_t range; - int64_t pos, size; - unsigned segidx; - off_t flatpos; - kdump_status status; - - fmap->map = addrxlat_map_new(); - if (!fmap->map) - return set_error(ctx, KDUMP_ERR_SYSTEM, - "Cannot allocate %s", "flattened map"); - - segidx = 0; - flatpos = MDF_HEADER_SIZE; - for (;;) { - status = fcache_pread(ctx->shared->fcache, &hdr, sizeof(hdr), - flatpos); - if (status != KDUMP_OK) - return set_error(ctx, status, - "Cannot read flattened header at %llu", - (unsigned long long) flatpos); - pos = be64toh(hdr.offset); - if (pos == MDF_OFFSET_END_FLAG) - break; - if (pos < 0) - return set_error(ctx, KDUMP_ERR_CORRUPT, - "Wrong flattened %s %"PRId64" at %llu", - "offset", pos, - (unsigned long long) flatpos); - size = be64toh(hdr.buf_size); - if (size <= 0) - return set_error(ctx, KDUMP_ERR_CORRUPT, - "Wrong flattened %s %"PRId64" at %llu", - "segment size", size, - (unsigned long long) flatpos); - - if ((segidx % FLATOFFS_ALLOC_INC) == 0) { - unsigned newlen = segidx + FLATOFFS_ALLOC_INC; - off_t *newbuf; - - newbuf = realloc(fmap->offs, - sizeof(*fmap->offs) * newlen); - if (!newbuf) - return set_error(ctx, KDUMP_ERR_SYSTEM, - "Cannot allocate %s", - "flattened offset array"); - fmap->offs = newbuf; - } - flatpos += sizeof(hdr); - fmap->offs[segidx] = flatpos - pos; - - range.endoff = size - 1; - range.meth = segidx; - if (addrxlat_map_set(fmap->map, pos, &range) != ADDRXLAT_OK) - return set_error(ctx, KDUMP_ERR_SYSTEM, - "Cannot allocate %s", - "flattened map entry"); - - ++segidx; - flatpos += size; - } - 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 -flatmap_init(struct flattened_map *map, kdump_ctx_t *ctx) -{ - kdump_status status; - - map->fcache = ctx->shared->fcache; - fcache_incref(map->fcache); - - status = flatmap_file_init(&map->fmap, ctx); - if (status != KDUMP_OK) - return set_error(ctx, status, - "Cannot rearrange file"); - - 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) { --- /dev/null +++ b/src/kdumpfile/flatmap.c @@ -0,0 +1,271 @@ +/** @internal @file src/kdumpfile/flatmap.c + * @brief Routines to handle files in the flattened format. + */ +/* Copyright (C) 2024 Petr Tesarik <petr@tesarici.cz> + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version + + or both in parallel, as here. + + libkdumpfile is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see <http://www.gnu.org/licenses/>. +*/ + +#define _GNU_SOURCE + +#include "kdumpfile-priv.h" + +#include <stdlib.h> + +#define MDF_HEADER_SIZE 4096 +#define MDF_OFFSET_END_FLAG (-(int64_t)1) + +/* Flattened segment header */ +struct makedumpfile_data_header { + int64_t offset; + int64_t buf_size; +} __attribute__((packed)); + +#define 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 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 +flatmap_file_init(struct flattened_file_map *fmap, kdump_ctx_t *ctx) +{ + struct makedumpfile_data_header hdr; + addrxlat_range_t range; + int64_t pos, size; + unsigned segidx; + off_t flatpos; + kdump_status status; + + fmap->map = addrxlat_map_new(); + if (!fmap->map) + return set_error(ctx, KDUMP_ERR_SYSTEM, + "Cannot allocate %s", "flattened map"); + + segidx = 0; + flatpos = MDF_HEADER_SIZE; + for (;;) { + status = fcache_pread(ctx->shared->fcache, &hdr, sizeof(hdr), + flatpos); + if (status != KDUMP_OK) + return set_error(ctx, status, + "Cannot read flattened header at %llu", + (unsigned long long) flatpos); + pos = be64toh(hdr.offset); + if (pos == MDF_OFFSET_END_FLAG) + break; + if (pos < 0) + return set_error(ctx, KDUMP_ERR_CORRUPT, + "Wrong flattened %s %"PRId64" at %llu", + "offset", pos, + (unsigned long long) flatpos); + size = be64toh(hdr.buf_size); + if (size <= 0) + return set_error(ctx, KDUMP_ERR_CORRUPT, + "Wrong flattened %s %"PRId64" at %llu", + "segment size", size, + (unsigned long long) flatpos); + + if ((segidx % ALLOC_INC) == 0) { + unsigned newlen = segidx + ALLOC_INC; + off_t *newbuf; + + newbuf = realloc(fmap->offs, + sizeof(*fmap->offs) * newlen); + if (!newbuf) + return set_error(ctx, KDUMP_ERR_SYSTEM, + "Cannot allocate %s", + "flattened offset array"); + fmap->offs = newbuf; + } + flatpos += sizeof(hdr); + fmap->offs[segidx] = flatpos - pos; + + range.endoff = size - 1; + range.meth = segidx; + if (addrxlat_map_set(fmap->map, pos, &range) != ADDRXLAT_OK) + return set_error(ctx, KDUMP_ERR_SYSTEM, + "Cannot allocate %s", + "flattened map entry"); + + ++segidx; + flatpos += size; + } + 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. + */ +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. + */ +kdump_status +flatmap_init(struct flattened_map *map, kdump_ctx_t *ctx) +{ + kdump_status status; + + map->fcache = ctx->shared->fcache; + fcache_incref(map->fcache); + + status = flatmap_file_init(&map->fmap, ctx); + if (status != KDUMP_OK) + return set_error(ctx, status, + "Cannot rearrange file"); + + return KDUMP_OK; +} + +/** Release all resources used by a flattened dump map. + * @param map Flattened offset map. + */ +void +flatmap_free(struct flattened_map *map) +{ + if (!map) + return; + flatmap_file_cleanup(&map->fmap); + if (map->fcache) + fcache_decref(map->fcache); + free(map); +} + +/** Read buffer from a flattened dump file. + * @param map Flattened format mapping to be initialized. + * @param buf Target I/O buffer. + * @param len Length of data. + * @param pos File position. + * @returns Error status. + * + * Read data from the flattened segment(s) which contain(s) @p len bytes + * at position @p pos after rearrangement. + */ +kdump_status +flatmap_pread(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; + off_t off; + + 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) { + size_t seglen; + + seglen = range->endoff + 1 - off; + if (seglen > len) + seglen = len; + + if (range->meth != ADDRXLAT_SYS_METH_NONE) { + off_t *flatoffs = fmap->offs; + unsigned segidx = range->meth; + kdump_status ret; + + ret = fcache_pread(map->fcache, buf, seglen, + pos + flatoffs[segidx]); + if (ret != KDUMP_OK) + return ret; + } else + memset(buf, 0, seglen); + + buf += seglen; + len -= seglen; + pos += seglen; + ++range; + off = 0; + } + + if (len) + memset(buf, 0, len); + return KDUMP_OK; +} + +/** Get a contiguous data chunk from a flattened dump file. + * @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. + * @returns Error status. + * + * 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) +{ + struct flattened_file_map *fmap = &map->fmap; + const addrxlat_range_t *range, *end; + off_t off; + + 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 += 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 flatmap_pread(map, fch->data, len, pos); +} --- a/src/kdumpfile/kdumpfile-priv.h +++ b/src/kdumpfile/kdumpfile-priv.h @@ -1505,6 +1505,39 @@ pfn_to_addr(struct kdump_shared *shared, return pfn << sget_page_shift(shared); } +/* Flattened files. */ + +/** Offset mapping for a file in the flattened format. */ +struct flattened_file_map { + /** Map (rearranged) offset to an index in the offset arrray. */ + addrxlat_map_t *map; + + /** Differences between flattened and rearranged file offsets. */ + 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; +}; + +INTERNAL_DECL(struct flattened_map *, flatmap_alloc, + (void)); +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, + (struct flattened_map *map, void *buf, size_t len, + off_t pos)); +INTERNAL_DECL(kdump_status, flatmap_get_chunk, + (struct flattened_map *map, struct fcache_chunk *fch, + size_t len, off_t pos)); + /** Check if a character is a POSIX white space. * @param c Character to check. * --- a/src/kdumpfile/Makefile.in +++ b/src/kdumpfile/Makefile.in @@ -145,8 +145,9 @@ libkdumpfile_la_DEPENDENCIES = \ $(am__DEPENDENCIES_1) am_libkdumpfile_la_OBJECTS = aarch64.lo attr.lo bitmap.lo blob.lo \ cache.lo context.lo devmem.lo diskdump.lo elfdump.lo fcache.lo \ - ia32.lo lkcd.lo notes.lo open.lo read.lo s390x.lo s390dump.lo \ - todo.lo util.lo vmcoreinfo.lo vtop.lo ppc64.lo x86_64.lo + flatmap.lo ia32.lo lkcd.lo notes.lo open.lo read.lo s390x.lo \ + s390dump.lo todo.lo util.lo vmcoreinfo.lo vtop.lo ppc64.lo \ + x86_64.lo libkdumpfile_la_OBJECTS = $(am_libkdumpfile_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -595,6 +596,7 @@ libkdumpfile_la_SOURCES = \ diskdump.c \ elfdump.c \ fcache.c \ + flatmap.c \ ia32.c \ lkcd.c \ notes.c \ @@ -734,6 +736,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskdump.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfdump.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcache.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flatmap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ia32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lkcd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/notes.Plo@am__quote@
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