about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-03-18T22·17+0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-03-18T22·22+0100
commit51800e06dec91282b81fc41e56d1e9325849d2c2 (patch)
tree57e25f836e644799107c481d2b622e024917f835
parentf93e97517e449cb1b3c7bdf8076812276b4cb2cd (diff)
Allow recovery from isValidPath RPCs with an invalid path
Currently, clients cannot recover from an isValidPath RPC with an
invalid path parameter because the daemon closes the connection when
that happens.

More precisely:

  1. in performOp, wopIsValidPath case, ‘readStorePath’ raises an
     ‘Error’ exception;

  2. that exception is caught by the handler in ‘processConnection’;

  3. the handler determines errorAllowed == false, and thus exits after
     sending the message.

This last part is fixed by calling ‘startWork’ early on, as in the patch
below.

The same reasoning could be applied to all the RPCs that take one or
more store paths as inputs, but isValidPath is, by definition, likely to
be passed invalid paths in the first place, so it’s important for this
one to allow recovery.
-rw-r--r--src/nix-daemon/nix-daemon.cc8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc
index 882078c08eb3..e678c9dfdb7c 100644
--- a/src/nix-daemon/nix-daemon.cc
+++ b/src/nix-daemon/nix-daemon.cc
@@ -294,8 +294,14 @@ static void performOp(bool trusted, unsigned int clientVersion,
 #endif
 
     case wopIsValidPath: {
-        Path path = readStorePath(from);
+	/* 'readStorePath' could raise an error leading to the connection
+	   being closed.  To be able to recover from an invalid path error,
+	   call 'startWork' early, and do 'assertStorePath' afterwards so
+	   that the 'Error' exception handler doesn't close the
+	   connection.  */
+        Path path = readString(from);
         startWork();
+	assertStorePath(path);
         bool result = store->isValidPath(path);
         stopWork();
         writeInt(result, to);