Daemonize option, by Anthony Liguori.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2261 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
ths 2006-12-22 02:11:31 +00:00
parent 73fc97427b
commit 71e3ceb800
2 changed files with 88 additions and 0 deletions

View File

@ -309,6 +309,12 @@ Start in full screen.
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
Windows 2000 is installed, you no longer need this option (this option

82
vl.c
View File

@ -163,6 +163,7 @@ const char *vnc_display;
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,10 +6833,61 @@ 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)
kqemu_allowed = 0;
@ -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;