aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2015-06-10 13:47:58 +0200
committerLudovic Courtès <ludo@gnu.org>2015-06-10 13:47:58 +0200
commit369755847b942806efe710b88146311849046017 (patch)
treed0b727384c489395be8ff34b2a4de524ecb492a0
parent4ae1fe14b90dba3b3394852079783ca43272a675 (diff)
downloadguix-369755847b942806efe710b88146311849046017.tar
guix-369755847b942806efe710b88146311849046017.tar.gz
guix-register: Perform deduplication even when --prefix is passed.
Fixes <http://bugs.gnu.org/19044>. * nix/guix-register/guix-register.cc (register_validity): Change the (optimize && prefix.empty ()) condition to just (optimize). Change settings.nixStore around the loop. Prepend PREFIX to the argument passed to 'optimisePath'. * tests/guix-register.sh: Use 'guix-register -p' with duplicate files, and make sure they are deduplicated on the target. Adjust existing tests.
-rw-r--r--nix/guix-register/guix-register.cc14
-rw-r--r--tests/guix-register.sh39
2 files changed, 45 insertions, 8 deletions
diff --git a/nix/guix-register/guix-register.cc b/nix/guix-register/guix-register.cc
index f5c610fde0..f8f0eab4c2 100644
--- a/nix/guix-register/guix-register.cc
+++ b/nix/guix-register/guix-register.cc
@@ -1,5 +1,5 @@
/* GNU Guix --- Functional package management for GNU
- Copyright (C) 2013, 2014 Ludovic Courtès <ludo@gnu.org>
+ Copyright (C) 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012,
2013 Eelco Dolstra <eelco.dolstra@logicblox.com>
@@ -192,13 +192,21 @@ register_validity (LocalStore *store, std::istream &input,
store's '.links' directory, which means 'optimisePath' would try to link
to that instead of linking to the target store. Thus, disable
deduplication in this case. */
- if (optimize && prefix.empty ())
+ if (optimize)
{
/* Make sure deduplication is enabled. */
settings.autoOptimiseStore = true;
+ std::string store_dir = settings.nixStore;
+
+ /* 'optimisePath' creates temporary links under 'settings.nixStore' and
+ this must be the real target store, under PREFIX, to avoid
+ cross-device links. Thus, temporarily switch the value of
+ 'settings.nixStore'. */
+ settings.nixStore = prefix + store_dir;
foreach (ValidPathInfos::const_iterator, i, infos)
- store->optimisePath (i->path);
+ store->optimisePath (prefix + i->path);
+ settings.nixStore = store_dir;
}
}
diff --git a/tests/guix-register.sh b/tests/guix-register.sh
index 30bc59a314..360cf55979 100644
--- a/tests/guix-register.sh
+++ b/tests/guix-register.sh
@@ -56,15 +56,14 @@ guile -c "
(exit (= (stat:ino (stat \"$new_file\"))
(stat:ino (stat \"$new_file2\"))))"
-# Make sure both are valid, and delete them.
+# Make sure both are valid.
guile -c "
(use-modules (guix store))
(define s (open-connection))
(exit (and (valid-path? s \"$new_file\")
(valid-path? s \"$new_file2\")
(null? (references s \"$new_file\"))
- (null? (references s \"$new_file2\"))
- (pair? (delete-paths s (list \"$new_file\" \"$new_file2\")))))"
+ (null? (references s \"$new_file2\"))))"
#
@@ -98,6 +97,33 @@ guix-register --prefix "$new_store" "$closure"
guix-register -p "$new_store" \
--state-directory "$new_store/chbouib" "$closure"
+# Register duplicate files.
+cp "$new_file" "$new_file2" "$new_store_dir"
+guix-register -p "$new_store" <<EOF
+$new_file
+
+0
+EOF
+guix-register -p "$new_store" <<EOF
+$new_file2
+
+0
+EOF
+
+copied_duplicate1="$new_store_dir/`basename $new_file`"
+copied_duplicate2="$new_store_dir/`basename $new_file2`"
+
+# Make sure there is indeed deduplication under $new_store and that there are
+# no cross-store hard links.
+guile -c "
+ (exit (and (= (stat:ino (stat \"$copied_duplicate1\"))
+ (stat:ino (stat \"$copied_duplicate2\")))
+ (not (= (stat:ino (stat \"$new_file\"))
+ (stat:ino (stat \"$copied_duplicate1\"))))))"
+
+# Delete them.
+guix gc -d "$new_file" "$new_file2"
+
# Now make sure this is recognized as valid.
ls -R "$new_store"
@@ -131,9 +157,12 @@ do
# that name in a 'valid-path?' query because 'assertStorePath' would kill
# us because of the wrong prefix. So we just list dead paths instead.
guile -c "
- (use-modules (guix store))
+ (use-modules (guix store) (srfi srfi-1))
(define s (open-connection \"$GUIX_DAEMON_SOCKET\"))
- (exit (equal? (list \"$copied\") (dead-paths s)))"
+ (exit (lset= string=?
+ (pk 1 (list \"$copied\" \"$copied_duplicate1\"
+ \"$copied_duplicate2\"))
+ (pk 2 (dead-paths s))))"
# Kill the daemon so we can access the database below (otherwise we may
# get "database is locked" errors.)