[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.