aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/build.cc13
-rw-r--r--src/libstore/local-store.cc2
-rw-r--r--src/libstore/optimise-store.cc88
-rw-r--r--src/libutil/immutable.cc22
-rw-r--r--src/libutil/immutable.hh6
5 files changed, 35 insertions, 96 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 0b7790a5b..4051adacc 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -1355,11 +1355,6 @@ void DerivationGoal::buildDone()
/* Delete the chroot (if we were using one). */
autoDelChroot.reset(); /* this runs the destructor */
- /* Deleting the chroot will have caused the immutable bits on
- hard-linked inputs to be cleared. So set them again. */
- foreach (PathSet::iterator, i, regularInputPaths)
- makeImmutable(*i);
-
/* Delete redirected outputs (when doing hash rewriting). */
foreach (PathSet::iterator, i, redirectedOutputs)
deletePath(*i);
@@ -1766,11 +1761,8 @@ void DerivationGoal::startBuilder()
/* Hard-linking fails if we exceed the maximum
link count on a file (e.g. 32000 of ext3),
which is quite possible after a `nix-store
- --optimise'. It can also fail if another
- process called makeImmutable() on *i after we
- did makeMutable(). In those cases, make a copy
- instead. */
- if (errno != EMLINK && errno != EPERM)
+ --optimise'. */
+ if (errno != EMLINK)
throw SysError(format("linking `%1%' to `%2%'") % p % *i);
StringSink sink;
dumpPath(*i, sink);
@@ -1778,7 +1770,6 @@ void DerivationGoal::startBuilder()
restorePath(p, source);
}
- makeImmutable(*i);
regularInputPaths.insert(*i);
}
}
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index bb755b821..3fd772f26 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -517,8 +517,6 @@ void canonicalisePathMetaData(const Path & path, bool recurse)
foreach (Strings::iterator, i, names)
canonicalisePathMetaData(path + "/" + *i, true);
}
-
- makeImmutable(path);
}
diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc
index 9d0242bbc..43b3c9b4f 100644
--- a/src/libstore/optimise-store.cc
+++ b/src/libstore/optimise-store.cc
@@ -33,8 +33,7 @@ struct MakeReadOnly
~MakeReadOnly()
{
try {
- /* This will make the path read-only (and restore the
- immutable bit on platforms that support it). */
+ /* This will make the path read-only. */
if (path != "") canonicalisePathMetaData(path, false);
} catch (...) {
ignoreException();
@@ -43,14 +42,6 @@ struct MakeReadOnly
};
-struct MakeImmutable
-{
- Path path;
- MakeImmutable(const Path & path) : path(path) { }
- ~MakeImmutable() { makeImmutable(path); }
-};
-
-
void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path)
{
checkInterrupt();
@@ -101,7 +92,6 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path)
if (!pathExists(linkPath)) {
/* Nope, create a hard link in the links directory. */
makeMutable(path);
- MakeImmutable mk1(path);
if (link(path.c_str(), linkPath.c_str()) == 0) return;
if (errno != EEXIST)
throw SysError(format("cannot link `%1%' to `%2%'") % linkPath % path);
@@ -134,58 +124,42 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path)
MakeReadOnly makeReadOnly(mustToggle ? dirOf(path) : "");
/* If ‘linkPath’ is immutable, we can't create hard links to it,
- so make it mutable first (and make it immutable again when
- we're done). We also have to make ‘path’ mutable, otherwise
- rename() will fail to delete it. */
+ so make it mutable first. We also have to make ‘path’ mutable,
+ otherwise rename() will fail to delete it. */
makeMutable(path);
- MakeImmutable mk2(path);
-
- /* Another process might be doing the same thing (creating a new
- link to ‘linkPath’) and make ‘linkPath’ immutable before we're
- done. In that case, just retry. */
- unsigned int retries = 1024;
- while (--retries > 0) {
- makeMutable(linkPath);
- MakeImmutable mk1(linkPath);
-
- Path tempLink = (format("%1%/.tmp-link-%2%-%3%")
- % settings.nixStore % getpid() % rand()).str();
-
- if (link(linkPath.c_str(), tempLink.c_str()) == -1) {
- if (errno == EMLINK) {
- /* Too many links to the same file (>= 32000 on most
- file systems). This is likely to happen with empty
- files. Just shrug and ignore. */
- if (st.st_size)
- printMsg(lvlInfo, format("`%1%' has maximum number of links") % linkPath);
- return;
- }
- if (errno == EPERM) continue;
- throw SysError(format("cannot link `%1%' to `%2%'") % tempLink % linkPath);
+ makeMutable(linkPath);
+
+ Path tempLink = (format("%1%/.tmp-link-%2%-%3%")
+ % settings.nixStore % getpid() % rand()).str();
+
+ if (link(linkPath.c_str(), tempLink.c_str()) == -1) {
+ if (errno == EMLINK) {
+ /* Too many links to the same file (>= 32000 on most file
+ systems). This is likely to happen with empty files.
+ Just shrug and ignore. */
+ if (st.st_size)
+ printMsg(lvlInfo, format("`%1%' has maximum number of links") % linkPath);
+ return;
}
+ throw SysError(format("cannot link `%1%' to `%2%'") % tempLink % linkPath);
+ }
- /* Atomically replace the old file with the new hard link. */
- if (rename(tempLink.c_str(), path.c_str()) == -1) {
- if (unlink(tempLink.c_str()) == -1)
- printMsg(lvlError, format("unable to unlink `%1%'") % tempLink);
- if (errno == EMLINK) {
- /* Some filesystems generate too many links on the
- rename, rather than on the original link.
- (Probably it temporarily increases the st_nlink
- field before decreasing it again.) */
- if (st.st_size)
- printMsg(lvlInfo, format("`%1%' has maximum number of links") % linkPath);
- return;
- }
- if (errno == EPERM) continue;
- throw SysError(format("cannot rename `%1%' to `%2%'") % tempLink % path);
+ /* Atomically replace the old file with the new hard link. */
+ if (rename(tempLink.c_str(), path.c_str()) == -1) {
+ if (unlink(tempLink.c_str()) == -1)
+ printMsg(lvlError, format("unable to unlink `%1%'") % tempLink);
+ if (errno == EMLINK) {
+ /* Some filesystems generate too many links on the rename,
+ rather than on the original link. (Probably it
+ temporarily increases the st_nlink field before
+ decreasing it again.) */
+ if (st.st_size)
+ printMsg(lvlInfo, format("`%1%' has maximum number of links") % linkPath);
+ return;
}
-
- break;
+ throw SysError(format("cannot rename `%1%' to `%2%'") % tempLink % path);
}
- if (retries == 0) throw Error(format("cannot link `%1%' to `%2%'") % path % linkPath);
-
stats.filesLinked++;
stats.bytesFreed += st.st_size;
stats.blocksFreed += st.st_blocks;
diff --git a/src/libutil/immutable.cc b/src/libutil/immutable.cc
index f72f85625..766af4939 100644
--- a/src/libutil/immutable.cc
+++ b/src/libutil/immutable.cc
@@ -16,7 +16,7 @@
namespace nix {
-void changeMutable(const Path & path, bool mut)
+void makeMutable(const Path & path)
{
#if defined(FS_IOC_SETFLAGS) && defined(FS_IOC_GETFLAGS) && defined(FS_IMMUTABLE_FL)
@@ -38,30 +38,12 @@ void changeMutable(const Path & path, bool mut)
/* Silently ignore errors getting/setting the immutable flag so
that we work correctly on filesystems that don't support it. */
if (ioctl(fd, FS_IOC_GETFLAGS, &flags)) return;
-
old = flags;
-
- if (mut) flags &= ~FS_IMMUTABLE_FL;
- else flags |= FS_IMMUTABLE_FL;
-
+ flags &= ~FS_IMMUTABLE_FL;
if (old == flags) return;
-
if (ioctl(fd, FS_IOC_SETFLAGS, &flags)) return;
-
#endif
}
-void makeImmutable(const Path & path)
-{
- changeMutable(path, false);
-}
-
-
-void makeMutable(const Path & path)
-{
- changeMutable(path, true);
-}
-
-
}
diff --git a/src/libutil/immutable.hh b/src/libutil/immutable.hh
index 8af419004..8e98b76a4 100644
--- a/src/libutil/immutable.hh
+++ b/src/libutil/immutable.hh
@@ -4,12 +4,6 @@
namespace nix {
-/* Make the given path immutable, i.e., prevent it from being modified
- in any way, even by root. This is a no-op on platforms that do not
- support this, or if the calling user is not privileged. On Linux,
- this is implemented by doing the equivalent of ‘chattr +i path’. */
-void makeImmutable(const Path & path);
-
/* Make the given path mutable. */
void makeMutable(const Path & path);