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 <glib.h> 14 #include "qga/guest-agent-core.h" 15 #include "qga-qmp-commands.h" 16 #include "qapi/qmp/qerror.h" 17 18 /* Maximum captured guest-exec out_data/err_data - 16MB */ 19 #define GUEST_EXEC_MAX_OUTPUT (16*1024*1024) 20 /* Allocation and I/O buffer for reading guest-exec out_data/err_data - 4KB */ 21 #define GUEST_EXEC_IO_SIZE (4*1024) 22 23 /* Note: in some situations, like with the fsfreeze, logging may be 24 * temporarilly disabled. if it is necessary that a command be able 25 * to log for accounting purposes, check ga_logging_enabled() beforehand, 26 * and use the QERR_QGA_LOGGING_DISABLED to generate an error 27 */ 28 void slog(const gchar *fmt, ...) 29 { 30 va_list ap; 31 32 va_start(ap, fmt); 33 g_logv("syslog", G_LOG_LEVEL_INFO, fmt, ap); 34 va_end(ap); 35 } 36 37 int64_t qmp_guest_sync_delimited(int64_t id, Error **errp) 38 { 39 ga_set_response_delimited(ga_state); 40 return id; 41 } 42 43 int64_t qmp_guest_sync(int64_t id, Error **errp) 44 { 45 return id; 46 } 47 48 void qmp_guest_ping(Error **errp) 49 { 50 slog("guest-ping called"); 51 } 52 53 static void qmp_command_info(QmpCommand *cmd, void *opaque) 54 { 55 GuestAgentInfo *info = opaque; 56 GuestAgentCommandInfo *cmd_info; 57 GuestAgentCommandInfoList *cmd_info_list; 58 59 cmd_info = g_new0(GuestAgentCommandInfo, 1); 60 cmd_info->name = g_strdup(qmp_command_name(cmd)); 61 cmd_info->enabled = qmp_command_is_enabled(cmd); 62 cmd_info->success_response = qmp_has_success_response(cmd); 63 64 cmd_info_list = g_new0(GuestAgentCommandInfoList, 1); 65 cmd_info_list->value = cmd_info; 66 cmd_info_list->next = info->supported_commands; 67 info->supported_commands = cmd_info_list; 68 } 69 70 struct GuestAgentInfo *qmp_guest_info(Error **errp) 71 { 72 GuestAgentInfo *info = g_new0(GuestAgentInfo, 1); 73 74 info->version = g_strdup(QEMU_VERSION); 75 qmp_for_each_command(qmp_command_info, info); 76 return info; 77 } 78 79 struct GuestExecIOData { 80 guchar *data; 81 gsize size; 82 gsize length; 83 gint closed; 84 bool truncated; 85 const char *name; 86 }; 87 typedef struct GuestExecIOData GuestExecIOData; 88 89 struct GuestExecInfo { 90 GPid pid; 91 int64_t pid_numeric; 92 gint status; 93 bool has_output; 94 gint finished; 95 GuestExecIOData in; 96 GuestExecIOData out; 97 GuestExecIOData err; 98 QTAILQ_ENTRY(GuestExecInfo) next; 99 }; 100 typedef struct GuestExecInfo GuestExecInfo; 101 102 static struct { 103 QTAILQ_HEAD(, GuestExecInfo) processes; 104 } guest_exec_state = { 105 .processes = QTAILQ_HEAD_INITIALIZER(guest_exec_state.processes), 106 }; 107 108 static int64_t gpid_to_int64(GPid pid) 109 { 110 #ifdef G_OS_WIN32 111 return GetProcessId(pid); 112 #else 113 return (int64_t)pid; 114 #endif 115 } 116 117 static GuestExecInfo *guest_exec_info_add(GPid pid) 118 { 119 GuestExecInfo *gei; 120 121 gei = g_new0(GuestExecInfo, 1); 122 gei->pid = pid; 123 gei->pid_numeric = gpid_to_int64(pid); 124 QTAILQ_INSERT_TAIL(&guest_exec_state.processes, gei, next); 125 126 return gei; 127 } 128 129 static GuestExecInfo *guest_exec_info_find(int64_t pid_numeric) 130 { 131 GuestExecInfo *gei; 132 133 QTAILQ_FOREACH(gei, &guest_exec_state.processes, next) { 134 if (gei->pid_numeric == pid_numeric) { 135 return gei; 136 } 137 } 138 139 return NULL; 140 } 141 142 GuestExecStatus *qmp_guest_exec_status(int64_t pid, Error **err) 143 { 144 GuestExecInfo *gei; 145 GuestExecStatus *ges; 146 147 slog("guest-exec-status called, pid: %u", (uint32_t)pid); 148 149 gei = guest_exec_info_find(pid); 150 if (gei == NULL) { 151 error_setg(err, QERR_INVALID_PARAMETER, "pid"); 152 return NULL; 153 } 154 155 ges = g_new0(GuestExecStatus, 1); 156 157 bool finished = g_atomic_int_get(&gei->finished); 158 159 /* need to wait till output channels are closed 160 * to be sure we captured all output at this point */ 161 if (gei->has_output) { 162 finished = finished && g_atomic_int_get(&gei->out.closed); 163 finished = finished && g_atomic_int_get(&gei->err.closed); 164 } 165 166 ges->exited = finished; 167 if (finished) { 168 /* Glib has no portable way to parse exit status. 169 * On UNIX, we can get either exit code from normal termination 170 * or signal number. 171 * On Windows, it is either the same exit code or the exception 172 * value for an unhandled exception that caused the process 173 * to terminate. 174 * See MSDN for GetExitCodeProcess() and ntstatus.h for possible 175 * well-known codes, e.g. C0000005 ACCESS_DENIED - analog of SIGSEGV 176 * References: 177 * https://msdn.microsoft.com/en-us/library/windows/desktop/ms683189(v=vs.85).aspx 178 * https://msdn.microsoft.com/en-us/library/aa260331(v=vs.60).aspx 179 */ 180 #ifdef G_OS_WIN32 181 /* Additionally WIN32 does not provide any additional information 182 * on whetherthe child exited or terminated via signal. 183 * We use this simple range check to distingish application exit code 184 * (usually value less then 256) and unhandled exception code with 185 * ntstatus (always value greater then 0xC0000005). */ 186 if ((uint32_t)gei->status < 0xC0000000U) { 187 ges->has_exitcode = true; 188 ges->exitcode = gei->status; 189 } else { 190 ges->has_signal = true; 191 ges->signal = gei->status; 192 } 193 #else 194 if (WIFEXITED(gei->status)) { 195 ges->has_exitcode = true; 196 ges->exitcode = WEXITSTATUS(gei->status); 197 } else if (WIFSIGNALED(gei->status)) { 198 ges->has_signal = true; 199 ges->signal = WTERMSIG(gei->status); 200 } 201 #endif 202 if (gei->out.length > 0) { 203 ges->has_out_data = true; 204 ges->out_data = g_base64_encode(gei->out.data, gei->out.length); 205 g_free(gei->out.data); 206 ges->has_out_truncated = gei->out.truncated; 207 } 208 209 if (gei->err.length > 0) { 210 ges->has_err_data = true; 211 ges->err_data = g_base64_encode(gei->err.data, gei->err.length); 212 g_free(gei->err.data); 213 ges->has_err_truncated = gei->err.truncated; 214 } 215 216 QTAILQ_REMOVE(&guest_exec_state.processes, gei, next); 217 g_free(gei); 218 } 219 220 return ges; 221 } 222 223 /* Get environment variables or arguments array for execve(). */ 224 static char **guest_exec_get_args(const strList *entry, bool log) 225 { 226 const strList *it; 227 int count = 1, i = 0; /* reserve for NULL terminator */ 228 char **args; 229 char *str; /* for logging array of arguments */ 230 size_t str_size = 1; 231 232 for (it = entry; it != NULL; it = it->next) { 233 count++; 234 str_size += 1 + strlen(it->value); 235 } 236 237 str = g_malloc(str_size); 238 *str = 0; 239 args = g_malloc(count * sizeof(char *)); 240 for (it = entry; it != NULL; it = it->next) { 241 args[i++] = it->value; 242 pstrcat(str, str_size, it->value); 243 if (it->next) { 244 pstrcat(str, str_size, " "); 245 } 246 } 247 args[i] = NULL; 248 249 if (log) { 250 slog("guest-exec called: \"%s\"", str); 251 } 252 g_free(str); 253 254 return args; 255 } 256 257 static void guest_exec_child_watch(GPid pid, gint status, gpointer data) 258 { 259 GuestExecInfo *gei = (GuestExecInfo *)data; 260 261 g_debug("guest_exec_child_watch called, pid: %d, status: %u", 262 (int32_t)gpid_to_int64(pid), (uint32_t)status); 263 264 gei->status = status; 265 gei->finished = true; 266 267 g_spawn_close_pid(pid); 268 } 269 270 /** Reset ignored signals back to default. */ 271 static void guest_exec_task_setup(gpointer data) 272 { 273 #if !defined(G_OS_WIN32) 274 struct sigaction sigact; 275 276 memset(&sigact, 0, sizeof(struct sigaction)); 277 sigact.sa_handler = SIG_DFL; 278 279 if (sigaction(SIGPIPE, &sigact, NULL) != 0) { 280 slog("sigaction() failed to reset child process's SIGPIPE: %s", 281 strerror(errno)); 282 } 283 #endif 284 } 285 286 static gboolean guest_exec_input_watch(GIOChannel *ch, 287 GIOCondition cond, gpointer p_) 288 { 289 GuestExecIOData *p = (GuestExecIOData *)p_; 290 gsize bytes_written = 0; 291 GIOStatus status; 292 GError *gerr = NULL; 293 294 /* nothing left to write */ 295 if (p->size == p->length) { 296 goto done; 297 } 298 299 status = g_io_channel_write_chars(ch, (gchar *)p->data + p->length, 300 p->size - p->length, &bytes_written, &gerr); 301 302 /* can be not 0 even if not G_IO_STATUS_NORMAL */ 303 if (bytes_written != 0) { 304 p->length += bytes_written; 305 } 306 307 /* continue write, our callback will be called again */ 308 if (status == G_IO_STATUS_NORMAL || status == G_IO_STATUS_AGAIN) { 309 return true; 310 } 311 312 if (gerr) { 313 g_warning("qga: i/o error writing to input_data channel: %s", 314 gerr->message); 315 g_error_free(gerr); 316 } 317 318 done: 319 g_io_channel_shutdown(ch, true, NULL); 320 g_io_channel_unref(ch); 321 g_atomic_int_set(&p->closed, 1); 322 g_free(p->data); 323 324 return false; 325 } 326 327 static gboolean guest_exec_output_watch(GIOChannel *ch, 328 GIOCondition cond, gpointer p_) 329 { 330 GuestExecIOData *p = (GuestExecIOData *)p_; 331 gsize bytes_read; 332 GIOStatus gstatus; 333 334 if (cond == G_IO_HUP || cond == G_IO_ERR) { 335 goto close; 336 } 337 338 if (p->size == p->length) { 339 gpointer t = NULL; 340 if (!p->truncated && p->size < GUEST_EXEC_MAX_OUTPUT) { 341 t = g_try_realloc(p->data, p->size + GUEST_EXEC_IO_SIZE); 342 } 343 if (t == NULL) { 344 /* ignore truncated output */ 345 gchar buf[GUEST_EXEC_IO_SIZE]; 346 347 p->truncated = true; 348 gstatus = g_io_channel_read_chars(ch, buf, sizeof(buf), 349 &bytes_read, NULL); 350 if (gstatus == G_IO_STATUS_EOF || gstatus == G_IO_STATUS_ERROR) { 351 goto close; 352 } 353 354 return true; 355 } 356 p->size += GUEST_EXEC_IO_SIZE; 357 p->data = t; 358 } 359 360 /* Calling read API once. 361 * On next available data our callback will be called again */ 362 gstatus = g_io_channel_read_chars(ch, (gchar *)p->data + p->length, 363 p->size - p->length, &bytes_read, NULL); 364 if (gstatus == G_IO_STATUS_EOF || gstatus == G_IO_STATUS_ERROR) { 365 goto close; 366 } 367 368 p->length += bytes_read; 369 370 return true; 371 372 close: 373 g_io_channel_unref(ch); 374 g_atomic_int_set(&p->closed, 1); 375 return false; 376 } 377 378 GuestExec *qmp_guest_exec(const char *path, 379 bool has_arg, strList *arg, 380 bool has_env, strList *env, 381 bool has_input_data, const char *input_data, 382 bool has_capture_output, bool capture_output, 383 Error **err) 384 { 385 GPid pid; 386 GuestExec *ge = NULL; 387 GuestExecInfo *gei; 388 char **argv, **envp; 389 strList arglist; 390 gboolean ret; 391 GError *gerr = NULL; 392 gint in_fd, out_fd, err_fd; 393 GIOChannel *in_ch, *out_ch, *err_ch; 394 GSpawnFlags flags; 395 bool has_output = (has_capture_output && capture_output); 396 397 arglist.value = (char *)path; 398 arglist.next = has_arg ? arg : NULL; 399 400 argv = guest_exec_get_args(&arglist, true); 401 envp = guest_exec_get_args(has_env ? env : NULL, false); 402 403 flags = G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD; 404 if (!has_output) { 405 flags |= G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL; 406 } 407 408 ret = g_spawn_async_with_pipes(NULL, argv, envp, flags, 409 guest_exec_task_setup, NULL, &pid, has_input_data ? &in_fd : NULL, 410 has_output ? &out_fd : NULL, has_output ? &err_fd : NULL, &gerr); 411 if (!ret) { 412 error_setg(err, QERR_QGA_COMMAND_FAILED, gerr->message); 413 g_error_free(gerr); 414 goto done; 415 } 416 417 ge = g_new0(GuestExec, 1); 418 ge->pid = gpid_to_int64(pid); 419 420 gei = guest_exec_info_add(pid); 421 gei->has_output = has_output; 422 g_child_watch_add(pid, guest_exec_child_watch, gei); 423 424 if (has_input_data) { 425 gei->in.data = g_base64_decode(input_data, &gei->in.size); 426 #ifdef G_OS_WIN32 427 in_ch = g_io_channel_win32_new_fd(in_fd); 428 #else 429 in_ch = g_io_channel_unix_new(in_fd); 430 #endif 431 g_io_channel_set_encoding(in_ch, NULL, NULL); 432 g_io_channel_set_buffered(in_ch, false); 433 g_io_channel_set_flags(in_ch, G_IO_FLAG_NONBLOCK, NULL); 434 g_io_add_watch(in_ch, G_IO_OUT, guest_exec_input_watch, &gei->in); 435 } 436 437 if (has_output) { 438 #ifdef G_OS_WIN32 439 out_ch = g_io_channel_win32_new_fd(out_fd); 440 err_ch = g_io_channel_win32_new_fd(err_fd); 441 #else 442 out_ch = g_io_channel_unix_new(out_fd); 443 err_ch = g_io_channel_unix_new(err_fd); 444 #endif 445 g_io_channel_set_encoding(out_ch, NULL, NULL); 446 g_io_channel_set_encoding(err_ch, NULL, NULL); 447 g_io_channel_set_buffered(out_ch, false); 448 g_io_channel_set_buffered(err_ch, false); 449 g_io_add_watch(out_ch, G_IO_IN | G_IO_HUP, 450 guest_exec_output_watch, &gei->out); 451 g_io_add_watch(err_ch, G_IO_IN | G_IO_HUP, 452 guest_exec_output_watch, &gei->err); 453 } 454 455 done: 456 g_free(argv); 457 g_free(envp); 458 459 return ge; 460 } 461