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.
This commit is contained in:
Ludovic Courtès 2015-06-10 13:47:58 +02:00
parent 4ae1fe14b9
commit 369755847b
2 changed files with 45 additions and 8 deletions

View File

@ -1,5 +1,5 @@
/* GNU Guix --- Functional package management for GNU /* 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, Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012,
2013 Eelco Dolstra <eelco.dolstra@logicblox.com> 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 store's '.links' directory, which means 'optimisePath' would try to link
to that instead of linking to the target store. Thus, disable to that instead of linking to the target store. Thus, disable
deduplication in this case. */ deduplication in this case. */
if (optimize && prefix.empty ()) if (optimize)
{ {
/* Make sure deduplication is enabled. */ /* Make sure deduplication is enabled. */
settings.autoOptimiseStore = true; 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) foreach (ValidPathInfos::const_iterator, i, infos)
store->optimisePath (i->path); store->optimisePath (prefix + i->path);
settings.nixStore = store_dir;
} }
} }

View File

@ -56,15 +56,14 @@ guile -c "
(exit (= (stat:ino (stat \"$new_file\")) (exit (= (stat:ino (stat \"$new_file\"))
(stat:ino (stat \"$new_file2\"))))" (stat:ino (stat \"$new_file2\"))))"
# Make sure both are valid, and delete them. # Make sure both are valid.
guile -c " guile -c "
(use-modules (guix store)) (use-modules (guix store))
(define s (open-connection)) (define s (open-connection))
(exit (and (valid-path? s \"$new_file\") (exit (and (valid-path? s \"$new_file\")
(valid-path? s \"$new_file2\") (valid-path? s \"$new_file2\")
(null? (references s \"$new_file\")) (null? (references s \"$new_file\"))
(null? (references s \"$new_file2\")) (null? (references s \"$new_file2\"))))"
(pair? (delete-paths s (list \"$new_file\" \"$new_file2\")))))"
# #
@ -98,6 +97,33 @@ guix-register --prefix "$new_store" "$closure"
guix-register -p "$new_store" \ guix-register -p "$new_store" \
--state-directory "$new_store/chbouib" "$closure" --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. # Now make sure this is recognized as valid.
ls -R "$new_store" ls -R "$new_store"
@ -131,9 +157,12 @@ do
# that name in a 'valid-path?' query because 'assertStorePath' would kill # that name in a 'valid-path?' query because 'assertStorePath' would kill
# us because of the wrong prefix. So we just list dead paths instead. # us because of the wrong prefix. So we just list dead paths instead.
guile -c " guile -c "
(use-modules (guix store)) (use-modules (guix store) (srfi srfi-1))
(define s (open-connection \"$GUIX_DAEMON_SOCKET\")) (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 # Kill the daemon so we can access the database below (otherwise we may
# get "database is locked" errors.) # get "database is locked" errors.)