[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH] Add xentrace/xen_crash.



On 10/14/13 11:03, Andrew Cooper wrote:
On 14/10/13 15:07, Don Slutz wrote:
From: Don Slutz <Don@xxxxxxxxxxxxxxx>

This allows crash to connect to a domU. Usage:

usage: xen_crash <domid> [<optional port>]

   xen_crash 1&
   crash localhost:5001 
/usr/lib/debug/lib/modules/3.8.11-100.fc17.x86_64/vmlinux

The domU will be paused while crash is connected.  Currently the code exits 
when crash disconnects.

Signed-off-by: Don Slutz <dslutz@xxxxxxxxxxx>
This looks good in principle.

However, I am not sure tools/xentrace/ is an appropriate place for it,
as it is unrelated to xentrace.
I was not sure either.  Parts are based on xenctx which is here.
Also, the name "xen_crash" is a bit too generic, and implies its purpose
is to crash a guest, rather than to attach `crash` to a guest.

What about xen-crashd, as it is a daemon?
That would be fine with me.

~Andrew
  -Don Slutz
---
  .gitignore                 |    1 +
  tools/xentrace/Makefile    |    5 +-
  tools/xentrace/xen_crash.c |  697 ++++++++++++++++++++++++++++++++++++++++++++
  3 files changed, 702 insertions(+), 1 deletions(-)
  create mode 100644 tools/xentrace/xen_crash.c

diff --git a/.gitignore b/.gitignore
index 3253675..51226f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -278,6 +278,7 @@ tools/xenstore/xs_watch_stress
  tools/xentrace/xentrace_setsize
  tools/xentrace/tbctl
  tools/xentrace/xenctx
+tools/xentrace/xen_crash
  tools/xentrace/xentrace
  tools/xm-test/ramdisk/buildroot
  tools/xm-test/aclocal.m4
diff --git a/tools/xentrace/Makefile b/tools/xentrace/Makefile
index 63b09c0..a2313c6 100644
--- a/tools/xentrace/Makefile
+++ b/tools/xentrace/Makefile
@@ -7,7 +7,7 @@ CFLAGS += $(CFLAGS_libxenctrl)
  LDLIBS += $(LDLIBS_libxenctrl)
BIN = xentrace xentrace_setsize
-LIBBIN   = xenctx
+LIBBIN   = xenctx xen_crash
  SCRIPTS  = xentrace_format
  MAN1     = $(wildcard *.1)
  MAN8     = $(wildcard *.8)
@@ -40,6 +40,9 @@ xentrace: xentrace.o
  xenctx: xenctx.o
        $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS) $(APPEND_LDFLAGS)
+xen_crash: xen_crash.o
+       $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS) $(APPEND_LDFLAGS)
+
  xentrace_setsize: setsize.o
        $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS) $(APPEND_LDFLAGS)
