guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

06/08: GC: Handle ENOSPC creating/moving to the trash directory


From: Ludovic Courtès
Subject: 06/08: GC: Handle ENOSPC creating/moving to the trash directory
Date: Thu, 02 Jul 2015 22:34:06 +0000

civodul pushed a commit to branch nix
in repository guix.

commit 6e38685ef65284093df79ebe7378bac33b0e7e5d
Author: Eelco Dolstra <address@hidden>
Date:   Tue Jun 30 21:41:26 2015 +0200

    GC: Handle ENOSPC creating/moving to the trash directory
    
    Issue #564.
---
 nix/libstore/gc.cc |   31 +++++++++++++++++++++++--------
 1 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/nix/libstore/gc.cc b/nix/libstore/gc.cc
index 3476832..72eff52 100644
--- a/nix/libstore/gc.cc
+++ b/nix/libstore/gc.cc
@@ -376,6 +376,7 @@ struct LocalStore::GCState
     bool gcKeepOutputs;
     bool gcKeepDerivations;
     unsigned long long bytesInvalidated;
+    bool moveToTrash = true;
     Path trashDir;
     bool shouldDelete;
     GCState(GCResults & results_) : results(results_), bytesInvalidated(0) { }
@@ -428,16 +429,23 @@ void LocalStore::deletePathRecursive(GCState & state, 
const Path & path)
        not holding the global GC lock) we can delete the path without
        being afraid that the path has become alive again.  Otherwise
        delete it right away. */
-    if (S_ISDIR(st.st_mode)) {
+    if (state.moveToTrash && S_ISDIR(st.st_mode)) {
         // Estimate the amount freed using the narSize field.  FIXME:
         // if the path was not valid, need to determine the actual
         // size.
-        state.bytesInvalidated += size;
-        if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
-            throw SysError(format("making `%1%' writable") % path);
-        Path tmp = state.trashDir + "/" + baseNameOf(path);
-        if (rename(path.c_str(), tmp.c_str()))
-            throw SysError(format("unable to rename `%1%' to `%2%'") % path % 
tmp);
+        try {
+            if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
+                throw SysError(format("making `%1%' writable") % path);
+            Path tmp = state.trashDir + "/" + baseNameOf(path);
+            if (rename(path.c_str(), tmp.c_str()))
+                throw SysError(format("unable to rename `%1%' to `%2%'") % 
path % tmp);
+            state.bytesInvalidated += size;
+        } catch (SysError & e) {
+            if (e.errNo == ENOSPC) {
+                printMsg(lvlInfo, format("note: can't create move `%1%': %2%") 
% path % e.msg());
+                deleteGarbage(state, path);
+            }
+        }
     } else
         deleteGarbage(state, path);
 
@@ -636,7 +644,14 @@ void LocalStore::collectGarbage(const GCOptions & options, 
GCResults & results)
 
     if (state.shouldDelete) {
         if (pathExists(state.trashDir)) deleteGarbage(state, state.trashDir);
-        createDirs(state.trashDir);
+        try {
+            createDirs(state.trashDir);
+        } catch (SysError & e) {
+            if (e.errNo == ENOSPC) {
+                printMsg(lvlInfo, format("note: can't create trash directory: 
%1%") % e.msg());
+                state.moveToTrash = false;
+            }
+        }
     }
 
     /* Now either delete all garbage paths, or just the specified



reply via email to

[Prev in Thread] Current Thread [Next in Thread]