-
Notifications
You must be signed in to change notification settings - Fork 53
RDKEMW-16534: Make container swap limit configurable independently of memory limit #425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
90c154b
f5dca9f
8e4394b
abd7d86
30d0b05
85d83e8
8cbd876
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -125,6 +125,51 @@ Usage: DobbyBundleGenerator <option(s)> | |||||
| -o, --outputDirectory=PATH Where to save the generated OCI bundle | ||||||
| ``` | ||||||
|
|
||||||
| ## Dobby Spec Format | ||||||
| When using `DobbyDaemon` or `DobbyBundleGenerator`, containers are described using a Dobby-specific JSON spec file. Example specs can be found in `tests/L2_testing/dobby_specs/`. | ||||||
|
|
||||||
| The table below lists the supported top-level fields. Fields marked **mandatory** must always be present. | ||||||
|
|
||||||
| | Field | Type | Mandatory | Description | | ||||||
| |-------|------|-----------|-------------| | ||||||
| | `version` | string | Yes | Spec version. Currently `"1.0"` or `"1.1"`. | | ||||||
| | `args` | array | Yes | Command and arguments to run inside the container. | | ||||||
| | `user` | object | Yes | `uid` and `gid` the container process runs as. | | ||||||
| | `memLimit` | integer | Yes | Memory limit in bytes (`memory.limit_in_bytes`). Must be ≥ 256 KiB. | | ||||||
|
||||||
| | `memLimit` | integer | Yes | Memory limit in bytes (`memory.limit_in_bytes`). Must be ≥ 256 KiB. | | |
| | `memLimit` | integer | Yes | Memory limit in bytes (`memory.limit_in_bytes`). Values below 256 KiB are accepted but only generate a warning and may not be effective. | |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -62,6 +62,8 @@ static const ctemplate::StaticTemplateString USERNS_DISABLED = | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| static const ctemplate::StaticTemplateString MEM_LIMIT = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| STS_INIT(MEM_LIMIT, "MEM_LIMIT"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| static const ctemplate::StaticTemplateString MEM_SWAP = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| STS_INIT(MEM_SWAP, "MEM_SWAP"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| static const ctemplate::StaticTemplateString CPU_SHARES_ENABLED = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| STS_INIT(CPU_SHARES_ENABLED, "CPU_SHARES_ENABLED"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -187,6 +189,7 @@ static const ctemplate::StaticTemplateString SECCOMP_SYSCALLS = | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #define JSON_FLAG_FILECAPABILITIES (0x1U << 20) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #define JSON_FLAG_VPU (0x1U << 21) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #define JSON_FLAG_SECCOMP (0x1U << 22) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #define JSON_FLAG_SWAPLIMIT (0x1U << 23) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int DobbySpecConfig::mNumCores = -1; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -504,7 +507,8 @@ bool DobbySpecConfig::parseSpec(ctemplate::TemplateDictionary* dictionary, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { "cpu", { JSON_FLAG_CPU, &DobbySpecConfig::processCpu } }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { "devices", { JSON_FLAG_DEVICES, &DobbySpecConfig::processDevices } }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { "capabilities", { JSON_FLAG_CAPABILITIES, &DobbySpecConfig::processCapabilities } }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { "seccomp", { JSON_FLAG_SECCOMP, &DobbySpecConfig::processSeccomp } } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { "seccomp", { JSON_FLAG_SECCOMP, &DobbySpecConfig::processSeccomp } }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { "swapLimit", { JSON_FLAG_SWAPLIMIT, &DobbySpecConfig::processSwapLimit } } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // step 1 - parse the 'dobby' spec document | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -627,6 +631,16 @@ bool DobbySpecConfig::parseSpec(ctemplate::TemplateDictionary* dictionary, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dictionary->SetIntValue(RLIMIT_RTPRIO, 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!(flags & JSON_FLAG_SWAPLIMIT)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // swapLimit not supplied: default swap to memLimit (no extra swap) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const Json::Value& memLimitVal = mSpec["memLimit"]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (memLimitVal.isIntegral()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dictionary->SetIntValue(MEM_SWAP, memLimitVal.asUInt()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+634
to
+642
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!(flags & JSON_FLAG_CAPABILITIES)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dictionary->SetValue(NO_NEW_PRIVS, "true"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1278,6 +1292,54 @@ bool DobbySpecConfig::processMemLimit(const Json::Value& value, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ----------------------------------------------------------------------------- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @brief Processes the optional swap limit field. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * When present, this value is used as the cgroup memory.memsw.limit_in_bytes, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * allowing swap to be configured independently of the memory limit. When | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * absent the swap limit defaults to the same value as memLimit (i.e. no | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * extra swap beyond the memory limit). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * The kernel requires swap >= memLimit, so an error is returned if the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * supplied value is smaller than the memLimit already set. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Example json: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * "swapLimit": 2097152 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param[in] value The json spec document from the client | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param[in] dictionary Pointer to the OCI dictionary to populate | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return true if correctly processed the value, otherwise false. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool DobbySpecConfig::processSwapLimit(const Json::Value& value, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ctemplate::TemplateDictionary* dictionary) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!value.isIntegral()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AI_LOG_ERROR("invalid swapLimit field"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unsigned memSwap = value.asUInt(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // the kernel requires memory.memsw.limit_in_bytes >= memory.limit_in_bytes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const Json::Value& memLimitVal = mSpec["memLimit"]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (memLimitVal.isIntegral() && (memSwap < memLimitVal.asUInt())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AI_LOG_ERROR("swapLimit (%u) must be >= memLimit (%u)", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| memSwap, memLimitVal.asUInt()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1327
to
+1337
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unsigned memSwap = value.asUInt(); | |
| // the kernel requires memory.memsw.limit_in_bytes >= memory.limit_in_bytes | |
| const Json::Value& memLimitVal = mSpec["memLimit"]; | |
| if (memLimitVal.isIntegral() && (memSwap < memLimitVal.asUInt())) | |
| { | |
| AI_LOG_ERROR("swapLimit (%u) must be >= memLimit (%u)", | |
| memSwap, memLimitVal.asUInt()); | |
| return false; | |
| } | |
| // Validate that swapLimit is not negative before converting to unsigned | |
| const int64_t memSwapSigned = value.asInt64(); | |
| if (memSwapSigned < 0) | |
| { | |
| AI_LOG_ERROR("swapLimit must be non-negative"); | |
| return false; | |
| } | |
| // the kernel requires memory.memsw.limit_in_bytes >= memory.limit_in_bytes | |
| const Json::Value& memLimitVal = mSpec["memLimit"]; | |
| if (memLimitVal.isIntegral()) | |
| { | |
| const int64_t memLimitSigned = memLimitVal.asInt64(); | |
| if (memLimitSigned < 0) | |
| { | |
| AI_LOG_ERROR("memLimit must be non-negative when swapLimit is specified"); | |
| return false; | |
| } | |
| if (memSwapSigned < memLimitSigned) | |
| { | |
| AI_LOG_ERROR("swapLimit (%lld) must be >= memLimit (%lld)", | |
| static_cast<long long>(memSwapSigned), | |
| static_cast<long long>(memLimitSigned)); | |
| return false; | |
| } | |
| } | |
| unsigned memSwap = static_cast<unsigned>(memSwapSigned); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The markdown table is using
||at the start of each row, which introduces an unintended empty first column and renders oddly on GitHub. Use a single leading|for the header/separator/rows to format the table correctly.