[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 |