WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] The existing xc_domain_dumpcore is very specific to disk

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] The existing xc_domain_dumpcore is very specific to disk/file based
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 13 Mar 2006 11:56:07 +0000
Delivery-date: Mon, 13 Mar 2006 11:57:11 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] The existing xc_domain_dumpcore is very specific to disk/file based, Xen patchbot -unstable <=