38 |
38 |
#include <sys/socket.h>
|
39 |
39 |
#include <net/if.h>
|
40 |
40 |
|
41 |
|
#if defined(__linux__) && defined(FIFREEZE)
|
|
41 |
#ifdef FIFREEZE
|
42 |
42 |
#define CONFIG_FSFREEZE
|
43 |
43 |
#endif
|
|
44 |
#ifdef FITRIM
|
|
45 |
#define CONFIG_FSTRIM
|
|
46 |
#endif
|
44 |
47 |
#endif
|
45 |
48 |
|
46 |
49 |
void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
|
... | ... | |
312 |
315 |
/* linux-specific implementations. avoid this if at all possible. */
|
313 |
316 |
#if defined(__linux__)
|
314 |
317 |
|
315 |
|
#if defined(CONFIG_FSFREEZE)
|
316 |
|
|
|
318 |
#if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM)
|
317 |
319 |
typedef struct FsMount {
|
318 |
320 |
char *dirname;
|
319 |
321 |
char *devtype;
|
... | ... | |
378 |
380 |
|
379 |
381 |
return 0;
|
380 |
382 |
}
|
|
383 |
#endif
|
|
384 |
|
|
385 |
#if defined(CONFIG_FSFREEZE)
|
381 |
386 |
|
382 |
387 |
/*
|
383 |
388 |
* Return status of freeze/thaw
|
... | ... | |
525 |
530 |
}
|
526 |
531 |
#endif /* CONFIG_FSFREEZE */
|
527 |
532 |
|
|
533 |
#if defined(CONFIG_FSTRIM)
|
|
534 |
/*
|
|
535 |
* Walk list of mounted file systems in the guest, and trim them.
|
|
536 |
*/
|
|
537 |
void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err)
|
|
538 |
{
|
|
539 |
int ret = 0;
|
|
540 |
FsMountList mounts;
|
|
541 |
struct FsMount *mount;
|
|
542 |
int fd;
|
|
543 |
char err_msg[512];
|
|
544 |
struct fstrim_range r = {
|
|
545 |
.start = 0,
|
|
546 |
.len = -1,
|
|
547 |
.minlen = has_minimum ? minimum : 0,
|
|
548 |
};
|
|
549 |
|
|
550 |
slog("guest-fstrim called");
|
|
551 |
|
|
552 |
QTAILQ_INIT(&mounts);
|
|
553 |
ret = build_fs_mount_list(&mounts);
|
|
554 |
if (ret < 0) {
|
|
555 |
return;
|
|
556 |
}
|
|
557 |
|
|
558 |
QTAILQ_FOREACH(mount, &mounts, next) {
|
|
559 |
fd = qemu_open(mount->dirname, O_RDONLY);
|
|
560 |
if (fd == -1) {
|
|
561 |
sprintf(err_msg, "failed to open %s, %s", mount->dirname,
|
|
562 |
strerror(errno));
|
|
563 |
error_set(err, QERR_QGA_COMMAND_FAILED, err_msg);
|
|
564 |
goto error;
|
|
565 |
}
|
|
566 |
|
|
567 |
/* We try to cull filesytems we know won't work in advance, but other
|
|
568 |
* filesytems may not implement fstrim for less obvious reasons. These
|
|
569 |
* will report EOPNOTSUPP; we simply ignore these errors. Any other
|
|
570 |
* error means an unexpected error, so return it in those cases. In
|
|
571 |
* some other cases ENOTTY will be reported (e.g. CD-ROMs).
|
|
572 |
*/
|
|
573 |
ret = ioctl(fd, FITRIM, &r);
|
|
574 |
if (ret == -1) {
|
|
575 |
if (errno != ENOTTY && errno != EOPNOTSUPP) {
|
|
576 |
sprintf(err_msg, "failed to trim %s, %s",
|
|
577 |
mount->dirname, strerror(errno));
|
|
578 |
error_set(err, QERR_QGA_COMMAND_FAILED, err_msg);
|
|
579 |
close(fd);
|
|
580 |
goto error;
|
|
581 |
}
|
|
582 |
}
|
|
583 |
close(fd);
|
|
584 |
}
|
|
585 |
|
|
586 |
error:
|
|
587 |
free_fs_mount_list(&mounts);
|
|
588 |
}
|
|
589 |
#endif /* CONFIG_FSTRIM */
|
|
590 |
|
|
591 |
|
528 |
592 |
#define LINUX_SYS_STATE_FILE "/sys/power/state"
|
529 |
593 |
#define SUSPEND_SUPPORTED 0
|
530 |
594 |
#define SUSPEND_NOT_SUPPORTED 1
|
... | ... | |
918 |
982 |
|
919 |
983 |
return 0;
|
920 |
984 |
}
|
|
985 |
#endif /* CONFIG_FSFREEZE */
|
|
986 |
|
|
987 |
#if !defined(CONFIG_FSTRIM)
|
|
988 |
void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err)
|
|
989 |
{
|
|
990 |
error_set(err, QERR_UNSUPPORTED);
|
921 |
991 |
|
|
992 |
return;
|
|
993 |
}
|
922 |
994 |
#endif
|
923 |
995 |
|
924 |
996 |
/* register init/cleanup routines for stateful command groups */
|