Slave( const SlaveInfo& _info, const protobuf::slave::Capabilities& _capabilities, bool _activated, const Resources& _total, const Resources& _allocated) : info(_info), capabilities(_capabilities), activated(_activated), total(_total), allocated(_allocated), shared(_total.shared()), hasGpu_(_total.gpus().getOrElse(0) > 0) { updateAvailable(); }
Future<Nothing> NvidiaGpuIsolatorProcess::update( const ContainerID& containerId, const Resources& resources) { if (containerId.has_parent()) { return Failure("Not supported for nested containers"); } if (!infos.contains(containerId)) { return Failure("Unknown container"); } Info* info = CHECK_NOTNULL(infos[containerId]); Option<double> gpus = resources.gpus(); // Make sure that the `gpus` resource is not fractional. // We rely on scalar resources only having 3 digits of precision. if (static_cast<long long>(gpus.getOrElse(0.0) * 1000.0) % 1000 != 0) { return Failure("The 'gpus' resource must be an unsigned integer"); } size_t requested = static_cast<size_t>(resources.gpus().getOrElse(0.0)); // Update the GPU allocation to reflect the new total. if (requested > info->allocated.size()) { size_t additional = requested - info->allocated.size(); return allocator.allocate(additional) .then(defer(PID<NvidiaGpuIsolatorProcess>(this), &NvidiaGpuIsolatorProcess::_update, containerId, lambda::_1)); } else if (requested < info->allocated.size()) { size_t fewer = info->allocated.size() - requested; set<Gpu> deallocated; for (size_t i = 0; i < fewer; i++) { const auto gpu = info->allocated.begin(); cgroups::devices::Entry entry; entry.selector.type = Entry::Selector::Type::CHARACTER; entry.selector.major = gpu->major; entry.selector.minor = gpu->minor; entry.access.read = true; entry.access.write = true; entry.access.mknod = true; Try<Nothing> deny = cgroups::devices::deny( hierarchy, info->cgroup, entry); if (deny.isError()) { return Failure("Failed to deny cgroups access to GPU device" " '" + stringify(entry) + "': " + deny.error()); } deallocated.insert(*gpu); info->allocated.erase(gpu); } return allocator.deallocate(deallocated); } return Nothing(); }