From patchwork Mon Jan 17 13:15:15 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Roth X-Patchwork-Id: 79177 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 9F3CDB7088 for ; Tue, 18 Jan 2011 00:51:42 +1100 (EST) Received: from localhost ([127.0.0.1]:44121 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PepSD-0007pi-R2 for incoming@patchwork.ozlabs.org; Mon, 17 Jan 2011 08:49:05 -0500 Received: from [140.186.70.92] (port=33048 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Peowo-00079U-V6 for qemu-devel@nongnu.org; Mon, 17 Jan 2011 08:16:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Peowj-0006Lx-Dr for qemu-devel@nongnu.org; Mon, 17 Jan 2011 08:16:35 -0500 Received: from e3.ny.us.ibm.com ([32.97.182.143]:59146) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Peowj-0006Lm-Ae for qemu-devel@nongnu.org; Mon, 17 Jan 2011 08:16:33 -0500 Received: from d01dlp02.pok.ibm.com (d01dlp02.pok.ibm.com [9.56.224.85]) by e3.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p0HCvJQs021827 for ; Mon, 17 Jan 2011 07:57:35 -0500 Received: from d01relay03.pok.ibm.com (d01relay03.pok.ibm.com [9.56.227.235]) by d01dlp02.pok.ibm.com (Postfix) with ESMTP id 45C454DE8041 for ; Mon, 17 Jan 2011 08:13:19 -0500 (EST) Received: from d01av04.pok.ibm.com (d01av04.pok.ibm.com [9.56.224.64]) by d01relay03.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p0HDGWYA261344 for ; Mon, 17 Jan 2011 08:16:32 -0500 Received: from d01av04.pok.ibm.com (loopback [127.0.0.1]) by d01av04.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p0HDGVZ2031683 for ; Mon, 17 Jan 2011 08:16:32 -0500 Received: from localhost.localdomain (sig-9-76-0-14.mts.ibm.com [9.76.0.14]) by d01av04.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p0HDFULH026421; Mon, 17 Jan 2011 08:16:30 -0500 From: Michael Roth To: qemu-devel@nongnu.org Date: Mon, 17 Jan 2011 07:15:15 -0600 Message-Id: <1295270117-24760-22-git-send-email-mdroth@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1295270117-24760-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1295270117-24760-1-git-send-email-mdroth@linux.vnet.ibm.com> X-Content-Scanned: Fidelis XPS MAILER X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) Cc: agl@linux.vnet.ibm.com, stefanha@linux.vnet.ibm.com, Jes.Sorensen@redhat.com, marcel.mittelstaedt@de.ibm.com, mdroth@linux.vnet.ibm.com, markus_mueller@de.ibm.com, aliguori@linux.vnet.ibm.com, ryanh@us.ibm.com, abeekhof@redhat.com Subject: [Qemu-devel] [RFC][PATCH v6 21/23] virtagent: add virtagent guest daemon X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Michael Roth --- Makefile | 4 +- qemu-va.c | 238 ++++++++++++++++++++++++++++++++++++++++++++++++++++ virtagent-common.h | 1 + 3 files changed, 242 insertions(+), 1 deletions(-) create mode 100644 qemu-va.c diff --git a/Makefile b/Makefile index 6d601ee..f1f4d18 100644 --- a/Makefile +++ b/Makefile @@ -151,7 +151,7 @@ version-obj-$(CONFIG_WIN32) += version.o ###################################################################### qemu-img.o: qemu-img-cmds.h -qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o: $(GENERATED_HEADERS) +qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o qemu-va.o: $(GENERATED_HEADERS) qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o @@ -159,6 +159,8 @@ qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-ob qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o +qemu-va$(EXESUF): qemu-va.o virtagent.o virtagent-server.o virtagent-common.o qemu-tool.o qemu-error.o qemu-sockets.c $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o qemu-timer.o + qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $@") diff --git a/qemu-va.c b/qemu-va.c new file mode 100644 index 0000000..5f1e2ab --- /dev/null +++ b/qemu-va.c @@ -0,0 +1,238 @@ +/* + * virtagent - QEMU guest agent + * + * Copyright IBM Corp. 2010 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include "qemu-ioh.h" +#include "qemu-tool.h" +#include "virtagent-common.h" + +static bool verbose_enabled; +#define DEBUG_ENABLED + +#ifdef DEBUG_ENABLED +#define DEBUG(msg, ...) do { \ + fprintf(stderr, "%s:%s():L%d: " msg "\n", \ + __FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \ +} while(0) +#else +#define DEBUG(msg, ...) do {} while (0) +#endif + +#define INFO(msg, ...) do { \ + if (!verbose_enabled) { \ + break; \ + } \ + warnx(msg, ## __VA_ARGS__); \ +} while(0) + +/* mirror qemu I/O loop for standalone daemon */ +static void main_loop_wait(int nonblocking) +{ + fd_set rfds, wfds, xfds; + int ret, nfds; + struct timeval tv; + int timeout = 100000; + + if (nonblocking) { + timeout = 0; + } + + /* poll any events */ + nfds = -1; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&xfds); + qemu_get_fdset(&nfds, &rfds, &wfds, &xfds); + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); + + if (ret > 0) { + qemu_process_fd_handlers(&rfds, &wfds, &xfds); + } + + DEBUG("running timers..."); + qemu_run_all_timers(); +} + +static void usage(const char *cmd) +{ + printf( +"Usage: %s -c \n" +"QEMU virtagent guest agent %s\n" +"\n" +" -c, --channel channel method: one of unix-connect, virtio-serial, or\n" +" isa-serial\n" +" -p, --path channel path\n" +" -v, --verbose display extra debugging information\n" +" -d, --daemonize become a daemon\n" +" -h, --help display this help and exit\n" +"\n" +"Report bugs to \n" + , cmd, VA_VERSION); +} + +static int init_virtagent(const char *method, const char *path) { + VAContext ctx; + int ret; + + INFO("initializing agent..."); + + if (method == NULL) { + /* try virtio-serial as our default */ + method = "virtio-serial"; + } + + if (path == NULL) { + if (strcmp(method, "virtio-serial")) { + errx(EXIT_FAILURE, "must specify a path for this channel"); + } + /* try the default name for the virtio-serial port */ + path = VA_GUEST_PATH_VIRTIO_DEFAULT; + } + + /* initialize virtagent */ + ctx.is_host = false; + ctx.channel_method = method; + ctx.channel_path = path; + ret = va_init(ctx); + if (ret) { + errx(EXIT_FAILURE, "unable to initialize virtagent"); + } + + return 0; +} + +static void become_daemon(void) +{ + pid_t pid, sid; + + pid = fork(); + if (pid < 0) + exit(EXIT_FAILURE); + if (pid > 0) { + FILE *pidfile = fopen(VA_PIDFILE, "wx"); + if (!pidfile) + errx(EXIT_FAILURE, "Error creating pid file"); + fprintf(pidfile, "%i", pid); + fclose(pidfile); + exit(EXIT_SUCCESS); + } + + umask(0); + sid = setsid(); + if (sid < 0) + goto fail; + if ((chdir("/")) < 0) + goto fail; + + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + return; + +fail: + unlink(VA_PIDFILE); + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) +{ + const char *sopt = "hVvdc:p:", *channel_method = NULL, *channel_path = NULL; + struct option lopt[] = { + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { "verbose", 0, NULL, 'v' }, + { "channel", 0, NULL, 'c' }, + { "path", 0, NULL, 'p' }, + { "daemonize", 0, NULL, 'd' }, + { NULL, 0, NULL, 0 } + }; + int opt_ind = 0, ch, ret, daemonize = 0; + + while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) { + switch (ch) { + case 'c': + channel_method = optarg; + break; + case 'p': + channel_path = optarg; + break; + case 'v': + verbose_enabled = 1; + break; + case 'V': + printf("QEMU Virtagent %s\n", VA_VERSION); + return 0; + case 'd': + daemonize = 1; + break; + case 'h': + usage(argv[0]); + return 0; + case '?': + errx(EXIT_FAILURE, "Try '%s --help' for more information.", + argv[0]); + } + } + + init_clocks(); + configure_alarms("dynticks"); + if (init_timer_alarm() < 0) { + errx(EXIT_FAILURE, "could not initialize alarm timer"); + } + + /* initialize virtagent */ + ret = init_virtagent(channel_method, channel_path); + if (ret) { + errx(EXIT_FAILURE, "error initializing communication channel"); + } + + if (daemonize) { + become_daemon(); + } + + /* main i/o loop */ + for (;;) { + DEBUG("entering main_loop_wait()"); + main_loop_wait(0); + DEBUG("left main_loop_wait()"); + } + + unlink(VA_PIDFILE); + return 0; +} diff --git a/virtagent-common.h b/virtagent-common.h index 6ad8036..cb2363c 100644 --- a/virtagent-common.h +++ b/virtagent-common.h @@ -44,6 +44,7 @@ #define VA_VERSION "1.0" #define EOL "\r\n" +#define VA_PIDFILE "/var/run/qemu-va.pid" #define VA_HDR_LEN_MAX 4096 /* http header limit */ #define VA_CONTENT_LEN_MAX 2*1024*1024 /* rpc/http send limit */ #define VA_CLIENT_JOBS_MAX 5 /* max client rpcs we can queue */