| 179 | |
| 180 | |
| 181 | void GarbageCollectorProcess::remove(const Timeout& removalTime) |
| 182 | { |
| 183 | if (paths.count(removalTime) > 0) { |
| 184 | list<Owned<PathInfo>> infos; |
| 185 | |
| 186 | foreach (const Owned<PathInfo>& info, paths.get(removalTime)) { |
| 187 | if (info->removing) { |
| 188 | VLOG(1) << "Skipping deletion of '" << info-> path |
| 189 | << "' as it is already in progress"; |
| 190 | continue; |
| 191 | } |
| 192 | |
| 193 | infos.push_back(info); |
| 194 | |
| 195 | // Set `removing` to signify that the path is being cleaned up. |
| 196 | info->removing = true; |
| 197 | } |
| 198 | |
| 199 | Counter _succeeded = metrics.path_removals_succeeded; |
| 200 | Counter _failed = metrics.path_removals_failed; |
| 201 | const string _workDir = workDir; |
| 202 | |
| 203 | auto rmdirs = |
| 204 | [_succeeded, _failed, _workDir, infos]() mutable -> Future<Nothing> { |
| 205 | // Make mutable copies of the counters to work around MESOS-7907. |
| 206 | Counter succeeded = _succeeded; |
| 207 | Counter failed = _failed; |
| 208 | |
| 209 | #ifdef __linux__ |
| 210 | // Clear any possible persistent volume mount points in `infos`. See |
| 211 | // MESOS-8830. |
| 212 | Try<fs::MountInfoTable> mountTable = fs::MountInfoTable::read(); |
| 213 | if (mountTable.isError()) { |
| 214 | LOG(ERROR) << "Skipping any path deletion because of failure on read " |
| 215 | "MountInfoTable for agent process: " |
| 216 | << mountTable.error(); |
| 217 | |
| 218 | foreach (const Owned<PathInfo>& info, infos) { |
| 219 | info->promise.fail(mountTable.error()); |
| 220 | ++failed; |
| 221 | } |
| 222 | |
| 223 | return Failure(mountTable.error()); |
| 224 | } |
| 225 | |
| 226 | foreach (const fs::MountInfoTable::Entry& entry, |
| 227 | adaptor::reverse(mountTable->entries)) { |
| 228 | // Ignore mounts whose targets are not under `workDir`. |
| 229 | if (!strings::startsWith( |
| 230 | path::join(entry.target, ""), |
| 231 | path::join(_workDir, ""))) { |
| 232 | continue; |
| 233 | } |
| 234 | |
| 235 | for (auto it = infos.begin(); it != infos.end(); ) { |
| 236 | const Owned<PathInfo>& info = *it; |
| 237 | // TODO(zhitao): Validate that both `info->path` and `workDir` are |
| 238 | // real paths. |