Automatically optimise the Nix store when a new path is added
Auto-optimisation is enabled by default. It can be turned off by setting auto-optimise-store to false in nix.conf.
This commit is contained in:
parent
564fb7d9fa
commit
6193105710
|
@ -338,6 +338,19 @@ build-use-chroot = /dev /proc /bin</programlisting>
|
||||||
|
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
|
<varlistentry><term><literal>auto-optimise-store</literal></term>
|
||||||
|
|
||||||
|
<listitem><para>If set to <literal>true</literal> (the default),
|
||||||
|
Nix automatically detects files in the store that have identical
|
||||||
|
contents, and replaces them with hard links to a single copy.
|
||||||
|
This saves disk space. If set to <literal>false</literal>, you
|
||||||
|
can still run <command>nix-store --optimise</command> to get rid
|
||||||
|
of duplicate files.</para></listitem>
|
||||||
|
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
|
@ -2093,6 +2093,8 @@ void DerivationGoal::computeClosure()
|
||||||
if (allowed.find(*i) == allowed.end())
|
if (allowed.find(*i) == allowed.end())
|
||||||
throw BuildError(format("output is not allowed to refer to path `%1%'") % *i);
|
throw BuildError(format("output is not allowed to refer to path `%1%'") % *i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
worker.store.optimisePath(path); // FIXME: combine with scanForReferences()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register each output path as valid, and register the sets of
|
/* Register each output path as valid, and register the sets of
|
||||||
|
@ -2546,6 +2548,8 @@ void SubstitutionGoal::finished()
|
||||||
|
|
||||||
HashResult hash = hashPath(htSHA256, storePath);
|
HashResult hash = hashPath(htSHA256, storePath);
|
||||||
|
|
||||||
|
worker.store.optimisePath(storePath); // FIXME: combine with hashPath()
|
||||||
|
|
||||||
ValidPathInfo info2;
|
ValidPathInfo info2;
|
||||||
info2.path = storePath;
|
info2.path = storePath;
|
||||||
info2.hash = hash.first;
|
info2.hash = hash.first;
|
||||||
|
|
|
@ -209,6 +209,7 @@ LocalStore::LocalStore(bool reserveSpace)
|
||||||
|
|
||||||
/* Create missing state directories if they don't already exist. */
|
/* Create missing state directories if they don't already exist. */
|
||||||
createDirs(nixStore);
|
createDirs(nixStore);
|
||||||
|
createDirs(linksDir = nixStore + "/.links");
|
||||||
Path profilesDir = nixStateDir + "/profiles";
|
Path profilesDir = nixStateDir + "/profiles";
|
||||||
createDirs(nixStateDir + "/profiles");
|
createDirs(nixStateDir + "/profiles");
|
||||||
createDirs(nixStateDir + "/temproots");
|
createDirs(nixStateDir + "/temproots");
|
||||||
|
@ -1117,6 +1118,8 @@ Path LocalStore::addToStoreFromDump(const string & dump, const string & name,
|
||||||
} else
|
} else
|
||||||
hash = hashPath(htSHA256, dstPath);
|
hash = hashPath(htSHA256, dstPath);
|
||||||
|
|
||||||
|
optimisePath(dstPath); // FIXME: combine with hashPath()
|
||||||
|
|
||||||
ValidPathInfo info;
|
ValidPathInfo info;
|
||||||
info.path = dstPath;
|
info.path = dstPath;
|
||||||
info.hash = hash.first;
|
info.hash = hash.first;
|
||||||
|
@ -1171,6 +1174,8 @@ Path LocalStore::addTextToStore(const string & name, const string & s,
|
||||||
|
|
||||||
HashResult hash = hashPath(htSHA256, dstPath);
|
HashResult hash = hashPath(htSHA256, dstPath);
|
||||||
|
|
||||||
|
optimisePath(dstPath);
|
||||||
|
|
||||||
ValidPathInfo info;
|
ValidPathInfo info;
|
||||||
info.path = dstPath;
|
info.path = dstPath;
|
||||||
info.hash = hash.first;
|
info.hash = hash.first;
|
||||||
|
@ -1406,6 +1411,8 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
|
||||||
here. */
|
here. */
|
||||||
HashResult hash = hashPath(htSHA256, dstPath);
|
HashResult hash = hashPath(htSHA256, dstPath);
|
||||||
|
|
||||||
|
optimisePath(dstPath); // FIXME: combine with hashPath()
|
||||||
|
|
||||||
ValidPathInfo info;
|
ValidPathInfo info;
|
||||||
info.path = dstPath;
|
info.path = dstPath;
|
||||||
info.hash = hash.first;
|
info.hash = hash.first;
|
||||||
|
|
|
@ -86,6 +86,8 @@ private:
|
||||||
typedef std::map<Path, RunningSubstituter> RunningSubstituters;
|
typedef std::map<Path, RunningSubstituter> RunningSubstituters;
|
||||||
RunningSubstituters runningSubstituters;
|
RunningSubstituters runningSubstituters;
|
||||||
|
|
||||||
|
Path linksDir;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* Initialise the local store, upgrading the schema if
|
/* Initialise the local store, upgrading the schema if
|
||||||
|
@ -169,6 +171,9 @@ public:
|
||||||
files with the same contents. */
|
files with the same contents. */
|
||||||
void optimiseStore(OptimiseStats & stats);
|
void optimiseStore(OptimiseStats & stats);
|
||||||
|
|
||||||
|
/* Optimise a single store path. */
|
||||||
|
void optimisePath(const Path & path);
|
||||||
|
|
||||||
/* Check the integrity of the Nix store. */
|
/* Check the integrity of the Nix store. */
|
||||||
void verifyStore(bool checkContents);
|
void verifyStore(bool checkContents);
|
||||||
|
|
||||||
|
@ -267,6 +272,8 @@ private:
|
||||||
Path importPath(bool requireSignature, Source & source);
|
Path importPath(bool requireSignature, Source & source);
|
||||||
|
|
||||||
void checkDerivationOutputs(const Path & drvPath, const Derivation & drv);
|
void checkDerivationOutputs(const Path & drvPath, const Derivation & drv);
|
||||||
|
|
||||||
|
void optimisePath_(OptimiseStats & stats, const Path & path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,10 +49,7 @@ struct MakeImmutable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const string linksDir = ".links";
|
void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path)
|
||||||
|
|
||||||
|
|
||||||
static void hashAndLink(OptimiseStats & stats, const Path & path)
|
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
|
@ -61,7 +58,7 @@ static void hashAndLink(OptimiseStats & stats, const Path & path)
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
Strings names = readDirectory(path);
|
Strings names = readDirectory(path);
|
||||||
foreach (Strings::iterator, i, names)
|
foreach (Strings::iterator, i, names)
|
||||||
hashAndLink(stats, path + "/" + *i);
|
optimisePath_(stats, path + "/" + *i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +88,7 @@ static void hashAndLink(OptimiseStats & stats, const Path & path)
|
||||||
printMsg(lvlDebug, format("`%1%' has hash `%2%'") % path % printHash(hash));
|
printMsg(lvlDebug, format("`%1%' has hash `%2%'") % path % printHash(hash));
|
||||||
|
|
||||||
/* Check if this is a known hash. */
|
/* Check if this is a known hash. */
|
||||||
Path linkPath = nixStore + "/" + linksDir + "/" + printHash32(hash);
|
Path linkPath = linksDir + "/" + printHash32(hash);
|
||||||
|
|
||||||
if (!pathExists(linkPath)) {
|
if (!pathExists(linkPath)) {
|
||||||
/* Nope, create a hard link in the links directory. */
|
/* Nope, create a hard link in the links directory. */
|
||||||
|
@ -177,15 +174,22 @@ static void hashAndLink(OptimiseStats & stats, const Path & path)
|
||||||
|
|
||||||
void LocalStore::optimiseStore(OptimiseStats & stats)
|
void LocalStore::optimiseStore(OptimiseStats & stats)
|
||||||
{
|
{
|
||||||
createDirs(nixStore + "/" + linksDir);
|
|
||||||
|
|
||||||
PathSet paths = queryValidPaths();
|
PathSet paths = queryValidPaths();
|
||||||
|
|
||||||
foreach (PathSet::iterator, i, paths) {
|
foreach (PathSet::iterator, i, paths) {
|
||||||
addTempRoot(*i);
|
addTempRoot(*i);
|
||||||
if (!isValidPath(*i)) continue; /* path was GC'ed, probably */
|
if (!isValidPath(*i)) continue; /* path was GC'ed, probably */
|
||||||
startNest(nest, lvlChatty, format("hashing files in `%1%'") % *i);
|
startNest(nest, lvlChatty, format("hashing files in `%1%'") % *i);
|
||||||
hashAndLink(stats, *i);
|
optimisePath_(stats, *i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LocalStore::optimisePath(const Path & path)
|
||||||
|
{
|
||||||
|
if (queryBoolSetting("auto-optimise-store", true)) {
|
||||||
|
OptimiseStats stats;
|
||||||
|
optimisePath_(stats, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue