ia64/xen-unstable

view tools/libxc/xc_core.c @ 7238:971e7c7411b3

Raise an exception if an error appears on the pipes to our children, and make
sure that the child's pipes are closed even under that exception. Move the
handling of POLLHUP to the end of the loop, so that we guarantee to read any
remaining data from the child if POLLHUP and POLLIN appear at the same time.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@ewan
date Thu Oct 06 10:13:11 2005 +0100 (2005-10-06)
parents 06d84bf87159
children b3a255e88810
line source
1 #include "xg_private.h"
2 #define ELFSIZE 32
3 #include "xc_elf.h"
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <zlib.h>
8 /* number of pages to write at a time */
9 #define DUMP_INCREMENT 4 * 1024
10 #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
12 static int
13 copy_from_domain_page(int xc_handle,
14 u32 domid,
15 unsigned long *page_array,
16 unsigned long src_pfn,
17 void *dst_page)
18 {
19 void *vaddr = xc_map_foreign_range(
20 xc_handle, domid, PAGE_SIZE, PROT_READ, page_array[src_pfn]);
21 if ( vaddr == NULL )
22 return -1;
23 memcpy(dst_page, vaddr, PAGE_SIZE);
24 munmap(vaddr, PAGE_SIZE);
25 return 0;
26 }
28 int
29 xc_domain_dumpcore(int xc_handle,
30 u32 domid,
31 const char *corename)
32 {
33 unsigned long nr_pages;
34 unsigned long *page_array;
35 xc_dominfo_t info;
36 int i, j, vcpu_map_size, dump_fd;
37 char *dump_mem, *dump_mem_start = NULL;
38 struct xc_core_header header;
39 vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
42 if ((dump_fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0) {
43 PERROR("Could not open corefile %s: %s", corename, strerror(errno));
44 goto error_out;
45 }
47 if ((dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL) {
48 PERROR("Could not allocate dump_mem");
49 goto error_out;
50 }
52 if (xc_domain_getinfo(xc_handle, domid, 1, &info) != 1) {
53 PERROR("Could not get info for domain");
54 goto error_out;
55 }
57 vcpu_map_size = sizeof(info.vcpu_to_cpu) / sizeof(info.vcpu_to_cpu[0]);
59 for (i = 0, j = 0; i < vcpu_map_size; i++) {
60 if (info.vcpu_to_cpu[i] == -1) {
61 continue;
62 }
63 if (xc_domain_get_vcpu_context(xc_handle, domid, i, &ctxt[j])) {
64 PERROR("Could not get all vcpu contexts for domain");
65 goto error_out;
66 }
67 j++;
68 }
70 nr_pages = info.nr_pages;
72 header.xch_magic = 0xF00FEBED;
73 header.xch_nr_vcpus = info.vcpus;
74 header.xch_nr_pages = nr_pages;
75 header.xch_ctxt_offset = sizeof(struct xc_core_header);
76 header.xch_index_offset = sizeof(struct xc_core_header) +
77 sizeof(vcpu_guest_context_t)*info.vcpus;
78 header.xch_pages_offset = round_pgup(sizeof(struct xc_core_header) +
79 (sizeof(vcpu_guest_context_t) * info.vcpus) +
80 (nr_pages * sizeof(unsigned long)));
82 write(dump_fd, &header, sizeof(struct xc_core_header));
83 write(dump_fd, &ctxt, sizeof(ctxt[0]) * info.vcpus);
85 if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
86 printf("Could not allocate memory\n");
87 goto error_out;
88 }
89 if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
90 printf("Could not get the page frame list\n");
91 goto error_out;
92 }
93 write(dump_fd, page_array, nr_pages * sizeof(unsigned long));
94 lseek(dump_fd, header.xch_pages_offset, SEEK_SET);
95 for (dump_mem = dump_mem_start, i = 0; i < nr_pages; i++) {
96 copy_from_domain_page(xc_handle, domid, page_array, i, dump_mem);
97 dump_mem += PAGE_SIZE;
98 if (((i + 1) % DUMP_INCREMENT == 0) || (i + 1) == nr_pages) {
99 if (write(dump_fd, dump_mem_start, dump_mem - dump_mem_start) <
100 dump_mem - dump_mem_start) {
101 PERROR("Partial write, file system full?");
102 goto error_out;
103 }
104 dump_mem = dump_mem_start;
105 }
106 }
108 close(dump_fd);
109 free(dump_mem_start);
110 return 0;
111 error_out:
112 if (dump_fd != -1)
113 close(dump_fd);
114 free(dump_mem_start);
115 return -1;
116 }
118 /*
119 * Local variables:
120 * mode: C
121 * c-set-style: "BSD"
122 * c-basic-offset: 4
123 * tab-width: 4
124 * indent-tabs-mode: nil
125 * End:
126 */