From b1beed97a0670befbfd5e105a81132e87e58ac37 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 10 Jun 2014 13:45:50 +0200 Subject: [PATCH] Report daemon OOM better When copying a large path causes the daemon to run out of memory, you now get: error: Nix daemon out of memory instead of: error: writing to file: Broken pipe --- src/libstore/remote-store.cc | 22 +++++++++++++++++----- src/nix-daemon/nix-daemon.cc | 6 ++---- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 177b8e7af..3b021bb2a 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -402,11 +402,23 @@ Path RemoteStore::addToStore(const Path & _srcPath, writeInt((hashAlgo == htSHA256 && recursive) ? 0 : 1, to); writeInt(recursive ? 1 : 0, to); writeString(printHashType(hashAlgo), to); - to.written = 0; - to.warn = true; - dumpPath(srcPath, to, filter); - to.warn = false; - processStderr(); + + try { + to.written = 0; + to.warn = true; + dumpPath(srcPath, to, filter); + to.warn = false; + processStderr(); + } catch (SysError & e) { + /* Daemon closed while we were sending the path. Probably OOM + or I/O error. */ + if (e.errNo == EPIPE) + try { + processStderr(); + } catch (EndOfFile & e) { } + throw; + } + return readStorePath(from); } diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index 8814fe315..0464ac965 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -735,12 +735,10 @@ static void processConnection(bool trusted) during addTextToStore() / importPath(). If that happens, just send the error message and exit. */ bool errorAllowed = canSendStderr; - if (!errorAllowed) printMsg(lvlError, format("error processing client input: %1%") % e.msg()); stopWork(false, e.msg(), GET_PROTOCOL_MINOR(clientVersion) >= 8 ? e.status : 0); - if (!errorAllowed) break; + if (!errorAllowed) throw; } catch (std::bad_alloc & e) { - if (canSendStderr) - stopWork(false, "Nix daemon out of memory", GET_PROTOCOL_MINOR(clientVersion) >= 8 ? 1 : 0); + stopWork(false, "Nix daemon out of memory", GET_PROTOCOL_MINOR(clientVersion) >= 8 ? 1 : 0); throw; }