Merge branch 'nix-doctor' of https://github.com/LnL7/nix
This commit is contained in:
		
						commit
						63575ffa38
					
				
					 7 changed files with 139 additions and 0 deletions
				
			
		|  | @ -303,6 +303,12 @@ struct LegacySSHStore : public Store | ||||||
|     { |     { | ||||||
|         auto conn(connections->get()); |         auto conn(connections->get()); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     unsigned int getProtocol() override | ||||||
|  |     { | ||||||
|  |         auto conn(connections->get()); | ||||||
|  |         return conn->remoteVersion; | ||||||
|  |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static RegisterStoreImplementation regStore([]( | static RegisterStoreImplementation regStore([]( | ||||||
|  |  | ||||||
|  | @ -1338,6 +1338,12 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | unsigned int LocalStore::getProtocol() | ||||||
|  | { | ||||||
|  |     return PROTOCOL_VERSION; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| #if defined(FS_IOC_SETFLAGS) && defined(FS_IOC_GETFLAGS) && defined(FS_IMMUTABLE_FL) | #if defined(FS_IOC_SETFLAGS) && defined(FS_IOC_GETFLAGS) && defined(FS_IMMUTABLE_FL) | ||||||
| 
 | 
 | ||||||
| static void makeMutable(const Path & path) | static void makeMutable(const Path & path) | ||||||
|  |  | ||||||
|  | @ -209,6 +209,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     void registerValidPaths(const ValidPathInfos & infos); |     void registerValidPaths(const ValidPathInfos & infos); | ||||||
| 
 | 
 | ||||||
|  |     unsigned int getProtocol() override; | ||||||
|  | 
 | ||||||
|     void vacuumDB(); |     void vacuumDB(); | ||||||
| 
 | 
 | ||||||
|     /* Repair the contents of the given path by redownloading it using
 |     /* Repair the contents of the given path by redownloading it using
 | ||||||
|  |  | ||||||
|  | @ -693,6 +693,13 @@ void RemoteStore::connect() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | unsigned int RemoteStore::getProtocol() | ||||||
|  | { | ||||||
|  |     auto conn(connections->get()); | ||||||
|  |     return conn->daemonVersion; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| void RemoteStore::flushBadConnections() | void RemoteStore::flushBadConnections() | ||||||
| { | { | ||||||
|     connections->flushBad(); |     connections->flushBad(); | ||||||
|  |  | ||||||
|  | @ -98,6 +98,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     void connect() override; |     void connect() override; | ||||||
| 
 | 
 | ||||||
|  |     unsigned int getProtocol() override; | ||||||
|  | 
 | ||||||
|     void flushBadConnections(); |     void flushBadConnections(); | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
|  | @ -599,6 +599,12 @@ public: | ||||||
|        a notion of connection. Otherwise this is a no-op. */ |        a notion of connection. Otherwise this is a no-op. */ | ||||||
|     virtual void connect() { }; |     virtual void connect() { }; | ||||||
| 
 | 
 | ||||||
|  |     /* Get the protocol version of this store or it's connection. */ | ||||||
|  |     virtual unsigned int getProtocol() | ||||||
|  |     { | ||||||
|  |         return 0; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     /* Get the priority of the store, used to order substituters. In
 |     /* Get the priority of the store, used to order substituters. In
 | ||||||
|        particular, binary caches can specify a priority field in their |        particular, binary caches can specify a priority field in their | ||||||
|        "nix-cache-info" file. Lower value means higher priority. */ |        "nix-cache-info" file. Lower value means higher priority. */ | ||||||
|  |  | ||||||
							
								
								
									
										110
									
								
								src/nix/doctor.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								src/nix/doctor.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,110 @@ | ||||||
|  | #include "command.hh" | ||||||
|  | #include "serve-protocol.hh" | ||||||
|  | #include "shared.hh" | ||||||
|  | #include "store-api.hh" | ||||||
|  | #include "worker-protocol.hh" | ||||||
|  | 
 | ||||||
|  | using namespace nix; | ||||||
|  | 
 | ||||||
|  | std::string formatProtocol(unsigned int proto) | ||||||
|  | { | ||||||
|  |     if (proto) { | ||||||
|  |         auto major = GET_PROTOCOL_MAJOR(proto) >> 8; | ||||||
|  |         auto minor = GET_PROTOCOL_MINOR(proto); | ||||||
|  |         return (format("%1%.%2%") % major % minor).str(); | ||||||
|  |     } | ||||||
|  |     return "unknown"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct CmdDoctor : StoreCommand | ||||||
|  | { | ||||||
|  |     std::string name() override | ||||||
|  |     { | ||||||
|  |         return "doctor"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     std::string description() override | ||||||
|  |     { | ||||||
|  |         return "check your system for potential problems"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void run(ref<Store> store) override | ||||||
|  |     { | ||||||
|  |         std::cout << "Store uri: " << store->getUri() << std::endl; | ||||||
|  |         std::cout << std::endl; | ||||||
|  | 
 | ||||||
|  |         auto type = getStoreType(); | ||||||
|  | 
 | ||||||
|  |         if (type < tOther) { | ||||||
|  |             checkNixInPath(); | ||||||
|  |             checkProfileRoots(store); | ||||||
|  |         } | ||||||
|  |         checkStoreProtocol(store->getProtocol()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void checkNixInPath() | ||||||
|  |     { | ||||||
|  |         PathSet dirs; | ||||||
|  | 
 | ||||||
|  |         for (auto & dir : tokenizeString<Strings>(getEnv("PATH"), ":")) | ||||||
|  |             if (pathExists(dir + "/nix-env")) | ||||||
|  |                 dirs.insert(dirOf(canonPath(dir + "/nix-env", true))); | ||||||
|  | 
 | ||||||
|  |         if (dirs.size() != 1) { | ||||||
|  |             std::cout << "Warning: multiple versions of nix found in PATH." << std::endl; | ||||||
|  |             std::cout << std::endl; | ||||||
|  |             for (auto & dir : dirs) | ||||||
|  |                 std::cout << "  " << dir << std::endl; | ||||||
|  |             std::cout << std::endl; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void checkProfileRoots(ref<Store> store) | ||||||
|  |     { | ||||||
|  |         PathSet dirs; | ||||||
|  | 
 | ||||||
|  |         for (auto & dir : tokenizeString<Strings>(getEnv("PATH"), ":")) { | ||||||
|  |             Path profileDir = dirOf(dir); | ||||||
|  |             try { | ||||||
|  |                 Path userEnv = canonPath(profileDir, true); | ||||||
|  | 
 | ||||||
|  |                 if (store->isStorePath(userEnv) && hasSuffix(userEnv, "user-environment")) { | ||||||
|  |                     while (profileDir.find("/profiles/") == std::string::npos && isLink(profileDir)) | ||||||
|  |                         profileDir = absPath(readLink(profileDir), dirOf(profileDir)); | ||||||
|  | 
 | ||||||
|  |                     if (profileDir.find("/profiles/") == std::string::npos) | ||||||
|  |                         dirs.insert(dir); | ||||||
|  |                 } | ||||||
|  |             } catch (SysError &) {} | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (!dirs.empty()) { | ||||||
|  |             std::cout << "Warning: found profiles outside of " << settings.nixStateDir << "/profiles." << std::endl; | ||||||
|  |             std::cout << "The generation this profile points to might not have a gcroot and could be" << std::endl; | ||||||
|  |             std::cout << "garbage collected, resulting in broken symlinks." << std::endl; | ||||||
|  |             std::cout << std::endl; | ||||||
|  |             for (auto & dir : dirs) | ||||||
|  |                 std::cout << "  " << dir << std::endl; | ||||||
|  |             std::cout << std::endl; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void checkStoreProtocol(unsigned int storeProto) | ||||||
|  |     { | ||||||
|  |         auto clientProto = GET_PROTOCOL_MAJOR(SERVE_PROTOCOL_VERSION) == GET_PROTOCOL_MAJOR(storeProto) | ||||||
|  |             ? SERVE_PROTOCOL_VERSION | ||||||
|  |             : PROTOCOL_VERSION; | ||||||
|  | 
 | ||||||
|  |         if (clientProto != storeProto) { | ||||||
|  |             std::cout << "Warning: protocol version of this client does not match the store." << std::endl; | ||||||
|  |             std::cout << "While this is not necessarily a problem it's recommended to keep the client in" << std::endl; | ||||||
|  |             std::cout << "sync with the daemon." << std::endl; | ||||||
|  |             std::cout << std::endl; | ||||||
|  |             std::cout << "Client protocol: " << formatProtocol(clientProto) << std::endl; | ||||||
|  |             std::cout << "Store protocol: " << formatProtocol(storeProto) << std::endl; | ||||||
|  |             std::cout << std::endl; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static RegisterCommand r1(make_ref<CmdDoctor>()); | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue