ia64/xen-unstable

view tools/libxc/xc_core.c @ 6946:e703abaf6e3d

Add behaviour to the remove methods to remove the transaction's path itself. This allows us to write Remove(path) to remove the specified path rather than having to slice the path ourselves.
author emellor@ewan
date Sun Sep 18 14:42:13 2005 +0100 (2005-09-18)
parents 3233e7ecfa9f
children 619e3d6f01b3 3133e64d0462
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 }