|
@@ -59,6 +59,7 @@
|
|
#include "sysemu/runstate.h"
|
|
#include "sysemu/runstate.h"
|
|
#include "trace/control.h"
|
|
#include "trace/control.h"
|
|
|
|
|
|
|
|
+static const char *pid_file;
|
|
static volatile bool exit_requested = false;
|
|
static volatile bool exit_requested = false;
|
|
|
|
|
|
void qemu_system_killed(int signal, pid_t pid)
|
|
void qemu_system_killed(int signal, pid_t pid)
|
|
@@ -115,6 +116,8 @@ static void help(void)
|
|
" See the qemu(1) man page for documentation of the\n"
|
|
" See the qemu(1) man page for documentation of the\n"
|
|
" objects that can be added.\n"
|
|
" objects that can be added.\n"
|
|
"\n"
|
|
"\n"
|
|
|
|
+" --pidfile <path> write process ID to a file after startup\n"
|
|
|
|
+"\n"
|
|
QEMU_HELP_BOTTOM "\n",
|
|
QEMU_HELP_BOTTOM "\n",
|
|
error_get_progname());
|
|
error_get_progname());
|
|
}
|
|
}
|
|
@@ -126,6 +129,7 @@ enum {
|
|
OPTION_MONITOR,
|
|
OPTION_MONITOR,
|
|
OPTION_NBD_SERVER,
|
|
OPTION_NBD_SERVER,
|
|
OPTION_OBJECT,
|
|
OPTION_OBJECT,
|
|
|
|
+ OPTION_PIDFILE,
|
|
};
|
|
};
|
|
|
|
|
|
extern QemuOptsList qemu_chardev_opts;
|
|
extern QemuOptsList qemu_chardev_opts;
|
|
@@ -178,6 +182,7 @@ static void process_options(int argc, char *argv[])
|
|
{"monitor", required_argument, NULL, OPTION_MONITOR},
|
|
{"monitor", required_argument, NULL, OPTION_MONITOR},
|
|
{"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
|
|
{"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
|
|
{"object", required_argument, NULL, OPTION_OBJECT},
|
|
{"object", required_argument, NULL, OPTION_OBJECT},
|
|
|
|
+ {"pidfile", required_argument, NULL, OPTION_PIDFILE},
|
|
{"trace", required_argument, NULL, 'T'},
|
|
{"trace", required_argument, NULL, 'T'},
|
|
{"version", no_argument, NULL, 'V'},
|
|
{"version", no_argument, NULL, 'V'},
|
|
{0, 0, 0, 0}
|
|
{0, 0, 0, 0}
|
|
@@ -289,6 +294,9 @@ static void process_options(int argc, char *argv[])
|
|
qobject_unref(args);
|
|
qobject_unref(args);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ case OPTION_PIDFILE:
|
|
|
|
+ pid_file = optarg;
|
|
|
|
+ break;
|
|
case 1:
|
|
case 1:
|
|
error_report("Unexpected argument");
|
|
error_report("Unexpected argument");
|
|
exit(EXIT_FAILURE);
|
|
exit(EXIT_FAILURE);
|
|
@@ -299,6 +307,27 @@ static void process_options(int argc, char *argv[])
|
|
loc_set_none();
|
|
loc_set_none();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void pid_file_cleanup(void)
|
|
|
|
+{
|
|
|
|
+ unlink(pid_file);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void pid_file_init(void)
|
|
|
|
+{
|
|
|
|
+ Error *err = NULL;
|
|
|
|
+
|
|
|
|
+ if (!pid_file) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!qemu_write_pidfile(pid_file, &err)) {
|
|
|
|
+ error_reportf_err(err, "cannot create PID file: ");
|
|
|
|
+ exit(EXIT_FAILURE);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ atexit(pid_file_cleanup);
|
|
|
|
+}
|
|
|
|
+
|
|
int main(int argc, char *argv[])
|
|
int main(int argc, char *argv[])
|
|
{
|
|
{
|
|
#ifdef CONFIG_POSIX
|
|
#ifdef CONFIG_POSIX
|
|
@@ -326,6 +355,13 @@ int main(int argc, char *argv[])
|
|
qemu_init_main_loop(&error_fatal);
|
|
qemu_init_main_loop(&error_fatal);
|
|
process_options(argc, argv);
|
|
process_options(argc, argv);
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Write the pid file after creating chardevs, exports, and NBD servers but
|
|
|
|
+ * before accepting connections. This ordering is documented. Do not change
|
|
|
|
+ * it.
|
|
|
|
+ */
|
|
|
|
+ pid_file_init();
|
|
|
|
+
|
|
while (!exit_requested) {
|
|
while (!exit_requested) {
|
|
main_loop_wait(false);
|
|
main_loop_wait(false);
|
|
}
|
|
}
|