guix_mirror_bot pushed a commit to branch master
in repository guix.
commit 7445776b7e7eeeb1a15df7eb9c15585cf410fae9
Author: Ludovic Courtès <[email protected]>
AuthorDate: Mon Sep 1 14:47:01 2025 +0200
gc: Open a connection to the daemon only when strictly necessary.
Fixes guix/guix#1901.
Previously, ‘guix gc --list-busy’ (which is invoked by ‘guix-daemon’) would
open a connection to the daemon, which in turn attempts to create
/var/guix/profiles/per-user/$USER. However, when ‘guix-daemon‘ is running
as
an unprivileged user, creating that directory fails with EPERM. Because of
this, garbage collection would always fail when running the unprivileged
daemon on Guix System.
* guix/scripts/gc.scm (guix-gc): Remove upfront call to ‘open-connection’.
Instead, use ‘with-store’ only for operations that require it.
Change-Id: I1fbfd97cf7ba9e3087f7287b4776ea2f6623400d
---
guix/scripts/gc.scm | 72 ++++++++++++++++++++++++++++++-----------------------
1 file changed, 41 insertions(+), 31 deletions(-)
diff --git a/guix/scripts/gc.scm b/guix/scripts/gc.scm
index 7663efe7f8..c5017a6e52 100644
--- a/guix/scripts/gc.scm
+++ b/guix/scripts/gc.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012-2013, 2015-2020, 2022 Ludovic Courtès <[email protected]>
+;;; Copyright © 2012-2013, 2015-2020, 2022, 2025 Ludovic Courtès <[email protected]>
;;; Copyright © 2022 Efraim Flashner <[email protected]>
;;; Copyright © 2022 Remco van 't Veer <[email protected]>
;;;
@@ -297,7 +297,6 @@ is deprecated; use '-D'~%"))
(with-error-handling
(let* ((opts (parse-options))
- (store (open-connection))
(paths (filter-map (match-lambda
(('argument . arg) arg)
(_ #f))
@@ -307,39 +306,44 @@ is deprecated; use '-D'~%"))
(leave (G_ "extraneous arguments: ~{~a ~}~%") paths)))
(define (list-relatives relatives)
- (for-each (compose (lambda (path)
- (for-each (cut simple-format #t "~a~%" <>)
- (relatives store path)))
- store-directory
- symlink-target)
- paths))
+ (with-store store
+ (for-each (compose (lambda (path)
+ (for-each (cut simple-format #t "~a~%" <>)
+ (relatives store path)))
+ store-directory
+ symlink-target)
+ paths)))
(case (assoc-ref opts 'action)
((collect-garbage)
(assert-no-extra-arguments)
(let ((min-freed (assoc-ref opts 'min-freed))
(free-space (assoc-ref opts 'free-space)))
- (match (assq 'delete-generations opts)
- (#f #t)
- ((_ . pattern)
- (delete-generations store pattern)))
- (cond
- (free-space
- (ensure-free-space store free-space))
- (min-freed
- (let-values (((paths freed) (collect-garbage store min-freed)))
- (info (G_ "freed ~a~%") (number->size freed))))
- (else
- (let-values (((paths freed) (collect-garbage store)))
- (info (G_ "freed ~a~%") (number->size freed)))))))
+ (with-store store
+ (match (assq 'delete-generations opts)
+ (#f #t)
+ ((_ . pattern)
+ (delete-generations store pattern)))
+ (cond
+ (free-space
+ (ensure-free-space store free-space))
+ (min-freed
+ (let-values (((paths freed) (collect-garbage store min-freed)))
+ (info (G_ "freed ~a~%") (number->size freed))))
+ (else
+ (let-values (((paths freed) (collect-garbage store)))
+ (info (G_ "freed ~a~%") (number->size freed))))))))
((list-roots)
(assert-no-extra-arguments)
(list-roots))
((list-busy)
+ ;; Note: This is invoked by 'guix-daemon' so it must not open a
+ ;; connection to the daemon.
(assert-no-extra-arguments)
(list-busy))
((delete)
- (delete-paths store (map direct-store-path paths)))
+ (with-store store
+ (delete-paths store (map direct-store-path paths))))
((list-references)
(list-relatives references))
((list-requisites)
@@ -351,22 +355,28 @@ is deprecated; use '-D'~%"))
(list-relatives valid-derivers))
((optimize)
(assert-no-extra-arguments)
- (optimize-store store))
+ (with-store store
+ (optimize-store store)))
((verify)
(assert-no-extra-arguments)
(let ((options (assoc-ref opts 'verify-options)))
(exit
- (verify-store store
- #:check-contents? (memq 'contents options)
- #:repair? (memq 'repair options)))))
+ (with-store store
+ (verify-store store
+ #:check-contents? (memq 'contents options)
+ #:repair? (memq 'repair options))))))
((list-failures)
- (for-each (cut simple-format #t "~a~%" <>)
- (query-failed-paths store)))
+ (with-store store
+ (for-each (cut simple-format #t "~a~%" <>)
+ (query-failed-paths store))))
((clear-failures)
- (clear-failed-paths store (map direct-store-path paths)))
+ (with-store store
+ (clear-failed-paths store (map direct-store-path paths))))
((list-dead)
(for-each (cut simple-format #t "~a~%" <>)
- (dead-paths store)))
+ (with-store store
+ (dead-paths store))))
((list-live)
(for-each (cut simple-format #t "~a~%" <>)
- (live-paths store)))))))
+ (with-store store
+ (live-paths store))))))))