diff options
Diffstat (limited to 'nix/libstore/optimise-store.cc')
| -rw-r--r-- | nix/libstore/optimise-store.cc | 61 |
1 files changed, 30 insertions, 31 deletions
diff --git a/nix/libstore/optimise-store.cc b/nix/libstore/optimise-store.cc index e17d9160d6c..d69c43e9978 100644 --- a/nix/libstore/optimise-store.cc +++ b/nix/libstore/optimise-store.cc | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | #include <unistd.h> | 12 | #include <unistd.h> |
| 13 | #include <errno.h> | 13 | #include <errno.h> |
| 14 | #include <stdio.h> | 14 | #include <stdio.h> |
| 15 | 15 | #include <format> | |
| 16 | 16 | ||
| 17 | namespace nix { | 17 | namespace nix { |
| 18 | 18 | ||
| @@ -24,9 +24,9 @@ static void makeWritable(const Path & path) | |||
| 24 | { | 24 | { |
| 25 | struct stat st; | 25 | struct stat st; |
| 26 | if (lstat(path.c_str(), &st)) | 26 | if (lstat(path.c_str(), &st)) |
| 27 | throw SysError(format("getting attributes of path `%1%'") % path); | 27 | throw SysError(std::format("getting attributes of path `{}'", path)); |
| 28 | if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1) | 28 | if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1) |
| 29 | throw SysError(format("changing writability of `%1%'") % path); | 29 | throw SysError(std::format("changing writability of `{}'", path)); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | 32 | ||
| @@ -52,7 +52,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash() | |||
| 52 | InodeHash inodeHash; | 52 | InodeHash inodeHash; |
| 53 | 53 | ||
| 54 | AutoCloseDir dir = opendir(linksDir.c_str()); | 54 | AutoCloseDir dir = opendir(linksDir.c_str()); |
| 55 | if (!dir) throw SysError(format("opening directory `%1%'") % linksDir); | 55 | if (!dir) throw SysError(std::format("opening directory `{}'", linksDir)); |
| 56 | 56 | ||
| 57 | struct dirent * dirent; | 57 | struct dirent * dirent; |
| 58 | while (errno = 0, dirent = readdir(dir)) { /* sic */ | 58 | while (errno = 0, dirent = readdir(dir)) { /* sic */ |
| @@ -60,9 +60,9 @@ LocalStore::InodeHash LocalStore::loadInodeHash() | |||
| 60 | // We don't care if we hit non-hash files, anything goes | 60 | // We don't care if we hit non-hash files, anything goes |
| 61 | inodeHash.insert(dirent->d_ino); | 61 | inodeHash.insert(dirent->d_ino); |
| 62 | } | 62 | } |
| 63 | if (errno) throw SysError(format("reading directory `%1%'") % linksDir); | 63 | if (errno) throw SysError(std::format("reading directory `{}'", linksDir)); |
| 64 | 64 | ||
| 65 | printMsg(lvlTalkative, format("loaded %1% hash inodes") % inodeHash.size()); | 65 | printMsg(lvlTalkative, std::format("loaded {} hash inodes", inodeHash.size())); |
| 66 | 66 | ||
| 67 | return inodeHash; | 67 | return inodeHash; |
| 68 | } | 68 | } |
| @@ -73,14 +73,14 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa | |||
| 73 | Strings names; | 73 | Strings names; |
| 74 | 74 | ||
| 75 | AutoCloseDir dir = opendir(path.c_str()); | 75 | AutoCloseDir dir = opendir(path.c_str()); |
| 76 | if (!dir) throw SysError(format("opening directory `%1%'") % path); | 76 | if (!dir) throw SysError(std::format("opening directory `{}'", path)); |
| 77 | 77 | ||
| 78 | struct dirent * dirent; | 78 | struct dirent * dirent; |
| 79 | while (errno = 0, dirent = readdir(dir)) { /* sic */ | 79 | while (errno = 0, dirent = readdir(dir)) { /* sic */ |
| 80 | checkInterrupt(); | 80 | checkInterrupt(); |
| 81 | 81 | ||
| 82 | if (inodeHash.count(dirent->d_ino)) { | 82 | if (inodeHash.count(dirent->d_ino)) { |
| 83 | printMsg(lvlDebug, format("`%1%' is already linked") % dirent->d_name); | 83 | printMsg(lvlDebug, std::format("`{}' is already linked", dirent->d_name)); |
| 84 | continue; | 84 | continue; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| @@ -88,7 +88,7 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa | |||
| 88 | if (name == "." || name == "..") continue; | 88 | if (name == "." || name == "..") continue; |
| 89 | names.push_back(name); | 89 | names.push_back(name); |
| 90 | } | 90 | } |
| 91 | if (errno) throw SysError(format("reading directory `%1%'") % path); | 91 | if (errno) throw SysError(std::format("reading directory `{}'", path)); |
| 92 | 92 | ||
| 93 | return names; | 93 | return names; |
| 94 | } | 94 | } |
| @@ -100,7 +100,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa | |||
| 100 | 100 | ||
| 101 | struct stat st; | 101 | struct stat st; |
| 102 | if (lstat(path.c_str(), &st)) | 102 | if (lstat(path.c_str(), &st)) |
| 103 | throw SysError(format("getting attributes of path `%1%'") % path); | 103 | throw SysError(std::format("getting attributes of path `{}'", path)); |
| 104 | 104 | ||
| 105 | if (S_ISDIR(st.st_mode)) { | 105 | if (S_ISDIR(st.st_mode)) { |
| 106 | Strings names = readDirectoryIgnoringInodes(path, inodeHash); | 106 | Strings names = readDirectoryIgnoringInodes(path, inodeHash); |
| @@ -121,13 +121,13 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa | |||
| 121 | Guix System (example: $fontconfig/var/cache being modified). Skip | 121 | Guix System (example: $fontconfig/var/cache being modified). Skip |
| 122 | those files. FIXME: check the modification time. */ | 122 | those files. FIXME: check the modification time. */ |
| 123 | if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) { | 123 | if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) { |
| 124 | printMsg(lvlError, format("skipping suspicious writable file `%1%'") % path); | 124 | printMsg(lvlError, std::format("skipping suspicious writable file `{}'", path)); |
| 125 | return; | 125 | return; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | /* This can still happen on top-level files. */ | 128 | /* This can still happen on top-level files. */ |
| 129 | if (st.st_nlink > 1 && inodeHash.count(st.st_ino)) { | 129 | if (st.st_nlink > 1 && inodeHash.count(st.st_ino)) { |
| 130 | printMsg(lvlDebug, format("`%1%' is already linked, with %2% other file(s).") % path % (st.st_nlink - 2)); | 130 | printMsg(lvlDebug, std::format("`{}' is already linked, with {} other file(s).", path, (st.st_nlink - 2))); |
| 131 | return; | 131 | return; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| @@ -141,7 +141,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa | |||
| 141 | contents of the symlink (i.e. the result of readlink()), not | 141 | contents of the symlink (i.e. the result of readlink()), not |
| 142 | the contents of the target (which may not even exist). */ | 142 | the contents of the target (which may not even exist). */ |
| 143 | Hash hash = hashPath(htSHA256, path).first; | 143 | Hash hash = hashPath(htSHA256, path).first; |
| 144 | printMsg(lvlDebug, format("`%1%' has hash `%2%'") % path % printHash(hash)); | 144 | printMsg(lvlDebug, std::format("`{}' has hash `{}'", path, printHash(hash))); |
| 145 | 145 | ||
| 146 | /* Check if this is a known hash. */ | 146 | /* Check if this is a known hash. */ |
| 147 | Path linkPath = linksDir + "/" + printHash32(hash); | 147 | Path linkPath = linksDir + "/" + printHash32(hash); |
| @@ -164,12 +164,12 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa | |||
| 164 | /* On ext4, that probably means the directory index is full. When | 164 | /* On ext4, that probably means the directory index is full. When |
| 165 | that happens, it's fine to ignore it: we just effectively | 165 | that happens, it's fine to ignore it: we just effectively |
| 166 | disable deduplication of this file. */ | 166 | disable deduplication of this file. */ |
| 167 | printMsg(lvlInfo, format("cannot link `%1%' to `%2%': %3%") | 167 | printMsg(lvlInfo, std::format("cannot link `{}' to `{}': {}", |
| 168 | % linkPath % path % strerror(ENOSPC)); | 168 | linkPath, path, strerror(ENOSPC))); |
| 169 | return; | 169 | return; |
| 170 | 170 | ||
| 171 | default: | 171 | default: |
| 172 | throw SysError(format("cannot link `%1%' to `%2%'") % linkPath % path); | 172 | throw SysError(std::format("cannot link `{}' to `{}'", linkPath, path)); |
| 173 | } | 173 | } |
| 174 | } | 174 | } |
| 175 | 175 | ||
| @@ -177,20 +177,20 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa | |||
| 177 | current file with a hard link to that file. */ | 177 | current file with a hard link to that file. */ |
| 178 | struct stat stLink; | 178 | struct stat stLink; |
| 179 | if (lstat(linkPath.c_str(), &stLink)) | 179 | if (lstat(linkPath.c_str(), &stLink)) |
| 180 | throw SysError(format("getting attributes of path `%1%'") % linkPath); | 180 | throw SysError(std::format("getting attributes of path `{}'", linkPath)); |
| 181 | 181 | ||
| 182 | if (st.st_ino == stLink.st_ino) { | 182 | if (st.st_ino == stLink.st_ino) { |
| 183 | printMsg(lvlDebug, format("`%1%' is already linked to `%2%'") % path % linkPath); | 183 | printMsg(lvlDebug, std::format("`{}' is already linked to `{}'", path, linkPath)); |
| 184 | return; | 184 | return; |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | if (st.st_size != stLink.st_size) { | 187 | if (st.st_size != stLink.st_size) { |
| 188 | printMsg(lvlError, format("removing corrupted link ‘%1%’") % linkPath); | 188 | printMsg(lvlError, std::format("removing corrupted link `%1%'", linkPath)); |
| 189 | unlink(linkPath.c_str()); | 189 | unlink(linkPath.c_str()); |
| 190 | goto retry; | 190 | goto retry; |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | printMsg(lvlTalkative, format("linking ‘%1%’ to ‘%2%’") % path % linkPath); | 193 | printMsg(lvlTalkative, std::format("linking `%1%' to `%2%'", path, linkPath)); |
| 194 | 194 | ||
| 195 | /* Make the containing directory writable, but only if it's not | 195 | /* Make the containing directory writable, but only if it's not |
| 196 | the store itself (we don't want or need to mess with its | 196 | the store itself (we don't want or need to mess with its |
| @@ -202,8 +202,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa | |||
| 202 | its timestamp back to 0. */ | 202 | its timestamp back to 0. */ |
| 203 | MakeReadOnly makeReadOnly(mustToggle ? dirOf(path) : ""); | 203 | MakeReadOnly makeReadOnly(mustToggle ? dirOf(path) : ""); |
| 204 | 204 | ||
| 205 | Path tempLink = (format("%1%/.tmp-link-%2%-%3%") | 205 | Path tempLink = std::format("{}/.tmp-link-{}-{}", settings.nixStore, getpid(), rand()); |
| 206 | % settings.nixStore % getpid() % rand()).str(); | ||
| 207 | 206 | ||
| 208 | if (link(linkPath.c_str(), tempLink.c_str()) == -1) { | 207 | if (link(linkPath.c_str(), tempLink.c_str()) == -1) { |
| 209 | if (errno == EMLINK) { | 208 | if (errno == EMLINK) { |
| @@ -211,27 +210,27 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa | |||
| 211 | systems). This is likely to happen with empty files. | 210 | systems). This is likely to happen with empty files. |
| 212 | Just shrug and ignore. */ | 211 | Just shrug and ignore. */ |
| 213 | if (st.st_size) | 212 | if (st.st_size) |
| 214 | printMsg(lvlInfo, format("`%1%' has maximum number of links") % linkPath); | 213 | printMsg(lvlInfo, std::format("`{}' has maximum number of links", linkPath)); |
| 215 | return; | 214 | return; |
| 216 | } | 215 | } |
| 217 | throw SysError(format("cannot link `%1%' to `%2%'") % tempLink % linkPath); | 216 | throw SysError(std::format("cannot link `{}' to `{}'", tempLink, linkPath)); |
| 218 | } | 217 | } |
| 219 | 218 | ||
| 220 | /* Atomically replace the old file with the new hard link. */ | 219 | /* Atomically replace the old file with the new hard link. */ |
| 221 | if (rename(tempLink.c_str(), path.c_str()) == -1) { | 220 | if (rename(tempLink.c_str(), path.c_str()) == -1) { |
| 222 | int renameErrno = errno; | 221 | int renameErrno = errno; |
| 223 | if (unlink(tempLink.c_str()) == -1) | 222 | if (unlink(tempLink.c_str()) == -1) |
| 224 | printMsg(lvlError, format("unable to unlink `%1%'") % tempLink); | 223 | printMsg(lvlError, std::format("unable to unlink `{}'", tempLink)); |
| 225 | if (renameErrno == EMLINK) { | 224 | if (renameErrno == EMLINK) { |
| 226 | /* Some filesystems generate too many links on the rename, | 225 | /* Some filesystems generate too many links on the rename, |
| 227 | rather than on the original link. (Probably it | 226 | rather than on the original link. (Probably it |
| 228 | temporarily increases the st_nlink field before | 227 | temporarily increases the st_nlink field before |
| 229 | decreasing it again.) */ | 228 | decreasing it again.) */ |
| 230 | if (st.st_size) | 229 | if (st.st_size) |
| 231 | printMsg(lvlInfo, format("`%1%' has maximum number of links") % linkPath); | 230 | printMsg(lvlInfo, std::format("`{}' has maximum number of links", linkPath)); |
| 232 | return; | 231 | return; |
| 233 | } | 232 | } |
| 234 | throw SysError(format("cannot rename `%1%' to `%2%'") % tempLink % path); | 233 | throw SysError(std::format("cannot rename `{}' to `{}'", tempLink, path)); |
| 235 | } | 234 | } |
| 236 | 235 | ||
| 237 | stats.filesLinked++; | 236 | stats.filesLinked++; |
| @@ -248,7 +247,7 @@ void LocalStore::optimiseStore(OptimiseStats & stats) | |||
| 248 | for (auto& i : paths) { | 247 | for (auto& i : paths) { |
| 249 | addTempRoot(i); | 248 | addTempRoot(i); |
| 250 | if (!isValidPath(i)) continue; /* path was GC'ed, probably */ | 249 | if (!isValidPath(i)) continue; /* path was GC'ed, probably */ |
| 251 | startNest(nest, lvlChatty, format("hashing files in `%1%'") % i); | 250 | startNest(nest, lvlChatty, std::format("hashing files in `{}'", i)); |
| 252 | optimisePath_(stats, i, inodeHash); | 251 | optimisePath_(stats, i, inodeHash); |
| 253 | } | 252 | } |
| 254 | } | 253 | } |
| @@ -260,9 +259,9 @@ void LocalStore::optimiseStore() | |||
| 260 | optimiseStore(stats); | 259 | optimiseStore(stats); |
| 261 | 260 | ||
| 262 | printMsg(lvlError, | 261 | printMsg(lvlError, |
| 263 | format("%1% freed by hard-linking %2% files") | 262 | std::format("{} freed by hard-linking {} files", |
| 264 | % showBytes(stats.bytesFreed) | 263 | showBytes(stats.bytesFreed), |
| 265 | % stats.filesLinked); | 264 | stats.filesLinked)); |
| 266 | } | 265 | } |
| 267 | 266 | ||
| 268 | void LocalStore::optimisePath(const Path & path) | 267 | void LocalStore::optimisePath(const Path & path) |
