qemu-storage-daemon: add --pidfile option
Daemons often have a --pidfile option where the pid is written to a file so that scripts can stop the daemon by sending a signal. The pid file also acts as a lock to prevent multiple instances of the daemon from launching for a given pid file. QEMU, qemu-nbd, qemu-ga, virtiofsd, and qemu-pr-helper all support the --pidfile option. Add it to qemu-storage-daemon too. Reported-by: Richard W.M. Jones <rjones@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Message-Id: <20210302142746.170535-1-stefanha@redhat.com> Reviewed-by: Richard W.M. Jones <rjones@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
501a4b3681
commit
03d2b412aa
@ -118,6 +118,20 @@ Standard options:
|
|||||||
List object properties with ``<type>,help``. See the :manpage:`qemu(1)`
|
List object properties with ``<type>,help``. See the :manpage:`qemu(1)`
|
||||||
manual page for a description of the object properties.
|
manual page for a description of the object properties.
|
||||||
|
|
||||||
|
.. option:: --pidfile PATH
|
||||||
|
|
||||||
|
is the path to a file where the daemon writes its pid. This allows scripts to
|
||||||
|
stop the daemon by sending a signal::
|
||||||
|
|
||||||
|
$ kill -SIGTERM $(<path/to/qsd.pid)
|
||||||
|
|
||||||
|
A file lock is applied to the file so only one instance of the daemon can run
|
||||||
|
with a given pid file path. The daemon unlinks its pid file when terminating.
|
||||||
|
|
||||||
|
The pid file is written after chardevs, exports, and NBD servers have been
|
||||||
|
created but before accepting connections. The daemon has started successfully
|
||||||
|
when the pid file is written and clients may begin connecting.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
Launch the daemon with QMP monitor socket ``qmp.sock`` so clients can execute
|
Launch the daemon with QMP monitor socket ``qmp.sock`` so clients can execute
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user