Skip to content

Commit

Permalink
Merge branch 'refs/heads/upstream-HEAD' into repo-HEAD
Browse files Browse the repository at this point in the history
  • Loading branch information
Delphix Engineering committed Nov 19, 2023
2 parents e89e370 + c6cc356 commit 4593db9
Show file tree
Hide file tree
Showing 14 changed files with 255 additions and 51 deletions.
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
next
----

0.5.4
-----
* Full support for 64-bit RISC-V.
* Improve error messages (detailed OS error, optional file names)
* Bug fixes and minor performance tweaks.

0.5.3
-----
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
dnl Package release versioning
m4_define([pkg_major_version], [0])
m4_define([pkg_minor_version], [5])
m4_define([pkg_micro_version], [3])
m4_define([pkg_micro_version], [4])
m4_define([pkg_version],
[pkg_major_version.pkg_minor_version.pkg_micro_version])

Expand Down
2 changes: 1 addition & 1 deletion src/addrxlat/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ libaddrxlat_la_SOURCES = \
s390x.c \
x86_64.c

libaddrxlat_la_LDFLAGS = -version-info 4:2:1
libaddrxlat_la_LDFLAGS = -version-info 4:3:1

if HAVE_LD_VERSION_SCRIPT
libaddrxlat_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libaddrxlat.map
Expand Down
47 changes: 3 additions & 44 deletions src/kdumpfile/devmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
#include <endian.h>
#include <sys/sysmacros.h>

#define FN_VMCOREINFO "/sys/kernel/vmcoreinfo"
#define FN_IOMEM "/proc/iomem"
#define FN_XEN "/proc/xen"
#define FN_XEN_CAPS FN_XEN "/capabilities"
Expand Down Expand Up @@ -112,47 +111,6 @@ check_xen(kdump_ctx_t *ctx)
return KDUMP_OK;
}

static kdump_status
get_vmcoreinfo(kdump_ctx_t *ctx)
{
FILE *f;
unsigned long long addr;
size_t length;
void *info;
kdump_status ret;

f = fopen(FN_VMCOREINFO, "r");
if (!f)
return errno == ENOENT
? KDUMP_OK
: set_error(ctx, KDUMP_ERR_SYSTEM,
"Cannot open %s", FN_VMCOREINFO);

if (fscanf(f, "%llx %zx", &addr, &length) == 2)
ret = KDUMP_OK;
else if (ferror(f))
ret = set_error(ctx, KDUMP_ERR_SYSTEM,
"Error reading %s", FN_VMCOREINFO);
else
ret = set_error(ctx, KDUMP_ERR_CORRUPT,
"Error parsing %s: Wrong file format",
FN_VMCOREINFO);
fclose(f);
if (ret != KDUMP_OK)
return ret;

info = ctx_malloc(length, ctx, "VMCOREINFO buffer");
if (!info)
return KDUMP_ERR_SYSTEM;

ret = read_locked(ctx, KDUMP_MACHPHYSADDR, addr, info, &length);
if (ret == KDUMP_OK)
ret = process_notes(ctx, info, length);

free(info);
return ret;
}

static kdump_status
check_kcode(kdump_ctx_t *ctx, char *line, kdump_paddr_t *paddr)
{
Expand Down Expand Up @@ -199,7 +157,7 @@ linux_iomem_kcode(kdump_ctx_t *ctx, kdump_paddr_t *paddr)
return errno == ENOENT
? KDUMP_ERR_NODATA
: set_error(ctx, KDUMP_ERR_SYSTEM,
"Cannot open %s", FN_VMCOREINFO);
"Cannot open %s", FN_IOMEM);

line = NULL;
linealloc = 0;
Expand Down Expand Up @@ -370,7 +328,8 @@ devmem_probe(kdump_ctx_t *ctx)
if (ret != KDUMP_OK)
return ret;

get_vmcoreinfo(ctx);
read_current_vmcoreinfo(ctx);
clear_error(ctx);

return KDUMP_OK;
}
Expand Down
28 changes: 23 additions & 5 deletions src/kdumpfile/elfdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
#include <unistd.h>
#include <elf.h>

#include <sys/statfs.h>
#include <linux/magic.h>

/* This definition is missing from older version of <elf.h> */
#ifndef EM_AARCH64
# define EM_AARCH64 183
Expand Down Expand Up @@ -459,9 +462,10 @@ elf_get_bits(struct kdump_shared *shared,
set_bits(bits, cur - first, last - first);
return;
}
set_bits(bits, cur - first, next - first);

