* 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)); | ||||
|     debug(format("adding `%1%' to the store") % 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); | ||||
|     std::pair<Path, Hash> pr = | ||||
|         computeStorePathForPath(fixed, recursive, hashAlgo, srcPath); | ||||
|     Path & dstPath(pr.first); | ||||
|     Hash & h(pr.second); | ||||
| 
 | ||||
|     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, | ||||
|     const PathSet & references) | ||||
| { | ||||
|     Hash hash = hashString(htSHA256, s); | ||||
| 
 | ||||
|     Path dstPath = makeStorePath("text", hash, suffix); | ||||
|     Path dstPath = computeStorePathForText(suffix, s); | ||||
|      | ||||
|     if (!readOnlyMode) addTempRoot(dstPath); | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| #include "remote-store.hh" | ||||
| #include "worker-protocol.hh" | ||||
| #include "archive.hh" | ||||
| #include "globals.hh" | ||||
| 
 | ||||
| #include <iostream> | ||||
| #include <unistd.h> | ||||
|  | @ -124,6 +125,12 @@ void RemoteStore::queryReferrers(const Path & path, | |||
| 
 | ||||
| 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); | ||||
|     writeString(baseNameOf(srcPath), to); | ||||
|     dumpPath(srcPath, to); | ||||
|  | @ -135,13 +142,29 @@ Path RemoteStore::addToStore(const Path & srcPath) | |||
| Path RemoteStore::addToStoreFixed(bool recursive, string hashAlgo, | ||||
|     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, | ||||
|     const PathSet & references) | ||||
| { | ||||
|     if (readOnlyMode) { | ||||
|         return computeStorePathForText(suffix, s); | ||||
|     } | ||||
|      | ||||
|     writeInt(wopAddTextToStore, to); | ||||
|     writeString(suffix, to); | ||||
|     writeString(s, to); | ||||
|  |  | |||
|  | @ -92,7 +92,45 @@ Path makeFixedOutputPath(bool recursive, | |||
|     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.
 | ||||
|        The result is not cleared. */ | ||||
|     virtual void queryReferences(const Path & storePath, | ||||
|     virtual void queryReferences(const Path & path, | ||||
|         PathSet & references) = 0; | ||||
| 
 | ||||
|     /* Queries the set of incoming FS references for a store path.
 | ||||
|        The result is not cleared. */ | ||||
|     virtual void queryReferrers(const Path & storePath, | ||||
|     virtual void queryReferrers(const Path & path, | ||||
|         PathSet & referrers) = 0; | ||||
| 
 | ||||
|     /* 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
 | ||||
|        may be made valid by running a substitute (if defined for the | ||||
|        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); | ||||
| 
 | ||||
| 
 | ||||
| /* 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
 | ||||
|    purify that in the future. */ | ||||
| extern boost::shared_ptr<StoreAPI> store; | ||||
|  |  | |||
|  | @ -37,11 +37,15 @@ void processConnection(Source & from, Sink & to) | |||
|     debug("greeting exchanged"); | ||||
| 
 | ||||
|     bool quit = false; | ||||
| 
 | ||||
|     unsigned int opCount = 0; | ||||
|      | ||||
|     do { | ||||
|          | ||||
|         WorkerOp op = (WorkerOp) readInt(from); | ||||
| 
 | ||||
|         opCount++; | ||||
| 
 | ||||
|         switch (op) { | ||||
| 
 | ||||
|         case wopQuit: | ||||
|  | @ -75,13 +79,26 @@ void processConnection(Source & from, Sink & to) | |||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         case wopAddToStore: { | ||||
|         case wopAddToStore: | ||||
|         case wopAddToStoreFixed: { | ||||
|             /* !!! uberquick hack */ | ||||
|             string baseName = readString(from); | ||||
|             bool recursive = false; | ||||
|             string hashAlgo; | ||||
|             if (op == wopAddToStoreFixed) { | ||||
|                 recursive = readInt(from) == 1; | ||||
|                 hashAlgo = readString(from); | ||||
|             } | ||||
| 
 | ||||
|             Path tmp = createTempDir(); | ||||
|             Path tmp2 = tmp + "/" + baseName; | ||||
|             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); | ||||
|             break; | ||||
|         } | ||||
|  | @ -113,6 +130,8 @@ void processConnection(Source & from, Sink & to) | |||
|         } | ||||
|          | ||||
|     } while (!quit); | ||||
| 
 | ||||
|     printMsg(lvlError, format("%1% worker operations") % opCount); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue