xref: /openbmc/qemu/qga/commands.c (revision 7f709ce7)
1 /*
2  * QEMU Guest Agent common/cross-platform command implementations
3  *
4  * Copyright IBM Corp. 2012
5  *
6  * Authors:
7  *  Michael Roth      <mdroth@linux.vnet.ibm.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10  * See the COPYING file in the top-level directory.
11  */
12 
13 #include "qemu/osdep.h"
14 #include "qga/guest-agent-core.h"
15 #include "qga-qmp-commands.h"
16 #include "qapi/qmp/qerror.h"
17 #include "qemu/base64.h"
18 #include "qemu/cutils.h"
19 #include "qemu/atomic.h"
20 
21 /* Maximum captured guest-exec out_data/err_data - 16MB */
22 #define GUEST_EXEC_MAX_OUTPUT (16*1024*1024)
23 /* Allocation and I/O buffer for reading guest-exec out_data/err_data - 4KB */
24 #define GUEST_EXEC_IO_SIZE (4*1024)
25 
26 /* Note: in some situations, like with the fsfreeze, logging may be
27  * temporarilly disabled. if it is necessary that a command be able
28  * to log for accounting purposes, check ga_logging_enabled() beforehand,
29  * and use the QERR_QGA_LOGGING_DISABLED to generate an error
30  */
31 void slog(const gchar *fmt, ...)
32 {
33     va_list ap;
34 
35     va_start(ap, fmt);
36     g_logv("syslog", G_LOG_LEVEL_INFO, fmt, ap);
37     va_end(ap);
38 }
39 
40 int64_t qmp_guest_sync_delimited(int64_t id, Error **errp)
41 {
42     ga_set_response_delimited(ga_state);
43     return id;
44 }
45 
46 int64_t qmp_guest_sync(int64_t id, Error **errp)
47 {
48     return id;
49 }
50 
51 void qmp_guest_ping(Error **errp)
52 {
53     slog("guest-ping called");
54 }
55 
56 static void qmp_command_info(QmpCommand *cmd, void *opaque)
57 {
58     GuestAgentInfo *info = opaque;
59     GuestAgentCommandInfo *cmd_info;
60     GuestAgentCommandInfoList *cmd_info_list;
61 
62     cmd_info = g_new0(GuestAgentCommandInfo, 1);
63     cmd_info->name = g_strdup(qmp_command_name(cmd));
64     cmd_info->enabled = qmp_command_is_enabled(cmd);
65     cmd_info->success_response = qmp_has_success_response(cmd);
66 
67     cmd_info_list = g_new0(GuestAgentCommandInfoList, 1);
68     cmd_info_list->value = cmd_info;
69     cmd_info_list->next = info->supported_commands;
70     info->supported_commands = cmd_info_list;
71 }
72 
73 struct GuestAgentInfo *qmp_guest_info(Error **errp)
74 {
75     GuestAgentInfo *info = g_new0(GuestAgentInfo, 1);
76 
77     info->version = g_strdup(QEMU_VERSION);
78     qmp_for_each_command(&ga_commands, qmp_command_info, info);
79     return info;
80 }
81 
82 struct GuestExecIOData {
83     guchar *data;
84     gsize size;
85     gsize length;
86     bool closed;
87     bool truncated;
88     const char *name;
89 };
90 typedef struct GuestExecIOData GuestExecIOData;
91 
92 struct GuestExecInfo {
93     GPid pid;
94     int64_t pid_numeric;
95     gint status;
96     bool has_output;
97     bool finished;
98     GuestExecIOData in;
99     GuestExecIOData out;
100     GuestExecIOData err;
101     QTAILQ_ENTRY(GuestExecInfo) next;
102 };
103 typedef struct GuestExecInfo GuestExecInfo;
104 
105 static struct {
106     QTAILQ_HEAD(, GuestExecInfo) processes;
107 } guest_exec_state = {
108     .processes = QTAILQ_HEAD_INITIALIZER(guest_exec_state.processes),
109 };
110 
111 static int64_t gpid_to_int64(GPid pid)
112 {
113 #ifdef G_OS_WIN32
114     return GetProcessId(pid);
115 #else
116     return (int64_t)pid;
117 #endif
118 }
119 
120 static GuestExecInfo *guest_exec_info_add(GPid pid)
121 {
122     GuestExecInfo *gei;
123 
124     gei = g_new0(GuestExecInfo, 1);
125     gei->pid = pid;
126     gei->pid_numeric = gpid_to_int64(pid);
127     QTAILQ_INSERT_TAIL(&guest_exec_state.processes, gei, next);
128 
129     return gei;
130 }
131 
132 static GuestExecInfo *guest_exec_info_find(int64_t pid_numeric)
133 {
134     GuestExecInfo *gei;
135 
136     QTAILQ_FOREACH(gei, &guest_exec_state.processes, next) {
137         if (gei->pid_numeric == pid_numeric) {
138             return gei;
139         }
140     }
141 
142     return NULL;
143 }
144 
145 GuestExecStatus *qmp_guest_exec_status(int64_t pid, Error **err)
146 {
147     GuestExecInfo *gei;
148     GuestExecStatus *ges;
149 
150     slog("guest-exec-status called, pid: %u", (uint32_t)pid);
151 
152     gei = guest_exec_info_find(pid);
153     if (gei == NULL) {
154         error_setg(err, QERR_INVALID_PARAMETER, "pid");
155         return NULL;
156     }
157 
158     ges = g_new0(GuestExecStatus, 1);
159 
160     bool finished = atomic_mb_read(&gei->finished);
161 
162     /* need to wait till output channels are closed
163      * to be sure we captured all output at this point */
164     if (gei->has_output) {
165         finished = finished && atomic_mb_read(&gei->out.closed);
166         finished = finished && atomic_mb_read(&gei->err.closed);
167     }
168 
169     ges->exited = finished;
170     if (finished) {
171         /* Glib has no portable way to parse exit status.
172          * On UNIX, we can get either exit code from normal termination
173          * or signal number.
174          * On Windows, it is either the same exit code or the exception
175          * value for an unhandled exception that caused the process
176          * to terminate.
177          * See MSDN for GetExitCodeProcess() and ntstatus.h for possible
178          * well-known codes, e.g. C0000005 ACCESS_DENIED - analog of SIGSEGV
179          * References:
180          *   https://msdn.microsoft.com/en-us/library/windows/desktop/ms683189(v=vs.85).aspx
181          *   https://msdn.microsoft.com/en-us/library/aa260331(v=vs.60).aspx
182          */
183 #ifdef G_OS_WIN32
184         /* Additionally WIN32 does not provide any additional information
185          * on whether the child exited or terminated via signal.
186          * We use this simple range check to distinguish application exit code
187          * (usually value less then 256) and unhandled exception code with
188          * ntstatus (always value greater then 0xC0000005). */
189         if ((uint32_t)gei->status < 0xC0000000U) {
190             ges->has_exitcode = true;
191             ges->exitcode = gei->status;
192         } else {
193             ges->has_signal = true;
194             ges->signal = gei->status;
195         }
196 #else
197         if (WIFEXITED(gei->status)) {
198             ges->has_exitcode = true;
199             ges->exitcode = WEXITSTATUS(gei->status);
200         } else if (WIFSIGNALED(gei->status)) {
201             ges->has_signal = true;
202             ges->signal = WTERMSIG(gei->status);
203         }
204 #endif
205         if (gei->out.length > 0) {
206             ges->has_out_data = true;
207             ges->out_data = g_base64_encode(gei->out.data, gei->out.length);
208             g_free(gei->out.data);
209             ges->has_out_truncated = gei->out.truncated;
210         }
211 
212         if (gei->err.length > 0) {
213             ges->has_err_data = true;
214             ges->err_data = g_base64_encode(gei->err.data, gei->err.length);
215             g_free(gei->err.data);
216             ges->has_err_truncated = gei->err.truncated;
217         }
218 
219         QTAILQ_REMOVE(&guest_exec_state.processes, gei, next);
220         g_free(gei);
221     }
222 
223     return ges;
224 }
225 
226 /* Get environment variables or arguments array for execve(). */
227 static char **guest_exec_get_args(const strList *entry, bool log)
228 {
229     const strList *it;
230     int count = 1, i = 0;  /* reserve for NULL terminator */
231     char **args;
232     char *str; /* for logging array of arguments */
233     size_t str_size = 1;
234 
235     for (it = entry; it != NULL; it = it->next) {
236         count++;
237         str_size += 1 + strlen(it->value);
238     }
239 
240     str = g_malloc(str_size);
241     *str = 0;
242     args = g_malloc(count * sizeof(char *));
243     for (it = entry; it != NULL; it = it->next) {
244         args[i++] = it->value;
245         pstrcat(str, str_size, it->value);
246         if (it->next) {
247             pstrcat(str, str_size, " ");
248         }
249     }
250     args[i] = NULL;
251 
252     if (log) {
253         slog("guest-exec called: \"%s\"", str);
254     }
255     g_free(str);
256 
257     return args;
258 }
259 
260 static void guest_exec_child_watch(GPid pid, gint status, gpointer data)
261 {
262     GuestExecInfo *gei = (GuestExecInfo *)data;
263 
264     g_debug("guest_exec_child_watch called, pid: %d, status: %u",
265             (int32_t)gpid_to_int64(pid), (uint32_t)status);
266 
267     gei->status = status;
268     atomic_mb_set(&gei->finished, true);
269 
270     g_spawn_close_pid(pid);
271 }
272 
273 /** Reset ignored signals back to default. */
274 static void guest_exec_task_setup(gpointer data)
275 {
276 #if !defined(G_OS_WIN32)
277     struct sigaction sigact;
278 
279     memset(&sigact, 0, sizeof(struct sigaction));
280     sigact.sa_handler = SIG_DFL;
281 
282     if (sigaction(SIGPIPE, &sigact, NULL) != 0) {
283         slog("sigaction() failed to reset child process's SIGPIPE: %s",
284              strerror(errno));
285     }
286 #endif
287 }
288 
289 static gboolean guest_exec_input_watch(GIOChannel *ch,
290         GIOCondition cond, gpointer p_)
291 {
292     GuestExecIOData *p = (GuestExecIOData *)p_;
293     gsize bytes_written = 0;
294     GIOStatus status;
295     GError *gerr = NULL;
296 
297     /* nothing left to write */
298     if (p->size == p->length) {
299         goto done;
300     }
301 
302     status = g_io_channel_write_chars(ch, (gchar *)p->data + p->length,
303             p->size - p->length, &bytes_written, &gerr);
304 
305     /* can be not 0 even if not G_IO_STATUS_NORMAL */
306     if (bytes_written != 0) {
307         p->length += bytes_written;
308     }
309 
310     /* continue write, our callback will be called again */
311     if (status == G_IO_STATUS_NORMAL || status == G_IO_STATUS_AGAIN) {
312         return true;
313     }
314 
315     if (gerr) {
316         g_warning("qga: i/o error writing to input_data channel: %s",
317                 gerr->message);
318         g_error_free(gerr);
319     }
320 
321 done:
322     g_io_channel_shutdown(ch, true, NULL);
323     g_io_channel_unref(ch);
324     atomic_mb_set(&p->closed, true);
325     g_free(p->data);
326 
327     return false;
328 }
329 
330 static gboolean guest_exec_output_watch(GIOChannel *ch,
331         GIOCondition cond, gpointer p_)
332 {
333     GuestExecIOData *p = (GuestExecIOData *)p_;
334     gsize bytes_read;
335     GIOStatus gstatus;
336 
337     if (cond == G_IO_HUP || cond == G_IO_ERR) {
338         goto close;
339     }
340 
341     if (p->size == p->length) {
342         gpointer t = NULL;
343         if (!p->truncated && p->size < GUEST_EXEC_MAX_OUTPUT) {
344             t = g_try_realloc(p->data, p->size + GUEST_EXEC_IO_SIZE);
345         }
346         if (t == NULL) {
347             /* ignore truncated output */
348             gchar buf[GUEST_EXEC_IO_SIZE];
349 
350             p->truncated = true;
351             gstatus = g_io_channel_read_chars(ch, buf, sizeof(buf),
352                                               &bytes_read, NULL);
353             if (gstatus == G_IO_STATUS_EOF || gstatus == G_IO_STATUS_ERROR) {
354                 goto close;
355             }
356 
357             return true;
358         }
359         p->size += GUEST_EXEC_IO_SIZE;
360         p->data = t;
361     }
362 
363     /* Calling read API once.
364      * On next available data our callback will be called again */
365     gstatus = g_io_channel_read_chars(ch, (gchar *)p->data + p->length,
366             p->size - p->length, &bytes_read, NULL);
367     if (gstatus == G_IO_STATUS_EOF || gstatus == G_IO_STATUS_ERROR) {
368         goto close;
369     }
370 
371     p->length += bytes_read;
372 
373     return true;
374 
375 close:
376     g_io_channel_shutdown(ch, true, NULL);
377     g_io_channel_unref(ch);
378     atomic_mb_set(&p->closed, true);
379     return false;
380 }
381 
382 GuestExec *qmp_guest_exec(const char *path,
383                        bool has_arg, strList *arg,
384                        bool has_env, strList *env,
385                        bool has_input_data, const char *input_data,
386                        bool has_capture_output, bool capture_output,
387                        Error **err)
388 {
389     GPid pid;
390     GuestExec *ge = NULL;
391     GuestExecInfo *gei;
392     char **argv, **envp;
393     strList arglist;
394     gboolean ret;
395     GError *gerr = NULL;
396     gint in_fd, out_fd, err_fd;
397     GIOChannel *in_ch, *out_ch, *err_ch;
398     GSpawnFlags flags;
399     bool has_output = (has_capture_output && capture_output);
400     uint8_t *input = NULL;
401     size_t ninput = 0;
402 
403     arglist.value = (char *)path;
404     arglist.next = has_arg ? arg : NULL;
405 
406     if (has_input_data) {
407         input = qbase64_decode(input_data, -1, &ninput, err);
408         if (!input) {
409             return NULL;
410         }
411     }
412 
413     argv = guest_exec_get_args(&arglist, true);
414     envp = has_env ? guest_exec_get_args(env, false) : NULL;
415 
416     flags = G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD;
417 #if GLIB_CHECK_VERSION(2, 33, 2)
418     flags |= G_SPAWN_SEARCH_PATH_FROM_ENVP;
419 #endif
420     if (!has_output) {
421         flags |= G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL;
422     }
423 
424     ret = g_spawn_async_with_pipes(NULL, argv, envp, flags,
425             guest_exec_task_setup, NULL, &pid, has_input_data ? &in_fd : NULL,
426             has_output ? &out_fd : NULL, has_output ? &err_fd : NULL, &gerr);
427     if (!ret) {
428         error_setg(err, QERR_QGA_COMMAND_FAILED, gerr->message);
429         g_error_free(gerr);
430         goto done;
431     }
432 
433     ge = g_new0(GuestExec, 1);
434     ge->pid = gpid_to_int64(pid);
435 
436     gei = guest_exec_info_add(pid);
437     gei->has_output = has_output;
438     g_child_watch_add(pid, guest_exec_child_watch, gei);
439 
440     if (has_input_data) {
441         gei->in.data = input;
442         gei->in.size = ninput;
443 #ifdef G_OS_WIN32
444         in_ch = g_io_channel_win32_new_fd(in_fd);
445 #else
446         in_ch = g_io_channel_unix_new(in_fd);
447 #endif
448         g_io_channel_set_encoding(in_ch, NULL, NULL);
449         g_io_channel_set_buffered(in_ch, false);
450         g_io_channel_set_flags(in_ch, G_IO_FLAG_NONBLOCK, NULL);
451         g_io_channel_set_close_on_unref(in_ch, true);
452         g_io_add_watch(in_ch, G_IO_OUT, guest_exec_input_watch, &gei->in);
453     }
454 
455     if (has_output) {
456 #ifdef G_OS_WIN32
457         out_ch = g_io_channel_win32_new_fd(out_fd);
458         err_ch = g_io_channel_win32_new_fd(err_fd);
459 #else
460         out_ch = g_io_channel_unix_new(out_fd);
461         err_ch = g_io_channel_unix_new(err_fd);
462 #endif
463         g_io_channel_set_encoding(out_ch, NULL, NULL);
464         g_io_channel_set_encoding(err_ch, NULL, NULL);
465         g_io_channel_set_buffered(out_ch, false);
466         g_io_channel_set_buffered(err_ch, false);
467         g_io_channel_set_close_on_unref(out_ch, true);
468         g_io_channel_set_close_on_unref(err_ch, true);
469         g_io_add_watch(out_ch, G_IO_IN | G_IO_HUP,
470                 guest_exec_output_watch, &gei->out);
471         g_io_add_watch(err_ch, G_IO_IN | G_IO_HUP,
472                 guest_exec_output_watch, &gei->err);
473     }
474 
475 done:
476     g_free(argv);
477     g_free(envp);
478 
479     return ge;
480 }
481 
482 /* Convert GuestFileWhence (either a raw integer or an enum value) into
483  * the guest's SEEK_ constants.  */
484 int ga_parse_whence(GuestFileWhence *whence, Error **errp)
485 {
486     /* Exploit the fact that we picked values to match QGA_SEEK_*. */
487     if (whence->type == QTYPE_QSTRING) {
488         whence->type = QTYPE_QNUM;
489         whence->u.value = whence->u.name;
490     }
491     switch (whence->u.value) {
492     case QGA_SEEK_SET:
493         return SEEK_SET;
494     case QGA_SEEK_CUR:
495         return SEEK_CUR;
496     case QGA_SEEK_END:
497         return SEEK_END;
498     }
499     error_setg(errp, "invalid whence code %"PRId64, whence->u.value);
500     return -1;
501 }
502 
503 GuestHostName *qmp_guest_get_host_name(Error **err)
504 {
505     GuestHostName *result = NULL;
506     gchar const *hostname = g_get_host_name();
507     if (hostname != NULL) {
508         result = g_new0(GuestHostName, 1);
509         result->host_name = g_strdup(hostname);
510     }
511     return result;
512 }
513 
514 GuestTimezone *qmp_guest_get_timezone(Error **errp)
515 {
516 #if GLIB_CHECK_VERSION(2, 28, 0)
517     GuestTimezone *info = NULL;
518     GTimeZone *tz = NULL;
519     gint64 now = 0;
520     gint32 intv = 0;
521     gchar const *name = NULL;
522 
523     info = g_new0(GuestTimezone, 1);
524     tz = g_time_zone_new_local();
525     if (tz == NULL) {
526         error_setg(errp, QERR_QGA_COMMAND_FAILED,
527                    "Couldn't retrieve local timezone");
528         goto error;
529     }
530 
531     now = g_get_real_time() / G_USEC_PER_SEC;
532     intv = g_time_zone_find_interval(tz, G_TIME_TYPE_UNIVERSAL, now);
533     info->offset = g_time_zone_get_offset(tz, intv);
534     name = g_time_zone_get_abbreviation(tz, intv);
535     if (name != NULL) {
536         info->has_zone = true;
537         info->zone = g_strdup(name);
538     }
539     g_time_zone_unref(tz);
540 
541     return info;
542 
543 error:
544     g_free(info);
545     return NULL;
546 #else
547     error_setg(errp, QERR_UNSUPPORTED);
548     return NULL;
549 #endif
550 }
551