Commit 71e3ceb800ec212acd78f613245bbb82278348d0
1 parent
73fc9742
Daemonize option, by Anthony Liguori.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2261 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
88 additions
and
0 deletions
qemu-doc.texi
@@ -309,6 +309,12 @@ Start in full screen. | @@ -309,6 +309,12 @@ Start in full screen. | ||
309 | Store the QEMU process PID in @var{file}. It is useful if you launch QEMU | 309 | Store the QEMU process PID in @var{file}. It is useful if you launch QEMU |
310 | from a script. | 310 | from a script. |
311 | 311 | ||
312 | +@item -daemonize | ||
313 | +Daemonize the QEMU process after initialization. QEMU will not detach from | ||
314 | +standard IO until it is ready to receive connections on any of its devices. | ||
315 | +This option is a useful way for external programs to launch QEMU without having | ||
316 | +to cope with initialization race conditions. | ||
317 | + | ||
312 | @item -win2k-hack | 318 | @item -win2k-hack |
313 | Use it when installing Windows 2000 to avoid a disk full bug. After | 319 | Use it when installing Windows 2000 to avoid a disk full bug. After |
314 | Windows 2000 is installed, you no longer need this option (this option | 320 | Windows 2000 is installed, you no longer need this option (this option |
vl.c
@@ -163,6 +163,7 @@ const char *vnc_display; | @@ -163,6 +163,7 @@ const char *vnc_display; | ||
163 | int acpi_enabled = 1; | 163 | int acpi_enabled = 1; |
164 | int fd_bootchk = 1; | 164 | int fd_bootchk = 1; |
165 | int no_reboot = 0; | 165 | int no_reboot = 0; |
166 | +int daemonize = 0; | ||
166 | 167 | ||
167 | /***********************************************************/ | 168 | /***********************************************************/ |
168 | /* x86 ISA bus support */ | 169 | /* x86 ISA bus support */ |
@@ -6018,6 +6019,9 @@ void help(void) | @@ -6018,6 +6019,9 @@ void help(void) | ||
6018 | "-no-reboot exit instead of rebooting\n" | 6019 | "-no-reboot exit instead of rebooting\n" |
6019 | "-loadvm file start right away with a saved state (loadvm in monitor)\n" | 6020 | "-loadvm file start right away with a saved state (loadvm in monitor)\n" |
6020 | "-vnc display start a VNC server on display\n" | 6021 | "-vnc display start a VNC server on display\n" |
6022 | +#ifndef _WIN32 | ||
6023 | + "-daemonize daemonize QEMU after initializing\n" | ||
6024 | +#endif | ||
6021 | "\n" | 6025 | "\n" |
6022 | "During emulation, the following keys are useful:\n" | 6026 | "During emulation, the following keys are useful:\n" |
6023 | "ctrl-alt-f toggle full screen\n" | 6027 | "ctrl-alt-f toggle full screen\n" |
@@ -6098,6 +6102,7 @@ enum { | @@ -6098,6 +6102,7 @@ enum { | ||
6098 | QEMU_OPTION_vnc, | 6102 | QEMU_OPTION_vnc, |
6099 | QEMU_OPTION_no_acpi, | 6103 | QEMU_OPTION_no_acpi, |
6100 | QEMU_OPTION_no_reboot, | 6104 | QEMU_OPTION_no_reboot, |
6105 | + QEMU_OPTION_daemonize, | ||
6101 | }; | 6106 | }; |
6102 | 6107 | ||
6103 | typedef struct QEMUOption { | 6108 | typedef struct QEMUOption { |
@@ -6178,6 +6183,7 @@ const QEMUOption qemu_options[] = { | @@ -6178,6 +6183,7 @@ const QEMUOption qemu_options[] = { | ||
6178 | { "cirrusvga", 0, QEMU_OPTION_cirrusvga }, | 6183 | { "cirrusvga", 0, QEMU_OPTION_cirrusvga }, |
6179 | { "no-acpi", 0, QEMU_OPTION_no_acpi }, | 6184 | { "no-acpi", 0, QEMU_OPTION_no_acpi }, |
6180 | { "no-reboot", 0, QEMU_OPTION_no_reboot }, | 6185 | { "no-reboot", 0, QEMU_OPTION_no_reboot }, |
6186 | + { "daemonize", 0, QEMU_OPTION_daemonize }, | ||
6181 | { NULL }, | 6187 | { NULL }, |
6182 | }; | 6188 | }; |
6183 | 6189 | ||
@@ -6408,6 +6414,7 @@ int main(int argc, char **argv) | @@ -6408,6 +6414,7 @@ int main(int argc, char **argv) | ||
6408 | QEMUMachine *machine; | 6414 | QEMUMachine *machine; |
6409 | char usb_devices[MAX_USB_CMDLINE][128]; | 6415 | char usb_devices[MAX_USB_CMDLINE][128]; |
6410 | int usb_devices_index; | 6416 | int usb_devices_index; |
6417 | + int fds[2]; | ||
6411 | 6418 | ||
6412 | LIST_INIT (&vm_change_state_head); | 6419 | LIST_INIT (&vm_change_state_head); |
6413 | #ifndef _WIN32 | 6420 | #ifndef _WIN32 |
@@ -6826,10 +6833,61 @@ int main(int argc, char **argv) | @@ -6826,10 +6833,61 @@ int main(int argc, char **argv) | ||
6826 | case QEMU_OPTION_no_reboot: | 6833 | case QEMU_OPTION_no_reboot: |
6827 | no_reboot = 1; | 6834 | no_reboot = 1; |
6828 | break; | 6835 | break; |
6836 | + case QEMU_OPTION_daemonize: | ||
6837 | + daemonize = 1; | ||
6838 | + break; | ||
6829 | } | 6839 | } |
6830 | } | 6840 | } |
6831 | } | 6841 | } |
6832 | 6842 | ||
6843 | +#ifndef _WIN32 | ||
6844 | + if (daemonize && !nographic && vnc_display == NULL) { | ||
6845 | + fprintf(stderr, "Can only daemonize if using -nographic or -vnc\n"); | ||
6846 | + daemonize = 0; | ||
6847 | + } | ||
6848 | + | ||
6849 | + if (daemonize) { | ||
6850 | + pid_t pid; | ||
6851 | + | ||
6852 | + if (pipe(fds) == -1) | ||
6853 | + exit(1); | ||
6854 | + | ||
6855 | + pid = fork(); | ||
6856 | + if (pid > 0) { | ||
6857 | + uint8_t status; | ||
6858 | + ssize_t len; | ||
6859 | + | ||
6860 | + close(fds[1]); | ||
6861 | + | ||
6862 | + again: | ||
6863 | + len = read(fds[0], &status, 1); | ||
6864 | + if (len == -1 && (errno == EINTR)) | ||
6865 | + goto again; | ||
6866 | + | ||
6867 | + if (len != 1 || status != 0) | ||
6868 | + exit(1); | ||
6869 | + else | ||
6870 | + exit(0); | ||
6871 | + } else if (pid < 0) | ||
6872 | + exit(1); | ||
6873 | + | ||
6874 | + setsid(); | ||
6875 | + | ||
6876 | + pid = fork(); | ||
6877 | + if (pid > 0) | ||
6878 | + exit(0); | ||
6879 | + else if (pid < 0) | ||
6880 | + exit(1); | ||
6881 | + | ||
6882 | + umask(027); | ||
6883 | + chdir("/"); | ||
6884 | + | ||
6885 | + signal(SIGTSTP, SIG_IGN); | ||
6886 | + signal(SIGTTOU, SIG_IGN); | ||
6887 | + signal(SIGTTIN, SIG_IGN); | ||
6888 | + } | ||
6889 | +#endif | ||
6890 | + | ||
6833 | #ifdef USE_KQEMU | 6891 | #ifdef USE_KQEMU |
6834 | if (smp_cpus > 1) | 6892 | if (smp_cpus > 1) |
6835 | kqemu_allowed = 0; | 6893 | kqemu_allowed = 0; |
@@ -7028,6 +7086,30 @@ int main(int argc, char **argv) | @@ -7028,6 +7086,30 @@ int main(int argc, char **argv) | ||
7028 | } | 7086 | } |
7029 | } | 7087 | } |
7030 | 7088 | ||
7089 | + if (daemonize) { | ||
7090 | + uint8_t status = 0; | ||
7091 | + ssize_t len; | ||
7092 | + int fd; | ||
7093 | + | ||
7094 | + again1: | ||
7095 | + len = write(fds[1], &status, 1); | ||
7096 | + if (len == -1 && (errno == EINTR)) | ||
7097 | + goto again1; | ||
7098 | + | ||
7099 | + if (len != 1) | ||
7100 | + exit(1); | ||
7101 | + | ||
7102 | + fd = open("/dev/null", O_RDWR); | ||
7103 | + if (fd == -1) | ||
7104 | + exit(1); | ||
7105 | + | ||
7106 | + dup2(fd, 0); | ||
7107 | + dup2(fd, 1); | ||
7108 | + dup2(fd, 2); | ||
7109 | + | ||
7110 | + close(fd); | ||
7111 | + } | ||
7112 | + | ||
7031 | main_loop(); | 7113 | main_loop(); |
7032 | quit_timers(); | 7114 | quit_timers(); |
7033 | return 0; | 7115 | return 0; |