diff options
| author | Christopher Baines <mail@cbaines.net> | 2026-08-07 20:34:24 +0100 |
|---|---|---|
| committer | Christopher Baines <mail@cbaines.net> | 2026-08-21 16:42:58 +0100 |
| commit | dd12ee28474c2e4b128e8ab37cc4113a2088b604 (patch) | |
| tree | dccbb075f59028b545eb860c24be269bf4481b1a /gnu | |
| parent | c3832cd497a8fcd87e84878c6ee3bbc10f42d0ca (diff) | |
gnu: services: pm: Add hd-idle.
* gnu/services/pm.scm: (hd-idle-disk, hd-idle-disk?, hd-idle-configuration, hd-idle-configuration?):
New prodedures.
(hd-idle-service-type): New variable.
* doc/guix.texi (Power Management Services): Document it.
Change-Id: I205b9a8de9aa8a15314d03962582aa3ae245a31e
Diffstat (limited to 'gnu')
| -rw-r--r-- | gnu/services/pm.scm | 143 |
1 files changed, 142 insertions, 1 deletions
diff --git a/gnu/services/pm.scm b/gnu/services/pm.scm index 12f05b4b335..ab867f7cad0 100644 --- a/gnu/services/pm.scm +++ b/gnu/services/pm.scm | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #:use-module (guix records) | 27 | #:use-module (guix records) |
| 28 | #:use-module (gnu packages admin) | 28 | #:use-module (gnu packages admin) |
| 29 | #:use-module (gnu packages freedesktop) | 29 | #:use-module (gnu packages freedesktop) |
| 30 | #:use-module (gnu packages hardware) | ||
| 30 | #:use-module (gnu packages linux) | 31 | #:use-module (gnu packages linux) |
| 31 | #:use-module (gnu services) | 32 | #:use-module (gnu services) |
| 32 | #:use-module (gnu services base) | 33 | #:use-module (gnu services base) |
| @@ -44,7 +45,13 @@ | |||
| 44 | thermald-service-type | 45 | thermald-service-type |
| 45 | 46 | ||
| 46 | powertop-configuration | 47 | powertop-configuration |
| 47 | powertop-service-type)) | 48 | powertop-service-type |
| 49 | |||
| 50 | hd-idle-disk | ||
| 51 | hd-idle-disk? | ||
| 52 | hd-idle-configuration | ||
| 53 | hd-idle-configuration? | ||
| 54 | hd-idle-service-type)) | ||
| 48 | 55 | ||
| 49 | ;;; | 56 | ;;; |
| 50 | ;;; power-profiles-daemon | 57 | ;;; power-profiles-daemon |
| @@ -579,3 +586,137 @@ prevent overheating."))) | |||
| 579 | (default-value (powertop-configuration)) | 586 | (default-value (powertop-configuration)) |
| 580 | (description "Tune power-related kernel parameters to reduce energy | 587 | (description "Tune power-related kernel parameters to reduce energy |
| 581 | consumption."))) | 588 | consumption."))) |
| 589 | |||
| 590 | |||
| 591 | |||
| 592 | ;;; | ||
| 593 | ;;; hd-idle | ||
| 594 | ;;; | ||
| 595 | ;;; Spins down hard disks that have been idle for a while. | ||
| 596 | |||
| 597 | (define (hd-idle-command-type? val) | ||
| 598 | (memq val '(scsi ata))) | ||
| 599 | (define-maybe/no-serialization hd-idle-command-type) | ||
| 600 | |||
| 601 | (define (hd-idle-power-condition? val) | ||
| 602 | (and (exact-integer? val) (<= 0 val 15))) | ||
| 603 | (define-maybe/no-serialization hd-idle-power-condition) | ||
| 604 | |||
| 605 | (define (hd-idle-symlink-policy? val) | ||
| 606 | (and (exact-integer? val) (<= 0 val 1))) | ||
| 607 | |||
| 608 | (define-configuration/no-serialization hd-idle-disk | ||
| 609 | (name | ||
| 610 | string | ||
| 611 | "The device to configure, either a name under @file{/dev} such as | ||
| 612 | @code{\"sda\"}, or an absolute file name such as | ||
| 613 | @code{\"/dev/disk/by-uuid/1234-5678\"}.") | ||
| 614 | |||
| 615 | (idle-time | ||
| 616 | maybe-non-negative-integer | ||
| 617 | "Number of seconds this disk must be idle before it is spun down.") | ||
| 618 | |||
| 619 | (command-type | ||
| 620 | maybe-hd-idle-command-type | ||
| 621 | "The command used to spin this disk down, either @code{'scsi} or | ||
| 622 | @code{'ata}.") | ||
| 623 | |||
| 624 | (power-condition | ||
| 625 | maybe-hd-idle-power-condition | ||
| 626 | "The power condition to use for this disk.")) | ||
| 627 | |||
| 628 | (define list-of-hd-idle-disks? | ||
| 629 | (list-of hd-idle-disk?)) | ||
| 630 | |||
| 631 | (define-configuration/no-serialization hd-idle-configuration | ||
| 632 | (idle-time | ||
| 633 | (non-negative-integer 600) | ||
| 634 | "Number of seconds a disk must be idle before it is spun down. A value | ||
| 635 | of @code{0} disables spinning down.") | ||
| 636 | |||
| 637 | (command-type | ||
| 638 | (hd-idle-command-type 'scsi) | ||
| 639 | "The command used to spin disks down, either @code{'scsi} or @code{'ata}.") | ||
| 640 | |||
| 641 | (power-condition | ||
| 642 | (hd-idle-power-condition 0) | ||
| 643 | "The power condition passed to the @acronym{SCSI, Small Computer System | ||
| 644 | Interface} @code{START STOP UNIT} command, an integer between @code{0} and | ||
| 645 | @code{15}. It is ignored when @code{command-type} is @code{'ata}.") | ||
| 646 | |||
| 647 | (symlink-policy | ||
| 648 | (hd-idle-symlink-policy 0) | ||
| 649 | "How to resolve disk names that are symbolic links. @code{0} resolves | ||
| 650 | them once at startup, whereas with @code{1} symlinks are also resolved on | ||
| 651 | runtime until success.") | ||
| 652 | |||
| 653 | (log-file | ||
| 654 | maybe-string | ||
| 655 | "A file name to which hd-idle logs disk spin-up and spin-down events, for | ||
| 656 | instance @code{\"/var/log/hd-idle.log\"}.") | ||
| 657 | |||
| 658 | (ignore-spin-down-detection? | ||
| 659 | (boolean #f) | ||
| 660 | "Whether to skip detection of disks that were spun down by some other | ||
| 661 | means.") | ||
| 662 | |||
| 663 | (debug? | ||
| 664 | (boolean #f) | ||
| 665 | "Whether to log the disk statistics that hd-idle reads on each poll.") | ||
| 666 | |||
| 667 | (disks | ||
| 668 | (list-of-hd-idle-disks '()) | ||
| 669 | "A list of @code{hd-idle-disk} records describing per-disk overrides. | ||
| 670 | Disks that are not listed here are still managed, using the values above.") | ||
| 671 | |||
| 672 | (hd-idle | ||
| 673 | (file-like hd-idle) | ||
| 674 | "The hd-idle package to use.")) | ||
| 675 | |||
| 676 | (define (hd-idle-disk-arguments disk) | ||
| 677 | (match-record disk <hd-idle-disk> | ||
| 678 | (name idle-time command-type power-condition) | ||
| 679 | `("-a" ,name | ||
| 680 | ,@(if (maybe-value-set? idle-time) | ||
| 681 | (list "-i" (number->string idle-time)) | ||
| 682 | '()) | ||
| 683 | ,@(if (maybe-value-set? command-type) | ||
| 684 | (list "-c" (symbol->string command-type)) | ||
| 685 | '()) | ||
| 686 | ,@(if (maybe-value-set? power-condition) | ||
| 687 | (list "-p" (number->string power-condition)) | ||
| 688 | '())))) | ||
| 689 | |||
| 690 | (define (hd-idle-arguments config) | ||
| 691 | (match-record config <hd-idle-configuration> | ||
| 692 | (idle-time command-type power-condition symlink-policy | ||
| 693 | log-file ignore-spin-down-detection? debug? disks) | ||
| 694 | `("-i" ,(number->string idle-time) | ||
| 695 | "-c" ,(symbol->string command-type) | ||
| 696 | "-p" ,(number->string power-condition) | ||
| 697 | "-s" ,(number->string symlink-policy) | ||
| 698 | ,@(if (maybe-value-set? log-file) (list "-l" log-file) '()) | ||
| 699 | ,@(if ignore-spin-down-detection? '("-I") '()) | ||
| 700 | ,@(if debug? '("-d") '()) | ||
| 701 | ,@(append-map hd-idle-disk-arguments disks)))) | ||
| 702 | |||
| 703 | (define (hd-idle-shepherd-service config) | ||
| 704 | (list | ||
| 705 | (shepherd-service | ||
| 706 | (provision '(hd-idle)) | ||
| 707 | (requirement '(user-processes udev)) | ||
| 708 | (documentation "Spin down idle hard disks.") | ||
| 709 | (start #~(make-forkexec-constructor | ||
| 710 | (list #$(file-append (hd-idle-configuration-hd-idle config) | ||
| 711 | "/bin/hd-idle") | ||
| 712 | #$@(hd-idle-arguments config)))) | ||
| 713 | (stop #~(make-kill-destructor))))) | ||
| 714 | |||
| 715 | (define hd-idle-service-type | ||
| 716 | (service-type | ||
| 717 | (name 'hd-idle) | ||
| 718 | (extensions (list (service-extension shepherd-root-service-type | ||
| 719 | hd-idle-shepherd-service))) | ||
| 720 | (default-value (hd-idle-configuration)) | ||
| 721 | (description "Run @command{hd-idle}, which spins down hard disks that have | ||
| 722 | not been accessed for a configurable period of time."))) | ||
