X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=qemu-ga.c;h=9b59a524619cab1f25ff3ae87a1ee2227785f1be;hb=f71d61216ea8eb914ee79459a58dc5343d95ddec;hp=cf61cb95e5c104737c848341bb79b34530ddcc49;hpb=ce8c8b7bd8958fde291f7736016015864e7638a2;p=qemu.git diff --git a/qemu-ga.c b/qemu-ga.c index cf61cb95e..9b59a5246 100644 --- a/qemu-ga.c +++ b/qemu-ga.c @@ -28,7 +28,6 @@ #include "module.h" #include "signal.h" #include "qerror.h" -#include "error_int.h" #include "qapi/qmp-core.h" #include "qga/channel.h" #ifdef _WIN32 @@ -41,8 +40,8 @@ #else #define QGA_VIRTIO_PATH_DEFAULT "\\\\.\\Global\\org.qemu.guest_agent.0" #endif -#define QGA_PIDFILE_DEFAULT "/var/run/qemu-ga.pid" -#define QGA_STATEDIR_DEFAULT "/tmp" +#define QGA_STATEDIR_DEFAULT CONFIG_QEMU_LOCALSTATEDIR "/run" +#define QGA_PIDFILE_DEFAULT QGA_STATEDIR_DEFAULT "/qemu-ga.pid" #define QGA_SENTINEL_BYTE 0xFF struct GAState { @@ -104,16 +103,9 @@ static void quit_handler(int sig) } #ifndef _WIN32 -/* reap _all_ terminated children */ -static void child_handler(int sig) -{ - int status; - while (waitpid(-1, &status, WNOHANG) > 0) /* NOTHING */; -} - static gboolean register_signal_handlers(void) { - struct sigaction sigact, sigact_chld; + struct sigaction sigact; int ret; memset(&sigact, 0, sizeof(struct sigaction)); @@ -122,23 +114,30 @@ static gboolean register_signal_handlers(void) ret = sigaction(SIGINT, &sigact, NULL); if (ret == -1) { g_error("error configuring signal handler: %s", strerror(errno)); - return false; } ret = sigaction(SIGTERM, &sigact, NULL); if (ret == -1) { g_error("error configuring signal handler: %s", strerror(errno)); - return false; } - memset(&sigact_chld, 0, sizeof(struct sigaction)); - sigact_chld.sa_handler = child_handler; - sigact_chld.sa_flags = SA_NOCLDSTOP; - ret = sigaction(SIGCHLD, &sigact_chld, NULL); - if (ret == -1) { - g_error("error configuring signal handler: %s", strerror(errno)); + return true; +} + +/* TODO: use this in place of all post-fork() fclose(std*) callers */ +void reopen_fd_to_null(int fd) +{ + int nullfd; + + nullfd = open("/dev/null", O_RDWR); + if (nullfd < 0) { + return; } - return true; + dup2(nullfd, fd); + + if (nullfd != fd) { + close(nullfd); + } } #endif @@ -167,7 +166,7 @@ static void usage(const char *cmd) " -h, --help display this help and exit\n" "\n" "Report bugs to \n" - , cmd, QGA_VERSION, QGA_VIRTIO_PATH_DEFAULT, QGA_PIDFILE_DEFAULT, + , cmd, QEMU_VERSION, QGA_VIRTIO_PATH_DEFAULT, QGA_PIDFILE_DEFAULT, QGA_STATEDIR_DEFAULT); } @@ -246,6 +245,9 @@ static bool ga_open_pidfile(const char *pidfile) pidfd = open(pidfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR); if (pidfd == -1 || lockf(pidfd, F_TLOCK, 0)) { g_critical("Cannot lock pid file, %s", strerror(errno)); + if (pidfd != -1) { + close(pidfd); + } return false; } @@ -253,7 +255,7 @@ static bool ga_open_pidfile(const char *pidfile) g_critical("Failed to truncate pid file"); goto fail; } - sprintf(pidstr, "%d", getpid()); + snprintf(pidstr, sizeof(pidstr), "%d\n", getpid()); if (write(pidfd, pidstr, strlen(pidstr)) != strlen(pidstr)) { g_critical("Failed to write pid file"); goto fail; @@ -428,13 +430,15 @@ static void become_daemon(const char *pidfile) goto fail; } - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); + reopen_fd_to_null(STDIN_FILENO); + reopen_fd_to_null(STDOUT_FILENO); + reopen_fd_to_null(STDERR_FILENO); return; fail: - unlink(pidfile); + if (pidfile) { + unlink(pidfile); + } g_critical("failed to daemonize"); exit(EXIT_FAILURE); #endif @@ -513,7 +517,7 @@ static void process_event(JSONMessageParser *parser, QList *tokens) } else { g_warning("failed to parse event: %s", error_get_pretty(err)); } - qdict_put_obj(qdict, "error", error_get_qobject(err)); + qdict_put_obj(qdict, "error", qmp_build_error_object(err)); error_free(err); } else { qdict = qobject_to_qdict(obj); @@ -530,7 +534,7 @@ static void process_event(JSONMessageParser *parser, QList *tokens) qdict = qdict_new(); g_warning("unrecognized payload format"); error_set(&err, QERR_UNSUPPORTED); - qdict_put_obj(qdict, "error", error_get_qobject(err)); + qdict_put_obj(qdict, "error", qmp_build_error_object(err)); error_free(err); } ret = send_response(s, QOBJECT(qdict)); @@ -727,14 +731,14 @@ int main(int argc, char **argv) log_level = G_LOG_LEVEL_MASK; break; case 'V': - printf("QEMU Guest Agent %s\n", QGA_VERSION); + printf("QEMU Guest Agent %s\n", QEMU_VERSION); return 0; case 'd': daemonize = 1; break; case 'b': { char **list_head, **list; - if (*optarg == '?') { + if (is_help_option(optarg)) { list_head = list = qmp_get_command_list(); while (*list != NULL) { printf("%s\n", *list); @@ -834,12 +838,13 @@ int main(int argc, char **argv) become_daemon(pid_filepath); } if (log_filepath) { - s->log_file = fopen(log_filepath, "a"); - if (!s->log_file) { + FILE *log_file = fopen(log_filepath, "a"); + if (!log_file) { g_critical("unable to open specified log file: %s", strerror(errno)); goto out_bad; } + s->log_file = log_file; } }