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
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;
}
}

View File

@ -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.)