ia64/xen-unstable

view tools/libxc/xc_core.c @ 6435:b4b3f6be5226

merge?
author cl349@firebug.cl.cam.ac.uk
date Thu Aug 25 17:27:49 2005 +0000 (2005-08-25)
parents 0610add7c3fe fdfd511768a3
children 8799d14bef77 9312a3e8a6f8 112d44270733
line source
1 #include "xg_private.h"
2 #define ELFSIZE 32
3 #include "xc_elf.h"
4 #include <stdlib.h>
5 #include <zlib.h>
7 /* number of pages to write at a time */
8 #define DUMP_INCREMENT 4 * 1024
9 #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
11 static int
12 copy_from_domain_page(int xc_handle,
13 u32 domid,
14 unsigned long *page_array,
15 unsigned long src_pfn,
16 void *dst_page)
17 {
18 void *vaddr = xc_map_foreign_range(
19 xc_handle, domid, PAGE_SIZE, PROT_READ, page_array[src_pfn]);
20 if ( vaddr == NULL )
21 return -1;
22 memcpy(dst_page, vaddr, PAGE_SIZE);
23 munmap(vaddr, PAGE_SIZE);
24 return 0;
25 }
27 int
28 xc_domain_dumpcore(int xc_handle,
29 u32 domid,
30 const char *corename)
31 {
32 unsigned long nr_pages;
33 unsigned long *page_array;
34 xc_dominfo_t info;
35 int i, j, vcpu_map_size, dump_fd;
36 char *dump_mem, *dump_mem_start = NULL;
37 struct xc_core_header header;
38 vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
41 if ((dump_fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0) {
42 PERROR("Could not open corefile %s: %s", corename, strerror(errno));
43 goto error_out;
44 }
46 if ((dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL) {
47 PERROR("Could not allocate dump_mem");
48 goto error_out;
49 }
51 if (xc_domain_getinfo(xc_handle, domid, 1, &info) != 1) {
52 PERROR("Could not get info for domain");
53 goto error_out;
54 }
56 vcpu_map_size = sizeof(info.vcpu_to_cpu) / sizeof(info.vcpu_to_cpu[0]);
58 for (i = 0, j = 0; i < vcpu_map_size; i++) {
59 if (info.vcpu_to_cpu[i] == -1) {
60 continue;
61 }
62 if (xc_domain_get_vcpu_context(xc_handle, domid, i, &ctxt[j])) {
63 PERROR("Could not get all vcpu contexts for domain");
64 goto error_out;
65 }
66 j++;
67 }
69 nr_pages = info.nr_pages;
71 header.xch_magic = 0xF00FEBED;
72 header.xch_nr_vcpus = info.vcpus;
73 header.xch_nr_pages = nr_pages;
74 header.xch_ctxt_offset = sizeof(struct xc_core_header);
75 header.xch_index_offset = sizeof(struct xc_core_header) +
76 sizeof(vcpu_guest_context_t)*info.vcpus;
77 header.xch_pages_offset = round_pgup(sizeof(struct xc_core_header) +
78 (sizeof(vcpu_guest_context_t) * info.vcpus) +
79 (nr_pages * sizeof(unsigned long)));
81 write(dump_fd, &header, sizeof(struct xc_core_header));
82 write(dump_fd, &ctxt, sizeof(ctxt[0]) * info.vcpus);
84 if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
85 printf("Could not allocate memory\n");
86 goto error_out;
87 }
88 if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
89 printf("Could not get the page frame list\n");
90 goto error_out;
91 }
92 write(dump_fd, page_array, nr_pages * sizeof(unsigned long));
93 lseek(dump_fd, header.xch_pages_offset, SEEK_SET);
94 for (dump_mem = dump_mem_start, i = 0; i < nr_pages; i++) {
95 copy_from_domain_page(xc_handle, domid, page_array, i, dump_mem);
96 dump_mem += PAGE_SIZE;
97 if (((i + 1) % DUMP_INCREMENT == 0) || (i + 1) == nr_pages) {
98 if (write(dump_fd, dump_mem_start, dump_mem - dump_mem_start) <
99 dump_mem - dump_mem_start) {
100 PERROR("Partial write, file system full?");
101 goto error_out;
102 }
103 dump_mem = dump_mem_start;
104 }
105 }
107 close(dump_fd);
108 free(dump_mem_start);
109 return 0;
110 error_out:
111 if (dump_fd != -1)
112 close(dump_fd);
113 free(dump_mem_start);
114 return -1;
115 }