From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1GwTSq-0007yj-NR for qemu-devel@nongnu.org; Mon, 18 Dec 2006 20:08:16 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1GwTSp-0007wg-H9 for qemu-devel@nongnu.org; Mon, 18 Dec 2006 20:08:16 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1GwTSp-0007wW-Cs for qemu-devel@nongnu.org; Mon, 18 Dec 2006 20:08:15 -0500 Received: from [128.83.139.10] (helo=mail.cs.utexas.edu) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA:32) (Exim 4.52) id 1GwTSo-0006dC-Tz for qemu-devel@nongnu.org; Mon, 18 Dec 2006 20:08:15 -0500 Received: from [192.168.1.102] (cpe-70-112-17-156.austin.res.rr.com [70.112.17.156]) (authenticated bits=0) by mail.cs.utexas.edu (8.13.8/8.13.8) with ESMTP id kBJ188hi011761 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 18 Dec 2006 19:08:11 -0600 (CST) Message-ID: <45873B73.4020308@cs.utexas.edu> Date: Mon, 18 Dec 2006 19:08:03 -0600 From: Anthony Liguori MIME-Version: 1.0 References: <4584337D.6040706@cs.utexas.edu> <45843615.9070606@cs.utexas.edu> In-Reply-To: <45843615.9070606@cs.utexas.edu> Content-Type: multipart/mixed; boundary="------------030002000200000001010407" Subject: [Qemu-devel] [PATCH 3/3] [UPDATE] Add daemonize option Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------030002000200000001010407 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Anthony Liguori wrote: > @@ -6826,9 +6833,59 @@ int main(int argc, char **argv) > case QEMU_OPTION_no_reboot: > no_reboot = 1; > break; > + case QEMU_OPTION_daemonize: > + daemonize = 1; > } > The indenting is off here and it's missing a break. New patch attached. Sorry 'bout that. BTW, all of these patches are available in my QEMU patch queue (including a few that I haven't yet submitted here). http://hg.codemonkey.ws/qemu-pq Regards, Anthony Liguori --------------030002000200000001010407 Content-Type: text/x-patch; name="qemu-daemonize.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="qemu-daemonize.diff" diff -r 74a061504619 qemu-doc.texi --- a/qemu-doc.texi Mon Dec 18 18:39:18 2006 -0600 +++ b/qemu-doc.texi Mon Dec 18 18:39:20 2006 -0600 @@ -308,6 +308,12 @@ Start in full screen. @item -pidfile file Store the QEMU process PID in @var{file}. It is useful if you launch QEMU from a script. + +@item -daemonize +Daemonize the QEMU process after initialization. QEMU will not detach from +standard IO until it is ready to receive connections on any of its devices. +This option is a useful way for external programs to launch QEMU without having +to cope with initialization race conditions. @item -win2k-hack Use it when installing Windows 2000 to avoid a disk full bug. After diff -r 74a061504619 vl.c --- a/vl.c Mon Dec 18 18:39:18 2006 -0600 +++ b/vl.c Mon Dec 18 18:39:32 2006 -0600 @@ -163,6 +163,7 @@ int acpi_enabled = 1; int acpi_enabled = 1; int fd_bootchk = 1; int no_reboot = 0; +int daemonize = 0; /***********************************************************/ /* x86 ISA bus support */ @@ -6018,6 +6019,9 @@ void help(void) "-no-reboot exit instead of rebooting\n" "-loadvm file start right away with a saved state (loadvm in monitor)\n" "-vnc display start a VNC server on display\n" +#ifndef _WIN32 + "-daemonize daemonize QEMU after initializing\n" +#endif "\n" "During emulation, the following keys are useful:\n" "ctrl-alt-f toggle full screen\n" @@ -6098,6 +6102,7 @@ enum { QEMU_OPTION_vnc, QEMU_OPTION_no_acpi, QEMU_OPTION_no_reboot, + QEMU_OPTION_daemonize, }; typedef struct QEMUOption { @@ -6178,6 +6183,7 @@ const QEMUOption qemu_options[] = { { "cirrusvga", 0, QEMU_OPTION_cirrusvga }, { "no-acpi", 0, QEMU_OPTION_no_acpi }, { "no-reboot", 0, QEMU_OPTION_no_reboot }, + { "daemonize", 0, QEMU_OPTION_daemonize }, { NULL }, }; @@ -6408,6 +6414,7 @@ int main(int argc, char **argv) QEMUMachine *machine; char usb_devices[MAX_USB_CMDLINE][128]; int usb_devices_index; + int fds[2]; LIST_INIT (&vm_change_state_head); #ifndef _WIN32 @@ -6826,9 +6833,60 @@ int main(int argc, char **argv) case QEMU_OPTION_no_reboot: no_reboot = 1; break; + case QEMU_OPTION_daemonize: + daemonize = 1; + break; } } } + +#ifndef _WIN32 + if (daemonize && !nographic && vnc_display == NULL) { + fprintf(stderr, "Can only daemonize if using -nographic or -vnc\n"); + daemonize = 0; + } + + if (daemonize) { + pid_t pid; + + if (pipe(fds) == -1) + exit(1); + + pid = fork(); + if (pid > 0) { + uint8_t status; + ssize_t len; + + close(fds[1]); + + again: + len = read(fds[0], &status, 1); + if (len == -1 && (errno == EINTR)) + goto again; + + if (len != 1 || status != 0) + exit(1); + else + exit(0); + } else if (pid < 0) + exit(1); + + setsid(); + + pid = fork(); + if (pid > 0) + exit(0); + else if (pid < 0) + exit(1); + + umask(027); + chdir("/"); + + signal(SIGTSTP, SIG_IGN); + signal(SIGTTOU, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + } +#endif #ifdef USE_KQEMU if (smp_cpus > 1) @@ -7028,6 +7086,30 @@ int main(int argc, char **argv) } } + if (daemonize) { + uint8_t status = 0; + ssize_t len; + int fd; + + again1: + len = write(fds[1], &status, 1); + if (len == -1 && (errno == EINTR)) + goto again1; + + if (len != 1) + exit(1); + + fd = open("/dev/null", O_RDWR); + if (fd == -1) + exit(1); + + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + + close(fd); + } + main_loop(); quit_timers(); return 0; --------------030002000200000001010407--