aboutsummaryrefslogtreecommitdiff
AgeCommit message (Expand)Author
2023-08-24gnu: Add texlive-proposal....* gnu/packages/tex.scm (texlive-proposal): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-prociagssymp....* gnu/packages/tex.scm (texlive-prociagssymp): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-pracjourn....* gnu/packages/tex.scm (texlive-pracjourn): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-powerdot-tuliplab....* gnu/packages/tex.scm (texlive-powerdot-tuliplab): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-powerdot-fuberlin....* gnu/packages/tex.scm (texlive-powerdot-fuberlin): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-pkuthss....* gnu/packages/tex.scm (texlive-pkuthss): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-pittetd....* gnu/packages/tex.scm (texlive-pittetd): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-philosophersimprint....* gnu/packages/tex.scm (texlive-philosophersimprint): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-oup-authoring-template....* gnu/packages/tex.scm (texlive-oup-authoring-template): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-opteng....* gnu/packages/tex.scm (texlive-opteng): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-onrannual....* gnu/packages/tex.scm (texlive-onrannual): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-nwejm....* gnu/packages/tex.scm (texlive-nwejm): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-nwafuthesis....* gnu/packages/tex.scm (texlive-nwafuthesis): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-nrc....* gnu/packages/tex.scm (texlive-nrc): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-nostarch....* gnu/packages/tex.scm (texlive-nostarch): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-njuvisual....* gnu/packages/tex.scm (texlive-njuvisual): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-njuthesis....* gnu/packages/tex.scm (texlive-njuthesis): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-njustthesis....* gnu/packages/tex.scm (texlive-njustthesis): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-nihbiosketch....* gnu/packages/tex.scm (texlive-nihbiosketch): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-nih....* gnu/packages/tex.scm (texlive-nih): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-ndsu-thesis-2022....* gnu/packages/tex.scm (texlive-ndsu-thesis-2022): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-ndsu-thesis....* gnu/packages/tex.scm (texlive-ndsu-thesis): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-nddiss....* gnu/packages/tex.scm (texlive-nddiss): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-navydocs....* gnu/packages/tex.scm (texlive-navydocs): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-nature....* gnu/packages/tex.scm (texlive-nature): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-mynsfc....* gnu/packages/tex.scm (texlive-mynsfc): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-muthesis....* gnu/packages/tex.scm (texlive-muthesis): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-musuos....* gnu/packages/tex.scm (texlive-musuos): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-muling....* gnu/packages/tex.scm (texlive-muling): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-mugsthesis....* gnu/packages/tex.scm (texlive-mugsthesis): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-mucproc....* gnu/packages/tex.scm (texlive-mucproc): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-msu-thesis....* gnu/packages/tex.scm (texlive-msu-thesis): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-modeles-factures-belges-assocs....* gnu/packages/tex.scm (texlive-modeles-factures-belges-assocs): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-mnras....* gnu/packages/tex.scm (texlive-mnras): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-mluexercise....* gnu/packages/tex.scm (texlive-mluexercise): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-mlacls....* gnu/packages/tex.scm (texlive-mlacls): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-mentis....* gnu/packages/tex.scm (texlive-mentis): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-mcmthesis....* gnu/packages/tex.scm (texlive-mcmthesis): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-matc3mem....* gnu/packages/tex.scm (texlive-matc3mem): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-matc3....* gnu/packages/tex.scm (texlive-matc3): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-lps....* gnu/packages/tex.scm (texlive-lps): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-lni....* gnu/packages/tex.scm (texlive-lni): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-llncsconf....* gnu/packages/tex.scm (texlive-llncsconf): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-llncs....* gnu/packages/tex.scm (texlive-llncs): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-lion-msc....* gnu/packages/tex.scm (texlive-lion-msc): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-limecv....* gnu/packages/tex.scm (texlive-limecv): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-langsci-avm....* gnu/packages/tex.scm (texlive-langsci-avm): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-langsci....* gnu/packages/tex.scm (texlive-langsci): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-ku-template....* gnu/packages/tex.scm (texlive-ku-template): New variable. Nicolas Goaziou
2023-08-24gnu: Add texlive-ksp-thesis....* gnu/packages/tex.scm (texlive-ksp-thesis): New variable. Nicolas Goaziou
rintMsg(lvlDebug, format("cannot delete `%1%' because it's a root") % path); state.alive.insert(path); return true; } visited.insert(path); if (!isValidPath(path)) return false; PathSet incoming; /* Don't delete this path if any of its referrers are alive. */ queryReferrers(path, incoming); /* If gc-keep-derivations is set and this is a derivation, then don't delete the derivation if any of the outputs are alive. */ if (state.gcKeepDerivations && isDerivation(path)) { PathSet outputs = queryDerivationOutputs(path); foreach (PathSet::iterator, i, outputs) if (isValidPath(*i) && queryDeriver(*i) == path) incoming.insert(*i); } /* If gc-keep-outputs is set, then don't delete this path if there are derivers of this path that are not garbage. */ if (state.gcKeepOutputs) { PathSet derivers = queryValidDerivers(path); foreach (PathSet::iterator, i, derivers) incoming.insert(*i); } foreach (PathSet::iterator, i, incoming) if (*i != path) if (canReachRoot(state, visited, *i)) { state.alive.insert(path); return true; } return false; } void LocalStore::tryToDelete(GCState & state, const Path & path) { checkInterrupt(); if (path == linksDir || path == state.trashDir) return; startNest(nest, lvlDebug, format("considering whether to delete `%1%'") % path); if (!isValidPath(path)) { /* A lock file belonging to a path that we're building right now isn't garbage. */ if (isActiveTempFile(state, path, ".lock")) return; /* Don't delete .chroot directories for derivations that are currently being built. */ if (isActiveTempFile(state, path, ".chroot")) return; } PathSet visited; if (canReachRoot(state, visited, path)) { printMsg(lvlDebug, format("cannot delete `%1%' because it's still reachable") % path); } else { /* No path we visited was a root, so everything is garbage. But we only delete ‘path’ and its referrers here so that ‘nix-store --delete’ doesn't have the unexpected effect of recursing into derivations and outputs. */ state.dead.insert(visited.begin(), visited.end()); if (state.shouldDelete) deletePathRecursive(state, path); } } /* Unlink all files in /nix/store/.links that have a link count of 1, which indicates that there are no other links and so they can be safely deleted. FIXME: race condition with optimisePath(): we might see a link count of 1 just before optimisePath() increases the link count. */ void LocalStore::removeUnusedLinks(const GCState & state) { AutoCloseDir dir = opendir(linksDir.c_str()); if (!dir) throw SysError(format("opening directory `%1%'") % linksDir); long long actualSize = 0, unsharedSize = 0; struct dirent * dirent; while (errno = 0, dirent = readdir(dir)) { checkInterrupt(); string name = dirent->d_name; if (name == "." || name == "..") continue; Path path = linksDir + "/" + name; #ifdef HAVE_STATX # define st_size stx_size # define st_nlink stx_nlink static int statx_flags = AT_SYMLINK_NOFOLLOW | AT_STATX_DONT_SYNC; struct statx st; if (statx(AT_FDCWD, path.c_str(), statx_flags, STATX_SIZE | STATX_NLINK, &st) == -1) { if (errno == EINVAL) { /* Old 3.10 kernels (CentOS 7) don't support AT_STATX_DONT_SYNC, so try again without it. */ statx_flags &= ~AT_STATX_DONT_SYNC; if (statx(AT_FDCWD, path.c_str(), statx_flags, STATX_SIZE | STATX_NLINK, &st) == -1) throw SysError(format("statting `%1%'") % path); } else { throw SysError(format("statting `%1%'") % path); } } #else struct stat st; if (lstat(path.c_str(), &st) == -1) throw SysError(format("statting `%1%'") % path); #endif /* Drop links for files smaller than 'deduplicationMinSize', even if they have more than one hard link. */ if (st.st_nlink != 1 && st.st_size >= deduplicationMinSize) { actualSize += st.st_size; unsharedSize += (st.st_nlink - 1) * st.st_size; continue; } printMsg(lvlTalkative, format("deleting unused link `%1%'") % path); if (unlink(path.c_str()) == -1) throw SysError(format("deleting `%1%'") % path); state.results.bytesFreed += st.st_size; #undef st_size #undef st_nlink } struct stat st; if (stat(linksDir.c_str(), &st) == -1) throw SysError(format("statting `%1%'") % linksDir); long long overhead = st.st_size; printMsg(lvlInfo, format("note: currently hard linking saves %.2f MiB") % ((unsharedSize - actualSize - overhead) / (1024.0 * 1024.0))); } void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) { GCState state(results); state.options = options; state.trashDir = settings.nixStore + "/trash"; state.gcKeepOutputs = settings.gcKeepOutputs; state.gcKeepDerivations = settings.gcKeepDerivations; /* Using `--ignore-liveness' with `--delete' can have unintended consequences if `gc-keep-outputs' or `gc-keep-derivations' are true (the garbage collector will recurse into deleting the outputs or derivers, respectively). So disable them. */ if (options.action == GCOptions::gcDeleteSpecific && options.ignoreLiveness) { state.gcKeepOutputs = false; state.gcKeepDerivations = false; } state.shouldDelete = options.action == GCOptions::gcDeleteDead || options.action == GCOptions::gcDeleteSpecific; /* Acquire the global GC root. This prevents a) New roots from being added. b) Processes from creating new temporary root files. */ AutoCloseFD fdGCLock = openGCLock(ltWrite); /* Find the roots. Since we've grabbed the GC lock, the set of permanent roots cannot increase now. */ printMsg(lvlError, format("finding garbage collector roots...")); Roots rootMap = options.ignoreLiveness ? Roots() : findRoots(); foreach (Roots::iterator, i, rootMap) state.roots.insert(i->second); /* Add additional roots returned by 'guix gc --list-busy'. This is typically used to add running programs to the set of roots (to prevent them from being garbage collected). */ if (!options.ignoreLiveness) addAdditionalRoots(*this, state.roots); /* Read the temporary roots. This acquires read locks on all per-process temporary root files. So after this point no paths can be added to the set of temporary roots. */ FDs fds; readTempRoots(state.tempRoots, fds); state.roots.insert(state.tempRoots.begin(), state.tempRoots.end()); /* After this point the set of roots or temporary roots cannot increase, since we hold locks on everything. So everything that is not reachable from `roots' is garbage. */ if (state.shouldDelete) { if (pathExists(state.trashDir)) deleteGarbage(state, state.trashDir); try { createDirs(state.trashDir); } catch (SysError & e) { if (e.errNo == ENOSPC) { printMsg(lvlInfo, format("note: can't create trash directory: %1%") % e.msg()); state.moveToTrash = false; } } } /* Now either delete all garbage paths, or just the specified paths (for gcDeleteSpecific). */ if (options.action == GCOptions::gcDeleteSpecific) { foreach (PathSet::iterator, i, options.pathsToDelete) { assertStorePath(*i); tryToDelete(state, *i); if (state.dead.find(*i) == state.dead.end()) throw Error(format("cannot delete path `%1%' since it is still alive") % *i); } } else if (options.maxFreed > 0) { if (state.shouldDelete) printMsg(lvlError, format("deleting garbage...")); else printMsg(lvlError, format("determining live/dead paths...")); try { AutoCloseDir dir = opendir(settings.nixStore.c_str()); if (!dir) throw SysError(format("opening directory `%1%'") % settings.nixStore); /* Read the store and immediately delete all paths that aren't valid. When using --max-freed etc., deleting invalid paths is preferred over deleting unreachable paths, since unreachable paths could become reachable again. We don't use readDirectory() here so that GCing can start faster. */ Paths entries; struct dirent * dirent; while (errno = 0, dirent = readdir(dir)) { checkInterrupt(); string name = dirent->d_name; if (name == "." || name == "..") continue; Path path = settings.nixStore + "/" + name; if (isValidPath(path)) entries.push_back(path); else tryToDelete(state, path); } dir.close(); /* Now delete the unreachable valid paths. Randomise the order in which we delete entries to make the collector less biased towards deleting paths that come alphabetically first (e.g. /nix/store/000...). This matters when using --max-freed etc. */ vector<Path> entries_(entries.begin(), entries.end()); random_shuffle(entries_.begin(), entries_.end()); foreach (vector<Path>::iterator, i, entries_) tryToDelete(state, *i); } catch (GCLimitReached & e) { } } if (state.options.action == GCOptions::gcReturnLive) { state.results.paths = state.alive; return; } if (state.options.action == GCOptions::gcReturnDead) { state.results.paths = state.dead; return; } /* Allow other processes to add to the store from here on. */ fdGCLock.close(); fds.clear(); /* Delete the trash directory. */ printMsg(lvlInfo, format("deleting `%1%'") % state.trashDir); deleteGarbage(state, state.trashDir); /* Clean up the links directory. */ if (options.action == GCOptions::gcDeleteDead || options.action == GCOptions::gcDeleteSpecific) { printMsg(lvlError, format("deleting unused links...")); removeUnusedLinks(state); } /* While we're at it, vacuum the database. */ //if (options.action == GCOptions::gcDeleteDead) vacuumDB(); } }