| 483 | |
| 484 | |
| 485 | Future<Nothing> NvidiaGpuIsolatorProcess::update( |
| 486 | const ContainerID& containerId, |
| 487 | const Resources& resourceRequests, |
| 488 | const google::protobuf::Map<string, Value::Scalar>& resourceLimits) |
| 489 | { |
| 490 | if (containerId.has_parent()) { |
| 491 | return Failure("Not supported for nested containers"); |
| 492 | } |
| 493 | |
| 494 | if (!infos.contains(containerId)) { |
| 495 | return Failure("Unknown container"); |
| 496 | } |
| 497 | |
| 498 | Info* info = CHECK_NOTNULL(infos[containerId]); |
| 499 | |
| 500 | Option<double> gpus = resourceRequests.gpus(); |
| 501 | |
| 502 | // Make sure that the `gpus` resource is not fractional. |
| 503 | // We rely on scalar resources only having 3 digits of precision. |
| 504 | if (static_cast<long long>(gpus.getOrElse(0.0) * 1000.0) % 1000 != 0) { |
| 505 | return Failure("The 'gpus' resource must be an unsigned integer"); |
| 506 | } |
| 507 | |
| 508 | size_t requested = |
| 509 | static_cast<size_t>(resourceRequests.gpus().getOrElse(0.0)); |
| 510 | |
| 511 | // Update the GPU allocation to reflect the new total. |
| 512 | if (requested > info->allocated.size()) { |
| 513 | size_t additional = requested - info->allocated.size(); |
| 514 | |
| 515 | return allocator.allocate(additional) |
| 516 | .then(defer(PID<NvidiaGpuIsolatorProcess>(this), |
| 517 | &NvidiaGpuIsolatorProcess::_update, |
| 518 | containerId, |
| 519 | lambda::_1)); |
| 520 | } else if (requested < info->allocated.size()) { |
| 521 | size_t fewer = info->allocated.size() - requested; |
| 522 | |
| 523 | set<Gpu> deallocated; |
| 524 | |
| 525 | for (size_t i = 0; i < fewer; i++) { |
| 526 | const auto gpu = info->allocated.begin(); |
| 527 | |
| 528 | cgroups::devices::Entry entry; |
| 529 | entry.selector.type = Entry::Selector::Type::CHARACTER; |
| 530 | entry.selector.major = gpu->major; |
| 531 | entry.selector.minor = gpu->minor; |
| 532 | entry.access.read = true; |
| 533 | entry.access.write = true; |
| 534 | entry.access.mknod = true; |
| 535 | |
| 536 | Try<Nothing> deny = cgroups::devices::deny( |
| 537 | hierarchy, info->cgroup, entry); |
| 538 | |
| 539 | if (deny.isError()) { |
| 540 | return Failure("Failed to deny cgroups access to GPU device" |
| 541 | " '" + stringify(entry) + "': " + deny.error()); |
| 542 | } |
nothing calls this directly
no test coverage detected