direct-io.hg

view tools/libxc/xc_core.c @ 11485:ef3a08ab559f

Revert 11475:11645dda144c3c8365dd2a6a64cb5a7d7da01170
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Mon Sep 18 14:25:26 2006 +0100 (2006-09-18)
parents 11645dda144c
children
line source
1 #include "xg_private.h"
2 #include <stdlib.h>
3 #include <unistd.h>
5 /* number of pages to write at a time */
6 #define DUMP_INCREMENT (4 * 1024)
7 #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
9 static int
10 copy_from_domain_page(int xc_handle,
11 uint32_t domid,
12 unsigned long mfn,
13 void *dst_page)
14 {
15 void *vaddr = xc_map_foreign_range(
16 xc_handle, domid, PAGE_SIZE, PROT_READ, mfn);
17 if ( vaddr == NULL )
18 return -1;
19 memcpy(dst_page, vaddr, PAGE_SIZE);
20 munmap(vaddr, PAGE_SIZE);
21 return 0;
22 }
24 int
25 xc_domain_dumpcore_via_callback(int xc_handle,
26 uint32_t domid,
27 void *args,
28 dumpcore_rtn_t dump_rtn)
29 {
30 unsigned long nr_pages;
31 xen_pfn_t *page_array = NULL;
32 xc_dominfo_t info;
33 int i, nr_vcpus = 0;
34 char *dump_mem, *dump_mem_start = NULL;
35 struct xc_core_header header;
36 vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
37 char dummy[PAGE_SIZE];
38 int dummy_len;
39 int sts;
41 if ( (dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL )
42 {
43 PERROR("Could not allocate dump_mem");
44 goto error_out;
45 }
47 if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 )
48 {
49 PERROR("Could not get info for domain");
50 goto error_out;
51 }
53 if ( domid != info.domid )
54 {
55 PERROR("Domain %d does not exist", domid);
56 goto error_out;
57 }
59 for ( i = 0; i <= info.max_vcpu_id; i++ )
60 if ( xc_vcpu_getcontext(xc_handle, domid, i, &ctxt[nr_vcpus]) == 0)
61 nr_vcpus++;
63 nr_pages = info.nr_pages;
65 header.xch_magic = XC_CORE_MAGIC;
66 header.xch_nr_vcpus = nr_vcpus;
67 header.xch_nr_pages = nr_pages;
68 header.xch_ctxt_offset = sizeof(struct xc_core_header);
69 header.xch_index_offset = sizeof(struct xc_core_header) +
70 sizeof(vcpu_guest_context_t)*nr_vcpus;
71 dummy_len = (sizeof(struct xc_core_header) +
72 (sizeof(vcpu_guest_context_t) * nr_vcpus) +
73 (nr_pages * sizeof(xen_pfn_t)));
74 header.xch_pages_offset = round_pgup(dummy_len);
76 sts = dump_rtn(args, (char *)&header, sizeof(struct xc_core_header));
77 if ( sts != 0 )
78 goto error_out;
80 sts = dump_rtn(args, (char *)&ctxt, sizeof(ctxt[0]) * nr_vcpus);
81 if ( sts != 0 )
82 goto error_out;
84 if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL )
85 {
86 IPRINTF("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 {
91 IPRINTF("Could not get the page frame list\n");
92 goto error_out;
93 }
94 sts = dump_rtn(args, (char *)page_array, nr_pages * sizeof(xen_pfn_t));
95 if ( sts != 0 )
96 goto error_out;
98 /* Pad the output data to page alignment. */
99 memset(dummy, 0, PAGE_SIZE);
100 sts = dump_rtn(args, dummy, header.xch_pages_offset - dummy_len);
101 if ( sts != 0 )
102 goto error_out;
104 for ( dump_mem = dump_mem_start, i = 0; i < nr_pages; i++ )
105 {
106 copy_from_domain_page(xc_handle, domid, page_array[i], dump_mem);
107 dump_mem += PAGE_SIZE;
108 if ( ((i + 1) % DUMP_INCREMENT == 0) || ((i + 1) == nr_pages) )
109 {
110 sts = dump_rtn(args, dump_mem_start, dump_mem - dump_mem_start);
111 if ( sts != 0 )
112 goto error_out;
113 dump_mem = dump_mem_start;
114 }
115 }
117 free(dump_mem_start);
118 free(page_array);
119 return 0;
121 error_out:
122 free(dump_mem_start);
123 free(page_array);
124 return -1;
125 }
127 /* Callback args for writing to a local dump file. */
128 struct dump_args {
129 int fd;
130 };
132 /* Callback routine for writing to a local dump file. */
133 static int local_file_dump(void *args, char *buffer, unsigned int length)
134 {
135 struct dump_args *da = args;
136 int bytes, offset;
138 for ( offset = 0; offset < length; offset += bytes )
139 {
140 bytes = write(da->fd, &buffer[offset], length-offset);
141 if ( bytes <= 0 )
142 {
143 PERROR("Failed to write buffer: %s", strerror(errno));
144 return -errno;
145 }
146 }
148 return 0;
149 }
151 int
152 xc_domain_dumpcore(int xc_handle,
153 uint32_t domid,
154 const char *corename)
155 {
156 struct dump_args da;
157 int sts;
159 if ( (da.fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0 )
160 {
161 PERROR("Could not open corefile %s: %s", corename, strerror(errno));
162 return -errno;
163 }
165 sts = xc_domain_dumpcore_via_callback(
166 xc_handle, domid, &da, &local_file_dump);
168 close(da.fd);
170 return sts;
171 }
173 /*
174 * Local variables:
175 * mode: C
176 * c-set-style: "BSD"
177 * c-basic-offset: 4
178 * tab-width: 4
179 * indent-tabs-mode: nil
180 * End:
181 */