master
c 1,417 lines 38.4 KB
Raw
1 /*
2 * QEMU Guest Agent POSIX-specific command implementations
3 *
4 * Copyright IBM Corp. 2011
5 *
6 * Authors:
7 * Michael Roth <mdroth@linux.vnet.ibm.com>
8 * Michal Privoznik <mprivozn@redhat.com>
9 *
10 * This work is licensed under the terms of the GNU GPL, version 2 or later.
11 * See the COPYING file in the top-level directory.
12 */
13
14 #include "qemu/osdep.h"
15 #include <sys/ioctl.h>
16 #include <sys/utsname.h>
17 #include <sys/wait.h>
18 #include <dirent.h>
19 #include "qga-qapi-commands.h"
20 #include "qapi/error.h"
21 #include "qemu/host-utils.h"
22 #include "qemu/sockets.h"
23 #include "qemu/base64.h"
24 #include "qemu/cutils.h"
25 #include "commands-common.h"
26 #include "cutils.h"
27
28 #ifdef HAVE_UTMPX
29 #include <utmpx.h>
30 #endif
31
32 #ifdef HAVE_GETIFADDRS
33 #include <arpa/inet.h>
34 #include <sys/socket.h>
35 #include <net/if.h>
36 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(CONFIG_SOLARIS)
37 #include <net/if_arp.h>
38 #include <netinet/if_ether.h>
39 #if !defined(ETHER_ADDR_LEN) && defined(ETHERADDRL)
40 #define ETHER_ADDR_LEN ETHERADDRL
41 #endif
42 #else
43 #include <net/ethernet.h>
44 #endif
45 #ifdef CONFIG_SOLARIS
46 #ifdef CONFIG_GETLOADAVG
47 #include <sys/loadavg.h>
48 #endif
49 #include <sys/sockio.h>
50 #endif
51 #endif
52
53 static bool ga_wait_child(pid_t pid, int *status, Error **errp)
54 {
55 pid_t rpid;
56
57 *status = 0;
58
59 rpid = RETRY_ON_EINTR(waitpid(pid, status, 0));
60
61 if (rpid == -1) {
62 error_setg_errno(errp, errno, "failed to wait for child (pid: %d)",
63 pid);
64 return false;
65 }
66
67 g_assert(rpid == pid);
68 return true;
69 }
70
71 static ssize_t ga_pipe_read_str(int fd[2], char **str)
72 {
73 ssize_t n, len = 0;
74 char buf[1024];
75
76 close(fd[1]);
77 fd[1] = -1;
78 while ((n = read(fd[0], buf, sizeof(buf))) != 0) {
79 if (n < 0) {
80 if (errno == EINTR) {
81 continue;
82 } else {
83 len = -errno;
84 break;
85 }
86 }
87 *str = g_realloc(*str, len + n + 1);
88 memcpy(*str + len, buf, n);
89 len += n;
90 (*str)[len] = '\0';
91 }
92 close(fd[0]);
93 fd[0] = -1;
94
95 return len;
96 }
97
98 /*
99 * Helper to run command with input/output redirection,
100 * sending string to stdin and taking error message from
101 * stdout/err.
102 */
103 static int ga_run_command(const char *argv[], const char *in_str,
104 const char *action, Error **errp)
105 {
106 pid_t pid;
107 int status;
108 int retcode = -1;
109 int infd[2] = { -1, -1 };
110 int outfd[2] = { -1, -1 };
111 char *str = NULL;
112 ssize_t len = 0;
113
114 if ((in_str && !g_unix_open_pipe(infd, FD_CLOEXEC, NULL)) ||
115 !g_unix_open_pipe(outfd, FD_CLOEXEC, NULL)) {
116 error_setg(errp, "cannot create pipe FDs");
117 goto out;
118 }
119
120 pid = fork();
121 if (pid == 0) {
122 char *cherr = NULL;
123
124 setsid();
125
126 if (in_str) {
127 /* Redirect stdin to infd. */
128 close(infd[1]);
129 dup2(infd[0], 0);
130 close(infd[0]);
131 } else {
132 reopen_fd_to_null(0);
133 }
134
135 /* Redirect stdout/stderr to outfd. */
136 close(outfd[0]);
137 dup2(outfd[1], 1);
138 dup2(outfd[1], 2);
139 close(outfd[1]);
140
141 execvp(argv[0], (char *const *)argv);
142
143 /* Write the cause of failed exec to pipe for the parent to read it. */
144 cherr = g_strdup_printf("failed to exec '%s'", argv[0]);
145 perror(cherr);
146 g_free(cherr);
147 _exit(EXIT_FAILURE);
148 } else if (pid < 0) {
149 error_setg_errno(errp, errno, "failed to create child process");
150 goto out;
151 }
152
153 if (in_str) {
154 close(infd[0]);
155 infd[0] = -1;
156 if (qemu_write_full(infd[1], in_str, strlen(in_str)) !=
157 strlen(in_str)) {
158 error_setg_errno(errp, errno, "%s: cannot write to stdin pipe",
159 action);
160 goto out;
161 }
162 close(infd[1]);
163 infd[1] = -1;
164 }
165
166 len = ga_pipe_read_str(outfd, &str);
167 if (len < 0) {
168 error_setg_errno(errp, -len, "%s: cannot read from stdout/stderr pipe",
169 action);
170 goto out;
171 }
172
173 if (!ga_wait_child(pid, &status, errp)) {
174 goto out;
175 }
176
177 if (!WIFEXITED(status)) {
178 if (len) {
179 error_setg(errp, "child process has terminated abnormally: %s",
180 str);
181 } else {
182 error_setg(errp, "child process has terminated abnormally");
183 }
184 goto out;
185 }
186
187 retcode = WEXITSTATUS(status);
188
189 if (WEXITSTATUS(status)) {
190 if (len) {
191 error_setg(errp, "child process has failed to %s: %s",
192 action, str);
193 } else {
194 error_setg(errp, "child process has failed to %s: exit status %d",
195 action, WEXITSTATUS(status));
196 }
197 goto out;
198 }
199
200 out:
201 g_free(str);
202
203 if (infd[0] != -1) {
204 close(infd[0]);
205 }
206 if (infd[1] != -1) {
207 close(infd[1]);
208 }
209 if (outfd[0] != -1) {
210 close(outfd[0]);
211 }
212 if (outfd[1] != -1) {
213 close(outfd[1]);
214 }
215
216 return retcode;
217 }
218
219 #define POWEROFF_CMD_PATH "/sbin/poweroff"
220 #define HALT_CMD_PATH "/sbin/halt"
221 #define REBOOT_CMD_PATH "/sbin/reboot"
222
223 void qmp_guest_shutdown(const char *mode, Error **errp)
224 {
225 const char *shutdown_flag;
226 const char *shutdown_cmd = NULL;
227 Error *local_err = NULL;
228
229 #ifdef CONFIG_SOLARIS
230 const char *powerdown_flag = "-i5";
231 const char *halt_flag = "-i0";
232 const char *reboot_flag = "-i6";
233 #elif defined(CONFIG_BSD)
234 const char *powerdown_flag = "-p";
235 const char *halt_flag = "-h";
236 const char *reboot_flag = "-r";
237 #else
238 const char *powerdown_flag = "-P";
239 const char *halt_flag = "-H";
240 const char *reboot_flag = "-r";
241 #endif
242
243 slog("guest-shutdown called, mode: %s", mode);
244 if (!mode || strcmp(mode, "powerdown") == 0) {
245 if (access(POWEROFF_CMD_PATH, X_OK) == 0) {
246 shutdown_cmd = POWEROFF_CMD_PATH;
247 }
248 shutdown_flag = powerdown_flag;
249 } else if (strcmp(mode, "halt") == 0) {
250 if (access(HALT_CMD_PATH, X_OK) == 0) {
251 shutdown_cmd = HALT_CMD_PATH;
252 }
253 shutdown_flag = halt_flag;
254 } else if (strcmp(mode, "reboot") == 0) {
255 if (access(REBOOT_CMD_PATH, X_OK) == 0) {
256 shutdown_cmd = REBOOT_CMD_PATH;
257 }
258 shutdown_flag = reboot_flag;
259 } else {
260 error_setg(errp,
261 "mode is invalid (valid values are: halt|powerdown|reboot");
262 return;
263 }
264
265 const char *argv[] = {"/sbin/shutdown",
266 #ifdef CONFIG_SOLARIS
267 shutdown_flag, "-g0", "-y",
268 #elif defined(CONFIG_BSD)
269 shutdown_flag, "+0",
270 #else
271 "-h", shutdown_flag, "+0",
272 #endif
273 "hypervisor initiated shutdown", (char *) NULL};
274
275 /*
276 * If the specific command exists (poweroff, halt or reboot), use it instead
277 * of /sbin/shutdown.
278 */
279 if (shutdown_cmd != NULL) {
280 argv[0] = shutdown_cmd;
281 argv[1] = NULL;
282 }
283
284 ga_run_command(argv, NULL, "shutdown", &local_err);
285 if (local_err) {
286 error_propagate(errp, local_err);
287 return;
288 }
289
290 /* succeeded */
291 }
292
293 void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
294 {
295 int ret;
296 Error *local_err = NULL;
297 struct timeval tv;
298 const char *argv[] = {"/sbin/hwclock", has_time ? "-w" : "-s", NULL};
299
300 /* If user has passed a time, validate and set it. */
301 if (has_time) {
302 GDate date = { 0, };
303
304 /* year-2038 will overflow in case time_t is 32bit */
305 if (time_ns / 1000000000 != (time_t)(time_ns / 1000000000)) {
306 error_setg(errp, "Time %" PRId64 " is too large", time_ns);
307 return;
308 }
309
310 tv.tv_sec = time_ns / 1000000000;
311 tv.tv_usec = (time_ns % 1000000000) / 1000;
312 g_date_set_time_t(&date, tv.tv_sec);
313 if (date.year < 1970 || date.year >= 2070) {
314 error_setg_errno(errp, errno, "Invalid time");
315 return;
316 }
317
318 ret = settimeofday(&tv, NULL);
319 if (ret < 0) {
320 error_setg_errno(errp, errno, "Failed to set time to guest");
321 return;
322 }
323 }
324
325 /* Now, if user has passed a time to set and the system time is set, we
326 * just need to synchronize the hardware clock. However, if no time was
327 * passed, user is requesting the opposite: set the system time from the
328 * hardware clock (RTC). */
329 ga_run_command(argv, NULL, "set hardware clock to system time",
330 &local_err);
331 if (local_err) {
332 error_propagate(errp, local_err);
333 return;
334 }
335 }
336
337 typedef enum {
338 RW_STATE_NEW,
339 RW_STATE_READING,
340 RW_STATE_WRITING,
341 } RwState;
342
343 struct GuestFileHandle {
344 uint64_t id;
345 FILE *fh;
346 RwState state;
347 QTAILQ_ENTRY(GuestFileHandle) next;
348 };
349
350 static struct {
351 QTAILQ_HEAD(, GuestFileHandle) filehandles;
352 } guest_file_state = {
353 .filehandles = QTAILQ_HEAD_INITIALIZER(guest_file_state.filehandles),
354 };
355
356 static int64_t guest_file_handle_add(FILE *fh, Error **errp)
357 {
358 GuestFileHandle *gfh;
359 int64_t handle;
360
361 handle = ga_get_fd_handle(ga_state, errp);
362 if (handle < 0) {
363 return -1;
364 }
365
366 gfh = g_new0(GuestFileHandle, 1);
367 gfh->id = handle;
368 gfh->fh = fh;
369 QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next);
370
371 return handle;
372 }
373
374 GuestFileHandle *guest_file_handle_find(int64_t id, Error **errp)
375 {
376 GuestFileHandle *gfh;
377
378 QTAILQ_FOREACH(gfh, &guest_file_state.filehandles, next)
379 {
380 if (gfh->id == id) {
381 return gfh;
382 }
383 }
384
385 error_setg(errp, "handle '%" PRId64 "' has not been found", id);
386 return NULL;
387 }
388
389 typedef const char * const ccpc;
390
391 #ifndef O_BINARY
392 #define O_BINARY 0
393 #endif
394
395 /* http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html */
396 static const struct {
397 ccpc *forms;
398 int oflag_base;
399 } guest_file_open_modes[] = {
400 { (ccpc[]){ "r", NULL }, O_RDONLY },
401 { (ccpc[]){ "rb", NULL }, O_RDONLY | O_BINARY },
402 { (ccpc[]){ "w", NULL }, O_WRONLY | O_CREAT | O_TRUNC },
403 { (ccpc[]){ "wb", NULL }, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY },
404 { (ccpc[]){ "a", NULL }, O_WRONLY | O_CREAT | O_APPEND },
405 { (ccpc[]){ "ab", NULL }, O_WRONLY | O_CREAT | O_APPEND | O_BINARY },
406 { (ccpc[]){ "r+", NULL }, O_RDWR },
407 { (ccpc[]){ "rb+", "r+b", NULL }, O_RDWR | O_BINARY },
408 { (ccpc[]){ "w+", NULL }, O_RDWR | O_CREAT | O_TRUNC },
409 { (ccpc[]){ "wb+", "w+b", NULL }, O_RDWR | O_CREAT | O_TRUNC | O_BINARY },
410 { (ccpc[]){ "a+", NULL }, O_RDWR | O_CREAT | O_APPEND },
411 { (ccpc[]){ "ab+", "a+b", NULL }, O_RDWR | O_CREAT | O_APPEND | O_BINARY }
412 };
413
414 static int
415 find_open_flag(const char *mode_str, Error **errp)
416 {
417 unsigned mode;
418
419 for (mode = 0; mode < ARRAY_SIZE(guest_file_open_modes); ++mode) {
420 ccpc *form;
421
422 form = guest_file_open_modes[mode].forms;
423 while (*form != NULL && strcmp(*form, mode_str) != 0) {
424 ++form;
425 }
426 if (*form != NULL) {
427 break;
428 }
429 }
430
431 if (mode == ARRAY_SIZE(guest_file_open_modes)) {
432 error_setg(errp, "invalid file open mode '%s'", mode_str);
433 return -1;
434 }
435 return guest_file_open_modes[mode].oflag_base | O_NOCTTY | O_NONBLOCK;
436 }
437
438 #define DEFAULT_NEW_FILE_MODE (S_IRUSR | S_IWUSR | \
439 S_IRGRP | S_IWGRP | \
440 S_IROTH | S_IWOTH)
441
442 static FILE *
443 safe_open_or_create(const char *path, const char *mode, Error **errp)
444 {
445 int oflag;
446 int fd = -1;
447 FILE *f = NULL;
448
449 oflag = find_open_flag(mode, errp);
450 if (oflag < 0) {
451 goto end;
452 }
453
454 /* If the caller wants / allows creation of a new file, we implement it
455 * with a two step process: open() + (open() / fchmod()).
456 *
457 * First we insist on creating the file exclusively as a new file. If
458 * that succeeds, we're free to set any file-mode bits on it. (The
459 * motivation is that we want to set those file-mode bits independently
460 * of the current umask.)
461 *
462 * If the exclusive creation fails because the file already exists
463 * (EEXIST is not possible for any other reason), we just attempt to
464 * open the file, but in this case we won't be allowed to change the
465 * file-mode bits on the preexistent file.
466 *
467 * The pathname should never disappear between the two open()s in
468 * practice. If it happens, then someone very likely tried to race us.
469 * In this case just go ahead and report the ENOENT from the second
470 * open() to the caller.
471 *
472 * If the caller wants to open a preexistent file, then the first
473 * open() is decisive and its third argument is ignored, and the second
474 * open() and the fchmod() are never called.
475 */
476 fd = qga_open_cloexec(path, oflag | ((oflag & O_CREAT) ? O_EXCL : 0), 0);
477 if (fd == -1 && errno == EEXIST) {
478 oflag &= ~(unsigned)O_CREAT;
479 fd = qga_open_cloexec(path, oflag, 0);
480 }
481 if (fd == -1) {
482 error_setg_errno(errp, errno,
483 "failed to open file '%s' (mode: '%s')",
484 path, mode);
485 goto end;
486 }
487
488 if ((oflag & O_CREAT) && fchmod(fd, DEFAULT_NEW_FILE_MODE) == -1) {
489 error_setg_errno(errp, errno, "failed to set permission "
490 "0%03o on new file '%s' (mode: '%s')",
491 (unsigned)DEFAULT_NEW_FILE_MODE, path, mode);
492 goto end;
493 }
494
495 f = fdopen(fd, mode);
496 if (f == NULL) {
497 error_setg_errno(errp, errno, "failed to associate stdio stream with "
498 "file descriptor %d, file '%s' (mode: '%s')",
499 fd, path, mode);
500 }
501
502 end:
503 if (f == NULL && fd != -1) {
504 close(fd);
505 if (oflag & O_CREAT) {
506 unlink(path);
507 }
508 }
509 return f;
510 }
511
512 int64_t qmp_guest_file_open(const char *path, const char *mode,
513 Error **errp)
514 {
515 FILE *fh;
516 Error *local_err = NULL;
517 int64_t handle;
518
519 if (!mode) {
520 mode = "r";
521 }
522 slog("guest-file-open called, filepath: %s, mode: %s", path, mode);
523 fh = safe_open_or_create(path, mode, &local_err);
524 if (local_err != NULL) {
525 error_propagate(errp, local_err);
526 return -1;
527 }
528
529 /* set fd non-blocking to avoid common use cases (like reading from a
530 * named pipe) from hanging the agent
531 */
532 if (!qemu_set_blocking(fileno(fh), false, errp)) {
533 fclose(fh);
534 return -1;
535 }
536
537 handle = guest_file_handle_add(fh, errp);
538 if (handle < 0) {
539 fclose(fh);
540 return -1;
541 }
542
543 slog("guest-file-open, handle: %" PRId64, handle);
544 return handle;
545 }
546
547 void qmp_guest_file_close(int64_t handle, Error **errp)
548 {
549 GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
550 int ret;
551
552 slog("guest-file-close called, handle: %" PRId64, handle);
553 if (!gfh) {
554 return;
555 }
556
557 ret = fclose(gfh->fh);
558 if (ret == EOF) {
559 error_setg_errno(errp, errno, "failed to close handle");
560 return;
561 }
562
563 QTAILQ_REMOVE(&guest_file_state.filehandles, gfh, next);
564 g_free(gfh);
565 }
566
567 GuestFileRead *guest_file_read_unsafe(GuestFileHandle *gfh,
568 int64_t count, Error **errp)
569 {
570 GuestFileRead *read_data = NULL;
571 guchar *buf;
572 FILE *fh = gfh->fh;
573 size_t read_count;
574
575 /* explicitly flush when switching from writing to reading */
576 if (gfh->state == RW_STATE_WRITING) {
577 int ret = fflush(fh);
578 if (ret == EOF) {
579 error_setg_errno(errp, errno, "failed to flush file");
580 return NULL;
581 }
582 gfh->state = RW_STATE_NEW;
583 }
584
585 buf = g_malloc0(count + 1);
586 read_count = fread(buf, 1, count, fh);
587 if (ferror(fh)) {
588 error_setg_errno(errp, errno, "failed to read file");
589 } else {
590 buf[read_count] = 0;
591 read_data = g_new0(GuestFileRead, 1);
592 read_data->count = read_count;
593 read_data->eof = feof(fh);
594 if (read_count) {
595 read_data->buf_b64 = g_base64_encode(buf, read_count);
596 }
597 gfh->state = RW_STATE_READING;
598 }
599 g_free(buf);
600 clearerr(fh);
601
602 return read_data;
603 }
604
605 GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
606 bool has_count, int64_t count,
607 Error **errp)
608 {
609 GuestFileWrite *write_data = NULL;
610 guchar *buf;
611 gsize buf_len;
612 int write_count;
613 GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
614 FILE *fh;
615
616 if (!gfh) {
617 return NULL;
618 }
619
620 fh = gfh->fh;
621
622 if (gfh->state == RW_STATE_READING) {
623 int ret = fseek(fh, 0, SEEK_CUR);
624 if (ret == -1) {
625 error_setg_errno(errp, errno, "failed to seek file");
626 return NULL;
627 }
628 gfh->state = RW_STATE_NEW;
629 }
630
631 buf = qbase64_decode(buf_b64, -1, &buf_len, errp);
632 if (!buf) {
633 return NULL;
634 }
635
636 if (!has_count) {
637 count = buf_len;
638 } else if (count < 0 || count > buf_len) {
639 error_setg(errp, "value '%" PRId64 "' is invalid for argument count",
640 count);
641 g_free(buf);
642 return NULL;
643 }
644
645 write_count = fwrite(buf, 1, count, fh);
646 if (ferror(fh)) {
647 error_setg_errno(errp, errno, "failed to write to file");
648 slog("guest-file-write failed, handle: %" PRId64, handle);
649 } else {
650 write_data = g_new0(GuestFileWrite, 1);
651 write_data->count = write_count;
652 write_data->eof = feof(fh);
653 gfh->state = RW_STATE_WRITING;
654 }
655 g_free(buf);
656 clearerr(fh);
657
658 return write_data;
659 }
660
661 struct GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
662 GuestFileWhence *whence_code,
663 Error **errp)
664 {
665 GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
666 GuestFileSeek *seek_data = NULL;
667 FILE *fh;
668 int ret;
669 int whence;
670 Error *err = NULL;
671
672 if (!gfh) {
673 return NULL;
674 }
675
676 /* We stupidly exposed 'whence':'int' in our qapi */
677 whence = ga_parse_whence(whence_code, &err);
678 if (err) {
679 error_propagate(errp, err);
680 return NULL;
681 }
682
683 fh = gfh->fh;
684 ret = fseek(fh, offset, whence);
685 if (ret == -1) {
686 error_setg_errno(errp, errno, "failed to seek file");
687 if (errno == ESPIPE) {
688 /* file is non-seekable, stdio shouldn't be buffering anyways */
689 gfh->state = RW_STATE_NEW;
690 }
691 } else {
692 seek_data = g_new0(GuestFileSeek, 1);
693 seek_data->position = ftell(fh);
694 seek_data->eof = feof(fh);
695 gfh->state = RW_STATE_NEW;
696 }
697 clearerr(fh);
698
699 return seek_data;
700 }
701
702 void qmp_guest_file_flush(int64_t handle, Error **errp)
703 {
704 GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
705 FILE *fh;
706 int ret;
707
708 if (!gfh) {
709 return;
710 }
711
712 fh = gfh->fh;
713 ret = fflush(fh);
714 if (ret == EOF) {
715 error_setg_errno(errp, errno, "failed to flush file");
716 } else {
717 gfh->state = RW_STATE_NEW;
718 }
719 }
720
721 #if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM)
722 void free_fs_mount_list(FsMountList *mounts)
723 {
724 FsMount *mount, *temp;
725
726 if (!mounts) {
727 return;
728 }
729
730 QTAILQ_FOREACH_SAFE(mount, mounts, next, temp) {
731 QTAILQ_REMOVE(mounts, mount, next);
732 g_free(mount->dirname);
733 g_free(mount->devtype);
734 g_free(mount);
735 }
736 }
737 #endif
738
739 #if defined(CONFIG_FSFREEZE)
740 typedef enum {
741 FSFREEZE_HOOK_THAW = 0,
742 FSFREEZE_HOOK_FREEZE,
743 } FsfreezeHookArg;
744
745 static const char *fsfreeze_hook_arg_string[] = {
746 "thaw",
747 "freeze",
748 };
749
750 static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **errp)
751 {
752 const char *hook;
753 const char *arg_str = fsfreeze_hook_arg_string[arg];
754 Error *local_err = NULL;
755
756 hook = ga_fsfreeze_hook(ga_state);
757 if (!hook) {
758 return;
759 }
760
761 const char *argv[] = {hook, arg_str, NULL};
762
763 slog("executing fsfreeze hook with arg '%s'", arg_str);
764 ga_run_command(argv, NULL, "execute fsfreeze hook", &local_err);
765 if (local_err) {
766 error_propagate(errp, local_err);
767 return;
768 }
769 }
770
771 /*
772 * Return status of freeze/thaw
773 */
774 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp)
775 {
776 if (ga_is_frozen(ga_state)) {
777 return GUEST_FSFREEZE_STATUS_FROZEN;
778 }
779
780 return GUEST_FSFREEZE_STATUS_THAWED;
781 }
782
783 int64_t qmp_guest_fsfreeze_freeze(Error **errp)
784 {
785 return qmp_guest_fsfreeze_freeze_list(false, NULL, errp);
786 }
787
788 int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
789 strList *mountpoints,
790 Error **errp)
791 {
792 int ret;
793 FsMountList mounts;
794 Error *local_err = NULL;
795
796 slog("guest-fsfreeze called");
797
798 execute_fsfreeze_hook(FSFREEZE_HOOK_FREEZE, &local_err);
799 if (local_err) {
800 error_propagate(errp, local_err);
801 return -1;
802 }
803
804 QTAILQ_INIT(&mounts);
805 if (!build_fs_mount_list(&mounts, &local_err)) {
806 error_propagate(errp, local_err);
807 return -1;
808 }
809
810 /* cannot risk guest agent blocking itself on a write in this state */
811 ga_set_frozen(ga_state);
812
813 ret = qmp_guest_fsfreeze_do_freeze_list(has_mountpoints, mountpoints,
814 mounts, errp);
815
816 free_fs_mount_list(&mounts);
817 /* We may not issue any FIFREEZE here.
818 * Just unset ga_state here and ready for the next call.
819 */
820 if (ret == 0) {
821 ga_unset_frozen(ga_state);
822 } else if (ret < 0) {
823 qmp_guest_fsfreeze_thaw(NULL);
824 }
825 return ret;
826 }
827
828 int64_t qmp_guest_fsfreeze_thaw(Error **errp)
829 {
830 int ret;
831
832 ret = qmp_guest_fsfreeze_do_thaw(errp);
833
834 if (ret >= 0) {
835 ga_unset_frozen(ga_state);
836 slog("guest-fsthaw called");
837 execute_fsfreeze_hook(FSFREEZE_HOOK_THAW, errp);
838 } else {
839 ret = 0;
840 }
841
842 return ret;
843 }
844
845 static void guest_fsfreeze_cleanup(void)
846 {
847 Error *err = NULL;
848
849 if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) {
850 qmp_guest_fsfreeze_thaw(&err);
851 if (err) {
852 slog("failed to clean up frozen filesystems: %s",
853 error_get_pretty(err));
854 error_free(err);
855 }
856 }
857 }
858 #endif
859
860 #if defined(__linux__) || defined(__FreeBSD__)
861 void qmp_guest_set_user_password(const char *username,
862 const char *password,
863 bool crypted,
864 Error **errp)
865 {
866 Error *local_err = NULL;
867 g_autofree char *rawpasswddata = NULL;
868 size_t rawpasswdlen;
869
870 rawpasswddata = (char *)qbase64_decode(password, -1, &rawpasswdlen, errp);
871 if (!rawpasswddata) {
872 return;
873 }
874 rawpasswddata = g_renew(char, rawpasswddata, rawpasswdlen + 1);
875 rawpasswddata[rawpasswdlen] = '\0';
876
877 if (strchr(rawpasswddata, '\n')) {
878 error_setg(errp, "forbidden characters in raw password");
879 return;
880 }
881
882 if (strchr(username, '\n') ||
883 strchr(username, ':')) {
884 error_setg(errp, "forbidden characters in username");
885 return;
886 }
887
888 #ifdef __FreeBSD__
889 g_autofree char *chpasswddata = g_strdup(rawpasswddata);
890 const char *crypt_flag = crypted ? "-H" : "-h";
891 const char *argv[] = {"pw", "usermod", "-n", username,
892 crypt_flag, "0", NULL};
893 #else
894 g_autofree char *chpasswddata = g_strdup_printf("%s:%s\n", username,
895 rawpasswddata);
896 const char *crypt_flag = crypted ? "-e" : NULL;
897 const char *argv[] = {"chpasswd", crypt_flag, NULL};
898 #endif
899
900 ga_run_command(argv, chpasswddata, "set user password", &local_err);
901 if (local_err) {
902 error_propagate(errp, local_err);
903 return;
904 }
905 }
906 #endif /* __linux__ || __FreeBSD__ */
907
908 #ifdef HAVE_GETIFADDRS
909 static GuestNetworkInterface *
910 guest_find_interface(GuestNetworkInterfaceList *head,
911 const char *name)
912 {
913 for (; head; head = head->next) {
914 if (strcmp(head->value->name, name) == 0) {
915 return head->value;
916 }
917 }
918
919 return NULL;
920 }
921
922 static int guest_get_network_stats(const char *name,
923 GuestNetworkInterfaceStat *stats)
924 {
925 #ifdef CONFIG_LINUX
926 int name_len;
927 char const *devinfo = "/proc/net/dev";
928 FILE *fp;
929 char *line = NULL, *colon;
930 size_t n = 0;
931 fp = fopen(devinfo, "r");
932 if (!fp) {
933 g_debug("failed to open network stats %s: %s", devinfo,
934 g_strerror(errno));
935 return -1;
936 }
937 name_len = strlen(name);
938 while (getline(&line, &n, fp) != -1) {
939 long long dummy;
940 long long rx_bytes;
941 long long rx_packets;
942 long long rx_errs;
943 long long rx_dropped;
944 long long tx_bytes;
945 long long tx_packets;
946 long long tx_errs;
947 long long tx_dropped;
948 char *trim_line;
949 trim_line = g_strchug(line);
950 if (trim_line[0] == '\0') {
951 continue;
952 }
953 colon = strchr(trim_line, ':');
954 if (!colon) {
955 continue;
956 }
957 if (colon - name_len == trim_line &&
958 strncmp(trim_line, name, name_len) == 0) {
959 if (sscanf(colon + 1,
960 "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld",
961 &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
962 &dummy, &dummy, &dummy, &dummy,
963 &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
964 &dummy, &dummy, &dummy, &dummy) != 16) {
965 continue;
966 }
967 stats->rx_bytes = rx_bytes;
968 stats->rx_packets = rx_packets;
969 stats->rx_errs = rx_errs;
970 stats->rx_dropped = rx_dropped;
971 stats->tx_bytes = tx_bytes;
972 stats->tx_packets = tx_packets;
973 stats->tx_errs = tx_errs;
974 stats->tx_dropped = tx_dropped;
975 fclose(fp);
976 g_free(line);
977 return 0;
978 }
979 }
980 fclose(fp);
981 g_free(line);
982 g_debug("/proc/net/dev: Interface '%s' not found", name);
983 #else /* !CONFIG_LINUX */
984 g_debug("Network stats reporting available only for Linux");
985 #endif /* !CONFIG_LINUX */
986 return -1;
987 }
988
989 #ifndef CONFIG_BSD
990 /*
991 * Fill "buf" with MAC address by ifaddrs. Pointer buf must point to a
992 * buffer with ETHER_ADDR_LEN length at least.
993 *
994 * Returns false in case of an error, otherwise true. "obtained" argument
995 * is true if a MAC address was obtained successful, otherwise false.
996 */
997 bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char *buf,
998 bool *obtained, Error **errp)
999 {
1000 struct ifreq ifr;
1001 int sock;
1002
1003 *obtained = false;
1004
1005 /* we haven't obtained HW address yet */
1006 sock = socket(PF_INET, SOCK_STREAM, 0);
1007 if (sock == -1) {
1008 error_setg_errno(errp, errno, "failed to create socket");
1009 return false;
1010 }
1011
1012 memset(&ifr, 0, sizeof(ifr));
1013 pstrcpy(ifr.ifr_name, IF_NAMESIZE, ifa->ifa_name);
1014 if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) {
1015 /*
1016 * We can't get the hw addr of this interface, but that's not a
1017 * fatal error.
1018 */
1019 if (errno == EADDRNOTAVAIL) {
1020 /* The interface doesn't have a hw addr (e.g. loopback). */
1021 g_debug("failed to get MAC address of %s: %s",
1022 ifa->ifa_name, strerror(errno));
1023 } else{
1024 g_warning("failed to get MAC address of %s: %s",
1025 ifa->ifa_name, strerror(errno));
1026 }
1027 } else {
1028 #ifdef CONFIG_SOLARIS
1029 memcpy(buf, &ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
1030 #else
1031 memcpy(buf, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
1032 #endif
1033 *obtained = true;
1034 }
1035 close(sock);
1036 return true;
1037 }
1038 #endif /* CONFIG_BSD */
1039
1040 /*
1041 * Build information about guest interfaces
1042 */
1043 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
1044 {
1045 GuestNetworkInterfaceList *head = NULL, **tail = &head;
1046 struct ifaddrs *ifap, *ifa;
1047
1048 if (getifaddrs(&ifap) < 0) {
1049 error_setg_errno(errp, errno, "getifaddrs failed");
1050 goto error;
1051 }
1052
1053 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1054 GuestNetworkInterface *info;
1055 GuestIpAddressList **address_tail;
1056 GuestIpAddress *address_item = NULL;
1057 GuestNetworkInterfaceStat *interface_stat = NULL;
1058 char addr4[INET_ADDRSTRLEN];
1059 char addr6[INET6_ADDRSTRLEN];
1060 unsigned char mac_addr[ETHER_ADDR_LEN];
1061 bool obtained;
1062 void *p;
1063
1064 g_debug("Processing %s interface", ifa->ifa_name);
1065
1066 info = guest_find_interface(head, ifa->ifa_name);
1067
1068 if (!info) {
1069 info = g_malloc0(sizeof(*info));
1070 info->name = g_strdup(ifa->ifa_name);
1071
1072 QAPI_LIST_APPEND(tail, info);
1073 }
1074
1075 if (!info->hardware_address) {
1076 if (!guest_get_hw_addr(ifa, mac_addr, &obtained, errp)) {
1077 goto error;
1078 }
1079 if (obtained) {
1080 info->hardware_address =
1081 g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x",
1082 (int) mac_addr[0], (int) mac_addr[1],
1083 (int) mac_addr[2], (int) mac_addr[3],
1084 (int) mac_addr[4], (int) mac_addr[5]);
1085 }
1086 }
1087
1088 if (ifa->ifa_addr &&
1089 ifa->ifa_addr->sa_family == AF_INET) {
1090 /* interface with IPv4 address */
1091 p = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
1092 if (!inet_ntop(AF_INET, p, addr4, sizeof(addr4))) {
1093 error_setg_errno(errp, errno, "inet_ntop failed");
1094 goto error;
1095 }
1096
1097 address_item = g_malloc0(sizeof(*address_item));
1098 address_item->ip_address = g_strdup(addr4);
1099 address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV4;
1100
1101 if (ifa->ifa_netmask) {
1102 /* Count the number of set bits in netmask.
1103 * This is safe as '1' and '0' cannot be shuffled in netmask. */
1104 p = &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
1105 address_item->prefix = ctpop32(((uint32_t *) p)[0]);
1106 }
1107 } else if (ifa->ifa_addr &&
1108 ifa->ifa_addr->sa_family == AF_INET6) {
1109 /* interface with IPv6 address */
1110 p = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
1111 if (!inet_ntop(AF_INET6, p, addr6, sizeof(addr6))) {
1112 error_setg_errno(errp, errno, "inet_ntop failed");
1113 goto error;
1114 }
1115
1116 address_item = g_malloc0(sizeof(*address_item));
1117 address_item->ip_address = g_strdup(addr6);
1118 address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV6;
1119
1120 if (ifa->ifa_netmask) {
1121 /* Count the number of set bits in netmask.
1122 * This is safe as '1' and '0' cannot be shuffled in netmask. */
1123 p = &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr;
1124 address_item->prefix =
1125 ctpop32(((uint32_t *) p)[0]) +
1126 ctpop32(((uint32_t *) p)[1]) +
1127 ctpop32(((uint32_t *) p)[2]) +
1128 ctpop32(((uint32_t *) p)[3]);
1129 }
1130 }
1131
1132 if (!address_item) {
1133 continue;
1134 }
1135
1136 address_tail = &info->ip_addresses;
1137 while (*address_tail) {
1138 address_tail = &(*address_tail)->next;
1139 }
1140 QAPI_LIST_APPEND(address_tail, address_item);
1141
1142 info->has_ip_addresses = true;
1143
1144 if (!info->statistics) {
1145 interface_stat = g_malloc0(sizeof(*interface_stat));
1146 if (guest_get_network_stats(info->name, interface_stat) == -1) {
1147 g_free(interface_stat);
1148 } else {
1149 info->statistics = interface_stat;
1150 }
1151 }
1152 }
1153
1154 freeifaddrs(ifap);
1155 return head;
1156
1157 error:
1158 freeifaddrs(ifap);
1159 qapi_free_GuestNetworkInterfaceList(head);
1160 return NULL;
1161 }
1162
1163 #endif /* HAVE_GETIFADDRS */
1164
1165 /* register init/cleanup routines for stateful command groups */
1166 void ga_command_state_init(GAState *s, GACommandState *cs)
1167 {
1168 #if defined(CONFIG_FSFREEZE)
1169 ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup);
1170 #endif
1171 }
1172
1173 #ifdef HAVE_UTMPX
1174
1175 #define QGA_MICRO_SECOND_TO_SECOND 1000000
1176
1177 static double ga_get_login_time(struct utmpx *user_info)
1178 {
1179 double seconds = (double)user_info->ut_tv.tv_sec;
1180 double useconds = (double)user_info->ut_tv.tv_usec;
1181 useconds /= QGA_MICRO_SECOND_TO_SECOND;
1182 return seconds + useconds;
1183 }
1184
1185 GuestUserList *qmp_guest_get_users(Error **errp)
1186 {
1187 GHashTable *cache = NULL;
1188 GuestUserList *head = NULL, **tail = &head;
1189 struct utmpx *user_info = NULL;
1190 gpointer value = NULL;
1191 GuestUser *user = NULL;
1192 double login_time = 0;
1193
1194 cache = g_hash_table_new(g_str_hash, g_str_equal);
1195 setutxent();
1196
1197 for (;;) {
1198 user_info = getutxent();
1199 if (user_info == NULL) {
1200 break;
1201 } else if (user_info->ut_type != USER_PROCESS) {
1202 continue;
1203 } else if (g_hash_table_contains(cache, user_info->ut_user)) {
1204 value = g_hash_table_lookup(cache, user_info->ut_user);
1205 user = (GuestUser *)value;
1206 login_time = ga_get_login_time(user_info);
1207 /* We're ensuring the earliest login time to be sent */
1208 if (login_time < user->login_time) {
1209 user->login_time = login_time;
1210 }
1211 continue;
1212 }
1213
1214 user = g_new0(GuestUser, 1);
1215 user->user = g_strdup(user_info->ut_user);
1216 user->login_time = ga_get_login_time(user_info);
1217
1218 g_hash_table_insert(cache, user->user, user);
1219
1220 QAPI_LIST_APPEND(tail, user);
1221 }
1222 endutxent();
1223 g_hash_table_destroy(cache);
1224 return head;
1225 }
1226
1227 #endif /* HAVE_UTMPX */
1228
1229 /* Replace escaped special characters with their real values. The replacement
1230 * is done in place -- returned value is in the original string.
1231 */
1232 static void ga_osrelease_replace_special(gchar *value)
1233 {
1234 gchar *p, *p2, quote;
1235
1236 /* Trim the string at first space or semicolon if it is not enclosed in
1237 * single or double quotes. */
1238 if ((value[0] != '"') || (value[0] == '\'')) {
1239 p = strchr(value, ' ');
1240 if (p != NULL) {
1241 *p = 0;
1242 }
1243 p = strchr(value, ';');
1244 if (p != NULL) {
1245 *p = 0;
1246 }
1247 return;
1248 }
1249
1250 quote = value[0];
1251 p2 = value;
1252 p = value + 1;
1253 while (*p != 0) {
1254 if (*p == '\\') {
1255 p++;
1256 switch (*p) {
1257 case '$':
1258 case '\'':
1259 case '"':
1260 case '\\':
1261 case '`':
1262 break;
1263 default:
1264 /* Keep literal backslash followed by whatever is there */
1265 p--;
1266 break;
1267 }
1268 } else if (*p == quote) {
1269 *p2 = 0;
1270 break;
1271 }
1272 *(p2++) = *(p++);
1273 }
1274 }
1275
1276 static GKeyFile *ga_parse_osrelease(const char *fname)
1277 {
1278 gchar *content = NULL;
1279 gchar *content2 = NULL;
1280 GError *err = NULL;
1281 GKeyFile *keys = g_key_file_new();
1282 const char *group = "[os-release]\n";
1283
1284 if (!g_file_get_contents(fname, &content, NULL, &err)) {
1285 slog("failed to read '%s', error: %s", fname, err->message);
1286 goto fail;
1287 }
1288
1289 if (!g_utf8_validate(content, -1, NULL)) {
1290 slog("file is not utf-8 encoded: %s", fname);
1291 goto fail;
1292 }
1293 content2 = g_strdup_printf("%s%s", group, content);
1294
1295 if (!g_key_file_load_from_data(keys, content2, -1, G_KEY_FILE_NONE,
1296 &err)) {
1297 slog("failed to parse file '%s', error: %s", fname, err->message);
1298 goto fail;
1299 }
1300
1301 g_free(content);
1302 g_free(content2);
1303 return keys;
1304
1305 fail:
1306 g_error_free(err);
1307 g_free(content);
1308 g_free(content2);
1309 g_key_file_free(keys);
1310 return NULL;
1311 }
1312
1313 GuestOSInfo *qmp_guest_get_osinfo(Error **errp)
1314 {
1315 GuestOSInfo *info = NULL;
1316 struct utsname kinfo;
1317 GKeyFile *osrelease = NULL;
1318 const char *qga_os_release = g_getenv("QGA_OS_RELEASE");
1319
1320 info = g_new0(GuestOSInfo, 1);
1321
1322 if (uname(&kinfo) != 0) {
1323 error_setg_errno(errp, errno, "uname failed");
1324 } else {
1325 info->kernel_version = g_strdup(kinfo.version);
1326 info->kernel_release = g_strdup(kinfo.release);
1327 info->machine = g_strdup(kinfo.machine);
1328 }
1329
1330 if (qga_os_release != NULL) {
1331 osrelease = ga_parse_osrelease(qga_os_release);
1332 } else {
1333 osrelease = ga_parse_osrelease("/etc/os-release");
1334 if (osrelease == NULL) {
1335 osrelease = ga_parse_osrelease("/usr/lib/os-release");
1336 }
1337 }
1338
1339 if (osrelease != NULL) {
1340 char *value;
1341
1342 #define GET_FIELD(field, osfield) do { \
1343 value = g_key_file_get_value(osrelease, "os-release", osfield, NULL); \
1344 if (value != NULL) { \
1345 ga_osrelease_replace_special(value); \
1346 info->field = value; \
1347 } \
1348 } while (0)
1349 GET_FIELD(id, "ID");
1350 GET_FIELD(name, "NAME");
1351 GET_FIELD(pretty_name, "PRETTY_NAME");
1352 GET_FIELD(version, "VERSION");
1353 GET_FIELD(version_id, "VERSION_ID");
1354 GET_FIELD(variant, "VARIANT");
1355 GET_FIELD(variant_id, "VARIANT_ID");
1356 #undef GET_FIELD
1357
1358 g_key_file_free(osrelease);
1359 }
1360
1361 return info;
1362 }
1363
1364 #ifndef HOST_NAME_MAX
1365 # ifdef _POSIX_HOST_NAME_MAX
1366 # define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
1367 # else
1368 # define HOST_NAME_MAX 255
1369 # endif
1370 #endif
1371
1372 char *qga_get_host_name(Error **errp)
1373 {
1374 long len = -1;
1375 g_autofree char *hostname = NULL;
1376
1377 #ifdef _SC_HOST_NAME_MAX
1378 len = sysconf(_SC_HOST_NAME_MAX);
1379 #endif /* _SC_HOST_NAME_MAX */
1380
1381 if (len < 0) {
1382 len = HOST_NAME_MAX;
1383 }
1384
1385 /* Unfortunately, gethostname() below does not guarantee a
1386 * NULL terminated string. Therefore, allocate one byte more
1387 * to be sure. */
1388 hostname = g_new0(char, len + 1);
1389
1390 if (gethostname(hostname, len) < 0) {
1391 error_setg_errno(errp, errno,
1392 "cannot get hostname");
1393 return NULL;
1394 }
1395
1396 return g_steal_pointer(&hostname);
1397 }
1398
1399 #ifdef CONFIG_GETLOADAVG
1400 GuestLoadAverage *qmp_guest_get_load(Error **errp)
1401 {
1402 double loadavg[3];
1403 GuestLoadAverage *ret = NULL;
1404
1405 if (getloadavg(loadavg, G_N_ELEMENTS(loadavg)) < 0) {
1406 error_setg_errno(errp, errno,
1407 "cannot query load average");
1408 return NULL;
1409 }
1410
1411 ret = g_new0(GuestLoadAverage, 1);
1412 ret->load1m = loadavg[0];
1413 ret->load5m = loadavg[1];
1414 ret->load15m = loadavg[2];
1415 return ret;
1416 }
1417 #endif