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 | 309 | Store the QEMU process PID in @var{file}. It is useful if you launch QEMU |
310 | 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 | 318 | @item -win2k-hack |
313 | 319 | Use it when installing Windows 2000 to avoid a disk full bug. After |
314 | 320 | Windows 2000 is installed, you no longer need this option (this option | ... | ... |
vl.c
... | ... | @@ -163,6 +163,7 @@ const char *vnc_display; |
163 | 163 | int acpi_enabled = 1; |
164 | 164 | int fd_bootchk = 1; |
165 | 165 | int no_reboot = 0; |
166 | +int daemonize = 0; | |
166 | 167 | |
167 | 168 | /***********************************************************/ |
168 | 169 | /* x86 ISA bus support */ |
... | ... | @@ -6018,6 +6019,9 @@ void help(void) |
6018 | 6019 | "-no-reboot exit instead of rebooting\n" |
6019 | 6020 | "-loadvm file start right away with a saved state (loadvm in monitor)\n" |
6020 | 6021 | "-vnc display start a VNC server on display\n" |
6022 | +#ifndef _WIN32 | |
6023 | + "-daemonize daemonize QEMU after initializing\n" | |
6024 | +#endif | |
6021 | 6025 | "\n" |
6022 | 6026 | "During emulation, the following keys are useful:\n" |
6023 | 6027 | "ctrl-alt-f toggle full screen\n" |
... | ... | @@ -6098,6 +6102,7 @@ enum { |
6098 | 6102 | QEMU_OPTION_vnc, |
6099 | 6103 | QEMU_OPTION_no_acpi, |
6100 | 6104 | QEMU_OPTION_no_reboot, |
6105 | + QEMU_OPTION_daemonize, | |
6101 | 6106 | }; |
6102 | 6107 | |
6103 | 6108 | typedef struct QEMUOption { |
... | ... | @@ -6178,6 +6183,7 @@ const QEMUOption qemu_options[] = { |
6178 | 6183 | { "cirrusvga", 0, QEMU_OPTION_cirrusvga }, |
6179 | 6184 | { "no-acpi", 0, QEMU_OPTION_no_acpi }, |
6180 | 6185 | { "no-reboot", 0, QEMU_OPTION_no_reboot }, |
6186 | + { "daemonize", 0, QEMU_OPTION_daemonize }, | |
6181 | 6187 | { NULL }, |
6182 | 6188 | }; |
6183 | 6189 | |
... | ... | @@ -6408,6 +6414,7 @@ int main(int argc, char **argv) |
6408 | 6414 | QEMUMachine *machine; |
6409 | 6415 | char usb_devices[MAX_USB_CMDLINE][128]; |
6410 | 6416 | int usb_devices_index; |
6417 | + int fds[2]; | |
6411 | 6418 | |
6412 | 6419 | LIST_INIT (&vm_change_state_head); |
6413 | 6420 | #ifndef _WIN32 |
... | ... | @@ -6826,10 +6833,61 @@ int main(int argc, char **argv) |
6826 | 6833 | case QEMU_OPTION_no_reboot: |
6827 | 6834 | no_reboot = 1; |
6828 | 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 | 6891 | #ifdef USE_KQEMU |
6834 | 6892 | if (smp_cpus > 1) |
6835 | 6893 | kqemu_allowed = 0; |
... | ... | @@ -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 | 7113 | main_loop(); |
7032 | 7114 | quit_timers(); |
7033 | 7115 | return 0; | ... | ... |