* More operations.
* addToStore() and friends: don't do a round-trip to the worker if we're only interested in the path (i.e., in read-only mode).
This commit is contained in:
		
							parent
							
								
									0565b5f2b3
								
							
						
					
					
						commit
						b0d8e05be1
					
				
					 5 changed files with 116 additions and 33 deletions
				
			
		|  | @ -625,29 +625,10 @@ Path LocalStore::_addToStore(bool fixed, bool recursive, | ||||||
|     Path srcPath(absPath(_srcPath)); |     Path srcPath(absPath(_srcPath)); | ||||||
|     debug(format("adding `%1%' to the store") % srcPath); |     debug(format("adding `%1%' to the store") % srcPath); | ||||||
| 
 | 
 | ||||||
|     Hash h(htSHA256); |     std::pair<Path, Hash> pr = | ||||||
|     { |         computeStorePathForPath(fixed, recursive, hashAlgo, srcPath); | ||||||
|         SwitchToOriginalUser sw; |     Path & dstPath(pr.first); | ||||||
|         h = hashPath(htSHA256, srcPath); |     Hash & h(pr.second); | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     string baseName = baseNameOf(srcPath); |  | ||||||
| 
 |  | ||||||
|     Path dstPath; |  | ||||||
|      |  | ||||||
|     if (fixed) { |  | ||||||
| 
 |  | ||||||
|         HashType ht(parseHashType(hashAlgo)); |  | ||||||
|         Hash h2(ht); |  | ||||||
|         { |  | ||||||
|             SwitchToOriginalUser sw; |  | ||||||
|             h2 = recursive ? hashPath(ht, srcPath) : hashFile(ht, srcPath); |  | ||||||
|         } |  | ||||||
|          |  | ||||||
|         dstPath = makeFixedOutputPath(recursive, hashAlgo, h2, baseName); |  | ||||||
|     } |  | ||||||
|          |  | ||||||
|     else dstPath = makeStorePath("source", h, baseName); |  | ||||||
| 
 | 
 | ||||||
|     if (!readOnlyMode) addTempRoot(dstPath); |     if (!readOnlyMode) addTempRoot(dstPath); | ||||||
| 
 | 
 | ||||||
|  | @ -698,9 +679,7 @@ Path LocalStore::addToStoreFixed(bool recursive, string hashAlgo, const Path & s | ||||||
| Path LocalStore::addTextToStore(const string & suffix, const string & s, | Path LocalStore::addTextToStore(const string & suffix, const string & s, | ||||||
|     const PathSet & references) |     const PathSet & references) | ||||||
| { | { | ||||||
|     Hash hash = hashString(htSHA256, s); |     Path dstPath = computeStorePathForText(suffix, s); | ||||||
| 
 |  | ||||||
|     Path dstPath = makeStorePath("text", hash, suffix); |  | ||||||
|      |      | ||||||
|     if (!readOnlyMode) addTempRoot(dstPath); |     if (!readOnlyMode) addTempRoot(dstPath); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| #include "remote-store.hh" | #include "remote-store.hh" | ||||||
| #include "worker-protocol.hh" | #include "worker-protocol.hh" | ||||||
| #include "archive.hh" | #include "archive.hh" | ||||||
|  | #include "globals.hh" | ||||||
| 
 | 
 | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
|  | @ -124,6 +125,12 @@ void RemoteStore::queryReferrers(const Path & path, | ||||||
| 
 | 
 | ||||||
| Path RemoteStore::addToStore(const Path & srcPath) | Path RemoteStore::addToStore(const Path & srcPath) | ||||||
| { | { | ||||||
|  |     if (readOnlyMode) { | ||||||
|  |         /* No sense in making a round trip, we can just compute the
 | ||||||
|  |            path here. */ | ||||||
|  |         return computeStorePathForPath(false, false, "", srcPath).first; | ||||||
|  |     } | ||||||
|  |      | ||||||
|     writeInt(wopAddToStore, to); |     writeInt(wopAddToStore, to); | ||||||
|     writeString(baseNameOf(srcPath), to); |     writeString(baseNameOf(srcPath), to); | ||||||
|     dumpPath(srcPath, to); |     dumpPath(srcPath, to); | ||||||
|  | @ -135,13 +142,29 @@ Path RemoteStore::addToStore(const Path & srcPath) | ||||||
| Path RemoteStore::addToStoreFixed(bool recursive, string hashAlgo, | Path RemoteStore::addToStoreFixed(bool recursive, string hashAlgo, | ||||||
|     const Path & srcPath) |     const Path & srcPath) | ||||||
| { | { | ||||||
|     throw Error("not implemented 6"); |     if (readOnlyMode) { | ||||||
|  |         /* No sense in making a round trip, we can just compute the
 | ||||||
|  |            path here. */ | ||||||
|  |         return computeStorePathForPath(true, recursive, hashAlgo, srcPath).first; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     writeInt(wopAddToStoreFixed, to); | ||||||
|  |     writeString(baseNameOf(srcPath), to); | ||||||
|  |     writeInt(recursive ? 1 : 0, to); | ||||||
|  |     writeString(hashAlgo, to); | ||||||
|  |     dumpPath(srcPath, to); | ||||||
|  |     Path path = readString(from); | ||||||
|  |     return path; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Path RemoteStore::addTextToStore(const string & suffix, const string & s, | Path RemoteStore::addTextToStore(const string & suffix, const string & s, | ||||||
|     const PathSet & references) |     const PathSet & references) | ||||||
| { | { | ||||||
|  |     if (readOnlyMode) { | ||||||
|  |         return computeStorePathForText(suffix, s); | ||||||
|  |     } | ||||||
|  |      | ||||||
|     writeInt(wopAddTextToStore, to); |     writeInt(wopAddTextToStore, to); | ||||||
|     writeString(suffix, to); |     writeString(suffix, to); | ||||||
|     writeString(s, to); |     writeString(s, to); | ||||||
|  |  | ||||||
|  | @ -92,7 +92,45 @@ Path makeFixedOutputPath(bool recursive, | ||||||
|     return makeStorePath("output:out", h, name); |     return makeStorePath("output:out", h, name); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|   | 
 | ||||||
|  | std::pair<Path, Hash> computeStorePathForPath(bool fixed, bool recursive, | ||||||
|  |     string hashAlgo, const Path & srcPath) | ||||||
|  | { | ||||||
|  |     Hash h(htSHA256); | ||||||
|  |     { | ||||||
|  |         SwitchToOriginalUser sw; | ||||||
|  |         h = hashPath(htSHA256, srcPath); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     string baseName = baseNameOf(srcPath); | ||||||
|  | 
 | ||||||
|  |     Path dstPath; | ||||||
|  |      | ||||||
|  |     if (fixed) { | ||||||
|  | 
 | ||||||
|  |         HashType ht(parseHashType(hashAlgo)); | ||||||
|  |         Hash h2(ht); | ||||||
|  |         { | ||||||
|  |             SwitchToOriginalUser sw; | ||||||
|  |             h2 = recursive ? hashPath(ht, srcPath) : hashFile(ht, srcPath); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         dstPath = makeFixedOutputPath(recursive, hashAlgo, h2, baseName); | ||||||
|  |     } | ||||||
|  |          | ||||||
|  |     else dstPath = makeStorePath("source", h, baseName); | ||||||
|  | 
 | ||||||
|  |     return std::pair<Path, Hash>(dstPath, h); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Path computeStorePathForText(const string & suffix, const string & s) | ||||||
|  | { | ||||||
|  |     Hash hash = hashString(htSHA256, s); | ||||||
|  |     return makeStorePath("text", hash, suffix); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -54,12 +54,12 @@ public: | ||||||
| 
 | 
 | ||||||
|     /* Queries the set of outgoing FS references for a store path.
 |     /* Queries the set of outgoing FS references for a store path.
 | ||||||
|        The result is not cleared. */ |        The result is not cleared. */ | ||||||
|     virtual void queryReferences(const Path & storePath, |     virtual void queryReferences(const Path & path, | ||||||
|         PathSet & references) = 0; |         PathSet & references) = 0; | ||||||
| 
 | 
 | ||||||
|     /* Queries the set of incoming FS references for a store path.
 |     /* Queries the set of incoming FS references for a store path.
 | ||||||
|        The result is not cleared. */ |        The result is not cleared. */ | ||||||
|     virtual void queryReferrers(const Path & storePath, |     virtual void queryReferrers(const Path & path, | ||||||
|         PathSet & referrers) = 0; |         PathSet & referrers) = 0; | ||||||
| 
 | 
 | ||||||
|     /* Copy the contents of a path to the store and register the
 |     /* Copy the contents of a path to the store and register the
 | ||||||
|  | @ -88,7 +88,7 @@ public: | ||||||
|     /* Ensure that a path is valid.  If it is not currently valid, it
 |     /* Ensure that a path is valid.  If it is not currently valid, it
 | ||||||
|        may be made valid by running a substitute (if defined for the |        may be made valid by running a substitute (if defined for the | ||||||
|        path). */ |        path). */ | ||||||
|     virtual void ensurePath(const Path & storePath) = 0; |     virtual void ensurePath(const Path & path) = 0; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -115,6 +115,30 @@ Path makeFixedOutputPath(bool recursive, | ||||||
|     string hashAlgo, Hash hash, string name); |     string hashAlgo, Hash hash, string name); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | /* This is the preparatory part of addToStore() and addToStoreFixed();
 | ||||||
|  |    it computes the store path to which srcPath is to be copied. | ||||||
|  |    Returns the store path and the cryptographic hash of the | ||||||
|  |    contents of srcPath. */ | ||||||
|  | std::pair<Path, Hash> computeStorePathForPath(bool fixed, bool recursive, | ||||||
|  |     string hashAlgo, const Path & srcPath); | ||||||
|  | 
 | ||||||
|  | /* Preparatory part of addTextToStore().
 | ||||||
|  | 
 | ||||||
|  |    !!! Computation of the path should take the references given to | ||||||
|  |    addTextToStore() into account, otherwise we have a (relatively | ||||||
|  |    minor) security hole: a caller can register a source file with | ||||||
|  |    bogus references.  If there are too many references, the path may | ||||||
|  |    not be garbage collected when it has to be (not really a problem, | ||||||
|  |    the caller could create a root anyway), or it may be garbage | ||||||
|  |    collected when it shouldn't be (more serious). | ||||||
|  | 
 | ||||||
|  |    Hashing the references would solve this (bogus references would | ||||||
|  |    simply yield a different store path, so other users wouldn't be | ||||||
|  |    affected), but it has some backwards compatibility issues (the | ||||||
|  |    hashing scheme changes), so I'm not doing that for now. */ | ||||||
|  | Path computeStorePathForText(const string & suffix, const string & s); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /* For now, there is a single global store API object, but we'll
 | /* For now, there is a single global store API object, but we'll
 | ||||||
|    purify that in the future. */ |    purify that in the future. */ | ||||||
| extern boost::shared_ptr<StoreAPI> store; | extern boost::shared_ptr<StoreAPI> store; | ||||||
|  |  | ||||||
|  | @ -37,11 +37,15 @@ void processConnection(Source & from, Sink & to) | ||||||
|     debug("greeting exchanged"); |     debug("greeting exchanged"); | ||||||
| 
 | 
 | ||||||
|     bool quit = false; |     bool quit = false; | ||||||
|  | 
 | ||||||
|  |     unsigned int opCount = 0; | ||||||
|      |      | ||||||
|     do { |     do { | ||||||
|          |          | ||||||
|         WorkerOp op = (WorkerOp) readInt(from); |         WorkerOp op = (WorkerOp) readInt(from); | ||||||
| 
 | 
 | ||||||
|  |         opCount++; | ||||||
|  | 
 | ||||||
|         switch (op) { |         switch (op) { | ||||||
| 
 | 
 | ||||||
|         case wopQuit: |         case wopQuit: | ||||||
|  | @ -75,13 +79,26 @@ void processConnection(Source & from, Sink & to) | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case wopAddToStore: { |         case wopAddToStore: | ||||||
|  |         case wopAddToStoreFixed: { | ||||||
|             /* !!! uberquick hack */ |             /* !!! uberquick hack */ | ||||||
|             string baseName = readString(from); |             string baseName = readString(from); | ||||||
|  |             bool recursive = false; | ||||||
|  |             string hashAlgo; | ||||||
|  |             if (op == wopAddToStoreFixed) { | ||||||
|  |                 recursive = readInt(from) == 1; | ||||||
|  |                 hashAlgo = readString(from); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             Path tmp = createTempDir(); |             Path tmp = createTempDir(); | ||||||
|             Path tmp2 = tmp + "/" + baseName; |             Path tmp2 = tmp + "/" + baseName; | ||||||
|             restorePath(tmp2, from); |             restorePath(tmp2, from); | ||||||
|             writeString(store->addToStore(tmp2), to); | 
 | ||||||
|  |             if (op == wopAddToStoreFixed) | ||||||
|  |                 writeString(store->addToStoreFixed(recursive, hashAlgo, tmp2), to); | ||||||
|  |             else | ||||||
|  |                 writeString(store->addToStore(tmp2), to); | ||||||
|  |              | ||||||
|             deletePath(tmp); |             deletePath(tmp); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  | @ -113,6 +130,8 @@ void processConnection(Source & from, Sink & to) | ||||||
|         } |         } | ||||||
|          |          | ||||||
|     } while (!quit); |     } while (!quit); | ||||||
|  | 
 | ||||||
|  |     printMsg(lvlError, format("%1% worker operations") % opCount); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue