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