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