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