cur = next + 1;
if (cur <= next) {
set_bits(bits, cur - first, next - first);
cur = next + 1;
}
++pls;
} while (pls < &edp->load_sorted[edp->num_load_sorted]);

Expand Down Expand Up @@ -557,8 +561,9 @@ elf_find_clear(kdump_errmsg_t *err, struct kdump_shared *shared,
while (pls < &edp->load_sorted[edp->num_load_sorted] &&
*idx >= addr_to_pfn(shared, pls->phys)) {
kdump_paddr_t size = ismem ? pls->memsz : pls->filesz;
*idx = addr_to_pfn(shared, pls->phys + size - 1);
++(*idx);
kdump_paddr_t pfn = addr_to_pfn(shared, pls->phys + size - 1);
if (pfn >= *idx)
*idx = pfn + 1;
++pls;
}
}
Expand Down Expand Up @@ -1565,6 +1570,19 @@ open_common(kdump_ctx_t *ctx)

set_addrspace_caps(ctx->xlat, as_caps);

if (!attr_isset(gattr(ctx, GKI_linux_vmcoreinfo_raw)) &&
attr_isset(gattr(ctx, GKI_linux_task_struct))) {
struct statfs stfs;

if (fstatfs(ctx->shared->fcache->info[0].fd, &stfs) < 0)
return set_error(ctx, KDUMP_ERR_SYSTEM,
"Cannot determine filesystem");
if (stfs.f_type == PROC_SUPER_MAGIC) {
read_current_vmcoreinfo(ctx);
clear_error(ctx);
}
}

return KDUMP_OK;
}

Expand Down
3 changes: 3 additions & 0 deletions src/kdumpfile/global-attr.def
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ ATTR(root, "linux", dir_linux, directory, struct attr_data *)
ATTR(linux, "version_code", linux_version_code, number, unsigned,
.ops = &linux_version_code_ops)

/* NT_TASKSTRUCT */
ATTR(linux, "task_struct", linux_task_struct, blob, kdump_blob_t *)

/* utsname */
ATTR(linux, "uts", dir_linux_uts, directory, struct attr_data *)
ATTR(linux_uts, "sysname", linux_uts_sysname, string, const char *)
Expand Down
3 changes: 3 additions & 0 deletions src/kdumpfile/kdumpfile-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,9 @@ INTERNAL_DECL(kdump_status, read_blob_attr,
(kdump_ctx_t *ctx, unsigned fidx, off_t off, size_t size,
enum global_keyidx attr, const char *desc));

INTERNAL_DECL(kdump_status, read_current_vmcoreinfo,
(kdump_ctx_t *ctx));

/** Definition of a derived attribute.
*
* This structure is used to translate raw binary data to an attribute
Expand Down
30 changes: 30 additions & 0 deletions src/kdumpfile/notes.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,34 @@ typedef kdump_status do_note_fn(kdump_ctx_t *ctx, Elf32_Word type,
const char *name, size_t namesz,
void *desc, size_t descsz);

/** Process a NT_TASKSTRUCT note.
* @ctx Dump file context.
* @data NT_TASKSTRUCT payload.
* @size Size of @p data.
* @returns Error status.
*/
static kdump_status
process_task_struct(kdump_ctx_t *ctx, void *data, size_t size)
{
kdump_attr_value_t val;
kdump_status status;

val.blob = internal_blob_new_dup(data, size);
if (!val.blob)
return set_error(ctx, KDUMP_ERR_SYSTEM,
"Blob allocation failed");

status = set_attr(ctx, gattr(ctx, GKI_linux_task_struct),
ATTR_DEFAULT, &val);
if (status != KDUMP_OK) {
internal_blob_decref(val.blob);
return set_error(ctx, status,
"Cannot set attribute");
}

return status;
}

