1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <inttypes.h>
#include <libkdumpfile/kdumpfile.h>
static kdump_vaddr_t
read_ptr(kdump_ctx_t *ctx, kdump_vaddr_t addr)
{
uint64_t ptr;
size_t sz = sizeof ptr;
if (kdump_read(ctx, KDUMP_KVADDR, addr, &ptr, &sz) != KDUMP_OK) {
fprintf(stderr, "read failed at 0x%llx: %s\n",
(unsigned long long) addr, kdump_get_err(ctx));
return 0;
}
return ptr;
}
static kdump_status
print_xen_domains(kdump_ctx_t *ctx)
{
kdump_addr_t domain;
uint64_t id;
kdump_num_t off_id, off_next;
kdump_status status;
status = kdump_get_number_attr(
ctx, "xen.vmcoreinfo.OFFSET.domain.domain_id", &off_id);
if (status != KDUMP_OK)
return status;
status = kdump_get_number_attr(
ctx, "xen.vmcoreinfo.OFFSET.domain.next_in_list", &off_next);
if (status != KDUMP_OK)
return status;
status = kdump_vmcoreinfo_symbol(ctx, "domain_list", &domain);
if (status != KDUMP_OK)
return status;
domain -= off_next;
while ( (domain = read_ptr(ctx, domain + off_next)) ) {
size_t sz = sizeof id;
status = kdump_read(ctx, KDUMP_KVADDR, domain + off_id,
&id, &sz);
if (status != KDUMP_OK)
return status;
printf("Domain ID 0x%"PRIx64" at 0x%llx\n",
id, (unsigned long long)domain);
}
return KDUMP_OK;
}
int
main(int argc, char **argv)
{
kdump_ctx_t *ctx;
int fd;
kdump_attr_t attr;
kdump_status status;
if (argc != 2) {
fprintf(stderr, "Usage: %s <dumpfile>\n", argv[0]);
return 1;
}
fd = open(argv[1], O_RDONLY);
if (fd < 0) {
perror(argv[1]);
return 2;
}
ctx = kdump_new();
if (!ctx) {
perror("Cannot allocate kdump context");
return -1;
}
status = kdump_set_filename(ctx, argv[1]);
if (status != KDUMP_OK)
fprintf(stderr, "Warning: Cannot set file name: %s\n",
kdump_get_err(ctx));
status = kdump_open_fd(ctx, fd);
if (status != KDUMP_OK) {
fprintf(stderr, "File initialization failed: %s\n",
kdump_get_err(ctx));
kdump_free(ctx);
return 2;
}
status = kdump_get_attr(ctx, KDUMP_ATTR_XEN_TYPE, &attr);
if (status == KDUMP_ERR_NODATA ||
(status == KDUMP_OK && attr.val.number != KDUMP_XEN_SYSTEM)) {
fputs("Not a Xen system dump\n", stderr);
return 1;
} else if (status != KDUMP_OK) {
fprintf(stderr, "Cannot get Xen type: %s\n",
kdump_get_err(ctx));
kdump_free(ctx);
return 2;
}
status = kdump_set_string_attr(ctx, KDUMP_ATTR_OSTYPE, "xen");
if (status != KDUMP_OK) {
fprintf(stderr, "Cannot set ostype: %s\n",
kdump_get_err(ctx));
return 1;
}
if (print_xen_domains(ctx) != KDUMP_OK)
printf("Cannot read domains: %s\n", kdump_get_err(ctx));
kdump_free(ctx);
close(fd);
return 0;
}
|