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

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



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.

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?

~Andrew

> ---
>  .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®.