| 1545 | |
| 1546 | |
| 1547 | Option<Error> validateResourceLimits( |
| 1548 | const TaskInfo& task, |
| 1549 | Slave* slave) |
| 1550 | { |
| 1551 | auto limits = task.limits(); |
| 1552 | |
| 1553 | if (!limits.empty()) { |
| 1554 | if (!slave->capabilities.taskResourceLimits) { |
| 1555 | return Error("Agent is not capable of handling task resource limits"); |
| 1556 | } |
| 1557 | |
| 1558 | // Ensure that only "cpus" and "mem" are included. |
| 1559 | const size_t cpuCount = limits.count("cpus"); |
| 1560 | const size_t memCount = limits.count("mem"); |
| 1561 | |
| 1562 | if (limits.size() > cpuCount + memCount) { |
| 1563 | return Error( |
| 1564 | "Only cpus and mem may be included in a task's resource limits"); |
| 1565 | } |
| 1566 | |
| 1567 | if (cpuCount) { |
| 1568 | Option<double> taskCpus = Resources(task.resources()).cpus(); |
| 1569 | if (taskCpus.isNone()) { |
| 1570 | return Error( |
| 1571 | "When a CPU limit is specified, a CPU request must also be " |
| 1572 | "specified"); |
| 1573 | } |
| 1574 | |
| 1575 | if (limits.at("cpus").value() < taskCpus.get()) { |
| 1576 | return Error( |
| 1577 | "The cpu limit must be greater than or equal to the cpu request"); |
| 1578 | } |
| 1579 | } |
| 1580 | |
| 1581 | if (memCount) { |
| 1582 | Option<Bytes> taskMem = Resources(task.resources()).mem(); |
| 1583 | if (taskMem.isNone()) { |
| 1584 | return Error( |
| 1585 | "When a memory limit is specified, a memory request must also be " |
| 1586 | "specified"); |
| 1587 | } |
| 1588 | |
| 1589 | if (!std::isinf(limits.at("mem").value()) && |
| 1590 | Bytes(limits.at("mem").value(), Bytes::MEGABYTES) < taskMem.get()) { |
| 1591 | return Error( |
| 1592 | "The memory limit must be greater" |
| 1593 | " than or equal to the memory request"); |
| 1594 | } |
| 1595 | } |
| 1596 | } |
| 1597 | |
| 1598 | return None(); |
| 1599 | } |
| 1600 | |
| 1601 | |
| 1602 | // This validation function should only be executed for tasks which are launched |