Revision eab5fd59 qga/commands-posix.c
b/qga/commands-posix.c | ||
---|---|---|
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 */ |
Also available in: Unified diff