qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

commands.c (16482B)


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