qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 3/3] [UPDATE] Add daemonize option


From: Anthony Liguori
Subject: [Qemu-devel] [PATCH 3/3] [UPDATE] Add daemonize option
Date: Mon, 18 Dec 2006 19:08:03 -0600
User-agent: Thunderbird 1.5.0.8 (X11/20061115)

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

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.
+
address@hidden -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;

reply via email to

[Prev in Thread] Current Thread [Next in Thread]