/* These fields in kdump_ctx_t must be initialised:
*
* arch_ops
Expand All @@ -148,6 +176,8 @@ process_core_note(kdump_ctx_t *ctx, uint32_t type,
if (ctx->shared->arch_ops && ctx->shared->arch_ops->process_prstatus)
return ctx->shared->arch_ops->process_prstatus(
ctx, desc, descsz);
} else if (type == NT_TASKSTRUCT) {
return process_task_struct(ctx, desc, descsz);
}

return KDUMP_OK;
Expand Down
50 changes: 50 additions & 0 deletions src/kdumpfile/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
# include <zlib.h>
#endif

#define FN_VMCOREINFO "/sys/kernel/vmcoreinfo"

/** Set an error message, returning @c kdump_status.
* @arg err Error message object.
* @arg status Status code.
Expand Down Expand Up @@ -1356,6 +1358,54 @@ read_blob_attr(kdump_ctx_t *ctx, unsigned fidx, off_t off, size_t size,
return ret;
}

/** Read running kernel's VMCOREINFO from
* @param ctx Dump file object.
* @returns Error status.
*
* Get VMCOREINFO location from /sys/kernel/vmcoreinfo and parse it
* using the currently opened dump file (which should be a live dump).
*/
kdump_status
read_current_vmcoreinfo(kdump_ctx_t *ctx)
{
FILE *f;
unsigned long long addr;
size_t length;
void *info;
kdump_status ret;

f = fopen(FN_VMCOREINFO, "r");
if (!f)
return errno == ENOENT
? KDUMP_OK
: set_error(ctx, KDUMP_ERR_SYSTEM,
"Cannot open %s", FN_VMCOREINFO);

if (fscanf(f, "%llx %zx", &addr, &length) == 2)
ret = KDUMP_OK;
else if (ferror(f))
ret = set_error(ctx, KDUMP_ERR_SYSTEM,
"Error reading %s", FN_VMCOREINFO);
else
ret = set_error(ctx, KDUMP_ERR_CORRUPT,
"Error parsing %s: Wrong file format",
FN_VMCOREINFO);
fclose(f);
if (ret != KDUMP_OK)
return ret;

info = ctx_malloc(length, ctx, "VMCOREINFO buffer");
if (!info)
return KDUMP_ERR_SYSTEM;

ret = read_locked(ctx, KDUMP_MACHPHYSADDR, addr, info, &length);
if (ret == KDUMP_OK)
ret = process_notes(ctx, info, length);

free(info);
return ret;
}

/** Get file name for error messages.
* @param ctx Dump file object.
* @param fidx File index.
Expand Down
3 changes: 3 additions & 0 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,15 @@ test_scripts = \
elf-prstatus-riscv64 \
elf-prstatus-s390x \
elf-prstatus-x86_64 \
elf-task_struct \
elf-basic \
elf-be \
elf-le \
elf-nonexistent \
elf-partial \
elf-fractional \
elf-multiread \
elf-overlap \
elf-virt-phys-clash \
elf-vmcoreinfo \
elf-dom0-no-phys_base \
Expand Down Expand Up @@ -350,6 +352,7 @@ dist_check_DATA = \
elf-prstatus-riscv64.data \
elf-prstatus-s390x.data \
elf-prstatus-x86_64.data \
elf-task_struct.data \
elf-endian.data \
elf-be16.expect \
elf-be32.expect \
Expand Down
19 changes: 19 additions & 0 deletions tests/checkattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,12 @@ check_attr_bmp(kdump_ctx_t *ctx, char *key, const struct number_array *expect)
return TEST_FAIL;

}
if (clear < bit) {
puts("FAILED");
fprintf(stderr, "Invalid %s bit: %" KDUMP_PRIuADDR
" < %" KDUMP_PRIuADDR "\n", "clear", clear, bit);
return TEST_FAIL;
}

status = kdump_bmp_find_set(attr.val.bitmap, &set);
if (status == KDUMP_ERR_NODATA) {
Expand All @@ -209,6 +215,19 @@ check_attr_bmp(kdump_ctx_t *ctx, char *key, const struct number_array *expect)
return TEST_FAIL;

}
if (set < bit) {
puts("FAILED");
fprintf(stderr, "Invalid %s bit: %" KDUMP_PRIuADDR
" < %" KDUMP_PRIuADDR "\n", "set", set, bit);
return TEST_FAIL;
}

if (set == clear) {
puts("FAILED");
fprintf(stderr, "Bit %" KDUMP_PRIuADDR " both %s and %s\n",
set, "clear", "set");
return TEST_FAIL;
}

for (next = bit; next < clear; ++next)
if (bit_value(expect, next) == 0) {
Expand Down
Loading

0 comments on commit 4593db9

Please sign in to comment.