[libvirt] [PATCH 5/6] virtlockd: make re-exec more robust
Michal Privoznik
mprivozn at redhat.com
Tue Dec 10 11:06:32 UTC 2013
On 09.12.2013 07:23, Michael Chapman wrote:
> virtlockd's argv[0] may not contain a full path to the binary, however
> it should contain something that can be looked up in the PATH. Use
> execvp() to do path lookup when re-executing ourselves.
>
> After re-execution, we must not attempt to daemonize again. It's not
> only unnecessary, but it also means we end up with the wrong PID and so
> we can't validate the state file.
>
> Instead, build a new argv for the new program that does not include
> --daemon.
>
> Signed-off-by: Michael Chapman <mike at very.puzzling.org>
> ---
> src/locking/lock_daemon.c | 49 +++++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 43 insertions(+), 6 deletions(-)
>
> diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c
> index ae09ef8..32ca4d6 100644
> --- a/src/locking/lock_daemon.c
> +++ b/src/locking/lock_daemon.c
> @@ -1000,6 +1000,7 @@ cleanup:
>
> static int
> virLockDaemonPreExecRestart(virNetServerPtr srv,
> + const char *argv0,
> char **argv)
> {
> virJSONValuePtr child;
> @@ -1075,7 +1076,7 @@ virLockDaemonPreExecRestart(virNetServerPtr srv,
> goto cleanup;
> }
>
> - if (execv(argv[0], argv) < 0) {
> + if (execvp(argv0, argv) < 0) {
> virReportSystemError(errno, "%s",
> _("Unable to restart self"));
While this chunk is okay,
> goto cleanup;
> @@ -1389,11 +1390,47 @@ int main(int argc, char **argv) {
> virNetServerUpdateServices(lockDaemon->srv, true);
> virNetServerRun(lockDaemon->srv);
>
> - if (execRestart &&
> - virLockDaemonPreExecRestart(lockDaemon->srv, argv) < 0)
> - ret = VIR_LOCK_DAEMON_ERR_REEXEC;
> - else
> - ret = 0;
> + ret = VIR_LOCK_DAEMON_ERR_NONE;
> + if (execRestart) {
> + char **restart_argv = NULL;
> + size_t count = 0;
> +
> + if (VIR_EXPAND_N(restart_argv, count, 1) < 0)
> + goto no_memory;
> + if (VIR_STRDUP(restart_argv[count - 1], argv[0]) < 0)
> + goto no_memory;
> + if (verbose) {
> + if (VIR_EXPAND_N(restart_argv, count, 1) < 0)
> + goto no_memory;
> + if (VIR_STRDUP(restart_argv[count - 1], "--verbose") < 0)
> + goto no_memory;
> + }
> + if (remote_config_file && !implicit_conf) {
> + if (VIR_EXPAND_N(restart_argv, count, 2) < 0)
> + goto no_memory;
> + if (VIR_STRDUP(restart_argv[count - 2], "--config") < 0)
> + goto no_memory;
> + if (VIR_STRDUP(restart_argv[count - 1], remote_config_file) < 0)
> + goto no_memory;
> + }
> + if (pid_file) {
> + if (VIR_EXPAND_N(restart_argv, count, 2) < 0)
> + goto no_memory;
> + if (VIR_STRDUP(restart_argv[count - 2], "--pid-file") < 0)
> + goto no_memory;
> + if (VIR_STRDUP(restart_argv[count - 1], pid_file) < 0)
> + goto no_memory;
> + }
> + if (VIR_EXPAND_N(restart_argv, count, 1) < 0)
> + goto no_memory;
> +
> + if (virLockDaemonPreExecRestart(lockDaemon->srv, argv[0], restart_argv) < 0)
> + ret = VIR_LOCK_DAEMON_ERR_REEXEC;
> +
> + while (count)
> + VIR_FREE(restart_argv[--count]);
> + VIR_FREE(restart_argv);
> + }
>
> cleanup:
> virObjectUnref(lockProgram);
>
This one isn't. It requires us to expand it whenever a new cmd line
argument is invented. How about copying all arguments but "--daemon" or
"-d"?
(Just an explicit note - I'm not pushing this one now)
Michal
More information about the libvir-list
mailing list