This adds a -daemonize option. This option is mostly useful for front-ends as it provides a deterministic way to connect to QEMU's various devices. For instance, if you wanted to execute:

qemu -hda ~/win2k.img -monitor telnet:localhost:1024,server &
telnet localhost:1024

Occasionally, you will get a connection refused as there is a race condition. However, with this option, you can write:

qemu -hda ~/win2k.img -monitor telnet:localhost:1024,server -daemonize
telnet localhost:1024

And it should always work. This is because the daemonize code doesn't detach until after all of the character devices are initialized.

Regards,

Anthony Liguori
diff -r 953722fbdf7e qemu-doc.texi
--- a/qemu-doc.texi	Sat Dec 16 11:50:12 2006 -0600
+++ b/qemu-doc.texi	Sat Dec 16 11:50:23 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.
+
[EMAIL PROTECTED] -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 953722fbdf7e vl.c
--- a/vl.c	Sat Dec 16 11:50:12 2006 -0600
+++ b/vl.c	Sat Dec 16 11:50:15 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,59 @@ int main(int argc, char **argv)
             case QEMU_OPTION_no_reboot:
                 no_reboot = 1;
                 break;
+	    case QEMU_OPTION_daemonize:
+		    daemonize = 1;
             }
         }
     }
+
+#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 +7085,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;
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to