xref: /qemu/qga/commands-posix.c (revision d709bbf3)
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 "qemu-common.h"
20 #include "guest-agent-core.h"
21 #include "qga-qapi-commands.h"
22 #include "qapi/error.h"
23 #include "qapi/qmp/qerror.h"
24 #include "qemu/queue.h"
25 #include "qemu/host-utils.h"
26 #include "qemu/sockets.h"
27 #include "qemu/base64.h"
28 #include "qemu/cutils.h"
29 #include "commands-common.h"
30 
31 #ifdef HAVE_UTMPX
32 #include <utmpx.h>
33 #endif
34 
35 #ifndef CONFIG_HAS_ENVIRON
36 #ifdef __APPLE__
37 #include <crt_externs.h>
38 #define environ (*_NSGetEnviron())
39 #else
40 extern char **environ;
41 #endif
42 #endif
43 
44 #if defined(__linux__)
45 #include <mntent.h>
46 #include <linux/fs.h>
47 #include <ifaddrs.h>
48 #include <arpa/inet.h>
49 #include <sys/socket.h>
50 #include <net/if.h>
51 #include <sys/statvfs.h>
52 
53 #ifdef CONFIG_LIBUDEV
54 #include <libudev.h>
55 #endif
56 
57 #ifdef FIFREEZE
58 #define CONFIG_FSFREEZE
59 #endif
60 #ifdef FITRIM
61 #define CONFIG_FSTRIM
62 #endif
63 #endif
64 
65 static void ga_wait_child(pid_t pid, int *status, Error **errp)
66 {
67     pid_t rpid;
68 
69     *status = 0;
70 
71     do {
72         rpid = waitpid(pid, status, 0);
73     } while (rpid == -1 && errno == EINTR);
74 
75     if (rpid == -1) {
76         error_setg_errno(errp, errno, "failed to wait for child (pid: %d)",
77                          pid);
78         return;
79     }
80 
81     g_assert(rpid == pid);
82 }
83 
84 void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp)
85 {
86     const char *shutdown_flag;
87     Error *local_err = NULL;
88     pid_t pid;
89     int status;
90 
91     slog("guest-shutdown called, mode: %s", mode);
92     if (!has_mode || strcmp(mode, "powerdown") == 0) {
93         shutdown_flag = "-P";
94     } else if (strcmp(mode, "halt") == 0) {
95         shutdown_flag = "-H";
96     } else if (strcmp(mode, "reboot") == 0) {
97         shutdown_flag = "-r";
98     } else {
99         error_setg(errp,
100                    "mode is invalid (valid values are: halt|powerdown|reboot");
101         return;
102     }
103 
104     pid = fork();
105     if (pid == 0) {
106         /* child, start the shutdown */
107         setsid();
108         reopen_fd_to_null(0);
109         reopen_fd_to_null(1);
110         reopen_fd_to_null(2);
111 
112         execle("/sbin/shutdown", "shutdown", "-h", shutdown_flag, "+0",
113                "hypervisor initiated shutdown", (char *)NULL, environ);
114         _exit(EXIT_FAILURE);
115     } else if (pid < 0) {
116         error_setg_errno(errp, errno, "failed to create child process");
117         return;
118     }
119 
120     ga_wait_child(pid, &status, &local_err);
121     if (local_err) {
122         error_propagate(errp, local_err);
123         return;
124     }
125 
126     if (!WIFEXITED(status)) {
127         error_setg(errp, "child process has terminated abnormally");
128         return;
129     }
130 
131     if (WEXITSTATUS(status)) {
132         error_setg(errp, "child process has failed to shutdown");
133         return;
134     }
135 
136     /* succeeded */
137 }
138 
139 void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
140 {
141     int ret;
142     int status;
143     pid_t pid;
144     Error *local_err = NULL;
145     struct timeval tv;
146     static const char hwclock_path[] = "/sbin/hwclock";
147     static int hwclock_available = -1;
148 
149     if (hwclock_available < 0) {
150         hwclock_available = (access(hwclock_path, X_OK) == 0);
151     }
152 
153     if (!hwclock_available) {
154         error_setg(errp, QERR_UNSUPPORTED);
155         return;
156     }
157 
158     /* If user has passed a time, validate and set it. */
159     if (has_time) {
160         GDate date = { 0, };
161 
162         /* year-2038 will overflow in case time_t is 32bit */
163         if (time_ns / 1000000000 != (time_t)(time_ns / 1000000000)) {
164             error_setg(errp, "Time %" PRId64 " is too large", time_ns);
165             return;
166         }
167 
168         tv.tv_sec = time_ns / 1000000000;
169         tv.tv_usec = (time_ns % 1000000000) / 1000;
170         g_date_set_time_t(&date, tv.tv_sec);
171         if (date.year < 1970 || date.year >= 2070) {
172             error_setg_errno(errp, errno, "Invalid time");
173             return;
174         }
175 
176         ret = settimeofday(&tv, NULL);
177         if (ret < 0) {
178             error_setg_errno(errp, errno, "Failed to set time to guest");
179             return;
180         }
181     }
182 
183     /* Now, if user has passed a time to set and the system time is set, we
184      * just need to synchronize the hardware clock. However, if no time was
185      * passed, user is requesting the opposite: set the system time from the
186      * hardware clock (RTC). */
187     pid = fork();
188     if (pid == 0) {
189         setsid();
190         reopen_fd_to_null(0);
191         reopen_fd_to_null(1);
192         reopen_fd_to_null(2);
193 
194         /* Use '/sbin/hwclock -w' to set RTC from the system time,
195          * or '/sbin/hwclock -s' to set the system time from RTC. */
196         execle(hwclock_path, "hwclock", has_time ? "-w" : "-s",
197                NULL, environ);
198         _exit(EXIT_FAILURE);
199     } else if (pid < 0) {
200         error_setg_errno(errp, errno, "failed to create child process");
201         return;
202     }
203 
204     ga_wait_child(pid, &status, &local_err);
205     if (local_err) {
206         error_propagate(errp, local_err);
207         return;
208     }
209 
210     if (!WIFEXITED(status)) {
211         error_setg(errp, "child process has terminated abnormally");
212         return;
213     }
214 
215     if (WEXITSTATUS(status)) {
216         error_setg(errp, "hwclock failed to set hardware clock to system time");
217         return;
218     }
219 }
220 
221 typedef enum {
222     RW_STATE_NEW,
223     RW_STATE_READING,
224     RW_STATE_WRITING,
225 } RwState;
226 
227 struct GuestFileHandle {
228     uint64_t id;
229     FILE *fh;
230     RwState state;
231     QTAILQ_ENTRY(GuestFileHandle) next;
232 };
233 
234 static struct {
235     QTAILQ_HEAD(, GuestFileHandle) filehandles;
236 } guest_file_state = {
237     .filehandles = QTAILQ_HEAD_INITIALIZER(guest_file_state.filehandles),
238 };
239 
240 static int64_t guest_file_handle_add(FILE *fh, Error **errp)
241 {
242     GuestFileHandle *gfh;
243     int64_t handle;
244 
245     handle = ga_get_fd_handle(ga_state, errp);
246     if (handle < 0) {
247         return -1;
248     }
249 
250     gfh = g_new0(GuestFileHandle, 1);
251     gfh->id = handle;
252     gfh->fh = fh;
253     QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next);
254 
255     return handle;
256 }
257 
258 GuestFileHandle *guest_file_handle_find(int64_t id, Error **errp)
259 {
260     GuestFileHandle *gfh;
261 
262     QTAILQ_FOREACH(gfh, &guest_file_state.filehandles, next)
263     {
264         if (gfh->id == id) {
265             return gfh;
266         }
267     }
268 
269     error_setg(errp, "handle '%" PRId64 "' has not been found", id);
270     return NULL;
271 }
272 
273 typedef const char * const ccpc;
274 
275 #ifndef O_BINARY
276 #define O_BINARY 0
277 #endif
278 
279 /* http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html */
280 static const struct {
281     ccpc *forms;
282     int oflag_base;
283 } guest_file_open_modes[] = {
284     { (ccpc[]){ "r",          NULL }, O_RDONLY                                 },
285     { (ccpc[]){ "rb",         NULL }, O_RDONLY                      | O_BINARY },
286     { (ccpc[]){ "w",          NULL }, O_WRONLY | O_CREAT | O_TRUNC             },
287     { (ccpc[]){ "wb",         NULL }, O_WRONLY | O_CREAT | O_TRUNC  | O_BINARY },
288     { (ccpc[]){ "a",          NULL }, O_WRONLY | O_CREAT | O_APPEND            },
289     { (ccpc[]){ "ab",         NULL }, O_WRONLY | O_CREAT | O_APPEND | O_BINARY },
290     { (ccpc[]){ "r+",         NULL }, O_RDWR                                   },
291     { (ccpc[]){ "rb+", "r+b", NULL }, O_RDWR                        | O_BINARY },
292     { (ccpc[]){ "w+",         NULL }, O_RDWR   | O_CREAT | O_TRUNC             },
293     { (ccpc[]){ "wb+", "w+b", NULL }, O_RDWR   | O_CREAT | O_TRUNC  | O_BINARY },
294     { (ccpc[]){ "a+",         NULL }, O_RDWR   | O_CREAT | O_APPEND            },
295     { (ccpc[]){ "ab+", "a+b", NULL }, O_RDWR   | O_CREAT | O_APPEND | O_BINARY }
296 };
297 
298 static int
299 find_open_flag(const char *mode_str, Error **errp)
300 {
301     unsigned mode;
302 
303     for (mode = 0; mode < ARRAY_SIZE(guest_file_open_modes); ++mode) {
304         ccpc *form;
305 
306         form = guest_file_open_modes[mode].forms;
307         while (*form != NULL && strcmp(*form, mode_str) != 0) {
308             ++form;
309         }
310         if (*form != NULL) {
311             break;
312         }
313     }
314 
315     if (mode == ARRAY_SIZE(guest_file_open_modes)) {
316         error_setg(errp, "invalid file open mode '%s'", mode_str);
317         return -1;
318     }
319     return guest_file_open_modes[mode].oflag_base | O_NOCTTY | O_NONBLOCK;
320 }
321 
322 #define DEFAULT_NEW_FILE_MODE (S_IRUSR | S_IWUSR | \
323                                S_IRGRP | S_IWGRP | \
324                                S_IROTH | S_IWOTH)
325 
326 static FILE *
327 safe_open_or_create(const char *path, const char *mode, Error **errp)
328 {
329     Error *local_err = NULL;
330     int oflag;
331 
332     oflag = find_open_flag(mode, &local_err);
333     if (local_err == NULL) {
334         int fd;
335 
336         /* If the caller wants / allows creation of a new file, we implement it
337          * with a two step process: open() + (open() / fchmod()).
338          *
339          * First we insist on creating the file exclusively as a new file. If
340          * that succeeds, we're free to set any file-mode bits on it. (The
341          * motivation is that we want to set those file-mode bits independently
342          * of the current umask.)
343          *
344          * If the exclusive creation fails because the file already exists
345          * (EEXIST is not possible for any other reason), we just attempt to
346          * open the file, but in this case we won't be allowed to change the
347          * file-mode bits on the preexistent file.
348          *
349          * The pathname should never disappear between the two open()s in
350          * practice. If it happens, then someone very likely tried to race us.
351          * In this case just go ahead and report the ENOENT from the second
352          * open() to the caller.
353          *
354          * If the caller wants to open a preexistent file, then the first
355          * open() is decisive and its third argument is ignored, and the second
356          * open() and the fchmod() are never called.
357          */
358         fd = open(path, oflag | ((oflag & O_CREAT) ? O_EXCL : 0), 0);
359         if (fd == -1 && errno == EEXIST) {
360             oflag &= ~(unsigned)O_CREAT;
361             fd = open(path, oflag);
362         }
363 
364         if (fd == -1) {
365             error_setg_errno(&local_err, errno, "failed to open file '%s' "
366                              "(mode: '%s')", path, mode);
367         } else {
368             qemu_set_cloexec(fd);
369 
370             if ((oflag & O_CREAT) && fchmod(fd, DEFAULT_NEW_FILE_MODE) == -1) {
371                 error_setg_errno(&local_err, errno, "failed to set permission "
372                                  "0%03o on new file '%s' (mode: '%s')",
373                                  (unsigned)DEFAULT_NEW_FILE_MODE, path, mode);
374             } else {
375                 FILE *f;
376 
377                 f = fdopen(fd, mode);
378                 if (f == NULL) {
379                     error_setg_errno(&local_err, errno, "failed to associate "
380                                      "stdio stream with file descriptor %d, "
381                                      "file '%s' (mode: '%s')", fd, path, mode);
382                 } else {
383                     return f;
384                 }
385             }
386 
387             close(fd);
388             if (oflag & O_CREAT) {
389                 unlink(path);
390             }
391         }
392     }
393 
394     error_propagate(errp, local_err);
395     return NULL;
396 }
397 
398 int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode,
399                             Error **errp)
400 {
401     FILE *fh;
402     Error *local_err = NULL;
403     int64_t handle;
404 
405     if (!has_mode) {
406         mode = "r";
407     }
408     slog("guest-file-open called, filepath: %s, mode: %s", path, mode);
409     fh = safe_open_or_create(path, mode, &local_err);
410     if (local_err != NULL) {
411         error_propagate(errp, local_err);
412         return -1;
413     }
414 
415     /* set fd non-blocking to avoid common use cases (like reading from a
416      * named pipe) from hanging the agent
417      */
418     qemu_set_nonblock(fileno(fh));
419 
420     handle = guest_file_handle_add(fh, errp);
421     if (handle < 0) {
422         fclose(fh);
423         return -1;
424     }
425 
426     slog("guest-file-open, handle: %" PRId64, handle);
427     return handle;
428 }
429 
430 void qmp_guest_file_close(int64_t handle, Error **errp)
431 {
432     GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
433     int ret;
434 
435     slog("guest-file-close called, handle: %" PRId64, handle);
436     if (!gfh) {
437         return;
438     }
439 
440     ret = fclose(gfh->fh);
441     if (ret == EOF) {
442         error_setg_errno(errp, errno, "failed to close handle");
443         return;
444     }
445 
446     QTAILQ_REMOVE(&guest_file_state.filehandles, gfh, next);
447     g_free(gfh);
448 }
449 
450 GuestFileRead *guest_file_read_unsafe(GuestFileHandle *gfh,
451                                       int64_t count, Error **errp)
452 {
453     GuestFileRead *read_data = NULL;
454     guchar *buf;
455     FILE *fh = gfh->fh;
456     size_t read_count;
457 
458     /* explicitly flush when switching from writing to reading */
459     if (gfh->state == RW_STATE_WRITING) {
460         int ret = fflush(fh);
461         if (ret == EOF) {
462             error_setg_errno(errp, errno, "failed to flush file");
463             return NULL;
464         }
465         gfh->state = RW_STATE_NEW;
466     }
467 
468     buf = g_malloc0(count + 1);
469     read_count = fread(buf, 1, count, fh);
470     if (ferror(fh)) {
471         error_setg_errno(errp, errno, "failed to read file");
472     } else {
473         buf[read_count] = 0;
474         read_data = g_new0(GuestFileRead, 1);
475         read_data->count = read_count;
476         read_data->eof = feof(fh);
477         if (read_count) {
478             read_data->buf_b64 = g_base64_encode(buf, read_count);
479         }
480         gfh->state = RW_STATE_READING;
481     }
482     g_free(buf);
483     clearerr(fh);
484 
485     return read_data;
486 }
487 
488 GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
489                                      bool has_count, int64_t count,
490                                      Error **errp)
491 {
492     GuestFileWrite *write_data = NULL;
493     guchar *buf;
494     gsize buf_len;
495     int write_count;
496     GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
497     FILE *fh;
498 
499     if (!gfh) {
500         return NULL;
501     }
502 
503     fh = gfh->fh;
504 
505     if (gfh->state == RW_STATE_READING) {
506         int ret = fseek(fh, 0, SEEK_CUR);
507         if (ret == -1) {
508             error_setg_errno(errp, errno, "failed to seek file");
509             return NULL;
510         }
511         gfh->state = RW_STATE_NEW;
512     }
513 
514     buf = qbase64_decode(buf_b64, -1, &buf_len, errp);
515     if (!buf) {
516         return NULL;
517     }
518 
519     if (!has_count) {
520         count = buf_len;
521     } else if (count < 0 || count > buf_len) {
522         error_setg(errp, "value '%" PRId64 "' is invalid for argument count",
523                    count);
524         g_free(buf);
525         return NULL;
526     }
527 
528     write_count = fwrite(buf, 1, count, fh);
529     if (ferror(fh)) {
530         error_setg_errno(errp, errno, "failed to write to file");
531         slog("guest-file-write failed, handle: %" PRId64, handle);
532     } else {
533         write_data = g_new0(GuestFileWrite, 1);
534         write_data->count = write_count;
535         write_data->eof = feof(fh);
536         gfh->state = RW_STATE_WRITING;
537     }
538     g_free(buf);
539     clearerr(fh);
540 
541     return write_data;
542 }
543 
544 struct GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
545                                           GuestFileWhence *whence_code,
546                                           Error **errp)
547 {
548     GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
549     GuestFileSeek *seek_data = NULL;
550     FILE *fh;
551     int ret;
552     int whence;
553     Error *err = NULL;
554 
555     if (!gfh) {
556         return NULL;
557     }
558 
559     /* We stupidly exposed 'whence':'int' in our qapi */
560     whence = ga_parse_whence(whence_code, &err);
561     if (err) {
562         error_propagate(errp, err);
563         return NULL;
564     }
565 
566     fh = gfh->fh;
567     ret = fseek(fh, offset, whence);
568     if (ret == -1) {
569         error_setg_errno(errp, errno, "failed to seek file");
570         if (errno == ESPIPE) {
571             /* file is non-seekable, stdio shouldn't be buffering anyways */
572             gfh->state = RW_STATE_NEW;
573         }
574     } else {
575         seek_data = g_new0(GuestFileSeek, 1);
576         seek_data->position = ftell(fh);
577         seek_data->eof = feof(fh);
578         gfh->state = RW_STATE_NEW;
579     }
580     clearerr(fh);
581 
582     return seek_data;
583 }
584 
585 void qmp_guest_file_flush(int64_t handle, Error **errp)
586 {
587     GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
588     FILE *fh;
589     int ret;
590 
591     if (!gfh) {
592         return;
593     }
594 
595     fh = gfh->fh;
596     ret = fflush(fh);
597     if (ret == EOF) {
598         error_setg_errno(errp, errno, "failed to flush file");
599     } else {
600         gfh->state = RW_STATE_NEW;
601     }
602 }
603 
604 /* linux-specific implementations. avoid this if at all possible. */
605 #if defined(__linux__)
606 
607 #if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM)
608 typedef struct FsMount {
609     char *dirname;
610     char *devtype;
611     unsigned int devmajor, devminor;
612     QTAILQ_ENTRY(FsMount) next;
613 } FsMount;
614 
615 typedef QTAILQ_HEAD(FsMountList, FsMount) FsMountList;
616 
617 static void free_fs_mount_list(FsMountList *mounts)
618 {
619      FsMount *mount, *temp;
620 
621      if (!mounts) {
622          return;
623      }
624 
625      QTAILQ_FOREACH_SAFE(mount, mounts, next, temp) {
626          QTAILQ_REMOVE(mounts, mount, next);
627          g_free(mount->dirname);
628          g_free(mount->devtype);
629          g_free(mount);
630      }
631 }
632 
633 static int dev_major_minor(const char *devpath,
634                            unsigned int *devmajor, unsigned int *devminor)
635 {
636     struct stat st;
637 
638     *devmajor = 0;
639     *devminor = 0;
640 
641     if (stat(devpath, &st) < 0) {
642         slog("failed to stat device file '%s': %s", devpath, strerror(errno));
643         return -1;
644     }
645     if (S_ISDIR(st.st_mode)) {
646         /* It is bind mount */
647         return -2;
648     }
649     if (S_ISBLK(st.st_mode)) {
650         *devmajor = major(st.st_rdev);
651         *devminor = minor(st.st_rdev);
652         return 0;
653     }
654     return -1;
655 }
656 
657 /*
658  * Walk the mount table and build a list of local file systems
659  */
660 static void build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp)
661 {
662     struct mntent *ment;
663     FsMount *mount;
664     char const *mtab = "/proc/self/mounts";
665     FILE *fp;
666     unsigned int devmajor, devminor;
667 
668     fp = setmntent(mtab, "r");
669     if (!fp) {
670         error_setg(errp, "failed to open mtab file: '%s'", mtab);
671         return;
672     }
673 
674     while ((ment = getmntent(fp))) {
675         /*
676          * An entry which device name doesn't start with a '/' is
677          * either a dummy file system or a network file system.
678          * Add special handling for smbfs and cifs as is done by
679          * coreutils as well.
680          */
681         if ((ment->mnt_fsname[0] != '/') ||
682             (strcmp(ment->mnt_type, "smbfs") == 0) ||
683             (strcmp(ment->mnt_type, "cifs") == 0)) {
684             continue;
685         }
686         if (dev_major_minor(ment->mnt_fsname, &devmajor, &devminor) == -2) {
687             /* Skip bind mounts */
688             continue;
689         }
690 
691         mount = g_new0(FsMount, 1);
692         mount->dirname = g_strdup(ment->mnt_dir);
693         mount->devtype = g_strdup(ment->mnt_type);
694         mount->devmajor = devmajor;
695         mount->devminor = devminor;
696 
697         QTAILQ_INSERT_TAIL(mounts, mount, next);
698     }
699 
700     endmntent(fp);
701 }
702 
703 static void decode_mntname(char *name, int len)
704 {
705     int i, j = 0;
706     for (i = 0; i <= len; i++) {
707         if (name[i] != '\\') {
708             name[j++] = name[i];
709         } else if (name[i + 1] == '\\') {
710             name[j++] = '\\';
711             i++;
712         } else if (name[i + 1] >= '0' && name[i + 1] <= '3' &&
713                    name[i + 2] >= '0' && name[i + 2] <= '7' &&
714                    name[i + 3] >= '0' && name[i + 3] <= '7') {
715             name[j++] = (name[i + 1] - '0') * 64 +
716                         (name[i + 2] - '0') * 8 +
717                         (name[i + 3] - '0');
718             i += 3;
719         } else {
720             name[j++] = name[i];
721         }
722     }
723 }
724 
725 static void build_fs_mount_list(FsMountList *mounts, Error **errp)
726 {
727     FsMount *mount;
728     char const *mountinfo = "/proc/self/mountinfo";
729     FILE *fp;
730     char *line = NULL, *dash;
731     size_t n;
732     char check;
733     unsigned int devmajor, devminor;
734     int ret, dir_s, dir_e, type_s, type_e, dev_s, dev_e;
735 
736     fp = fopen(mountinfo, "r");
737     if (!fp) {
738         build_fs_mount_list_from_mtab(mounts, errp);
739         return;
740     }
741 
742     while (getline(&line, &n, fp) != -1) {
743         ret = sscanf(line, "%*u %*u %u:%u %*s %n%*s%n%c",
744                      &devmajor, &devminor, &dir_s, &dir_e, &check);
745         if (ret < 3) {
746             continue;
747         }
748         dash = strstr(line + dir_e, " - ");
749         if (!dash) {
750             continue;
751         }
752         ret = sscanf(dash, " - %n%*s%n %n%*s%n%c",
753                      &type_s, &type_e, &dev_s, &dev_e, &check);
754         if (ret < 1) {
755             continue;
756         }
757         line[dir_e] = 0;
758         dash[type_e] = 0;
759         dash[dev_e] = 0;
760         decode_mntname(line + dir_s, dir_e - dir_s);
761         decode_mntname(dash + dev_s, dev_e - dev_s);
762         if (devmajor == 0) {
763             /* btrfs reports major number = 0 */
764             if (strcmp("btrfs", dash + type_s) != 0 ||
765                 dev_major_minor(dash + dev_s, &devmajor, &devminor) < 0) {
766                 continue;
767             }
768         }
769 
770         mount = g_new0(FsMount, 1);
771         mount->dirname = g_strdup(line + dir_s);
772         mount->devtype = g_strdup(dash + type_s);
773         mount->devmajor = devmajor;
774         mount->devminor = devminor;
775 
776         QTAILQ_INSERT_TAIL(mounts, mount, next);
777     }
778     free(line);
779 
780     fclose(fp);
781 }
782 #endif
783 
784 #if defined(CONFIG_FSFREEZE)
785 
786 static char *get_pci_driver(char const *syspath, int pathlen, Error **errp)
787 {
788     char *path;
789     char *dpath;
790     char *driver = NULL;
791     char buf[PATH_MAX];
792     ssize_t len;
793 
794     path = g_strndup(syspath, pathlen);
795     dpath = g_strdup_printf("%s/driver", path);
796     len = readlink(dpath, buf, sizeof(buf) - 1);
797     if (len != -1) {
798         buf[len] = 0;
799         driver = g_path_get_basename(buf);
800     }
801     g_free(dpath);
802     g_free(path);
803     return driver;
804 }
805 
806 static int compare_uint(const void *_a, const void *_b)
807 {
808     unsigned int a = *(unsigned int *)_a;
809     unsigned int b = *(unsigned int *)_b;
810 
811     return a < b ? -1 : a > b ? 1 : 0;
812 }
813 
814 /* Walk the specified sysfs and build a sorted list of host or ata numbers */
815 static int build_hosts(char const *syspath, char const *host, bool ata,
816                        unsigned int *hosts, int hosts_max, Error **errp)
817 {
818     char *path;
819     DIR *dir;
820     struct dirent *entry;
821     int i = 0;
822 
823     path = g_strndup(syspath, host - syspath);
824     dir = opendir(path);
825     if (!dir) {
826         error_setg_errno(errp, errno, "opendir(\"%s\")", path);
827         g_free(path);
828         return -1;
829     }
830 
831     while (i < hosts_max) {
832         entry = readdir(dir);
833         if (!entry) {
834             break;
835         }
836         if (ata && sscanf(entry->d_name, "ata%d", hosts + i) == 1) {
837             ++i;
838         } else if (!ata && sscanf(entry->d_name, "host%d", hosts + i) == 1) {
839             ++i;
840         }
841     }
842 
843     qsort(hosts, i, sizeof(hosts[0]), compare_uint);
844 
845     g_free(path);
846     closedir(dir);
847     return i;
848 }
849 
850 /*
851  * Store disk device info for devices on the PCI bus.
852  * Returns true if information has been stored, or false for failure.
853  */
854 static bool build_guest_fsinfo_for_pci_dev(char const *syspath,
855                                            GuestDiskAddress *disk,
856                                            Error **errp)
857 {
858     unsigned int pci[4], host, hosts[8], tgt[3];
859     int i, nhosts = 0, pcilen;
860     GuestPCIAddress *pciaddr = disk->pci_controller;
861     bool has_ata = false, has_host = false, has_tgt = false;
862     char *p, *q, *driver = NULL;
863     bool ret = false;
864 
865     p = strstr(syspath, "/devices/pci");
866     if (!p || sscanf(p + 12, "%*x:%*x/%x:%x:%x.%x%n",
867                      pci, pci + 1, pci + 2, pci + 3, &pcilen) < 4) {
868         g_debug("only pci device is supported: sysfs path '%s'", syspath);
869         return false;
870     }
871 
872     p += 12 + pcilen;
873     while (true) {
874         driver = get_pci_driver(syspath, p - syspath, errp);
875         if (driver && (g_str_equal(driver, "ata_piix") ||
876                        g_str_equal(driver, "sym53c8xx") ||
877                        g_str_equal(driver, "virtio-pci") ||
878                        g_str_equal(driver, "ahci"))) {
879             break;
880         }
881 
882         g_free(driver);
883         if (sscanf(p, "/%x:%x:%x.%x%n",
884                           pci, pci + 1, pci + 2, pci + 3, &pcilen) == 4) {
885             p += pcilen;
886             continue;
887         }
888 
889         g_debug("unsupported driver or sysfs path '%s'", syspath);
890         return false;
891     }
892 
893     p = strstr(syspath, "/target");
894     if (p && sscanf(p + 7, "%*u:%*u:%*u/%*u:%u:%u:%u",
895                     tgt, tgt + 1, tgt + 2) == 3) {
896         has_tgt = true;
897     }
898 
899     p = strstr(syspath, "/ata");
900     if (p) {
901         q = p + 4;
902         has_ata = true;
903     } else {
904         p = strstr(syspath, "/host");
905         q = p + 5;
906     }
907     if (p && sscanf(q, "%u", &host) == 1) {
908         has_host = true;
909         nhosts = build_hosts(syspath, p, has_ata, hosts,
910                              ARRAY_SIZE(hosts), errp);
911         if (nhosts < 0) {
912             goto cleanup;
913         }
914     }
915 
916     pciaddr->domain = pci[0];
917     pciaddr->bus = pci[1];
918     pciaddr->slot = pci[2];
919     pciaddr->function = pci[3];
920 
921     if (strcmp(driver, "ata_piix") == 0) {
922         /* a host per ide bus, target*:0:<unit>:0 */
923         if (!has_host || !has_tgt) {
924             g_debug("invalid sysfs path '%s' (driver '%s')", syspath, driver);
925             goto cleanup;
926         }
927         for (i = 0; i < nhosts; i++) {
928             if (host == hosts[i]) {
929                 disk->bus_type = GUEST_DISK_BUS_TYPE_IDE;
930                 disk->bus = i;
931                 disk->unit = tgt[1];
932                 break;
933             }
934         }
935         if (i >= nhosts) {
936             g_debug("no host for '%s' (driver '%s')", syspath, driver);
937             goto cleanup;
938         }
939     } else if (strcmp(driver, "sym53c8xx") == 0) {
940         /* scsi(LSI Logic): target*:0:<unit>:0 */
941         if (!has_tgt) {
942             g_debug("invalid sysfs path '%s' (driver '%s')", syspath, driver);
943             goto cleanup;
944         }
945         disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI;
946         disk->unit = tgt[1];
947     } else if (strcmp(driver, "virtio-pci") == 0) {
948         if (has_tgt) {
949             /* virtio-scsi: target*:0:0:<unit> */
950             disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI;
951             disk->unit = tgt[2];
952         } else {
953             /* virtio-blk: 1 disk per 1 device */
954             disk->bus_type = GUEST_DISK_BUS_TYPE_VIRTIO;
955         }
956     } else if (strcmp(driver, "ahci") == 0) {
957         /* ahci: 1 host per 1 unit */
958         if (!has_host || !has_tgt) {
959             g_debug("invalid sysfs path '%s' (driver '%s')", syspath, driver);
960             goto cleanup;
961         }
962         for (i = 0; i < nhosts; i++) {
963             if (host == hosts[i]) {
964                 disk->unit = i;
965                 disk->bus_type = GUEST_DISK_BUS_TYPE_SATA;
966                 break;
967             }
968         }
969         if (i >= nhosts) {
970             g_debug("no host for '%s' (driver '%s')", syspath, driver);
971             goto cleanup;
972         }
973     } else {
974         g_debug("unknown driver '%s' (sysfs path '%s')", driver, syspath);
975         goto cleanup;
976     }
977 
978     ret = true;
979 
980 cleanup:
981     g_free(driver);
982     return ret;
983 }
984 
985 /*
986  * Store disk device info for non-PCI virtio devices (for example s390x
987  * channel I/O devices). Returns true if information has been stored, or
988  * false for failure.
989  */
990 static bool build_guest_fsinfo_for_nonpci_virtio(char const *syspath,
991                                                  GuestDiskAddress *disk,
992                                                  Error **errp)
993 {
994     unsigned int tgt[3];
995     char *p;
996 
997     if (!strstr(syspath, "/virtio") || !strstr(syspath, "/block")) {
998         g_debug("Unsupported virtio device '%s'", syspath);
999         return false;
1000     }
1001 
1002     p = strstr(syspath, "/target");
1003     if (p && sscanf(p + 7, "%*u:%*u:%*u/%*u:%u:%u:%u",
1004                     &tgt[0], &tgt[1], &tgt[2]) == 3) {
1005         /* virtio-scsi: target*:0:<target>:<unit> */
1006         disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI;
1007         disk->bus = tgt[0];
1008         disk->target = tgt[1];
1009         disk->unit = tgt[2];
1010     } else {
1011         /* virtio-blk: 1 disk per 1 device */
1012         disk->bus_type = GUEST_DISK_BUS_TYPE_VIRTIO;
1013     }
1014 
1015     return true;
1016 }
1017 
1018 /*
1019  * Store disk device info for CCW devices (s390x channel I/O devices).
1020  * Returns true if information has been stored, or false for failure.
1021  */
1022 static bool build_guest_fsinfo_for_ccw_dev(char const *syspath,
1023                                            GuestDiskAddress *disk,
1024                                            Error **errp)
1025 {
1026     unsigned int cssid, ssid, subchno, devno;
1027     char *p;
1028 
1029     p = strstr(syspath, "/devices/css");
1030     if (!p || sscanf(p + 12, "%*x/%x.%x.%x/%*x.%*x.%x/",
1031                      &cssid, &ssid, &subchno, &devno) < 4) {
1032         g_debug("could not parse ccw device sysfs path: %s", syspath);
1033         return false;
1034     }
1035 
1036     disk->has_ccw_address = true;
1037     disk->ccw_address = g_new0(GuestCCWAddress, 1);
1038     disk->ccw_address->cssid = cssid;
1039     disk->ccw_address->ssid = ssid;
1040     disk->ccw_address->subchno = subchno;
1041     disk->ccw_address->devno = devno;
1042 
1043     if (strstr(p, "/virtio")) {
1044         build_guest_fsinfo_for_nonpci_virtio(syspath, disk, errp);
1045     }
1046 
1047     return true;
1048 }
1049 
1050 /* Store disk device info specified by @sysfs into @fs */
1051 static void build_guest_fsinfo_for_real_device(char const *syspath,
1052                                                GuestFilesystemInfo *fs,
1053                                                Error **errp)
1054 {
1055     GuestDiskAddress *disk;
1056     GuestPCIAddress *pciaddr;
1057     bool has_hwinf;
1058 #ifdef CONFIG_LIBUDEV
1059     struct udev *udev = NULL;
1060     struct udev_device *udevice = NULL;
1061 #endif
1062 
1063     pciaddr = g_new0(GuestPCIAddress, 1);
1064     pciaddr->domain = -1;                       /* -1 means field is invalid */
1065     pciaddr->bus = -1;
1066     pciaddr->slot = -1;
1067     pciaddr->function = -1;
1068 
1069     disk = g_new0(GuestDiskAddress, 1);
1070     disk->pci_controller = pciaddr;
1071     disk->bus_type = GUEST_DISK_BUS_TYPE_UNKNOWN;
1072 
1073 #ifdef CONFIG_LIBUDEV
1074     udev = udev_new();
1075     udevice = udev_device_new_from_syspath(udev, syspath);
1076     if (udev == NULL || udevice == NULL) {
1077         g_debug("failed to query udev");
1078     } else {
1079         const char *devnode, *serial;
1080         devnode = udev_device_get_devnode(udevice);
1081         if (devnode != NULL) {
1082             disk->dev = g_strdup(devnode);
1083             disk->has_dev = true;
1084         }
1085         serial = udev_device_get_property_value(udevice, "ID_SERIAL");
1086         if (serial != NULL && *serial != 0) {
1087             disk->serial = g_strdup(serial);
1088             disk->has_serial = true;
1089         }
1090     }
1091 
1092     udev_unref(udev);
1093     udev_device_unref(udevice);
1094 #endif
1095 
1096     if (strstr(syspath, "/devices/pci")) {
1097         has_hwinf = build_guest_fsinfo_for_pci_dev(syspath, disk, errp);
1098     } else if (strstr(syspath, "/devices/css")) {
1099         has_hwinf = build_guest_fsinfo_for_ccw_dev(syspath, disk, errp);
1100     } else if (strstr(syspath, "/virtio")) {
1101         has_hwinf = build_guest_fsinfo_for_nonpci_virtio(syspath, disk, errp);
1102     } else {
1103         g_debug("Unsupported device type for '%s'", syspath);
1104         has_hwinf = false;
1105     }
1106 
1107     if (has_hwinf || disk->has_dev || disk->has_serial) {
1108         QAPI_LIST_PREPEND(fs->disk, disk);
1109     } else {
1110         qapi_free_GuestDiskAddress(disk);
1111     }
1112 }
1113 
1114 static void build_guest_fsinfo_for_device(char const *devpath,
1115                                           GuestFilesystemInfo *fs,
1116                                           Error **errp);
1117 
1118 /* Store a list of slave devices of virtual volume specified by @syspath into
1119  * @fs */
1120 static void build_guest_fsinfo_for_virtual_device(char const *syspath,
1121                                                   GuestFilesystemInfo *fs,
1122                                                   Error **errp)
1123 {
1124     Error *err = NULL;
1125     DIR *dir;
1126     char *dirpath;
1127     struct dirent *entry;
1128 
1129     dirpath = g_strdup_printf("%s/slaves", syspath);
1130     dir = opendir(dirpath);
1131     if (!dir) {
1132         if (errno != ENOENT) {
1133             error_setg_errno(errp, errno, "opendir(\"%s\")", dirpath);
1134         }
1135         g_free(dirpath);
1136         return;
1137     }
1138 
1139     for (;;) {
1140         errno = 0;
1141         entry = readdir(dir);
1142         if (entry == NULL) {
1143             if (errno) {
1144                 error_setg_errno(errp, errno, "readdir(\"%s\")", dirpath);
1145             }
1146             break;
1147         }
1148 
1149         if (entry->d_type == DT_LNK) {
1150             char *path;
1151 
1152             g_debug(" slave device '%s'", entry->d_name);
1153             path = g_strdup_printf("%s/slaves/%s", syspath, entry->d_name);
1154             build_guest_fsinfo_for_device(path, fs, &err);
1155             g_free(path);
1156 
1157             if (err) {
1158                 error_propagate(errp, err);
1159                 break;
1160             }
1161         }
1162     }
1163 
1164     g_free(dirpath);
1165     closedir(dir);
1166 }
1167 
1168 static bool is_disk_virtual(const char *devpath, Error **errp)
1169 {
1170     g_autofree char *syspath = realpath(devpath, NULL);
1171 
1172     if (!syspath) {
1173         error_setg_errno(errp, errno, "realpath(\"%s\")", devpath);
1174         return false;
1175     }
1176     return strstr(syspath, "/devices/virtual/block/") != NULL;
1177 }
1178 
1179 /* Dispatch to functions for virtual/real device */
1180 static void build_guest_fsinfo_for_device(char const *devpath,
1181                                           GuestFilesystemInfo *fs,
1182                                           Error **errp)
1183 {
1184     ERRP_GUARD();
1185     g_autofree char *syspath = NULL;
1186     bool is_virtual = false;
1187 
1188     syspath = realpath(devpath, NULL);
1189     if (!syspath) {
1190         error_setg_errno(errp, errno, "realpath(\"%s\")", devpath);
1191         return;
1192     }
1193 
1194     if (!fs->name) {
1195         fs->name = g_path_get_basename(syspath);
1196     }
1197 
1198     g_debug("  parse sysfs path '%s'", syspath);
1199     is_virtual = is_disk_virtual(syspath, errp);
1200     if (*errp != NULL) {
1201         return;
1202     }
1203     if (is_virtual) {
1204         build_guest_fsinfo_for_virtual_device(syspath, fs, errp);
1205     } else {
1206         build_guest_fsinfo_for_real_device(syspath, fs, errp);
1207     }
1208 }
1209 
1210 #ifdef CONFIG_LIBUDEV
1211 
1212 /*
1213  * Wrapper around build_guest_fsinfo_for_device() for getting just
1214  * the disk address.
1215  */
1216 static GuestDiskAddress *get_disk_address(const char *syspath, Error **errp)
1217 {
1218     g_autoptr(GuestFilesystemInfo) fs = NULL;
1219 
1220     fs = g_new0(GuestFilesystemInfo, 1);
1221     build_guest_fsinfo_for_device(syspath, fs, errp);
1222     if (fs->disk != NULL) {
1223         return g_steal_pointer(&fs->disk->value);
1224     }
1225     return NULL;
1226 }
1227 
1228 static char *get_alias_for_syspath(const char *syspath)
1229 {
1230     struct udev *udev = NULL;
1231     struct udev_device *udevice = NULL;
1232     char *ret = NULL;
1233 
1234     udev = udev_new();
1235     if (udev == NULL) {
1236         g_debug("failed to query udev");
1237         goto out;
1238     }
1239     udevice = udev_device_new_from_syspath(udev, syspath);
1240     if (udevice == NULL) {
1241         g_debug("failed to query udev for path: %s", syspath);
1242         goto out;
1243     } else {
1244         const char *alias = udev_device_get_property_value(
1245             udevice, "DM_NAME");
1246         /*
1247          * NULL means there was an error and empty string means there is no
1248          * alias. In case of no alias we return NULL instead of empty string.
1249          */
1250         if (alias == NULL) {
1251             g_debug("failed to query udev for device alias for: %s",
1252                 syspath);
1253         } else if (*alias != 0) {
1254             ret = g_strdup(alias);
1255         }
1256     }
1257 
1258 out:
1259     udev_unref(udev);
1260     udev_device_unref(udevice);
1261     return ret;
1262 }
1263 
1264 static char *get_device_for_syspath(const char *syspath)
1265 {
1266     struct udev *udev = NULL;
1267     struct udev_device *udevice = NULL;
1268     char *ret = NULL;
1269 
1270     udev = udev_new();
1271     if (udev == NULL) {
1272         g_debug("failed to query udev");
1273         goto out;
1274     }
1275     udevice = udev_device_new_from_syspath(udev, syspath);
1276     if (udevice == NULL) {
1277         g_debug("failed to query udev for path: %s", syspath);
1278         goto out;
1279     } else {
1280         ret = g_strdup(udev_device_get_devnode(udevice));
1281     }
1282 
1283 out:
1284     udev_unref(udev);
1285     udev_device_unref(udevice);
1286     return ret;
1287 }
1288 
1289 static void get_disk_deps(const char *disk_dir, GuestDiskInfo *disk)
1290 {
1291     g_autofree char *deps_dir = NULL;
1292     const gchar *dep;
1293     GDir *dp_deps = NULL;
1294 
1295     /* List dependent disks */
1296     deps_dir = g_strdup_printf("%s/slaves", disk_dir);
1297     g_debug("  listing entries in: %s", deps_dir);
1298     dp_deps = g_dir_open(deps_dir, 0, NULL);
1299     if (dp_deps == NULL) {
1300         g_debug("failed to list entries in %s", deps_dir);
1301         return;
1302     }
1303     disk->has_dependencies = true;
1304     while ((dep = g_dir_read_name(dp_deps)) != NULL) {
1305         g_autofree char *dep_dir = NULL;
1306         char *dev_name;
1307 
1308         /* Add dependent disks */
1309         dep_dir = g_strdup_printf("%s/%s", deps_dir, dep);
1310         dev_name = get_device_for_syspath(dep_dir);
1311         if (dev_name != NULL) {
1312             g_debug("  adding dependent device: %s", dev_name);
1313             QAPI_LIST_PREPEND(disk->dependencies, dev_name);
1314         }
1315     }
1316     g_dir_close(dp_deps);
1317 }
1318 
1319 /*
1320  * Detect partitions subdirectory, name is "<disk_name><number>" or
1321  * "<disk_name>p<number>"
1322  *
1323  * @disk_name -- last component of /sys path (e.g. sda)
1324  * @disk_dir -- sys path of the disk (e.g. /sys/block/sda)
1325  * @disk_dev -- device node of the disk (e.g. /dev/sda)
1326  */
1327 static GuestDiskInfoList *get_disk_partitions(
1328     GuestDiskInfoList *list,
1329     const char *disk_name, const char *disk_dir,
1330     const char *disk_dev)
1331 {
1332     GuestDiskInfoList *ret = list;
1333     struct dirent *de_disk;
1334     DIR *dp_disk = NULL;
1335     size_t len = strlen(disk_name);
1336 
1337     dp_disk = opendir(disk_dir);
1338     while ((de_disk = readdir(dp_disk)) != NULL) {
1339         g_autofree char *partition_dir = NULL;
1340         char *dev_name;
1341         GuestDiskInfo *partition;
1342 
1343         if (!(de_disk->d_type & DT_DIR)) {
1344             continue;
1345         }
1346 
1347         if (!(strncmp(disk_name, de_disk->d_name, len) == 0 &&
1348             ((*(de_disk->d_name + len) == 'p' &&
1349             isdigit(*(de_disk->d_name + len + 1))) ||
1350                 isdigit(*(de_disk->d_name + len))))) {
1351             continue;
1352         }
1353 
1354         partition_dir = g_strdup_printf("%s/%s",
1355             disk_dir, de_disk->d_name);
1356         dev_name = get_device_for_syspath(partition_dir);
1357         if (dev_name == NULL) {
1358             g_debug("Failed to get device name for syspath: %s",
1359                 disk_dir);
1360             continue;
1361         }
1362         partition = g_new0(GuestDiskInfo, 1);
1363         partition->name = dev_name;
1364         partition->partition = true;
1365         partition->has_dependencies = true;
1366         /* Add parent disk as dependent for easier tracking of hierarchy */
1367         QAPI_LIST_PREPEND(partition->dependencies, g_strdup(disk_dev));
1368 
1369         QAPI_LIST_PREPEND(ret, partition);
1370     }
1371     closedir(dp_disk);
1372 
1373     return ret;
1374 }
1375 
1376 GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
1377 {
1378     GuestDiskInfoList *ret = NULL;
1379     GuestDiskInfo *disk;
1380     DIR *dp = NULL;
1381     struct dirent *de = NULL;
1382 
1383     g_debug("listing /sys/block directory");
1384     dp = opendir("/sys/block");
1385     if (dp == NULL) {
1386         error_setg_errno(errp, errno, "Can't open directory \"/sys/block\"");
1387         return NULL;
1388     }
1389     while ((de = readdir(dp)) != NULL) {
1390         g_autofree char *disk_dir = NULL, *line = NULL,
1391             *size_path = NULL;
1392         char *dev_name;
1393         Error *local_err = NULL;
1394         if (de->d_type != DT_LNK) {
1395             g_debug("  skipping entry: %s", de->d_name);
1396             continue;
1397         }
1398 
1399         /* Check size and skip zero-sized disks */
1400         g_debug("  checking disk size");
1401         size_path = g_strdup_printf("/sys/block/%s/size", de->d_name);
1402         if (!g_file_get_contents(size_path, &line, NULL, NULL)) {
1403             g_debug("  failed to read disk size");
1404             continue;
1405         }
1406         if (g_strcmp0(line, "0\n") == 0) {
1407             g_debug("  skipping zero-sized disk");
1408             continue;
1409         }
1410 
1411         g_debug("  adding %s", de->d_name);
1412         disk_dir = g_strdup_printf("/sys/block/%s", de->d_name);
1413         dev_name = get_device_for_syspath(disk_dir);
1414         if (dev_name == NULL) {
1415             g_debug("Failed to get device name for syspath: %s",
1416                 disk_dir);
1417             continue;
1418         }
1419         disk = g_new0(GuestDiskInfo, 1);
1420         disk->name = dev_name;
1421         disk->partition = false;
1422         disk->alias = get_alias_for_syspath(disk_dir);
1423         disk->has_alias = (disk->alias != NULL);
1424         QAPI_LIST_PREPEND(ret, disk);
1425 
1426         /* Get address for non-virtual devices */
1427         bool is_virtual = is_disk_virtual(disk_dir, &local_err);
1428         if (local_err != NULL) {
1429             g_debug("  failed to check disk path, ignoring error: %s",
1430                 error_get_pretty(local_err));
1431             error_free(local_err);
1432             local_err = NULL;
1433             /* Don't try to get the address */
1434             is_virtual = true;
1435         }
1436         if (!is_virtual) {
1437             disk->address = get_disk_address(disk_dir, &local_err);
1438             if (local_err != NULL) {
1439                 g_debug("  failed to get device info, ignoring error: %s",
1440                     error_get_pretty(local_err));
1441                 error_free(local_err);
1442                 local_err = NULL;
1443             } else if (disk->address != NULL) {
1444                 disk->has_address = true;
1445             }
1446         }
1447 
1448         get_disk_deps(disk_dir, disk);
1449         ret = get_disk_partitions(ret, de->d_name, disk_dir, dev_name);
1450     }
1451 
1452     closedir(dp);
1453 
1454     return ret;
1455 }
1456 
1457 #else
1458 
1459 GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
1460 {
1461     error_setg(errp, QERR_UNSUPPORTED);
1462     return NULL;
1463 }
1464 
1465 #endif
1466 
1467 /* Return a list of the disk device(s)' info which @mount lies on */
1468 static GuestFilesystemInfo *build_guest_fsinfo(struct FsMount *mount,
1469                                                Error **errp)
1470 {
1471     GuestFilesystemInfo *fs = g_malloc0(sizeof(*fs));
1472     struct statvfs buf;
1473     unsigned long used, nonroot_total, fr_size;
1474     char *devpath = g_strdup_printf("/sys/dev/block/%u:%u",
1475                                     mount->devmajor, mount->devminor);
1476 
1477     fs->mountpoint = g_strdup(mount->dirname);
1478     fs->type = g_strdup(mount->devtype);
1479     build_guest_fsinfo_for_device(devpath, fs, errp);
1480 
1481     if (statvfs(fs->mountpoint, &buf) == 0) {
1482         fr_size = buf.f_frsize;
1483         used = buf.f_blocks - buf.f_bfree;
1484         nonroot_total = used + buf.f_bavail;
1485         fs->used_bytes = used * fr_size;
1486         fs->total_bytes = nonroot_total * fr_size;
1487 
1488         fs->has_total_bytes = true;
1489         fs->has_used_bytes = true;
1490     }
1491 
1492     g_free(devpath);
1493 
1494     return fs;
1495 }
1496 
1497 GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp)
1498 {
1499     FsMountList mounts;
1500     struct FsMount *mount;
1501     GuestFilesystemInfoList *ret = NULL;
1502     Error *local_err = NULL;
1503 
1504     QTAILQ_INIT(&mounts);
1505     build_fs_mount_list(&mounts, &local_err);
1506     if (local_err) {
1507         error_propagate(errp, local_err);
1508         return NULL;
1509     }
1510 
1511     QTAILQ_FOREACH(mount, &mounts, next) {
1512         g_debug("Building guest fsinfo for '%s'", mount->dirname);
1513 
1514         QAPI_LIST_PREPEND(ret, build_guest_fsinfo(mount, &local_err));
1515         if (local_err) {
1516             error_propagate(errp, local_err);
1517             qapi_free_GuestFilesystemInfoList(ret);
1518             ret = NULL;
1519             break;
1520         }
1521     }
1522 
1523     free_fs_mount_list(&mounts);
1524     return ret;
1525 }
1526 
1527 
1528 typedef enum {
1529     FSFREEZE_HOOK_THAW = 0,
1530     FSFREEZE_HOOK_FREEZE,
1531 } FsfreezeHookArg;
1532 
1533 static const char *fsfreeze_hook_arg_string[] = {
1534     "thaw",
1535     "freeze",
1536 };
1537 
1538 static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **errp)
1539 {
1540     int status;
1541     pid_t pid;
1542     const char *hook;
1543     const char *arg_str = fsfreeze_hook_arg_string[arg];
1544     Error *local_err = NULL;
1545 
1546     hook = ga_fsfreeze_hook(ga_state);
1547     if (!hook) {
1548         return;
1549     }
1550     if (access(hook, X_OK) != 0) {
1551         error_setg_errno(errp, errno, "can't access fsfreeze hook '%s'", hook);
1552         return;
1553     }
1554 
1555     slog("executing fsfreeze hook with arg '%s'", arg_str);
1556     pid = fork();
1557     if (pid == 0) {
1558         setsid();
1559         reopen_fd_to_null(0);
1560         reopen_fd_to_null(1);
1561         reopen_fd_to_null(2);
1562 
1563         execle(hook, hook, arg_str, NULL, environ);
1564         _exit(EXIT_FAILURE);
1565     } else if (pid < 0) {
1566         error_setg_errno(errp, errno, "failed to create child process");
1567         return;
1568     }
1569 
1570     ga_wait_child(pid, &status, &local_err);
1571     if (local_err) {
1572         error_propagate(errp, local_err);
1573         return;
1574     }
1575 
1576     if (!WIFEXITED(status)) {
1577         error_setg(errp, "fsfreeze hook has terminated abnormally");
1578         return;
1579     }
1580 
1581     status = WEXITSTATUS(status);
1582     if (status) {
1583         error_setg(errp, "fsfreeze hook has failed with status %d", status);
1584         return;
1585     }
1586 }
1587 
1588 /*
1589  * Return status of freeze/thaw
1590  */
1591 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp)
1592 {
1593     if (ga_is_frozen(ga_state)) {
1594         return GUEST_FSFREEZE_STATUS_FROZEN;
1595     }
1596 
1597     return GUEST_FSFREEZE_STATUS_THAWED;
1598 }
1599 
1600 int64_t qmp_guest_fsfreeze_freeze(Error **errp)
1601 {
1602     return qmp_guest_fsfreeze_freeze_list(false, NULL, errp);
1603 }
1604 
1605 /*
1606  * Walk list of mounted file systems in the guest, and freeze the ones which
1607  * are real local file systems.
1608  */
1609 int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
1610                                        strList *mountpoints,
1611                                        Error **errp)
1612 {
1613     int ret = 0, i = 0;
1614     strList *list;
1615     FsMountList mounts;
1616     struct FsMount *mount;
1617     Error *local_err = NULL;
1618     int fd;
1619 
1620     slog("guest-fsfreeze called");
1621 
1622     execute_fsfreeze_hook(FSFREEZE_HOOK_FREEZE, &local_err);
1623     if (local_err) {
1624         error_propagate(errp, local_err);
1625         return -1;
1626     }
1627 
1628     QTAILQ_INIT(&mounts);
1629     build_fs_mount_list(&mounts, &local_err);
1630     if (local_err) {
1631         error_propagate(errp, local_err);
1632         return -1;
1633     }
1634 
1635     /* cannot risk guest agent blocking itself on a write in this state */
1636     ga_set_frozen(ga_state);
1637 
1638     QTAILQ_FOREACH_REVERSE(mount, &mounts, next) {
1639         /* To issue fsfreeze in the reverse order of mounts, check if the
1640          * mount is listed in the list here */
1641         if (has_mountpoints) {
1642             for (list = mountpoints; list; list = list->next) {
1643                 if (strcmp(list->value, mount->dirname) == 0) {
1644                     break;
1645                 }
1646             }
1647             if (!list) {
1648                 continue;
1649             }
1650         }
1651 
1652         fd = qemu_open_old(mount->dirname, O_RDONLY);
1653         if (fd == -1) {
1654             error_setg_errno(errp, errno, "failed to open %s", mount->dirname);
1655             goto error;
1656         }
1657 
1658         /* we try to cull filesystems we know won't work in advance, but other
1659          * filesystems may not implement fsfreeze for less obvious reasons.
1660          * these will report EOPNOTSUPP. we simply ignore these when tallying
1661          * the number of frozen filesystems.
1662          * if a filesystem is mounted more than once (aka bind mount) a
1663          * consecutive attempt to freeze an already frozen filesystem will
1664          * return EBUSY.
1665          *
1666          * any other error means a failure to freeze a filesystem we
1667          * expect to be freezable, so return an error in those cases
1668          * and return system to thawed state.
1669          */
1670         ret = ioctl(fd, FIFREEZE);
1671         if (ret == -1) {
1672             if (errno != EOPNOTSUPP && errno != EBUSY) {
1673                 error_setg_errno(errp, errno, "failed to freeze %s",
1674                                  mount->dirname);
1675                 close(fd);
1676                 goto error;
1677             }
1678         } else {
1679             i++;
1680         }
1681         close(fd);
1682     }
1683 
1684     free_fs_mount_list(&mounts);
1685     /* We may not issue any FIFREEZE here.
1686      * Just unset ga_state here and ready for the next call.
1687      */
1688     if (i == 0) {
1689         ga_unset_frozen(ga_state);
1690     }
1691     return i;
1692 
1693 error:
1694     free_fs_mount_list(&mounts);
1695     qmp_guest_fsfreeze_thaw(NULL);
1696     return 0;
1697 }
1698 
1699 /*
1700  * Walk list of frozen file systems in the guest, and thaw them.
1701  */
1702 int64_t qmp_guest_fsfreeze_thaw(Error **errp)
1703 {
1704     int ret;
1705     FsMountList mounts;
1706     FsMount *mount;
1707     int fd, i = 0, logged;
1708     Error *local_err = NULL;
1709 
1710     QTAILQ_INIT(&mounts);
1711     build_fs_mount_list(&mounts, &local_err);
1712     if (local_err) {
1713         error_propagate(errp, local_err);
1714         return 0;
1715     }
1716 
1717     QTAILQ_FOREACH(mount, &mounts, next) {
1718         logged = false;
1719         fd = qemu_open_old(mount->dirname, O_RDONLY);
1720         if (fd == -1) {
1721             continue;
1722         }
1723         /* we have no way of knowing whether a filesystem was actually unfrozen
1724          * as a result of a successful call to FITHAW, only that if an error
1725          * was returned the filesystem was *not* unfrozen by that particular
1726          * call.
1727          *
1728          * since multiple preceding FIFREEZEs require multiple calls to FITHAW
1729          * to unfreeze, continuing issuing FITHAW until an error is returned,
1730          * in which case either the filesystem is in an unfreezable state, or,
1731          * more likely, it was thawed previously (and remains so afterward).
1732          *
1733          * also, since the most recent successful call is the one that did
1734          * the actual unfreeze, we can use this to provide an accurate count
1735          * of the number of filesystems unfrozen by guest-fsfreeze-thaw, which
1736          * may * be useful for determining whether a filesystem was unfrozen
1737          * during the freeze/thaw phase by a process other than qemu-ga.
1738          */
1739         do {
1740             ret = ioctl(fd, FITHAW);
1741             if (ret == 0 && !logged) {
1742                 i++;
1743                 logged = true;
1744             }
1745         } while (ret == 0);
1746         close(fd);
1747     }
1748 
1749     ga_unset_frozen(ga_state);
1750     free_fs_mount_list(&mounts);
1751 
1752     execute_fsfreeze_hook(FSFREEZE_HOOK_THAW, errp);
1753 
1754     return i;
1755 }
1756 
1757 static void guest_fsfreeze_cleanup(void)
1758 {
1759     Error *err = NULL;
1760 
1761     if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) {
1762         qmp_guest_fsfreeze_thaw(&err);
1763         if (err) {
1764             slog("failed to clean up frozen filesystems: %s",
1765                  error_get_pretty(err));
1766             error_free(err);
1767         }
1768     }
1769 }
1770 #endif /* CONFIG_FSFREEZE */
1771 
1772 #if defined(CONFIG_FSTRIM)
1773 /*
1774  * Walk list of mounted file systems in the guest, and trim them.
1775  */
1776 GuestFilesystemTrimResponse *
1777 qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
1778 {
1779     GuestFilesystemTrimResponse *response;
1780     GuestFilesystemTrimResult *result;
1781     int ret = 0;
1782     FsMountList mounts;
1783     struct FsMount *mount;
1784     int fd;
1785     Error *local_err = NULL;
1786     struct fstrim_range r;
1787 
1788     slog("guest-fstrim called");
1789 
1790     QTAILQ_INIT(&mounts);
1791     build_fs_mount_list(&mounts, &local_err);
1792     if (local_err) {
1793         error_propagate(errp, local_err);
1794         return NULL;
1795     }
1796 
1797     response = g_malloc0(sizeof(*response));
1798 
1799     QTAILQ_FOREACH(mount, &mounts, next) {
1800         result = g_malloc0(sizeof(*result));
1801         result->path = g_strdup(mount->dirname);
1802 
1803         QAPI_LIST_PREPEND(response->paths, result);
1804 
1805         fd = qemu_open_old(mount->dirname, O_RDONLY);
1806         if (fd == -1) {
1807             result->error = g_strdup_printf("failed to open: %s",
1808                                             strerror(errno));
1809             result->has_error = true;
1810             continue;
1811         }
1812 
1813         /* We try to cull filesystems we know won't work in advance, but other
1814          * filesystems may not implement fstrim for less obvious reasons.
1815          * These will report EOPNOTSUPP; while in some other cases ENOTTY
1816          * will be reported (e.g. CD-ROMs).
1817          * Any other error means an unexpected error.
1818          */
1819         r.start = 0;
1820         r.len = -1;
1821         r.minlen = has_minimum ? minimum : 0;
1822         ret = ioctl(fd, FITRIM, &r);
1823         if (ret == -1) {
1824             result->has_error = true;
1825             if (errno == ENOTTY || errno == EOPNOTSUPP) {
1826                 result->error = g_strdup("trim not supported");
1827             } else {
1828                 result->error = g_strdup_printf("failed to trim: %s",
1829                                                 strerror(errno));
1830             }
1831             close(fd);
1832             continue;
1833         }
1834 
1835         result->has_minimum = true;
1836         result->minimum = r.minlen;
1837         result->has_trimmed = true;
1838         result->trimmed = r.len;
1839         close(fd);
1840     }
1841 
1842     free_fs_mount_list(&mounts);
1843     return response;
1844 }
1845 #endif /* CONFIG_FSTRIM */
1846 
1847 
1848 #define LINUX_SYS_STATE_FILE "/sys/power/state"
1849 #define SUSPEND_SUPPORTED 0
1850 #define SUSPEND_NOT_SUPPORTED 1
1851 
1852 typedef enum {
1853     SUSPEND_MODE_DISK = 0,
1854     SUSPEND_MODE_RAM = 1,
1855     SUSPEND_MODE_HYBRID = 2,
1856 } SuspendMode;
1857 
1858 /*
1859  * Executes a command in a child process using g_spawn_sync,
1860  * returning an int >= 0 representing the exit status of the
1861  * process.
1862  *
1863  * If the program wasn't found in path, returns -1.
1864  *
1865  * If a problem happened when creating the child process,
1866  * returns -1 and errp is set.
1867  */
1868 static int run_process_child(const char *command[], Error **errp)
1869 {
1870     int exit_status, spawn_flag;
1871     GError *g_err = NULL;
1872     bool success;
1873 
1874     spawn_flag = G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL |
1875                  G_SPAWN_STDERR_TO_DEV_NULL;
1876 
1877     success =  g_spawn_sync(NULL, (char **)command, environ, spawn_flag,
1878                             NULL, NULL, NULL, NULL,
1879                             &exit_status, &g_err);
1880 
1881     if (success) {
1882         return WEXITSTATUS(exit_status);
1883     }
1884 
1885     if (g_err && (g_err->code != G_SPAWN_ERROR_NOENT)) {
1886         error_setg(errp, "failed to create child process, error '%s'",
1887                    g_err->message);
1888     }
1889 
1890     g_error_free(g_err);
1891     return -1;
1892 }
1893 
1894 static bool systemd_supports_mode(SuspendMode mode, Error **errp)
1895 {
1896     const char *systemctl_args[3] = {"systemd-hibernate", "systemd-suspend",
1897                                      "systemd-hybrid-sleep"};
1898     const char *cmd[4] = {"systemctl", "status", systemctl_args[mode], NULL};
1899     int status;
1900 
1901     status = run_process_child(cmd, errp);
1902 
1903     /*
1904      * systemctl status uses LSB return codes so we can expect
1905      * status > 0 and be ok. To assert if the guest has support
1906      * for the selected suspend mode, status should be < 4. 4 is
1907      * the code for unknown service status, the return value when
1908      * the service does not exist. A common value is status = 3
1909      * (program is not running).
1910      */
1911     if (status > 0 && status < 4) {
1912         return true;
1913     }
1914 
1915     return false;
1916 }
1917 
1918 static void systemd_suspend(SuspendMode mode, Error **errp)
1919 {
1920     Error *local_err = NULL;
1921     const char *systemctl_args[3] = {"hibernate", "suspend", "hybrid-sleep"};
1922     const char *cmd[3] = {"systemctl", systemctl_args[mode], NULL};
1923     int status;
1924 
1925     status = run_process_child(cmd, &local_err);
1926 
1927     if (status == 0) {
1928         return;
1929     }
1930 
1931     if ((status == -1) && !local_err) {
1932         error_setg(errp, "the helper program 'systemctl %s' was not found",
1933                    systemctl_args[mode]);
1934         return;
1935     }
1936 
1937     if (local_err) {
1938         error_propagate(errp, local_err);
1939     } else {
1940         error_setg(errp, "the helper program 'systemctl %s' returned an "
1941                    "unexpected exit status code (%d)",
1942                    systemctl_args[mode], status);
1943     }
1944 }
1945 
1946 static bool pmutils_supports_mode(SuspendMode mode, Error **errp)
1947 {
1948     Error *local_err = NULL;
1949     const char *pmutils_args[3] = {"--hibernate", "--suspend",
1950                                    "--suspend-hybrid"};
1951     const char *cmd[3] = {"pm-is-supported", pmutils_args[mode], NULL};
1952     int status;
1953 
1954     status = run_process_child(cmd, &local_err);
1955 
1956     if (status == SUSPEND_SUPPORTED) {
1957         return true;
1958     }
1959 
1960     if ((status == -1) && !local_err) {
1961         return false;
1962     }
1963 
1964     if (local_err) {
1965         error_propagate(errp, local_err);
1966     } else {
1967         error_setg(errp,
1968                    "the helper program '%s' returned an unexpected exit"
1969                    " status code (%d)", "pm-is-supported", status);
1970     }
1971 
1972     return false;
1973 }
1974 
1975 static void pmutils_suspend(SuspendMode mode, Error **errp)
1976 {
1977     Error *local_err = NULL;
1978     const char *pmutils_binaries[3] = {"pm-hibernate", "pm-suspend",
1979                                        "pm-suspend-hybrid"};
1980     const char *cmd[2] = {pmutils_binaries[mode], NULL};
1981     int status;
1982 
1983     status = run_process_child(cmd, &local_err);
1984 
1985     if (status == 0) {
1986         return;
1987     }
1988 
1989     if ((status == -1) && !local_err) {
1990         error_setg(errp, "the helper program '%s' was not found",
1991                    pmutils_binaries[mode]);
1992         return;
1993     }
1994 
1995     if (local_err) {
1996         error_propagate(errp, local_err);
1997     } else {
1998         error_setg(errp,
1999                    "the helper program '%s' returned an unexpected exit"
2000                    " status code (%d)", pmutils_binaries[mode], status);
2001     }
2002 }
2003 
2004 static bool linux_sys_state_supports_mode(SuspendMode mode, Error **errp)
2005 {
2006     const char *sysfile_strs[3] = {"disk", "mem", NULL};
2007     const char *sysfile_str = sysfile_strs[mode];
2008     char buf[32]; /* hopefully big enough */
2009     int fd;
2010     ssize_t ret;
2011 
2012     if (!sysfile_str) {
2013         error_setg(errp, "unknown guest suspend mode");
2014         return false;
2015     }
2016 
2017     fd = open(LINUX_SYS_STATE_FILE, O_RDONLY);
2018     if (fd < 0) {
2019         return false;
2020     }
2021 
2022     ret = read(fd, buf, sizeof(buf) - 1);
2023     close(fd);
2024     if (ret <= 0) {
2025         return false;
2026     }
2027     buf[ret] = '\0';
2028 
2029     if (strstr(buf, sysfile_str)) {
2030         return true;
2031     }
2032     return false;
2033 }
2034 
2035 static void linux_sys_state_suspend(SuspendMode mode, Error **errp)
2036 {
2037     Error *local_err = NULL;
2038     const char *sysfile_strs[3] = {"disk", "mem", NULL};
2039     const char *sysfile_str = sysfile_strs[mode];
2040     pid_t pid;
2041     int status;
2042 
2043     if (!sysfile_str) {
2044         error_setg(errp, "unknown guest suspend mode");
2045         return;
2046     }
2047 
2048     pid = fork();
2049     if (!pid) {
2050         /* child */
2051         int fd;
2052 
2053         setsid();
2054         reopen_fd_to_null(0);
2055         reopen_fd_to_null(1);
2056         reopen_fd_to_null(2);
2057 
2058         fd = open(LINUX_SYS_STATE_FILE, O_WRONLY);
2059         if (fd < 0) {
2060             _exit(EXIT_FAILURE);
2061         }
2062 
2063         if (write(fd, sysfile_str, strlen(sysfile_str)) < 0) {
2064             _exit(EXIT_FAILURE);
2065         }
2066 
2067         _exit(EXIT_SUCCESS);
2068     } else if (pid < 0) {
2069         error_setg_errno(errp, errno, "failed to create child process");
2070         return;
2071     }
2072 
2073     ga_wait_child(pid, &status, &local_err);
2074     if (local_err) {
2075         error_propagate(errp, local_err);
2076         return;
2077     }
2078 
2079     if (WEXITSTATUS(status)) {
2080         error_setg(errp, "child process has failed to suspend");
2081     }
2082 
2083 }
2084 
2085 static void guest_suspend(SuspendMode mode, Error **errp)
2086 {
2087     Error *local_err = NULL;
2088     bool mode_supported = false;
2089 
2090     if (systemd_supports_mode(mode, &local_err)) {
2091         mode_supported = true;
2092         systemd_suspend(mode, &local_err);
2093     }
2094 
2095     if (!local_err) {
2096         return;
2097     }
2098 
2099     error_free(local_err);
2100     local_err = NULL;
2101 
2102     if (pmutils_supports_mode(mode, &local_err)) {
2103         mode_supported = true;
2104         pmutils_suspend(mode, &local_err);
2105     }
2106 
2107     if (!local_err) {
2108         return;
2109     }
2110 
2111     error_free(local_err);
2112     local_err = NULL;
2113 
2114     if (linux_sys_state_supports_mode(mode, &local_err)) {
2115         mode_supported = true;
2116         linux_sys_state_suspend(mode, &local_err);
2117     }
2118 
2119     if (!mode_supported) {
2120         error_free(local_err);
2121         error_setg(errp,
2122                    "the requested suspend mode is not supported by the guest");
2123     } else {
2124         error_propagate(errp, local_err);
2125     }
2126 }
2127 
2128 void qmp_guest_suspend_disk(Error **errp)
2129 {
2130     guest_suspend(SUSPEND_MODE_DISK, errp);
2131 }
2132 
2133 void qmp_guest_suspend_ram(Error **errp)
2134 {
2135     guest_suspend(SUSPEND_MODE_RAM, errp);
2136 }
2137 
2138 void qmp_guest_suspend_hybrid(Error **errp)
2139 {
2140     guest_suspend(SUSPEND_MODE_HYBRID, errp);
2141 }
2142 
2143 static GuestNetworkInterface *
2144 guest_find_interface(GuestNetworkInterfaceList *head,
2145                      const char *name)
2146 {
2147     for (; head; head = head->next) {
2148         if (strcmp(head->value->name, name) == 0) {
2149             return head->value;
2150         }
2151     }
2152 
2153     return NULL;
2154 }
2155 
2156 static int guest_get_network_stats(const char *name,
2157                        GuestNetworkInterfaceStat *stats)
2158 {
2159     int name_len;
2160     char const *devinfo = "/proc/net/dev";
2161     FILE *fp;
2162     char *line = NULL, *colon;
2163     size_t n = 0;
2164     fp = fopen(devinfo, "r");
2165     if (!fp) {
2166         return -1;
2167     }
2168     name_len = strlen(name);
2169     while (getline(&line, &n, fp) != -1) {
2170         long long dummy;
2171         long long rx_bytes;
2172         long long rx_packets;
2173         long long rx_errs;
2174         long long rx_dropped;
2175         long long tx_bytes;
2176         long long tx_packets;
2177         long long tx_errs;
2178         long long tx_dropped;
2179         char *trim_line;
2180         trim_line = g_strchug(line);
2181         if (trim_line[0] == '\0') {
2182             continue;
2183         }
2184         colon = strchr(trim_line, ':');
2185         if (!colon) {
2186             continue;
2187         }
2188         if (colon - name_len  == trim_line &&
2189            strncmp(trim_line, name, name_len) == 0) {
2190             if (sscanf(colon + 1,
2191                 "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld",
2192                   &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
2193                   &dummy, &dummy, &dummy, &dummy,
2194                   &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
2195                   &dummy, &dummy, &dummy, &dummy) != 16) {
2196                 continue;
2197             }
2198             stats->rx_bytes = rx_bytes;
2199             stats->rx_packets = rx_packets;
2200             stats->rx_errs = rx_errs;
2201             stats->rx_dropped = rx_dropped;
2202             stats->tx_bytes = tx_bytes;
2203             stats->tx_packets = tx_packets;
2204             stats->tx_errs = tx_errs;
2205             stats->tx_dropped = tx_dropped;
2206             fclose(fp);
2207             g_free(line);
2208             return 0;
2209         }
2210     }
2211     fclose(fp);
2212     g_free(line);
2213     g_debug("/proc/net/dev: Interface '%s' not found", name);
2214     return -1;
2215 }
2216 
2217 /*
2218  * Build information about guest interfaces
2219  */
2220 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
2221 {
2222     GuestNetworkInterfaceList *head = NULL, **tail = &head;
2223     struct ifaddrs *ifap, *ifa;
2224 
2225     if (getifaddrs(&ifap) < 0) {
2226         error_setg_errno(errp, errno, "getifaddrs failed");
2227         goto error;
2228     }
2229 
2230     for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
2231         GuestNetworkInterface *info;
2232         GuestIpAddressList **address_tail;
2233         GuestIpAddress *address_item = NULL;
2234         GuestNetworkInterfaceStat *interface_stat = NULL;
2235         char addr4[INET_ADDRSTRLEN];
2236         char addr6[INET6_ADDRSTRLEN];
2237         int sock;
2238         struct ifreq ifr;
2239         unsigned char *mac_addr;
2240         void *p;
2241 
2242         g_debug("Processing %s interface", ifa->ifa_name);
2243 
2244         info = guest_find_interface(head, ifa->ifa_name);
2245 
2246         if (!info) {
2247             info = g_malloc0(sizeof(*info));
2248             info->name = g_strdup(ifa->ifa_name);
2249 
2250             QAPI_LIST_APPEND(tail, info);
2251         }
2252 
2253         if (!info->has_hardware_address && ifa->ifa_flags & SIOCGIFHWADDR) {
2254             /* we haven't obtained HW address yet */
2255             sock = socket(PF_INET, SOCK_STREAM, 0);
2256             if (sock == -1) {
2257                 error_setg_errno(errp, errno, "failed to create socket");
2258                 goto error;
2259             }
2260 
2261             memset(&ifr, 0, sizeof(ifr));
2262             pstrcpy(ifr.ifr_name, IF_NAMESIZE, info->name);
2263             if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) {
2264                 error_setg_errno(errp, errno,
2265                                  "failed to get MAC address of %s",
2266                                  ifa->ifa_name);
2267                 close(sock);
2268                 goto error;
2269             }
2270 
2271             close(sock);
2272             mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
2273 
2274             info->hardware_address =
2275                 g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x",
2276                                 (int) mac_addr[0], (int) mac_addr[1],
2277                                 (int) mac_addr[2], (int) mac_addr[3],
2278                                 (int) mac_addr[4], (int) mac_addr[5]);
2279 
2280             info->has_hardware_address = true;
2281         }
2282 
2283         if (ifa->ifa_addr &&
2284             ifa->ifa_addr->sa_family == AF_INET) {
2285             /* interface with IPv4 address */
2286             p = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
2287             if (!inet_ntop(AF_INET, p, addr4, sizeof(addr4))) {
2288                 error_setg_errno(errp, errno, "inet_ntop failed");
2289                 goto error;
2290             }
2291 
2292             address_item = g_malloc0(sizeof(*address_item));
2293             address_item->ip_address = g_strdup(addr4);
2294             address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV4;
2295 
2296             if (ifa->ifa_netmask) {
2297                 /* Count the number of set bits in netmask.
2298                  * This is safe as '1' and '0' cannot be shuffled in netmask. */
2299                 p = &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
2300                 address_item->prefix = ctpop32(((uint32_t *) p)[0]);
2301             }
2302         } else if (ifa->ifa_addr &&
2303                    ifa->ifa_addr->sa_family == AF_INET6) {
2304             /* interface with IPv6 address */
2305             p = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
2306             if (!inet_ntop(AF_INET6, p, addr6, sizeof(addr6))) {
2307                 error_setg_errno(errp, errno, "inet_ntop failed");
2308                 goto error;
2309             }
2310 
2311             address_item = g_malloc0(sizeof(*address_item));
2312             address_item->ip_address = g_strdup(addr6);
2313             address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV6;
2314 
2315             if (ifa->ifa_netmask) {
2316                 /* Count the number of set bits in netmask.
2317                  * This is safe as '1' and '0' cannot be shuffled in netmask. */
2318                 p = &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr;
2319                 address_item->prefix =
2320                     ctpop32(((uint32_t *) p)[0]) +
2321                     ctpop32(((uint32_t *) p)[1]) +
2322                     ctpop32(((uint32_t *) p)[2]) +
2323                     ctpop32(((uint32_t *) p)[3]);
2324             }
2325         }
2326 
2327         if (!address_item) {
2328             continue;
2329         }
2330 
2331         address_tail = &info->ip_addresses;
2332         while (*address_tail) {
2333             address_tail = &(*address_tail)->next;
2334         }
2335         QAPI_LIST_APPEND(address_tail, address_item);
2336 
2337         info->has_ip_addresses = true;
2338 
2339         if (!info->has_statistics) {
2340             interface_stat = g_malloc0(sizeof(*interface_stat));
2341             if (guest_get_network_stats(info->name, interface_stat) == -1) {
2342                 info->has_statistics = false;
2343                 g_free(interface_stat);
2344             } else {
2345                 info->statistics = interface_stat;
2346                 info->has_statistics = true;
2347             }
2348         }
2349     }
2350 
2351     freeifaddrs(ifap);
2352     return head;
2353 
2354 error:
2355     freeifaddrs(ifap);
2356     qapi_free_GuestNetworkInterfaceList(head);
2357     return NULL;
2358 }
2359 
2360 /* Transfer online/offline status between @vcpu and the guest system.
2361  *
2362  * On input either @errp or *@errp must be NULL.
2363  *
2364  * In system-to-@vcpu direction, the following @vcpu fields are accessed:
2365  * - R: vcpu->logical_id
2366  * - W: vcpu->online
2367  * - W: vcpu->can_offline
2368  *
2369  * In @vcpu-to-system direction, the following @vcpu fields are accessed:
2370  * - R: vcpu->logical_id
2371  * - R: vcpu->online
2372  *
2373  * Written members remain unmodified on error.
2374  */
2375 static void transfer_vcpu(GuestLogicalProcessor *vcpu, bool sys2vcpu,
2376                           char *dirpath, Error **errp)
2377 {
2378     int fd;
2379     int res;
2380     int dirfd;
2381     static const char fn[] = "online";
2382 
2383     dirfd = open(dirpath, O_RDONLY | O_DIRECTORY);
2384     if (dirfd == -1) {
2385         error_setg_errno(errp, errno, "open(\"%s\")", dirpath);
2386         return;
2387     }
2388 
2389     fd = openat(dirfd, fn, sys2vcpu ? O_RDONLY : O_RDWR);
2390     if (fd == -1) {
2391         if (errno != ENOENT) {
2392             error_setg_errno(errp, errno, "open(\"%s/%s\")", dirpath, fn);
2393         } else if (sys2vcpu) {
2394             vcpu->online = true;
2395             vcpu->can_offline = false;
2396         } else if (!vcpu->online) {
2397             error_setg(errp, "logical processor #%" PRId64 " can't be "
2398                        "offlined", vcpu->logical_id);
2399         } /* otherwise pretend successful re-onlining */
2400     } else {
2401         unsigned char status;
2402 
2403         res = pread(fd, &status, 1, 0);
2404         if (res == -1) {
2405             error_setg_errno(errp, errno, "pread(\"%s/%s\")", dirpath, fn);
2406         } else if (res == 0) {
2407             error_setg(errp, "pread(\"%s/%s\"): unexpected EOF", dirpath,
2408                        fn);
2409         } else if (sys2vcpu) {
2410             vcpu->online = (status != '0');
2411             vcpu->can_offline = true;
2412         } else if (vcpu->online != (status != '0')) {
2413             status = '0' + vcpu->online;
2414             if (pwrite(fd, &status, 1, 0) == -1) {
2415                 error_setg_errno(errp, errno, "pwrite(\"%s/%s\")", dirpath,
2416                                  fn);
2417             }
2418         } /* otherwise pretend successful re-(on|off)-lining */
2419 
2420         res = close(fd);
2421         g_assert(res == 0);
2422     }
2423 
2424     res = close(dirfd);
2425     g_assert(res == 0);
2426 }
2427 
2428 GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp)
2429 {
2430     GuestLogicalProcessorList *head, **tail;
2431     const char *cpu_dir = "/sys/devices/system/cpu";
2432     const gchar *line;
2433     g_autoptr(GDir) cpu_gdir = NULL;
2434     Error *local_err = NULL;
2435 
2436     head = NULL;
2437     tail = &head;
2438     cpu_gdir = g_dir_open(cpu_dir, 0, NULL);
2439 
2440     if (cpu_gdir == NULL) {
2441         error_setg_errno(errp, errno, "failed to list entries: %s", cpu_dir);
2442         return NULL;
2443     }
2444 
2445     while (local_err == NULL && (line = g_dir_read_name(cpu_gdir)) != NULL) {
2446         GuestLogicalProcessor *vcpu;
2447         int64_t id;
2448         if (sscanf(line, "cpu%" PRId64, &id)) {
2449             g_autofree char *path = g_strdup_printf("/sys/devices/system/cpu/"
2450                                                     "cpu%" PRId64 "/", id);
2451             vcpu = g_malloc0(sizeof *vcpu);
2452             vcpu->logical_id = id;
2453             vcpu->has_can_offline = true; /* lolspeak ftw */
2454             transfer_vcpu(vcpu, true, path, &local_err);
2455             QAPI_LIST_APPEND(tail, vcpu);
2456         }
2457     }
2458 
2459     if (local_err == NULL) {
2460         /* there's no guest with zero VCPUs */
2461         g_assert(head != NULL);
2462         return head;
2463     }
2464 
2465     qapi_free_GuestLogicalProcessorList(head);
2466     error_propagate(errp, local_err);
2467     return NULL;
2468 }
2469 
2470 int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp)
2471 {
2472     int64_t processed;
2473     Error *local_err = NULL;
2474 
2475     processed = 0;
2476     while (vcpus != NULL) {
2477         char *path = g_strdup_printf("/sys/devices/system/cpu/cpu%" PRId64 "/",
2478                                      vcpus->value->logical_id);
2479 
2480         transfer_vcpu(vcpus->value, false, path, &local_err);
2481         g_free(path);
2482         if (local_err != NULL) {
2483             break;
2484         }
2485         ++processed;
2486         vcpus = vcpus->next;
2487     }
2488 
2489     if (local_err != NULL) {
2490         if (processed == 0) {
2491             error_propagate(errp, local_err);
2492         } else {
2493             error_free(local_err);
2494         }
2495     }
2496 
2497     return processed;
2498 }
2499 
2500 void qmp_guest_set_user_password(const char *username,
2501                                  const char *password,
2502                                  bool crypted,
2503                                  Error **errp)
2504 {
2505     Error *local_err = NULL;
2506     char *passwd_path = NULL;
2507     pid_t pid;
2508     int status;
2509     int datafd[2] = { -1, -1 };
2510     char *rawpasswddata = NULL;
2511     size_t rawpasswdlen;
2512     char *chpasswddata = NULL;
2513     size_t chpasswdlen;
2514 
2515     rawpasswddata = (char *)qbase64_decode(password, -1, &rawpasswdlen, errp);
2516     if (!rawpasswddata) {
2517         return;
2518     }
2519     rawpasswddata = g_renew(char, rawpasswddata, rawpasswdlen + 1);
2520     rawpasswddata[rawpasswdlen] = '\0';
2521 
2522     if (strchr(rawpasswddata, '\n')) {
2523         error_setg(errp, "forbidden characters in raw password");
2524         goto out;
2525     }
2526 
2527     if (strchr(username, '\n') ||
2528         strchr(username, ':')) {
2529         error_setg(errp, "forbidden characters in username");
2530         goto out;
2531     }
2532 
2533     chpasswddata = g_strdup_printf("%s:%s\n", username, rawpasswddata);
2534     chpasswdlen = strlen(chpasswddata);
2535 
2536     passwd_path = g_find_program_in_path("chpasswd");
2537 
2538     if (!passwd_path) {
2539         error_setg(errp, "cannot find 'passwd' program in PATH");
2540         goto out;
2541     }
2542 
2543     if (pipe(datafd) < 0) {
2544         error_setg(errp, "cannot create pipe FDs");
2545         goto out;
2546     }
2547 
2548     pid = fork();
2549     if (pid == 0) {
2550         close(datafd[1]);
2551         /* child */
2552         setsid();
2553         dup2(datafd[0], 0);
2554         reopen_fd_to_null(1);
2555         reopen_fd_to_null(2);
2556 
2557         if (crypted) {
2558             execle(passwd_path, "chpasswd", "-e", NULL, environ);
2559         } else {
2560             execle(passwd_path, "chpasswd", NULL, environ);
2561         }
2562         _exit(EXIT_FAILURE);
2563     } else if (pid < 0) {
2564         error_setg_errno(errp, errno, "failed to create child process");
2565         goto out;
2566     }
2567     close(datafd[0]);
2568     datafd[0] = -1;
2569 
2570     if (qemu_write_full(datafd[1], chpasswddata, chpasswdlen) != chpasswdlen) {
2571         error_setg_errno(errp, errno, "cannot write new account password");
2572         goto out;
2573     }
2574     close(datafd[1]);
2575     datafd[1] = -1;
2576 
2577     ga_wait_child(pid, &status, &local_err);
2578     if (local_err) {
2579         error_propagate(errp, local_err);
2580         goto out;
2581     }
2582 
2583     if (!WIFEXITED(status)) {
2584         error_setg(errp, "child process has terminated abnormally");
2585         goto out;
2586     }
2587 
2588     if (WEXITSTATUS(status)) {
2589         error_setg(errp, "child process has failed to set user password");
2590         goto out;
2591     }
2592 
2593 out:
2594     g_free(chpasswddata);
2595     g_free(rawpasswddata);
2596     g_free(passwd_path);
2597     if (datafd[0] != -1) {
2598         close(datafd[0]);
2599     }
2600     if (datafd[1] != -1) {
2601         close(datafd[1]);
2602     }
2603 }
2604 
2605 static void ga_read_sysfs_file(int dirfd, const char *pathname, char *buf,
2606                                int size, Error **errp)
2607 {
2608     int fd;
2609     int res;
2610 
2611     errno = 0;
2612     fd = openat(dirfd, pathname, O_RDONLY);
2613     if (fd == -1) {
2614         error_setg_errno(errp, errno, "open sysfs file \"%s\"", pathname);
2615         return;
2616     }
2617 
2618     res = pread(fd, buf, size, 0);
2619     if (res == -1) {
2620         error_setg_errno(errp, errno, "pread sysfs file \"%s\"", pathname);
2621     } else if (res == 0) {
2622         error_setg(errp, "pread sysfs file \"%s\": unexpected EOF", pathname);
2623     }
2624     close(fd);
2625 }
2626 
2627 static void ga_write_sysfs_file(int dirfd, const char *pathname,
2628                                 const char *buf, int size, Error **errp)
2629 {
2630     int fd;
2631 
2632     errno = 0;
2633     fd = openat(dirfd, pathname, O_WRONLY);
2634     if (fd == -1) {
2635         error_setg_errno(errp, errno, "open sysfs file \"%s\"", pathname);
2636         return;
2637     }
2638 
2639     if (pwrite(fd, buf, size, 0) == -1) {
2640         error_setg_errno(errp, errno, "pwrite sysfs file \"%s\"", pathname);
2641     }
2642 
2643     close(fd);
2644 }
2645 
2646 /* Transfer online/offline status between @mem_blk and the guest system.
2647  *
2648  * On input either @errp or *@errp must be NULL.
2649  *
2650  * In system-to-@mem_blk direction, the following @mem_blk fields are accessed:
2651  * - R: mem_blk->phys_index
2652  * - W: mem_blk->online
2653  * - W: mem_blk->can_offline
2654  *
2655  * In @mem_blk-to-system direction, the following @mem_blk fields are accessed:
2656  * - R: mem_blk->phys_index
2657  * - R: mem_blk->online
2658  *-  R: mem_blk->can_offline
2659  * Written members remain unmodified on error.
2660  */
2661 static void transfer_memory_block(GuestMemoryBlock *mem_blk, bool sys2memblk,
2662                                   GuestMemoryBlockResponse *result,
2663                                   Error **errp)
2664 {
2665     char *dirpath;
2666     int dirfd;
2667     char *status;
2668     Error *local_err = NULL;
2669 
2670     if (!sys2memblk) {
2671         DIR *dp;
2672 
2673         if (!result) {
2674             error_setg(errp, "Internal error, 'result' should not be NULL");
2675             return;
2676         }
2677         errno = 0;
2678         dp = opendir("/sys/devices/system/memory/");
2679          /* if there is no 'memory' directory in sysfs,
2680          * we think this VM does not support online/offline memory block,
2681          * any other solution?
2682          */
2683         if (!dp) {
2684             if (errno == ENOENT) {
2685                 result->response =
2686                     GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_NOT_SUPPORTED;
2687             }
2688             goto out1;
2689         }
2690         closedir(dp);
2691     }
2692 
2693     dirpath = g_strdup_printf("/sys/devices/system/memory/memory%" PRId64 "/",
2694                               mem_blk->phys_index);
2695     dirfd = open(dirpath, O_RDONLY | O_DIRECTORY);
2696     if (dirfd == -1) {
2697         if (sys2memblk) {
2698             error_setg_errno(errp, errno, "open(\"%s\")", dirpath);
2699         } else {
2700             if (errno == ENOENT) {
2701                 result->response = GUEST_MEMORY_BLOCK_RESPONSE_TYPE_NOT_FOUND;
2702             } else {
2703                 result->response =
2704                     GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED;
2705             }
2706         }
2707         g_free(dirpath);
2708         goto out1;
2709     }
2710     g_free(dirpath);
2711 
2712     status = g_malloc0(10);
2713     ga_read_sysfs_file(dirfd, "state", status, 10, &local_err);
2714     if (local_err) {
2715         /* treat with sysfs file that not exist in old kernel */
2716         if (errno == ENOENT) {
2717             error_free(local_err);
2718             if (sys2memblk) {
2719                 mem_blk->online = true;
2720                 mem_blk->can_offline = false;
2721             } else if (!mem_blk->online) {
2722                 result->response =
2723                     GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_NOT_SUPPORTED;
2724             }
2725         } else {
2726             if (sys2memblk) {
2727                 error_propagate(errp, local_err);
2728             } else {
2729                 error_free(local_err);
2730                 result->response =
2731                     GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED;
2732             }
2733         }
2734         goto out2;
2735     }
2736 
2737     if (sys2memblk) {
2738         char removable = '0';
2739 
2740         mem_blk->online = (strncmp(status, "online", 6) == 0);
2741 
2742         ga_read_sysfs_file(dirfd, "removable", &removable, 1, &local_err);
2743         if (local_err) {
2744             /* if no 'removable' file, it doesn't support offline mem blk */
2745             if (errno == ENOENT) {
2746                 error_free(local_err);
2747                 mem_blk->can_offline = false;
2748             } else {
2749                 error_propagate(errp, local_err);
2750             }
2751         } else {
2752             mem_blk->can_offline = (removable != '0');
2753         }
2754     } else {
2755         if (mem_blk->online != (strncmp(status, "online", 6) == 0)) {
2756             const char *new_state = mem_blk->online ? "online" : "offline";
2757 
2758             ga_write_sysfs_file(dirfd, "state", new_state, strlen(new_state),
2759                                 &local_err);
2760             if (local_err) {
2761                 error_free(local_err);
2762                 result->response =
2763                     GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED;
2764                 goto out2;
2765             }
2766 
2767             result->response = GUEST_MEMORY_BLOCK_RESPONSE_TYPE_SUCCESS;
2768             result->has_error_code = false;
2769         } /* otherwise pretend successful re-(on|off)-lining */
2770     }
2771     g_free(status);
2772     close(dirfd);
2773     return;
2774 
2775 out2:
2776     g_free(status);
2777     close(dirfd);
2778 out1:
2779     if (!sys2memblk) {
2780         result->has_error_code = true;
2781         result->error_code = errno;
2782     }
2783 }
2784 
2785 GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp)
2786 {
2787     GuestMemoryBlockList *head, **tail;
2788     Error *local_err = NULL;
2789     struct dirent *de;
2790     DIR *dp;
2791 
2792     head = NULL;
2793     tail = &head;
2794 
2795     dp = opendir("/sys/devices/system/memory/");
2796     if (!dp) {
2797         /* it's ok if this happens to be a system that doesn't expose
2798          * memory blocks via sysfs, but otherwise we should report
2799          * an error
2800          */
2801         if (errno != ENOENT) {
2802             error_setg_errno(errp, errno, "Can't open directory"
2803                              "\"/sys/devices/system/memory/\"");
2804         }
2805         return NULL;
2806     }
2807 
2808     /* Note: the phys_index of memory block may be discontinuous,
2809      * this is because a memblk is the unit of the Sparse Memory design, which
2810      * allows discontinuous memory ranges (ex. NUMA), so here we should
2811      * traverse the memory block directory.
2812      */
2813     while ((de = readdir(dp)) != NULL) {
2814         GuestMemoryBlock *mem_blk;
2815 
2816         if ((strncmp(de->d_name, "memory", 6) != 0) ||
2817             !(de->d_type & DT_DIR)) {
2818             continue;
2819         }
2820 
2821         mem_blk = g_malloc0(sizeof *mem_blk);
2822         /* The d_name is "memoryXXX",  phys_index is block id, same as XXX */
2823         mem_blk->phys_index = strtoul(&de->d_name[6], NULL, 10);
2824         mem_blk->has_can_offline = true; /* lolspeak ftw */
2825         transfer_memory_block(mem_blk, true, NULL, &local_err);
2826         if (local_err) {
2827             break;
2828         }
2829 
2830         QAPI_LIST_APPEND(tail, mem_blk);
2831     }
2832 
2833     closedir(dp);
2834     if (local_err == NULL) {
2835         /* there's no guest with zero memory blocks */
2836         if (head == NULL) {
2837             error_setg(errp, "guest reported zero memory blocks!");
2838         }
2839         return head;
2840     }
2841 
2842     qapi_free_GuestMemoryBlockList(head);
2843     error_propagate(errp, local_err);
2844     return NULL;
2845 }
2846 
2847 GuestMemoryBlockResponseList *
2848 qmp_guest_set_memory_blocks(GuestMemoryBlockList *mem_blks, Error **errp)
2849 {
2850     GuestMemoryBlockResponseList *head, **tail;
2851     Error *local_err = NULL;
2852 
2853     head = NULL;
2854     tail = &head;
2855 
2856     while (mem_blks != NULL) {
2857         GuestMemoryBlockResponse *result;
2858         GuestMemoryBlock *current_mem_blk = mem_blks->value;
2859 
2860         result = g_malloc0(sizeof(*result));
2861         result->phys_index = current_mem_blk->phys_index;
2862         transfer_memory_block(current_mem_blk, false, result, &local_err);
2863         if (local_err) { /* should never happen */
2864             goto err;
2865         }
2866 
2867         QAPI_LIST_APPEND(tail, result);
2868         mem_blks = mem_blks->next;
2869     }
2870 
2871     return head;
2872 err:
2873     qapi_free_GuestMemoryBlockResponseList(head);
2874     error_propagate(errp, local_err);
2875     return NULL;
2876 }
2877 
2878 GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp)
2879 {
2880     Error *local_err = NULL;
2881     char *dirpath;
2882     int dirfd;
2883     char *buf;
2884     GuestMemoryBlockInfo *info;
2885 
2886     dirpath = g_strdup_printf("/sys/devices/system/memory/");
2887     dirfd = open(dirpath, O_RDONLY | O_DIRECTORY);
2888     if (dirfd == -1) {
2889         error_setg_errno(errp, errno, "open(\"%s\")", dirpath);
2890         g_free(dirpath);
2891         return NULL;
2892     }
2893     g_free(dirpath);
2894 
2895     buf = g_malloc0(20);
2896     ga_read_sysfs_file(dirfd, "block_size_bytes", buf, 20, &local_err);
2897     close(dirfd);
2898     if (local_err) {
2899         g_free(buf);
2900         error_propagate(errp, local_err);
2901         return NULL;
2902     }
2903 
2904     info = g_new0(GuestMemoryBlockInfo, 1);
2905     info->size = strtol(buf, NULL, 16); /* the unit is bytes */
2906 
2907     g_free(buf);
2908 
2909     return info;
2910 }
2911 
2912 #else /* defined(__linux__) */
2913 
2914 void qmp_guest_suspend_disk(Error **errp)
2915 {
2916     error_setg(errp, QERR_UNSUPPORTED);
2917 }
2918 
2919 void qmp_guest_suspend_ram(Error **errp)
2920 {
2921     error_setg(errp, QERR_UNSUPPORTED);
2922 }
2923 
2924 void qmp_guest_suspend_hybrid(Error **errp)
2925 {
2926     error_setg(errp, QERR_UNSUPPORTED);
2927 }
2928 
2929 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
2930 {
2931     error_setg(errp, QERR_UNSUPPORTED);
2932     return NULL;
2933 }
2934 
2935 GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp)
2936 {
2937     error_setg(errp, QERR_UNSUPPORTED);
2938     return NULL;
2939 }
2940 
2941 int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp)
2942 {
2943     error_setg(errp, QERR_UNSUPPORTED);
2944     return -1;
2945 }
2946 
2947 void qmp_guest_set_user_password(const char *username,
2948                                  const char *password,
2949                                  bool crypted,
2950                                  Error **errp)
2951 {
2952     error_setg(errp, QERR_UNSUPPORTED);
2953 }
2954 
2955 GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp)
2956 {
2957     error_setg(errp, QERR_UNSUPPORTED);
2958     return NULL;
2959 }
2960 
2961 GuestMemoryBlockResponseList *
2962 qmp_guest_set_memory_blocks(GuestMemoryBlockList *mem_blks, Error **errp)
2963 {
2964     error_setg(errp, QERR_UNSUPPORTED);
2965     return NULL;
2966 }
2967 
2968 GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp)
2969 {
2970     error_setg(errp, QERR_UNSUPPORTED);
2971     return NULL;
2972 }
2973 
2974 #endif
2975 
2976 #if !defined(CONFIG_FSFREEZE)
2977 
2978 GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp)
2979 {
2980     error_setg(errp, QERR_UNSUPPORTED);
2981     return NULL;
2982 }
2983 
2984 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp)
2985 {
2986     error_setg(errp, QERR_UNSUPPORTED);
2987 
2988     return 0;
2989 }
2990 
2991 int64_t qmp_guest_fsfreeze_freeze(Error **errp)
2992 {
2993     error_setg(errp, QERR_UNSUPPORTED);
2994 
2995     return 0;
2996 }
2997 
2998 int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
2999                                        strList *mountpoints,
3000                                        Error **errp)
3001 {
3002     error_setg(errp, QERR_UNSUPPORTED);
3003 
3004     return 0;
3005 }
3006 
3007 int64_t qmp_guest_fsfreeze_thaw(Error **errp)
3008 {
3009     error_setg(errp, QERR_UNSUPPORTED);
3010 
3011     return 0;
3012 }
3013 
3014 GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
3015 {
3016     error_setg(errp, QERR_UNSUPPORTED);
3017     return NULL;
3018 }
3019 
3020 #endif /* CONFIG_FSFREEZE */
3021 
3022 #if !defined(CONFIG_FSTRIM)
3023 GuestFilesystemTrimResponse *
3024 qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
3025 {
3026     error_setg(errp, QERR_UNSUPPORTED);
3027     return NULL;
3028 }
3029 #endif
3030 
3031 /* add unsupported commands to the blacklist */
3032 GList *ga_command_blacklist_init(GList *blacklist)
3033 {
3034 #if !defined(__linux__)
3035     {
3036         const char *list[] = {
3037             "guest-suspend-disk", "guest-suspend-ram",
3038             "guest-suspend-hybrid", "guest-network-get-interfaces",
3039             "guest-get-vcpus", "guest-set-vcpus",
3040             "guest-get-memory-blocks", "guest-set-memory-blocks",
3041             "guest-get-memory-block-size", "guest-get-memory-block-info",
3042             NULL};
3043         char **p = (char **)list;
3044 
3045         while (*p) {
3046             blacklist = g_list_append(blacklist, g_strdup(*p++));
3047         }
3048     }
3049 #endif
3050 
3051 #if !defined(CONFIG_FSFREEZE)
3052     {
3053         const char *list[] = {
3054             "guest-get-fsinfo", "guest-fsfreeze-status",
3055             "guest-fsfreeze-freeze", "guest-fsfreeze-freeze-list",
3056             "guest-fsfreeze-thaw", "guest-get-fsinfo",
3057             "guest-get-disks", NULL};
3058         char **p = (char **)list;
3059 
3060         while (*p) {
3061             blacklist = g_list_append(blacklist, g_strdup(*p++));
3062         }
3063     }
3064 #endif
3065 
3066 #if !defined(CONFIG_FSTRIM)
3067     blacklist = g_list_append(blacklist, g_strdup("guest-fstrim"));
3068 #endif
3069 
3070     blacklist = g_list_append(blacklist, g_strdup("guest-get-devices"));
3071 
3072     return blacklist;
3073 }
3074 
3075 /* register init/cleanup routines for stateful command groups */
3076 void ga_command_state_init(GAState *s, GACommandState *cs)
3077 {
3078 #if defined(CONFIG_FSFREEZE)
3079     ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup);
3080 #endif
3081 }
3082 
3083 #ifdef HAVE_UTMPX
3084 
3085 #define QGA_MICRO_SECOND_TO_SECOND 1000000
3086 
3087 static double ga_get_login_time(struct utmpx *user_info)
3088 {
3089     double seconds = (double)user_info->ut_tv.tv_sec;
3090     double useconds = (double)user_info->ut_tv.tv_usec;
3091     useconds /= QGA_MICRO_SECOND_TO_SECOND;
3092     return seconds + useconds;
3093 }
3094 
3095 GuestUserList *qmp_guest_get_users(Error **errp)
3096 {
3097     GHashTable *cache = NULL;
3098     GuestUserList *head = NULL, **tail = &head;
3099     struct utmpx *user_info = NULL;
3100     gpointer value = NULL;
3101     GuestUser *user = NULL;
3102     double login_time = 0;
3103 
3104     cache = g_hash_table_new(g_str_hash, g_str_equal);
3105     setutxent();
3106 
3107     for (;;) {
3108         user_info = getutxent();
3109         if (user_info == NULL) {
3110             break;
3111         } else if (user_info->ut_type != USER_PROCESS) {
3112             continue;
3113         } else if (g_hash_table_contains(cache, user_info->ut_user)) {
3114             value = g_hash_table_lookup(cache, user_info->ut_user);
3115             user = (GuestUser *)value;
3116             login_time = ga_get_login_time(user_info);
3117             /* We're ensuring the earliest login time to be sent */
3118             if (login_time < user->login_time) {
3119                 user->login_time = login_time;
3120             }
3121             continue;
3122         }
3123 
3124         user = g_new0(GuestUser, 1);
3125         user->user = g_strdup(user_info->ut_user);
3126         user->login_time = ga_get_login_time(user_info);
3127 
3128         g_hash_table_insert(cache, user->user, user);
3129 
3130         QAPI_LIST_APPEND(tail, user);
3131     }
3132     endutxent();
3133     g_hash_table_destroy(cache);
3134     return head;
3135 }
3136 
3137 #else
3138 
3139 GuestUserList *qmp_guest_get_users(Error **errp)
3140 {
3141     error_setg(errp, QERR_UNSUPPORTED);
3142     return NULL;
3143 }
3144 
3145 #endif
3146 
3147 /* Replace escaped special characters with theire real values. The replacement
3148  * is done in place -- returned value is in the original string.
3149  */
3150 static void ga_osrelease_replace_special(gchar *value)
3151 {
3152     gchar *p, *p2, quote;
3153 
3154     /* Trim the string at first space or semicolon if it is not enclosed in
3155      * single or double quotes. */
3156     if ((value[0] != '"') || (value[0] == '\'')) {
3157         p = strchr(value, ' ');
3158         if (p != NULL) {
3159             *p = 0;
3160         }
3161         p = strchr(value, ';');
3162         if (p != NULL) {
3163             *p = 0;
3164         }
3165         return;
3166     }
3167 
3168     quote = value[0];
3169     p2 = value;
3170     p = value + 1;
3171     while (*p != 0) {
3172         if (*p == '\\') {
3173             p++;
3174             switch (*p) {
3175             case '$':
3176             case '\'':
3177             case '"':
3178             case '\\':
3179             case '`':
3180                 break;
3181             default:
3182                 /* Keep literal backslash followed by whatever is there */
3183                 p--;
3184                 break;
3185             }
3186         } else if (*p == quote) {
3187             *p2 = 0;
3188             break;
3189         }
3190         *(p2++) = *(p++);
3191     }
3192 }
3193 
3194 static GKeyFile *ga_parse_osrelease(const char *fname)
3195 {
3196     gchar *content = NULL;
3197     gchar *content2 = NULL;
3198     GError *err = NULL;
3199     GKeyFile *keys = g_key_file_new();
3200     const char *group = "[os-release]\n";
3201 
3202     if (!g_file_get_contents(fname, &content, NULL, &err)) {
3203         slog("failed to read '%s', error: %s", fname, err->message);
3204         goto fail;
3205     }
3206 
3207     if (!g_utf8_validate(content, -1, NULL)) {
3208         slog("file is not utf-8 encoded: %s", fname);
3209         goto fail;
3210     }
3211     content2 = g_strdup_printf("%s%s", group, content);
3212 
3213     if (!g_key_file_load_from_data(keys, content2, -1, G_KEY_FILE_NONE,
3214                                    &err)) {
3215         slog("failed to parse file '%s', error: %s", fname, err->message);
3216         goto fail;
3217     }
3218 
3219     g_free(content);
3220     g_free(content2);
3221     return keys;
3222 
3223 fail:
3224     g_error_free(err);
3225     g_free(content);
3226     g_free(content2);
3227     g_key_file_free(keys);
3228     return NULL;
3229 }
3230 
3231 GuestOSInfo *qmp_guest_get_osinfo(Error **errp)
3232 {
3233     GuestOSInfo *info = NULL;
3234     struct utsname kinfo;
3235     GKeyFile *osrelease = NULL;
3236     const char *qga_os_release = g_getenv("QGA_OS_RELEASE");
3237 
3238     info = g_new0(GuestOSInfo, 1);
3239 
3240     if (uname(&kinfo) != 0) {
3241         error_setg_errno(errp, errno, "uname failed");
3242     } else {
3243         info->has_kernel_version = true;
3244         info->kernel_version = g_strdup(kinfo.version);
3245         info->has_kernel_release = true;
3246         info->kernel_release = g_strdup(kinfo.release);
3247         info->has_machine = true;
3248         info->machine = g_strdup(kinfo.machine);
3249     }
3250 
3251     if (qga_os_release != NULL) {
3252         osrelease = ga_parse_osrelease(qga_os_release);
3253     } else {
3254         osrelease = ga_parse_osrelease("/etc/os-release");
3255         if (osrelease == NULL) {
3256             osrelease = ga_parse_osrelease("/usr/lib/os-release");
3257         }
3258     }
3259 
3260     if (osrelease != NULL) {
3261         char *value;
3262 
3263 #define GET_FIELD(field, osfield) do { \
3264     value = g_key_file_get_value(osrelease, "os-release", osfield, NULL); \
3265     if (value != NULL) { \
3266         ga_osrelease_replace_special(value); \
3267         info->has_ ## field = true; \
3268         info->field = value; \
3269     } \
3270 } while (0)
3271         GET_FIELD(id, "ID");
3272         GET_FIELD(name, "NAME");
3273         GET_FIELD(pretty_name, "PRETTY_NAME");
3274         GET_FIELD(version, "VERSION");
3275         GET_FIELD(version_id, "VERSION_ID");
3276         GET_FIELD(variant, "VARIANT");
3277         GET_FIELD(variant_id, "VARIANT_ID");
3278 #undef GET_FIELD
3279 
3280         g_key_file_free(osrelease);
3281     }
3282 
3283     return info;
3284 }
3285 
3286 GuestDeviceInfoList *qmp_guest_get_devices(Error **errp)
3287 {
3288     error_setg(errp, QERR_UNSUPPORTED);
3289 
3290     return NULL;
3291 }
3292