findRoots(): Prevent a call to lstat()

This means that getting the roots from /nix/var/nix/.../hydra-roots
doesn't need any I/O other than reading the directory.
This commit is contained in:
Eelco Dolstra 2014-08-01 17:20:25 +02:00
parent daf3f2c11f
commit e0d7d0e45c

View file

@ -294,18 +294,23 @@ static void foundRoot(StoreAPI & store,
} }
static void findRoots(StoreAPI & store, const Path & path, Roots & roots) static void findRoots(StoreAPI & store, const Path & path, unsigned char type, Roots & roots)
{ {
try { try {
if (type == DT_UNKNOWN) {
struct stat st = lstat(path); struct stat st = lstat(path);
if (S_ISDIR(st.st_mode)) type = DT_DIR;
if (S_ISDIR(st.st_mode)) { else if (S_ISLNK(st.st_mode)) type = DT_LNK;
for (auto & i : readDirectory(path)) else if (S_ISREG(st.st_mode)) type = DT_REG;
findRoots(store, path + "/" + i.name, roots);
} }
else if (S_ISLNK(st.st_mode)) { if (type == DT_DIR) {
for (auto & i : readDirectory(path))
findRoots(store, path + "/" + i.name, i.type, roots);
}
else if (type == DT_LNK) {
Path target = readLink(path); Path target = readLink(path);
if (isInStore(target)) if (isInStore(target))
foundRoot(store, path, target, roots); foundRoot(store, path, target, roots);
@ -327,7 +332,7 @@ static void findRoots(StoreAPI & store, const Path & path, Roots & roots)
} }
} }
else if (S_ISREG(st.st_mode)) { else if (type == DT_REG) {
Path storePath = settings.nixStore + "/" + baseNameOf(path); Path storePath = settings.nixStore + "/" + baseNameOf(path);
if (store.isValidPath(storePath)) if (store.isValidPath(storePath))
roots[path] = storePath; roots[path] = storePath;
@ -350,9 +355,9 @@ Roots LocalStore::findRoots()
Roots roots; Roots roots;
/* Process direct roots in {gcroots,manifests,profiles}. */ /* Process direct roots in {gcroots,manifests,profiles}. */
nix::findRoots(*this, settings.nixStateDir + "/" + gcRootsDir, roots); nix::findRoots(*this, settings.nixStateDir + "/" + gcRootsDir, DT_UNKNOWN, roots);
nix::findRoots(*this, settings.nixStateDir + "/manifests", roots); nix::findRoots(*this, settings.nixStateDir + "/manifests", DT_UNKNOWN, roots);
nix::findRoots(*this, settings.nixStateDir + "/profiles", roots); nix::findRoots(*this, settings.nixStateDir + "/profiles", DT_UNKNOWN, roots);
return roots; return roots;
} }