File: listxendoms.c

package info (click to toggle)
libkdumpfile 0.5.5-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,156 kB
  • sloc: ansic: 36,541; sh: 4,219; python: 1,569; makefile: 812
file content (126 lines) | stat: -rw-r--r-- 2,731 bytes parent folder | download | duplicates (2)
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;
}