linux.scm 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
  3. ;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
  4. ;;; Copyright © 2020, 2023 Efraim Flashner <efraim@flashner.co.il>
  5. ;;; Copyright © 2021 raid5atemyhomework <raid5atemyhomework@protonmail.com>
  6. ;;; Copyright © 2021 B. Wilson <elaexuotee@wilsonb.com>
  7. ;;; Copyright © 2022 Josselin Poiret <dev@jpoiret.xyz>
  8. ;;; Copyright © 2023 Bruno Victal <mirai@makinata.eu>
  9. ;;; Copyright © 2023 Felix Lechner <felix.lechner@lease-up.com>
  10. ;;;
  11. ;;; This file is part of GNU Guix.
  12. ;;;
  13. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  14. ;;; under the terms of the GNU General Public License as published by
  15. ;;; the Free Software Foundation; either version 3 of the License, or (at
  16. ;;; your option) any later version.
  17. ;;;
  18. ;;; GNU Guix is distributed in the hope that it will be useful, but
  19. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  20. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. ;;; GNU General Public License for more details.
  22. ;;;
  23. ;;; You should have received a copy of the GNU General Public License
  24. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  25. (define-module (gnu services linux)
  26. #:use-module (guix diagnostics)
  27. #:use-module (guix gexp)
  28. #:use-module (guix records)
  29. #:use-module (guix modules)
  30. #:use-module (guix i18n)
  31. #:use-module (guix ui)
  32. #:use-module (gnu services)
  33. #:use-module (gnu services admin)
  34. #:use-module (gnu services base)
  35. #:use-module (gnu services configuration)
  36. #:use-module (gnu services mcron)
  37. #:use-module (gnu services shepherd)
  38. #:use-module (gnu packages linux)
  39. #:use-module (srfi srfi-1)
  40. #:use-module (srfi srfi-26)
  41. #:use-module (srfi srfi-34)
  42. #:use-module (srfi srfi-35)
  43. #:use-module (ice-9 format)
  44. #:use-module (ice-9 match)
  45. #:export (earlyoom-configuration
  46. earlyoom-configuration?
  47. earlyoom-configuration-earlyoom
  48. earlyoom-configuration-minimum-available-memory
  49. earlyoom-configuration-minimum-free-swap
  50. earlyoom-configuration-prefer-regexp
  51. earlyoom-configuration-avoid-regexp
  52. earlyoom-configuration-memory-report-interval
  53. earlyoom-configuration-ignore-positive-oom-score-adj?
  54. earlyoom-configuration-show-debug-messages?
  55. earlyoom-configuration-send-notification-command
  56. earlyoom-service-type
  57. fstrim-configuration
  58. fstrim-configuration?
  59. fstrim-configuration-package
  60. fstrim-configuration-schedule
  61. fstrim-configuration-listed-in
  62. fstrim-configuration-verbose?
  63. fstrim-configuration-quiet-unsupported?
  64. fstrim-configuration-extra-arguments
  65. fstrim-service-type
  66. kernel-module-loader-service-type
  67. cachefilesd-configuration
  68. cachefilesd-configuration?
  69. cachefilesd-configuration-cachefilesd
  70. cachefilesd-configuration-debug-output?
  71. cachefilesd-configuration-use-syslog?
  72. cachefilesd-configuration-scan?
  73. cachefilesd-configuration-cache-directory
  74. cachefilesd-configuration-cache-name
  75. cachefilesd-configuration-security-context
  76. cachefilesd-configuration-pause-culling-for-block-percentage
  77. cachefilesd-configuration-pause-culling-for-file-percentage
  78. cachefilesd-configuration-resume-culling-for-block-percentage
  79. cachefilesd-configuration-resume-culling-for-file-percentage
  80. cachefilesd-configuration-pause-caching-for-block-percentage
  81. cachefilesd-configuration-pause-caching-for-file-percentage
  82. cachefilesd-configuration-log2-table-size
  83. cachefilesd-configuration-cull?
  84. cachefilesd-configuration-trace-function-entry-in-kernel-module
  85. cachefilesd-configuration-trace-function-exit-in-kernel-module
  86. cachefilesd-configuration-trace-internal-checkpoints-in-kernel-module
  87. cachefilesd-service-type
  88. rasdaemon-configuration
  89. rasdaemon-configuration?
  90. rasdaemon-configuration-record?
  91. rasdaemon-service-type
  92. zram-device-configuration
  93. zram-device-configuration?
  94. zram-device-configuration-size
  95. zram-device-configuration-compression-algorithm
  96. zram-device-configuration-memory-limit
  97. zram-device-configuration-priority
  98. zram-device-service-type))
  99. ;;;
  100. ;;; Early OOM daemon.
  101. ;;;
  102. (define-record-type* <earlyoom-configuration>
  103. earlyoom-configuration make-earlyoom-configuration
  104. earlyoom-configuration?
  105. (earlyoom earlyoom-configuration-earlyoom
  106. (default earlyoom))
  107. (minimum-available-memory earlyoom-configuration-minimum-available-memory
  108. (default 10)) ; in percent
  109. (minimum-free-swap earlyoom-configuration-minimum-free-swap
  110. (default 10)) ; in percent
  111. (prefer-regexp earlyoom-configuration-prefer-regexp ; <string>
  112. (default #f))
  113. (avoid-regexp earlyoom-configuration-avoid-regexp ; <string>
  114. (default #f))
  115. (memory-report-interval earlyoom-configuration-memory-report-interval
  116. (default 0)) ; in seconds; 0 means disabled
  117. (ignore-positive-oom-score-adj?
  118. earlyoom-configuration-ignore-positive-oom-score-adj? (default #f))
  119. (run-with-higher-priority? earlyoom-configuration-run-with-higher-priority?
  120. (default #f))
  121. (show-debug-messages? earlyoom-configuration-show-debug-messages?
  122. (default #f))
  123. (send-notification-command
  124. earlyoom-configuration-send-notification-command ; <string>
  125. (default #f)))
  126. (define (earlyoom-configuration->command-line-args config)
  127. "Translate a <earlyoom-configuration> object to its command line arguments
  128. representation."
  129. (match config
  130. (($ <earlyoom-configuration> earlyoom minimum-available-memory
  131. minimum-free-swap prefer-regexp avoid-regexp
  132. memory-report-interval
  133. ignore-positive-oom-score-adj?
  134. run-with-higher-priority? show-debug-messages?
  135. send-notification-command)
  136. `(,(file-append earlyoom "/bin/earlyoom")
  137. ,@(if minimum-available-memory
  138. (list "-m" (format #f "~s" minimum-available-memory))
  139. '())
  140. ,@(if minimum-free-swap
  141. (list "-s" (format #f "~s" minimum-free-swap))
  142. '())
  143. ,@(if prefer-regexp
  144. (list "--prefer" prefer-regexp)
  145. '())
  146. ,@(if avoid-regexp
  147. (list "--avoid" avoid-regexp)
  148. '())
  149. "-r" ,(format #f "~s" memory-report-interval)
  150. ,@(if ignore-positive-oom-score-adj?
  151. (list "-i")
  152. '())
  153. ,@(if run-with-higher-priority?
  154. (list "-p")
  155. '())
  156. ,@(if show-debug-messages?
  157. (list "-d")
  158. '())
  159. ,@(if send-notification-command
  160. (list "-N" send-notification-command)
  161. '())))))
  162. (define (earlyoom-shepherd-service config)
  163. (shepherd-service
  164. (documentation "Run the Early OOM daemon.")
  165. (provision '(earlyoom))
  166. (requirement '(user-processes))
  167. (start #~(make-forkexec-constructor
  168. '#$(earlyoom-configuration->command-line-args config)
  169. #:log-file "/var/log/earlyoom.log"))
  170. (stop #~(make-kill-destructor))))
  171. (define %earlyoom-log-rotation
  172. (list (log-rotation
  173. (files '("/var/log/earlyoom.log")))))
  174. (define earlyoom-service-type
  175. (service-type
  176. (name 'earlyoom)
  177. (default-value (earlyoom-configuration))
  178. (extensions
  179. (list (service-extension shepherd-root-service-type
  180. (compose list earlyoom-shepherd-service))
  181. (service-extension rottlog-service-type
  182. (const %earlyoom-log-rotation))))
  183. (description "Run @command{earlyoom}, a daemon that quickly responds to
  184. @acronym{OOM, out-of-memory} conditions by terminating relevant processes.")))
  185. ;;;
  186. ;;; fstrim
  187. ;;;
  188. (define (mcron-time? x)
  189. (or (procedure? x) (string? x) (list? x)))
  190. (define-maybe list-of-strings (prefix fstrim-))
  191. (define (fstrim-serialize-boolean field-name value)
  192. (list (format #f "~:[~;--~a~]" value
  193. ;; Drop trailing '?' character.
  194. (string-drop-right (symbol->string field-name) 1))))
  195. (define (fstrim-serialize-list-of-strings field-name value)
  196. (list (string-append "--" (symbol->string field-name))
  197. #~(string-join '#$value ":")))
  198. (define-configuration fstrim-configuration
  199. (package
  200. (file-like util-linux)
  201. "The package providing the @command{fstrim} command."
  202. empty-serializer)
  203. (schedule
  204. (mcron-time "0 0 * * 0")
  205. "Schedule for launching @command{fstrim}. This can be a procedure, a list
  206. or a string. For additional information, see @ref{Guile Syntax,,
  207. Job specification, mcron, the mcron manual}. By default this is set to run
  208. weekly on Sunday at 00:00."
  209. empty-serializer)
  210. ;; The following are fstrim-related options.
  211. (listed-in
  212. (maybe-list-of-strings '("/etc/fstab" "/proc/self/mountinfo"))
  213. ;; Note: documentation sourced from the fstrim manpage.
  214. "List of files in fstab or kernel mountinfo format. All missing or
  215. empty files are silently ignored. The evaluation of the list @emph{stops}
  216. after the first non-empty file. File systems with @code{X-fstrim.notrim} mount
  217. option in fstab are skipped.")
  218. (verbose?
  219. (boolean #t)
  220. "Verbose execution.")
  221. (quiet-unsupported?
  222. (boolean #t)
  223. "Suppress error messages if trim operation (ioctl) is unsupported.")
  224. (extra-arguments
  225. maybe-list-of-strings
  226. "Extra options to append to @command{fstrim} (run @samp{man fstrim} for
  227. more information)."
  228. (serializer
  229. (lambda (_ value)
  230. (if (maybe-value-set? value)
  231. value '()))))
  232. (prefix fstrim-))
  233. (define (serialize-fstrim-configuration config)
  234. (concatenate
  235. (filter list?
  236. (map (lambda (field)
  237. ((configuration-field-serializer field)
  238. (configuration-field-name field)
  239. ((configuration-field-getter field) config)))
  240. fstrim-configuration-fields))))
  241. (define (fstrim-mcron-job config)
  242. (match-record config <fstrim-configuration> (package schedule)
  243. #~(job
  244. ;; Note: The “if” below is to ensure that
  245. ;; lists are ungexp'd correctly since @var{schedule}
  246. ;; can be either a procedure, a string or a list.
  247. #$(if (list? schedule)
  248. #~'(#$@schedule)
  249. schedule)
  250. (lambda ()
  251. (system* #$(file-append package "/sbin/fstrim")
  252. #$@(serialize-fstrim-configuration config)))
  253. "fstrim")))
  254. (define fstrim-service-type
  255. (service-type
  256. (name 'fstrim)
  257. (extensions
  258. (list (service-extension mcron-service-type
  259. (compose list fstrim-mcron-job))))
  260. (description "Discard unused blocks from file systems.")
  261. (default-value (fstrim-configuration))))
  262. ;;;
  263. ;;; Kernel module loader.
  264. ;;;
  265. (define kernel-module-loader-shepherd-service
  266. (match-lambda
  267. ((and (? list? kernel-modules) ((? string?) ...))
  268. (shepherd-service
  269. (documentation "Load kernel modules.")
  270. (provision '(kernel-module-loader))
  271. (requirement '())
  272. (one-shot? #t)
  273. (modules `((srfi srfi-1)
  274. (srfi srfi-34)
  275. (srfi srfi-35)
  276. (rnrs io ports)
  277. ,@%default-modules))
  278. (start
  279. #~(lambda _
  280. (cond
  281. ((null? '#$kernel-modules) #t)
  282. ((file-exists? "/proc/sys/kernel/modprobe")
  283. (let ((modprobe (call-with-input-file
  284. "/proc/sys/kernel/modprobe" get-line)))
  285. (guard (c ((message-condition? c)
  286. (format (current-error-port) "~a~%"
  287. (condition-message c))
  288. #f))
  289. (every (lambda (module)
  290. (invoke/quiet modprobe "--" module))
  291. '#$kernel-modules))))
  292. (else
  293. (format (current-error-port) "error: ~a~%"
  294. "Kernel is missing loadable module support.")
  295. #f))))))))
  296. (define kernel-module-loader-service-type
  297. (service-type
  298. (name 'kernel-module-loader)
  299. (description "Load kernel modules.")
  300. (extensions
  301. (list (service-extension shepherd-root-service-type
  302. (compose list kernel-module-loader-shepherd-service))))
  303. (compose concatenate)
  304. (extend append)
  305. (default-value '())))
  306. ;;;
  307. ;;; Cachefilesd, an FS-Cache daemon
  308. ;;;
  309. (define (serialize-string variable-symbol value)
  310. #~(format #f "~a ~a~%" #$(symbol->string variable-symbol) #$value))
  311. (define-maybe string)
  312. (define (non-negative-integer? val)
  313. (and (exact-integer? val) (not (negative? val))))
  314. (define (serialize-non-negative-integer variable-symbol value)
  315. #~(format #f "~a ~d~%" #$(symbol->string variable-symbol) #$value))
  316. (define-maybe non-negative-integer)
  317. (define (make-option-serializer option-symbol)
  318. (lambda (variable-symbol text)
  319. (if (maybe-value-set? text)
  320. #~(format #f "~a ~a~%" #$(symbol->string option-symbol) #$text)
  321. "")))
  322. (define (make-percentage-threshold-serializer threshold-symbol)
  323. (lambda (variable-symbol percentage)
  324. (if (maybe-value-set? percentage)
  325. #~(format #f "~a ~a%~%" #$(symbol->string threshold-symbol) #$percentage)
  326. "")))
  327. (define-configuration cachefilesd-configuration
  328. (cachefilesd
  329. (file-like cachefilesd)
  330. "The cachefilesd package to use."
  331. (serializer empty-serializer))
  332. ;; command-line options
  333. (debug-output?
  334. (boolean #f)
  335. "Print debugging output to stderr."
  336. (serializer empty-serializer))
  337. (use-syslog?
  338. (boolean #t)
  339. "Log to syslog facility instead of stdout."
  340. (serializer empty-serializer))
  341. ;; culling is part of the configuration file
  342. ;; despite the name of the command-line option
  343. (scan?
  344. (boolean #t)
  345. "Scan for cachable objects."
  346. (serializer empty-serializer))
  347. ;; sole required field in the configuration file
  348. (cache-directory
  349. maybe-string
  350. "Location of the cache directory."
  351. (serializer (make-option-serializer 'dir)))
  352. (cache-name
  353. (maybe-string "CacheFiles")
  354. "Name of cache (keep unique)."
  355. (serializer (make-option-serializer 'tag)))
  356. (security-context
  357. maybe-string
  358. "SELinux security context."
  359. (serializer (make-option-serializer 'secctx)))
  360. ;; percentage thresholds in the configuration file
  361. (pause-culling-for-block-percentage
  362. (maybe-non-negative-integer 7)
  363. "Pause culling when available blocks exceed this percentage."
  364. (serializer (make-percentage-threshold-serializer 'brun)))
  365. (pause-culling-for-file-percentage
  366. (maybe-non-negative-integer 7)
  367. "Pause culling when available files exceed this percentage."
  368. (serializer (make-percentage-threshold-serializer 'frun)))
  369. (resume-culling-for-block-percentage
  370. (maybe-non-negative-integer 5)
  371. "Start culling when available blocks drop below this percentage."
  372. (serializer (make-percentage-threshold-serializer 'bcull)))
  373. (resume-culling-for-file-percentage
  374. (maybe-non-negative-integer 5)
  375. "Start culling when available files drop below this percentage."
  376. (serializer (make-percentage-threshold-serializer 'fcull)))
  377. (pause-caching-for-block-percentage
  378. (maybe-non-negative-integer 1)
  379. "Pause further allocations when available blocks drop below this percentage."
  380. (serializer (make-percentage-threshold-serializer 'bstop)))
  381. (pause-caching-for-file-percentage
  382. (maybe-non-negative-integer 1)
  383. "Pause further allocations when available files drop below this percentage."
  384. (serializer (make-percentage-threshold-serializer 'fstop)))
  385. ;; run time optimizations in the configuration file
  386. (log2-table-size
  387. (maybe-non-negative-integer 12)
  388. "Size of tables holding cullable objects in logarithm of base 2."
  389. (serializer (make-option-serializer 'culltable)))
  390. (cull?
  391. (boolean #t)
  392. "Create free space by culling (consumes system load)."
  393. (serializer
  394. (lambda (variable-symbol value)
  395. (if value "" "nocull\n"))))
  396. ;; kernel module debugging in the configuration file
  397. (trace-function-entry-in-kernel-module?
  398. (boolean #f)
  399. "Trace function entry in the kernel module (for debugging)."
  400. (serializer empty-serializer))
  401. (trace-function-exit-in-kernel-module?
  402. (boolean #f)
  403. "Trace function exit in the kernel module (for debugging)."
  404. (serializer empty-serializer))
  405. (trace-internal-checkpoints-in-kernel-module?
  406. (boolean #f)
  407. "Trace internal checkpoints in the kernel module (for debugging)."
  408. (serializer empty-serializer)))
  409. (define (serialize-cachefilesd-configuration configuration)
  410. (mixed-text-file
  411. "cachefilesd.conf"
  412. (serialize-configuration configuration cachefilesd-configuration-fields)))
  413. (define (cachefilesd-shepherd-service config)
  414. "Return a list of <shepherd-service> for cachefilesd for CONFIG."
  415. (match-record
  416. config <cachefilesd-configuration> (cachefilesd
  417. debug-output?
  418. use-syslog?
  419. scan?
  420. cache-directory)
  421. (let ((configuration-file (serialize-cachefilesd-configuration config)))
  422. (shepherd-service
  423. (documentation "Run the cachefilesd daemon for FS-Cache.")
  424. (provision '(cachefilesd))
  425. (requirement (append '(file-systems)
  426. (if use-syslog? '(syslogd) '())))
  427. (start #~(begin
  428. (and=> #$(maybe-value cache-directory) mkdir-p)
  429. (make-forkexec-constructor
  430. `(#$(file-append cachefilesd "/sbin/cachefilesd")
  431. ;; do not detach
  432. "-n"
  433. #$@(if debug-output? '("-d") '())
  434. #$@(if use-syslog? '() '("-s"))
  435. #$@(if scan? '() '("-N"))
  436. "-f" #$configuration-file))))
  437. (stop #~(make-kill-destructor))))))
  438. (define cachefilesd-service-type
  439. (service-type
  440. (name 'cachefilesd)
  441. (description
  442. "Run the file system cache daemon @command{cachefilesd}, which relies on
  443. the Linux @code{cachefiles} module.")
  444. (extensions
  445. (list (service-extension kernel-module-loader-service-type
  446. (const '("cachefiles")))
  447. (service-extension shepherd-root-service-type
  448. (compose list cachefilesd-shepherd-service))))
  449. (default-value (cachefilesd-configuration))))
  450. ;;;
  451. ;;; Reliability, Availability, and Serviceability (RAS) daemon
  452. ;;;
  453. (define-record-type* <rasdaemon-configuration>
  454. rasdaemon-configuration make-rasdaemon-configuration
  455. rasdaemon-configuration?
  456. (record? rasdaemon-configuration-record? (default #f)))
  457. (define (rasdaemon-configuration->command-line-args config)
  458. "Translate <rasdaemon-configuration> to its command line arguments
  459. representation"
  460. (let ((record? (rasdaemon-configuration-record? config)))
  461. `(,(file-append rasdaemon "/sbin/rasdaemon")
  462. "--foreground" ,@(if record? '("--record") '()))))
  463. (define (rasdaemon-activation config)
  464. (let ((record? (rasdaemon-configuration-record? config))
  465. (rasdaemon-dir "/var/lib/rasdaemon"))
  466. (with-imported-modules '((guix build utils))
  467. #~(if #$record? (mkdir-p #$rasdaemon-dir)))))
  468. (define (rasdaemon-shepherd-service config)
  469. (shepherd-service
  470. (documentation "Run rasdaemon")
  471. (provision '(rasdaemon))
  472. (requirement '(syslogd))
  473. (start #~(make-forkexec-constructor
  474. '#$(rasdaemon-configuration->command-line-args config)))
  475. (stop #~(make-kill-destructor))))
  476. (define rasdaemon-service-type
  477. (service-type
  478. (name 'rasdaemon)
  479. (default-value (rasdaemon-configuration))
  480. (extensions
  481. (list (service-extension shepherd-root-service-type
  482. (compose list rasdaemon-shepherd-service))
  483. (service-extension activation-service-type rasdaemon-activation)))
  484. (compose concatenate)
  485. (description "Run @command{rasdaemon}, the RAS monitor")))
  486. ;;;
  487. ;;; Zram device
  488. ;;;
  489. (define-record-type* <zram-device-configuration>
  490. zram-device-configuration make-zram-device-configuration
  491. zram-device-configuration?
  492. (size zram-device-configuration-size
  493. (default "1G")) ; string or integer
  494. (compression-algorithm zram-device-configuration-compression-algorithm
  495. (default 'lzo)) ; symbol
  496. (memory-limit zram-device-configuration-memory-limit
  497. (default 0)) ; string or integer
  498. (priority zram-device-configuration-priority
  499. (default #f) ; integer | #f
  500. (delayed) ; to avoid printing the deprecation
  501. ; warning multiple times
  502. (sanitize warn-zram-priority-change)))
  503. (define-with-syntax-properties
  504. (warn-zram-priority-change (priority properties))
  505. (if (eqv? priority -1)
  506. (begin
  507. (warning (source-properties->location properties)
  508. (G_ "using -1 for zram priority is deprecated~%"))
  509. (display-hint (G_ "Use #f or leave as default instead (@pxref{Linux \
  510. Services})."))
  511. #f)
  512. priority))
  513. (define (zram-device-configuration->udev-string config)
  514. "Translate a <zram-device-configuration> into a string which can be
  515. placed in a udev rules file."
  516. (match config
  517. (($ <zram-device-configuration> size compression-algorithm memory-limit priority)
  518. (string-append
  519. "KERNEL==\"zram0\", "
  520. "ATTR{comp_algorithm}=\"" (symbol->string compression-algorithm) "\" "
  521. (if (not (or (equal? "0" size)
  522. (equal? 0 size)))
  523. (string-append "ATTR{disksize}=\"" (if (number? size)
  524. (number->string size)
  525. size)
  526. "\" ")
  527. "")
  528. (if (not (or (equal? "0" memory-limit)
  529. (equal? 0 memory-limit)))
  530. (string-append "ATTR{mem_limit}=\"" (if (number? memory-limit)
  531. (number->string memory-limit)
  532. memory-limit)
  533. "\" ")
  534. "")
  535. "RUN+=\"/run/current-system/profile/sbin/mkswap /dev/zram0\" "
  536. "RUN+=\"/run/current-system/profile/sbin/swapon "
  537. ;; TODO: Revert to simply use 'priority' after removing the deprecation
  538. ;; warning and the delayed property of the field.
  539. (let ((priority* (force priority)))
  540. (if priority*
  541. (format #f "--priority ~a " priority*)
  542. ""))
  543. "/dev/zram0\"\n"))))
  544. (define %zram-device-config
  545. `("modprobe.d/zram.conf"
  546. ,(plain-file "zram.conf"
  547. "options zram num_devices=1")))
  548. (define (zram-device-udev-rule config)
  549. (file->udev-rule "99-zram.rules"
  550. (plain-file "99-zram.rules"
  551. (zram-device-configuration->udev-string config))))
  552. (define zram-device-service-type
  553. (service-type
  554. (name 'zram)
  555. (default-value (zram-device-configuration))
  556. (extensions
  557. (list (service-extension kernel-module-loader-service-type
  558. (const (list "zram")))
  559. (service-extension etc-service-type
  560. (const (list %zram-device-config)))
  561. (service-extension udev-service-type
  562. (compose list zram-device-udev-rule))))
  563. (description "Creates a zram swap device.")))