|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |