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