|
10 | 10 | #include <algorithm> |
11 | 11 | #include <chrono> |
12 | 12 | #include <stdexcept> |
| 13 | +#include <string> |
13 | 14 | #include <thread> |
14 | 15 | #include <utility> |
15 | 16 | #include <variant> |
16 | 17 |
|
| 18 | +#include <fmt/format.h> |
17 | 19 | #include <re2/re2.h> |
18 | 20 |
|
19 | 21 | #include <folly/Executor.h> |
@@ -280,7 +282,7 @@ void SaplingBackingStore::initializeOBCCounters() { |
280 | 282 | getTreePerRepoLatencies_ = monitoring::OBCP99P95P50( |
281 | 283 | monitoring::OdsCategoryId::ODS_EDEN, |
282 | 284 | fmt::format("eden.store.sapling.fetch_tree_{}_us", repoName_), |
283 | | - {hostname}); |
| 285 | + {std::move(hostname)}); |
284 | 286 | isOBCEnabled_ = true; |
285 | 287 | } |
286 | 288 | #endif |
@@ -2492,6 +2494,79 @@ ImmediateFuture<bool> SaplingBackingStore::checkPermission( |
2492 | 2494 | return result.has_access; |
2493 | 2495 | } |
2494 | 2496 |
|
| 2497 | +folly::coro::now_task<std::vector<folly::Try<std::vector<EntryAcl>>>> |
| 2498 | +SaplingBackingStore::co_getPathAcls( |
| 2499 | + const RootId& rootId, |
| 2500 | + const std::vector<std::string>& paths, |
| 2501 | + const ObjectFetchContextPtr& context) { |
| 2502 | + auto self = shared_from_this(); |
| 2503 | + // TODO(T272514471): Plumb ObjectFetchContext through the Sapling FFI so path |
| 2504 | + // ACL lookups are attributed in fetch traces like other backing-store calls. |
| 2505 | + (void)context; |
| 2506 | + co_await self->faultInjector_.co_checkAsync( |
| 2507 | + "SaplingBackingStore::getPathAcls", rootId.value()); |
| 2508 | + co_return co_await folly::coro::co_withExecutor( |
| 2509 | + self->serverThreadPool_, |
| 2510 | + folly::coro::co_invoke( |
| 2511 | + [self, rootId = rootId, paths = std::vector<std::string>(paths)]() |
| 2512 | + -> folly::coro::Task< |
| 2513 | + std::vector<folly::Try<std::vector<EntryAcl>>>> { |
| 2514 | + rust::Vec<rust::String> rustPaths; |
| 2515 | + rustPaths.reserve(paths.size()); |
| 2516 | + std::copy( |
| 2517 | + paths.begin(), paths.end(), std::back_inserter(rustPaths)); |
| 2518 | + |
| 2519 | + auto result = sapling_backingstore_check_path_permissions( |
| 2520 | + *self->store_.get(), |
| 2521 | + rust::Str{rootId.value().data(), rootId.value().size()}, |
| 2522 | + std::move(rustPaths)); |
| 2523 | + if (result.error != nullptr) { |
| 2524 | + throw std::runtime_error(result.error->what()); |
| 2525 | + } |
| 2526 | + |
| 2527 | + std::vector<folly::Try<std::vector<EntryAcl>>> aclInfos; |
| 2528 | + aclInfos.reserve(paths.size()); |
| 2529 | + if (result.data.size() != paths.size()) { |
| 2530 | + throw std::runtime_error( |
| 2531 | + fmt::format( |
| 2532 | + "path ACL lookup returned {} result(s) for {} path(s)", |
| 2533 | + result.data.size(), |
| 2534 | + paths.size())); |
| 2535 | + } |
| 2536 | + |
| 2537 | + for (size_t index = 0; index < paths.size(); ++index) { |
| 2538 | + const auto& pathAclInfo = result.data[index]; |
| 2539 | + std::string responsePath{pathAclInfo.path}; |
| 2540 | + if (responsePath != paths[index]) { |
| 2541 | + throw std::runtime_error( |
| 2542 | + fmt::format( |
| 2543 | + "path ACL lookup returned response for {} at index {} instead of {}", |
| 2544 | + responsePath, |
| 2545 | + index, |
| 2546 | + paths[index])); |
| 2547 | + } |
| 2548 | + |
| 2549 | + std::string error{pathAclInfo.error}; |
| 2550 | + if (!error.empty()) { |
| 2551 | + aclInfos.emplace_back(std::runtime_error(error)); |
| 2552 | + continue; |
| 2553 | + } |
| 2554 | + |
| 2555 | + std::vector<EntryAcl> entries; |
| 2556 | + entries.reserve(pathAclInfo.entries.size()); |
| 2557 | + for (const auto& entry : pathAclInfo.entries) { |
| 2558 | + entries.push_back( |
| 2559 | + EntryAcl{ |
| 2560 | + std::string{entry.restriction_root}, |
| 2561 | + std::string{entry.repo_region_acl}, |
| 2562 | + std::string{entry.permission_request_group}}); |
| 2563 | + } |
| 2564 | + aclInfos.emplace_back(std::move(entries)); |
| 2565 | + } |
| 2566 | + co_return aclInfos; |
| 2567 | + })); |
| 2568 | +} |
| 2569 | + |
2495 | 2570 | void SaplingBackingStore::logBackingStoreFetch( |
2496 | 2571 | const ObjectFetchContext& context, |
2497 | 2572 | folly::Range<SlOidView*> slOids, |
|
0 commit comments