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 Store the QEMU process PID in @var{file}. It is useful if you launch QEMU
from a script. 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 @item -win2k-hack
Use it when installing Windows 2000 to avoid a disk full bug. After 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 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 acpi_enabled = 1;
int fd_bootchk = 1; int fd_bootchk = 1;
int no_reboot = 0; int no_reboot = 0;
int daemonize = 0;
/***********************************************************/ /***********************************************************/
/* x86 ISA bus support */ /* x86 ISA bus support */
@ -6018,6 +6019,9 @@ void help(void)
"-no-reboot exit instead of rebooting\n" "-no-reboot exit instead of rebooting\n"
"-loadvm file start right away with a saved state (loadvm in monitor)\n" "-loadvm file start right away with a saved state (loadvm in monitor)\n"
"-vnc display start a VNC server on display\n" "-vnc display start a VNC server on display\n"
#ifndef _WIN32
"-daemonize daemonize QEMU after initializing\n"
#endif
"\n" "\n"
"During emulation, the following keys are useful:\n" "During emulation, the following keys are useful:\n"
"ctrl-alt-f toggle full screen\n" "ctrl-alt-f toggle full screen\n"
@ -6098,6 +6102,7 @@ enum {
QEMU_OPTION_vnc, QEMU_OPTION_vnc,
QEMU_OPTION_no_acpi, QEMU_OPTION_no_acpi,
QEMU_OPTION_no_reboot, QEMU_OPTION_no_reboot,
QEMU_OPTION_daemonize,
}; };
typedef struct QEMUOption { typedef struct QEMUOption {
@ -6178,6 +6183,7 @@ const QEMUOption qemu_options[] = {
{ "cirrusvga", 0, QEMU_OPTION_cirrusvga }, { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
{ "no-acpi", 0, QEMU_OPTION_no_acpi }, { "no-acpi", 0, QEMU_OPTION_no_acpi },
{ "no-reboot", 0, QEMU_OPTION_no_reboot }, { "no-reboot", 0, QEMU_OPTION_no_reboot },
{ "daemonize", 0, QEMU_OPTION_daemonize },
{ NULL }, { NULL },
}; };
@ -6408,6 +6414,7 @@ int main(int argc, char **argv)
QEMUMachine *machine; QEMUMachine *machine;
char usb_devices[MAX_USB_CMDLINE][128]; char usb_devices[MAX_USB_CMDLINE][128];
int usb_devices_index; int usb_devices_index;
int fds[2];
LIST_INIT (&vm_change_state_head); LIST_INIT (&vm_change_state_head);
#ifndef _WIN32 #ifndef _WIN32
@ -6826,10 +6833,61 @@ int main(int argc, char **argv)
case QEMU_OPTION_no_reboot: case QEMU_OPTION_no_reboot:
no_reboot = 1; no_reboot = 1;
break; 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 #ifdef USE_KQEMU
if (smp_cpus > 1) if (smp_cpus > 1)
kqemu_allowed = 0; 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(); main_loop();
quit_timers(); quit_timers();
return 0; return 0;