diff --git a/tools/xentrace/xen_crash.c b/tools/xentrace/xen_crash.c
new file mode 100644
index 0000000..6a4bb34
--- /dev/null
+++ b/tools/xentrace/xen_crash.c
@@ -0,0 +1,697 @@
+/******************************************************************************
+ * tools/xentrace/xen_crash.c
+ *
+ * Connect crash to DOMu.
+ *
+ * Copyright (C) 2012 by Cloud Switch, Inc.
+ *
+ */
+
+#include <ctype.h>
+#include <time.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <inttypes.h>
+#include <getopt.h>
+
+#include "xenctrl.h"
+#include <xen/foreign/x86_32.h>
+#include <xen/foreign/x86_64.h>
+#include <xen/hvm/save.h>
+
+xc_interface *xc_handle = 0;
+int domid = 0;
+int debug = 0;
+
+typedef unsigned long long guest_word_t;
+#define FMT_32B_WORD "%08llx"
+#define FMT_64B_WORD "%016llx"
+
+/* Word-length of the guest's own data structures */
+int guest_word_size = sizeof (unsigned long);
+/* Word-length of the context record we get from xen */
+int ctxt_word_size = sizeof (unsigned long);
+int guest_protected_mode = 1;
+
+#define MACHINE_TYPE       "X86_64"
+
+#define STRNEQ(A, B)     (B && \
+        (strncmp((char *)(A), (char *)(B), strlen((char *)(B))) == 0))
+#define FAILMSG "FAIL "
+#define DONEMSG "DONE "
+#define DATAMSG "DATA "
+
+#define DATA_HDRSIZE    13   /* strlen("XXXX ") + strlen("0131072") + NULL */
+
+#define BUFSIZE         127
+#define READBUFSIZE     DATA_HDRSIZE + XC_PAGE_SIZE
+
+#define MAX_REMOTE_FDS  10
+
+void
+print_now(void)
+{
+   struct timeval  tp;
+   struct timezone tzp;
+   char  *timeout;
+   int             imil;
+
+   gettimeofday(&tp, &tzp);
+   timeout = ctime(&tp.tv_sec);
+   imil = tp.tv_usec / 1000;
+   timeout += 4;                /* Skip day of week */
+   *(timeout + 3) = 0;          /* Trim at space after month */
+   *(timeout + 6) = 0;          /* Trim at space after day */
+   *(timeout + 15) = 0;         /* Trim at seconds. */
+   *(timeout + 20) = 0;         /* Trim after year. */
+   printf("%s %s %s %s.%.3d ", timeout + 4, timeout, timeout + 18,
+           timeout + 7, imil);
+}
+
+int
+RTTcpWrite(int Sock, const void *pvBuffer, size_t cbBuffer)
+{
+    if (debug & 4) {
+        print_now();
+        printf("rtn: %s\n", (char*)pvBuffer);
+    }
+    do
+    {
+        size_t cbNow = cbBuffer;
+        ssize_t cbWritten = send(Sock, (const char *)pvBuffer, cbNow, 
MSG_NOSIGNAL);
+
+        if (cbWritten < 0)
+            return 1;
+        cbBuffer -= cbWritten;
+        pvBuffer = (char *)pvBuffer + cbWritten;
+    } while (cbBuffer);
+
+    return 0;
+}
+
+
+static void *
+map_page(int vcpu, guest_word_t phys)
+{
+    static unsigned long previous_mfn = 0;
+    static void *mapped = NULL;
+
+    unsigned long mfn = phys >> XC_PAGE_SHIFT;
+    unsigned long offset = phys & ~XC_PAGE_MASK;
+
+    if (mapped && mfn == previous_mfn)
+        goto out;
+
+    if (mapped)
+        munmap(mapped, XC_PAGE_SIZE);
+
+    previous_mfn = mfn;
+
+    mapped = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE, PROT_READ, 
mfn);
+
+    if (mapped == NULL) {
+        if (debug & 2) {
+            print_now();
+            printf("failed to map page for %08llx.\n", phys);
+        }
+        return NULL;
+    }
+
+ out:
+    return (void *)(mapped + offset);
+}
+
+static int
+copy_phys(int vcpu, char * pvDst, size_t cb, guest_word_t phys)
+{
+    void * localAddr;
+    size_t cbPage = XC_PAGE_SIZE - (phys & ~XC_PAGE_MASK);
+
+    /* optimize for the case where access is completely within the first page. 
*/
+    localAddr = map_page(vcpu, phys);
+    if (!localAddr) {
+        return 2;
+    }
+    if (cb <= cbPage) {
+        memcpy(pvDst, localAddr, cb);
+        return 0;
+    }
+    memcpy(pvDst, localAddr, cbPage);
+    pvDst += cbPage;
+    phys += cbPage;
+    cb -= cbPage;
+
+    /* Max transfer is XC_PAGE_SIZE... */
+    if (cb > XC_PAGE_SIZE)
+        return 1;
+    localAddr = map_page(vcpu, phys);
+    if (!localAddr) {
+        return 3;
+    }
+    memcpy(pvDst, localAddr, cb);
+    return 0;
+}
+
+static guest_word_t
+convert_to_phys(int vcpu, guest_word_t virt)
+{
+    unsigned long mfn = xc_translate_foreign_address(xc_handle, domid, vcpu, 
virt);
+    unsigned long offset = virt & ~XC_PAGE_MASK;
+
+    return (mfn << XC_PAGE_SHIFT) + offset;
+}
+
+static int
+copy_virt(int vcpu, char * pvDst, size_t cb, guest_word_t virt)
+{
+    void * localAddr;
+    unsigned long mfn = xc_translate_foreign_address(xc_handle, domid, vcpu, 
virt);
+    unsigned long offset = virt & ~XC_PAGE_MASK;
+    guest_word_t phys = (mfn << XC_PAGE_SHIFT) + offset;
+    size_t cbPage = XC_PAGE_SIZE - offset;
+
+    /* optimize for the case where access is completely within the first page. 
*/
+
+    localAddr = map_page(vcpu, phys);
+    if (!localAddr) {
+        return 2;
+    }
+    if (cb <= cbPage) {
+        memcpy(pvDst, localAddr, cb);
+        return 0;
+    }
+    memcpy(pvDst, localAddr, cbPage);
+    pvDst += cbPage;
+    phys += cbPage;
+    cb -= cbPage;
+
+    /* Max transfer is XC_PAGE_SIZE... */
+    if (cb > XC_PAGE_SIZE)
+        return 1;
+    localAddr = map_page(vcpu, phys);
+    if (!localAddr) {
+        return 3;
+    }
+    memcpy(pvDst, localAddr, cb);
+    return 0;
+}
+
+int main(int argc, char **argv)
+{
+    int             port=5001;
+    int             sock;
+    unsigned int    length;
+    struct sockaddr_in server;
+    int             msgsock;
+    int             nfds;
+    int             reuseaddr;
+    int             count;
+    int             pass;
+    int             i;
+    char            recvbuf[BUFSIZE + 1];
+    char            sendbuf[READBUFSIZE + 1];
+    int             fds[MAX_REMOTE_FDS];
+    size_t          cbRead = 0;
+
+    int             ret;
+    int             vcpu;
+    vcpu_guest_context_any_t ctx;
+    xc_dominfo_t    dominfo;
+    struct hvm_hw_cpu cpuctx;
+
+    if (argc < 2 || argc > 4) {
+        printf("usage: xen_crash <domid> [<optional port>]\n");
+        exit(-1);
+    }
+
+    domid = atoi(argv[1]);
+    if (domid==0) {
+        fprintf(stderr, "cannot trace dom0\n");
+        exit(-1);
+    }
+
+    if (argc > 2)
+        port = atoi(argv[2]);
+    if (argc > 3)
+        debug = atoi(argv[3]);
+
+    signal(SIGPIPE, SIG_IGN);
+
+    sock = socket(AF_INET, SOCK_STREAM, 0);
+    if (sock < 0) {
+        perror("socket()");
+        exit(1);
+    }
+    reuseaddr = 1;
+    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseaddr,
+                   sizeof reuseaddr) < 0) {
+        perror("setsockopt()");
+        exit(2);
+    }
+    server.sin_family = AF_INET;
+    server.sin_addr.s_addr = INADDR_ANY;
+    server.sin_port = htons(port);
+    count = -1;
+    errno = EADDRINUSE;
+    for (pass=0; (errno == EADDRINUSE) && (count < 0); pass++) {
+        if ((count = bind(sock, (struct sockaddr *) & server, sizeof server)) <
+            0) {
+            if (errno != EADDRINUSE) {
+                /* printf("Errno is %d\n", errno); */
+                perror("bind()");
+                exit(3);
+            }
+            sleep(1); /* Waiting for kernel... */
+        }
+    }
+    length = sizeof server;
+    if (getsockname(sock, (struct sockaddr *) & server, &length) < 0) {
+        perror("getsockname()");
+        exit(4);
+    }
+    print_now();
+    if (pass == 1)
+        printf("Socket ready on port %d after 1 bind call\n", port);
+    else
+        printf("Socket ready on port %d after %d bind calls\n", port, pass);
+    listen(sock, 1);
+    msgsock = accept(sock, NULL, NULL);
+    if (msgsock == -1)
+        perror("accept()");
+    else {
+        print_now();
+        printf("Accepted a connection.\n");
+        close(sock); /* All done for now */
+        errno = 0;                           /* Just in case */
+        nfds = msgsock + 1;
+    }
+
+    xc_handle = xc_interface_open(0,0,0); /* for accessing control interface */
+
+    ret = xc_domain_getinfo(xc_handle, domid, 1, &dominfo);
+    if (ret < 0) {
+        perror("xc_domain_getinfo");
+        exit(-1);
+    }
+
+    ret = xc_domain_pause(xc_handle, domid);
+    if (ret < 0) {
+        perror("xc_domain_pause");
+        exit(-1);
+    }
+
+    vcpu = 0;
+    ret = xc_vcpu_getcontext(xc_handle, domid, vcpu, &ctx);
+    if (ret < 0) {
+        if (!dominfo.paused)
+            xc_domain_unpause(xc_handle, domid);
+        perror("xc_vcpu_getcontext");
+        exit(-1);
+    }
+
+    if (dominfo.hvm) {
+            xen_capabilities_info_t xen_caps = "";
+            if (xc_domain_hvm_getcontext_partial(
+                    xc_handle, domid, HVM_SAVE_CODE(CPU),
+                    vcpu, &cpuctx, sizeof cpuctx) != 0) {
+                perror("xc_domain_hvm_getcontext_partial");
+                exit(-1);
+            }
+            guest_word_size = (cpuctx.msr_efer & 0x400) ? 8 : 4;
+            guest_protected_mode = (cpuctx.cr0 & 0x1);
+            /* HVM guest context records are always host-sized */
+            if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) {
+                perror("xc_version");
+                exit(-1);
+            }
+            ctxt_word_size = (strstr(xen_caps, "xen-3.0-x86_64")) ? 8 : 4;
+    } else {
+            struct xen_domctl domctl;
+            memset(&domctl, 0, sizeof domctl);
+            domctl.domain = domid;
+            domctl.cmd = XEN_DOMCTL_get_address_size;
+            if (xc_domctl(xc_handle, &domctl) == 0)
+                ctxt_word_size = guest_word_size = domctl.u.address_size.size 
/ 8;
+    }
+
+    for (i = 0; i < MAX_REMOTE_FDS; i++)
+        fds[i] = -1;
+
+    do {
+        cbRead = recv(msgsock, recvbuf, BUFSIZE, MSG_NOSIGNAL);
+        if (cbRead <= 0) {
+            close(msgsock);
+            msgsock = -1;
+            break;
+        }
+        recvbuf[cbRead] = 0;
+
+        if (debug & 1) {
+            print_now();
+            printf("req: %s\n", recvbuf);
+        }
+
+        if (STRNEQ(recvbuf, "READ_LIVE"))
+        {
+            char *p1, *p2, *p3, *p4;
+            int rc2 = 0;
+            guest_word_t addr;
+            int fid;
+            int len;
+
+            p1 = strtok(recvbuf, " ");   /* READ_LIVE */
+            p1 = strtok(NULL, " ");      /* fid */
+            p2 = strtok(NULL, " ");      /* paddress or vaddress */
+            p3 = strtok(NULL, " ");      /* length */
+            p4 = strtok(NULL, " ");      /* vaddress or vcpu */
+
+            fid = atoi(p1);
+            addr = strtoull(p2, NULL, 16);
+            len = atoi(p3);
+            if (len < 0 || len > XC_PAGE_SIZE)
+            {
+                print_now();
+                printf("bad len=%d page_size=%ld;%s %s %s %s %s\n",
+                       len, XC_PAGE_SIZE, recvbuf, p1, p2, p3, p4);
+                len = 0;
+                rc2 = 4;
+            }
+
+            if (len)
+            {
+                if (p4 && (fds[fid] == 3)) {
+                    int myCpu = atoi(p4);
+                    guest_word_t pAddr = convert_to_phys(myCpu, addr);
+
+                    if (debug & 2) {
+                        print_now();
+                        printf("copy_virt(%d,,%d, 0x%llx)[%s %s %s %s] 
pAddr=0x%lx\n",
+                               myCpu, len, addr, p1, p2, p3, p4, (long)pAddr);
+                    }
+                    rc2 = copy_virt(myCpu, &sendbuf[DATA_HDRSIZE], len, addr);
+                } else {
+                    if (debug & 2) {
+                        print_now();
+                        printf("copy_phys(%d,,%d, 0x%llx)[%s %s %s]\n",
+                               vcpu, len, addr, p1, p2, p3);
+                    }
+                    rc2 = copy_phys(vcpu, &sendbuf[DATA_HDRSIZE], len, addr);
+                }
+                if (rc2) {
+                    if (debug & 2) {
+                        print_now();
+                        printf("Failed rc2=%d\n", rc2);
+                    }
+                    len = 0;
+                }
+            }
+
+            if (!len) {
+                snprintf(sendbuf, sizeof(sendbuf), "%s%07ld", FAILMSG, 
(ulong)rc2);
+            } else {
+                snprintf(sendbuf, sizeof(sendbuf), "%s%07ld", DONEMSG, 
(ulong)len);
+            }
+            if (RTTcpWrite(msgsock, sendbuf, len + DATA_HDRSIZE))
+                break;
+        }
+        else if (STRNEQ(recvbuf, "FETCH_LIVE_IP_SP_BP "))
+        {
+            char *p1, *p2;
+            int cpu;
+            long g2ip = 0;
+            short g2cs = 0;
+            short g2ss = 0;
+            long g2sp = 0;
+            long g2bp = 0;
+
+            p1 = strtok(recvbuf, " ");   /* FETCH_LIVE_IP_SP_BP */
+            p2 = strtok(NULL, " ");      /* cpu */
+
+            cpu = atoi(p2);
+            if (cpu != vcpu) {
+                vcpu = cpu;
+                ret = xc_vcpu_getcontext(xc_handle, domid, vcpu, &ctx);
+                if (ret < 0) {
+                    if (!dominfo.paused)
+                        xc_domain_unpause(xc_handle, domid);
+                    perror("xc_vcpu_getcontext");
+                    exit(-1);
+                }
+                if (dominfo.hvm) {
+                    if (xc_domain_hvm_getcontext_partial(
+                            xc_handle, domid, HVM_SAVE_CODE(CPU),
+                            vcpu, &cpuctx, sizeof cpuctx) != 0) {
+                        perror("xc_domain_hvm_getcontext_partial");
+                        exit(-1);
+                    }
+                }
+            }
+
+            if (ctxt_word_size == 4) {
+                struct cpu_user_regs_x86_32 * regs = &(ctx.x32.user_regs);
+
+                g2ip = regs->eip;
+                g2sp = regs->esp;
+                g2bp = regs->ebp;
+                g2cs = regs->cs;
+                g2ss = regs->ss;
+            } else {
+                struct cpu_user_regs_x86_64 * regs = &(ctx.x64.user_regs);
+
+                if (dominfo.hvm) {
+                    g2ip = cpuctx.rip;
+                    g2sp = cpuctx.rsp;
+                    g2bp = cpuctx.rbp;
+                    g2cs = cpuctx.cs_sel;
+                    g2ss = cpuctx.ss_sel;
+                    if (debug & 0x100) {
+                        if (g2ip != regs->rip) {
+                            printf("g2ip(%lx) != rip(%lx)\n", g2ip, regs->rip);
+                        }
+                        if (g2sp != regs->rsp) {
+                            printf("g2sp(%lx) != rsp(%lx)\n", g2sp, regs->rsp);
+                        }
+                        if (g2bp != regs->rbp) {
+                            printf("g2bp(%lx) != rbp(%lx)\n", g2bp, regs->rbp);
+                        }
+                        if (g2cs != regs->cs) {
+                            printf("g2cs(%x) != cs(%x)\n", g2cs, regs->cs);
+                        }
+                        if (g2ss != regs->ss) {
+                            printf("g2ss(%x) != ss(%x)\n", g2ss, regs->ss);
+                        }
+                    }
+                } else {
+                    g2ip = regs->rip;
+                    g2sp = regs->rsp;
+                    g2bp = regs->rbp;
+                    g2cs = regs->cs;
+                    g2ss = regs->ss;
+                }
+            }
+
+            snprintf(sendbuf, sizeof(sendbuf), "%s %d %04x:%lx %04x:%lx %lx",
+                     p1, cpu, g2cs, g2ip, g2ss, g2sp, g2bp);
+            if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
+                break;
+        }
+        else if (STRNEQ(recvbuf, "FETCH_LIVE_CR3 "))
+        {
+            char *p1, *p2;
+            int cpu;
+            long g2cr3 = 0;
+
+            p1 = strtok(recvbuf, " ");   /* FETCH_LIVE_CR3 */
+            p2 = strtok(NULL, " ");      /* cpu */
+
+            cpu = atoi(p2);
+            if (cpu != vcpu) {
+                vcpu = cpu;
+                ret = xc_vcpu_getcontext(xc_handle, domid, vcpu, &ctx);
+                if (ret < 0) {
+                    if (!dominfo.paused)
+                        xc_domain_unpause(xc_handle, domid);
+                    perror("xc_vcpu_getcontext");
+                    exit(-1);
+                }
+                if (dominfo.hvm) {
+                    if (xc_domain_hvm_getcontext_partial(
+                            xc_handle, domid, HVM_SAVE_CODE(CPU),
+                            vcpu, &cpuctx, sizeof cpuctx) != 0) {
+                        perror("xc_domain_hvm_getcontext_partial");
+                        exit(-1);
+                    }
+                }
+            }
+
+            if (ctxt_word_size == 4) {
+                g2cr3 = ctx.x32.ctrlreg[3];
+            } else {
+                if (dominfo.hvm) {
+                    g2cr3 = cpuctx.cr3;
+                    if (debug & 0x100) {
+                        if (g2cr3 != ctx.x64.ctrlreg[3]) {
+                            printf("g2cr3(%lx) != cr3(%lx)\n", g2cr3, 
ctx.x64.ctrlreg[3]);
+                        }
+                    }
+                } else {
+                    g2cr3 = ctx.x64.ctrlreg[3];
+                }
+            }
+
+            snprintf(sendbuf, sizeof(sendbuf), "%s %d %lx",
+                     p1, cpu, g2cr3);
+            if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
+                break;
+        }
+        else if (STRNEQ(recvbuf, "MACHINE_PID"))
+        {
+            snprintf(sendbuf, sizeof(sendbuf), "%s %s %d",
+                    recvbuf, MACHINE_TYPE, 0);
+            if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
+                break;
+        }
+        else if (STRNEQ(recvbuf, "VTOP"))
+        {
+            char *p1, *p2, *p3;
+            int cpu;
+            guest_word_t vAddr, pAddr;
+
+            p1 = strtok(recvbuf, " ");   /* VTOP */
+            p2 = strtok(NULL, " ");      /* cpu */
+            p3 = strtok(NULL, " ");      /* vaddress */
+
+            cpu = atoi(p2);
+            vAddr = strtoull(p3, NULL, 16);
+
+            pAddr = convert_to_phys(cpu, vAddr);
+
+            snprintf(sendbuf, sizeof(sendbuf), "%s %d %lx %lx",
+                     p1, cpu, (long)vAddr, (long)pAddr);
+            if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
+                break;
+        }
+        else if (STRNEQ(recvbuf, "OPEN "))
+        {
+            char *p1;
+            char *file;
+
+            p1 = strtok(recvbuf, " ");  /* OPEN */
+            file = strtok(NULL, " ");   /* filename */
+
+            for (i = 0; i < MAX_REMOTE_FDS; i++) {
+                if (fds[i] == -1)
+                    break;
+            }
+
+            if (i < MAX_REMOTE_FDS) {
+                if (STRNEQ(file, "/dev/mem"))
+                {
+                    fds[i] = 1;
+                    snprintf(sendbuf, sizeof(sendbuf), "%s %s %d O_RDONLY 
%lld", p1, file, i, 1024LL * 1024LL * 1024LL * 1024LL);
+                }
+                else if (STRNEQ(file, "/dev/kmem"))
+                {
+                    fds[i] = 2;
+                    snprintf(sendbuf, sizeof(sendbuf), "%s %s %d O_RDONLY 
%lld", p1, file, i, 1024LL * 1024LL * 1024LL * 1024LL);
+                }
+                else if (STRNEQ(file, "/dev/vmem"))
+                {
+                    fds[i] = 3;
+                    snprintf(sendbuf, sizeof(sendbuf), "%s %s %d O_RDONLY 
%lld", p1, file, i, 1024LL * 1024LL * 1024LL * 1024LL);
+                }
+                else
+                {
+                    snprintf(sendbuf, sizeof(sendbuf), "%s %s <FAIL>", p1, 
file);
+                }
+            }
+            else
+            {
+                snprintf(sendbuf, sizeof(sendbuf), "%s %s <FAIL>", p1, file);
+            }
+            if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
+                break;
+        }
+        else if (STRNEQ(recvbuf, "CLOSE "))
+        {
+            char *p1, *p2;
+
+            p1 = strtok(recvbuf, " ");   /* SIZE */
+            p2 = strtok(NULL, " ");      /* filename id */
+            snprintf(sendbuf, sizeof(sendbuf), "%s %s <FAIL>", p1, p2);
+            if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
+                break;
+        }
+        else if (STRNEQ(recvbuf, "PROC_VERSION"))
+        {
+            /*
+             * Perform the detection.
+             */
+            snprintf(sendbuf, sizeof(sendbuf), "<FAIL>");
+            if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
+                break;
+        }
+        else if (STRNEQ(recvbuf, "PAGESIZE LIVE"))
+        {
+            snprintf(sendbuf, sizeof(sendbuf), "%s %ld XEN %d",
+                     recvbuf, XC_PAGE_SIZE, dominfo.max_vcpu_id + 1);
+            if (RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
+                break;
+        }
+        else if (STRNEQ(recvbuf, "EXIT"))
+        {
+            snprintf(sendbuf, sizeof(sendbuf), "%s OK", recvbuf);
+            RTTcpWrite(msgsock, sendbuf, strlen(sendbuf));
+            break;
+        }
+        else
+        {
+            print_now();
+            printf("unknown: %s\n", recvbuf);
+            snprintf(sendbuf, sizeof(sendbuf), "%s <FAIL>", recvbuf);
+            if(RTTcpWrite(msgsock, sendbuf, strlen(sendbuf)))
+                break;
+        }
+    } while (msgsock >= 0);
+    if (msgsock >= 0)
+        close(msgsock);
+
+    if (!dominfo.paused) {
+        ret = xc_domain_unpause(xc_handle, domid);
+        if (ret < 0) {
+            perror("xc_domain_unpause");
+            exit(-1);
+        }
+    }
+
+    xc_interface_close(xc_handle);
+    if (ret < 0) {
+        perror("xc_interface_close");
+        exit(-1);
+    }
+
+    return 0;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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