[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] The existing xc_domain_dumpcore is very specific to disk/file based
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 1439cfa5ee8c1ee5a1d3e6ade3ab0185afc329e7 # Parent 68b4edadd1614f9cae7e1951dd35dc7b52d28d27 The existing xc_domain_dumpcore is very specific to disk/file based output. Refactor the code slightly to allow more user-specified control. This is done by adding a parallel xc_domain_dumpcore_via_callback, which allows the specification of a callback routine and an opaque argument block. The existing dumpcore routine is modified to use the callback for all write operations and to turn the single seek into a small write (it's for page alignment). Signed-off-by: Ben Thomas <bthomas@xxxxxxxxxxxxxxx> diff -r 68b4edadd161 -r 1439cfa5ee8c tools/libxc/xc_core.c --- a/tools/libxc/xc_core.c Mon Mar 13 10:10:27 2006 +++ b/tools/libxc/xc_core.c Mon Mar 13 10:47:56 2006 @@ -26,98 +26,150 @@ } int -xc_domain_dumpcore(int xc_handle, - uint32_t domid, - const char *corename) +xc_domain_dumpcore_via_callback(int xc_handle, + uint32_t domid, + void *args, + dumpcore_rtn_t dump_rtn) { unsigned long nr_pages; unsigned long *page_array; xc_dominfo_t info; - int i, nr_vcpus = 0, dump_fd; + int i, nr_vcpus = 0; char *dump_mem, *dump_mem_start = NULL; struct xc_core_header header; vcpu_guest_context_t ctxt[MAX_VIRT_CPUS]; + char dummy[PAGE_SIZE]; + int dummy_len; + int sts; - - if ((dump_fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0) { - PERROR("Could not open corefile %s: %s", corename, strerror(errno)); - goto error_out; - } - - if ((dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL) { + if ( (dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL ) + { PERROR("Could not allocate dump_mem"); goto error_out; } - if (xc_domain_getinfo(xc_handle, domid, 1, &info) != 1) { + if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 ) + { PERROR("Could not get info for domain"); goto error_out; } - if (domid != info.domid) { + if ( domid != info.domid ) + { PERROR("Domain %d does not exist", domid); goto error_out; } - for (i = 0; i <= info.max_vcpu_id; i++) - if (xc_vcpu_getcontext(xc_handle, domid, - i, &ctxt[nr_vcpus]) == 0) + for ( i = 0; i <= info.max_vcpu_id; i++ ) + if ( xc_vcpu_getcontext(xc_handle, domid, i, &ctxt[nr_vcpus]) == 0) nr_vcpus++; nr_pages = info.nr_pages; - header.xch_magic = XC_CORE_MAGIC; + header.xch_magic = XC_CORE_MAGIC; header.xch_nr_vcpus = nr_vcpus; header.xch_nr_pages = nr_pages; header.xch_ctxt_offset = sizeof(struct xc_core_header); header.xch_index_offset = sizeof(struct xc_core_header) + sizeof(vcpu_guest_context_t)*nr_vcpus; - header.xch_pages_offset = round_pgup(sizeof(struct xc_core_header) + - (sizeof(vcpu_guest_context_t) * nr_vcpus) + - (nr_pages * sizeof(unsigned long))); + dummy_len = (sizeof(struct xc_core_header) + + (sizeof(vcpu_guest_context_t) * nr_vcpus) + + (nr_pages * sizeof(unsigned long))); + header.xch_pages_offset = round_pgup(dummy_len); + + sts = dump_rtn(args, (char *)&header, sizeof(struct xc_core_header)); + if ( sts != 0 ) + return sts; - if (write(dump_fd, &header, sizeof(struct xc_core_header)) < 0 || - write(dump_fd, &ctxt, sizeof(ctxt[0]) * nr_vcpus) < 0) + sts = dump_rtn(args, (char *)&ctxt, sizeof(ctxt[0]) * nr_vcpus); + if ( sts != 0 ) + return sts; + + if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ) { - PERROR("write failed"); - goto error_out; - } - - if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) { printf("Could not allocate memory\n"); goto error_out; } - if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) { + if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages ) + { printf("Could not get the page frame list\n"); goto error_out; } - if (write(dump_fd, page_array, nr_pages * sizeof(unsigned long)) < 0) + sts = dump_rtn(args, (char *)page_array, nr_pages * sizeof(unsigned long)); + if ( sts != 0 ) + return sts; + + /* Pad the output data to page alignment. */ + memset(dummy, 0, PAGE_SIZE); + sts = dump_rtn(args, dummy, header.xch_pages_offset - dummy_len); + if ( sts != 0 ) + return sts; + + for ( dump_mem = dump_mem_start, i = 0; i < nr_pages; i++ ) { - PERROR("write failed"); - goto error_out; - } - lseek(dump_fd, header.xch_pages_offset, SEEK_SET); - for (dump_mem = dump_mem_start, i = 0; i < nr_pages; i++) { copy_from_domain_page(xc_handle, domid, page_array, i, dump_mem); dump_mem += PAGE_SIZE; - if (((i + 1) % DUMP_INCREMENT == 0) || (i + 1) == nr_pages) { - if (write(dump_fd, dump_mem_start, dump_mem - dump_mem_start) < - dump_mem - dump_mem_start) { - PERROR("Partial write, file system full?"); + if ( ((i + 1) % DUMP_INCREMENT == 0) || ((i + 1) == nr_pages) ) + { + sts = dump_rtn(args, dump_mem_start, dump_mem - dump_mem_start); + if ( sts != 0 ) goto error_out; - } dump_mem = dump_mem_start; } } - close(dump_fd); free(dump_mem_start); return 0; + error_out: - if (dump_fd != -1) - close(dump_fd); free(dump_mem_start); return -1; +} + +/* Callback args for writing to a local dump file. */ +struct dump_args { + int fd; +}; + +/* Callback routine for writing to a local dump file. */ +static int local_file_dump(void *args, char *buffer, unsigned int length) +{ + struct dump_args *da = args; + int bytes, offset; + + for ( offset = 0; offset < length; offset += bytes ) + { + bytes = write(da->fd, &buffer[offset], length-offset); + if ( bytes <= 0 ) + { + PERROR("Failed to write buffer: %s", strerror(errno)); + return -errno; + } + } + + return 0; +} + +int +xc_domain_dumpcore(int xc_handle, + uint32_t domid, + const char *corename) +{ + struct dump_args da; + int sts; + + if ( (da.fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0 ) + { + PERROR("Could not open corefile %s: %s", corename, strerror(errno)); + return -errno; + } + + sts = xc_domain_dumpcore_via_callback( + xc_handle, domid, &da, &local_file_dump); + + close(da.fd); + + return sts; } /* diff -r 68b4edadd161 -r 1439cfa5ee8c tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Mon Mar 13 10:10:27 2006 +++ b/tools/libxc/xenctrl.h Mon Mar 13 10:47:56 2006 @@ -139,9 +139,27 @@ uint32_t *pdomid); +/* Functions to produce a dump of a given domain + * xc_domain_dumpcore - produces a dump to a specified file + * xc_domain_dumpcore_via_callback - produces a dump, using a specified + * callback function + */ int xc_domain_dumpcore(int xc_handle, uint32_t domid, const char *corename); + +/* Define the callback function type for xc_domain_dumpcore_via_callback. + * + * This function is called by the coredump code for every "write", + * and passes an opaque object for the use of the function and + * created by the caller of xc_domain_dumpcore_via_callback. + */ +typedef int (dumpcore_rtn_t)(void *arg, char *buffer, unsigned int length); + +int xc_domain_dumpcore_via_callback(int xc_handle, + uint32_t domid, + void *arg, + dumpcore_rtn_t dump_rtn); /* * This function sets the maximum number of vcpus that a domain may create. @@ -372,13 +390,13 @@ unsigned long nr_extents, unsigned int extent_order, unsigned int address_bits, - unsigned long *extent_start); + unsigned long *extent_start); int xc_domain_memory_decrease_reservation(int xc_handle, uint32_t domid, unsigned long nr_extents, unsigned int extent_order, - unsigned long *extent_start); + unsigned long *extent_start); int xc_domain_memory_populate_physmap(int xc_handle, uint32_t domid, @@ -411,7 +429,7 @@ uint8_t allow_access); unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid, - unsigned long mfn); + unsigned long mfn); typedef dom0_perfc_desc_t xc_perfc_desc_t; /* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */ @@ -457,7 +475,7 @@ * @parm virt the virtual address to translate */ unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom, - int vcpu, unsigned long long virt); + int vcpu, unsigned long long virt); int xc_get_pfn_list(int xc_handle, uint32_t domid, unsigned long *pfn_buf, unsigned long max_pfns); @@ -467,7 +485,7 @@ unsigned int start_page, unsigned int nr_pages); int xc_copy_to_domain_page(int xc_handle, uint32_t domid, - unsigned long dst_pfn, const char *src_page); + unsigned long dst_pfn, const char *src_page); int xc_clear_domain_page(int xc_handle, uint32_t domid, unsigned long dst_pfn); @@ -478,7 +496,7 @@ long xc_get_max_pages(int xc_handle, uint32_t domid); int xc_mmuext_op(int xc_handle, struct mmuext_op *op, unsigned int nr_ops, - domid_t dom); + domid_t dom); int xc_memory_op(int xc_handle, int cmd, void *arg); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |