{"id":18497817,"url":"https://github.com/containers/qm","last_synced_at":"2025-10-03T17:57:14.312Z","repository":{"id":81215640,"uuid":"572471573","full_name":"containers/qm","owner":"containers","description":"QM is a containerized environment for running Functional Safety qm (Quality Management) software","archived":false,"fork":false,"pushed_at":"2024-12-11T17:43:08.000Z","size":9040,"stargazers_count":24,"open_issues_count":29,"forks_count":26,"subscribers_count":13,"default_branch":"main","last_synced_at":"2024-12-11T18:44:02.346Z","etag":null,"topics":["auto","car","container","embedded","linux","podman","qm","quadlet","safety","safety-critical","secure","secure-by-design"],"latest_commit_sha":null,"homepage":"https://github.com/containers/qm","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/containers.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-30T10:51:37.000Z","updated_at":"2024-12-05T15:00:18.000Z","dependencies_parsed_at":"2023-05-04T08:01:40.803Z","dependency_job_id":"a3f80813-606a-4205-bf3a-70d23da9877c","html_url":"https://github.com/containers/qm","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Fqm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Fqm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Fqm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Fqm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/containers","download_url":"https://codeload.github.com/containers/qm/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230537062,"owners_count":18241515,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auto","car","container","embedded","linux","podman","qm","quadlet","safety","safety-critical","secure","secure-by-design"],"created_at":"2024-11-06T13:36:03.682Z","updated_at":"2025-10-03T17:57:09.272Z","avatar_url":"https://github.com/containers.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Topics\n\n- [Topics](#topics)\n  - [QM is a containerized environment for running functional safety Quality Management software](#qm-is-a-containerized-environment-for-running-functional-safety-quality-management-software)\n  - [QM SELinux policy](#qm-selinux-policy)\n  - [BlueChi](#bluechi)\n  - [RPM building dependencies](#rpm-building-dependencies)\n  - [How OOM score adjustment is used in QM](#how-oom-score-adjustment-is-used-in-qm)\n    - [Priority process of OOM killer in the QM context](#priority-process-of-oom-killer-in-the-qm-context)\n  - [Contributing to the QM project](#contributing-to-the-qm-project)\n  - [Realtime](#realtime)\n  - [Talks and videos](#talks-and-videos)\n  - [RPM mirrors](#rpm-mirrors)\n  - [Configuring QM](#configuring-qm)\n    - [Modifying the `MemoryHigh` variable](#modifying-the-memoryhigh-variable)\n\n## QM is a containerized environment for running functional safety Quality Management software\n\nThe main purpose of the Quality Management (QM) environment is to allow users to configure\nan environment that prevents applications and container tools from interfering with\nother processes on the system, such as in Automotive Safety Integrity Level (ASIL)\nprocesses and applications. AutoSD is not a certified safety product. In the context of\nAutoSD, QM is not for use in production environments but for research and learning purposes only.\n\nThe QM environment uses containerization tools, such as cgroups, namespaces, and\nsecurity isolation, to prevent accidental interference by processes in the QM.\n\nThe QM runs its own version of systemd and Podman to isolate not only the\napplications and containers launched by systemd and Podman, but also systemd and\nPodman commands themselves.\n\nThis package requires the Podman package to establish the containerized\nenvironment and uses Quadlet to set it up. Refer to the [docs directory](docs/quadlet-examples/)\nfor example Quadlet files.\n\nSoftware installed in the QM environment under `/usr/lib/qm/rootfs` is\nautomatically isolated from the host. To further isolate these processes\nfrom other processes in the QM, developers can use container tools, such as Podman.\n\n## QM SELinux policy\n\nThe QM SELinux policy isolates QM parts of the operating system\nfrom the other domain-specific functional safety levels, such as ASIL.\n\nThe main purpose of this policy is to prevent applications and container\ntools from interfering with other processes on the system. The QM must\nisolate containers from `qm_t` processes as well as from other containers.\n\nFor now, all of the control processes in the QM other than containers run\nwith the same `qm_t` type. For more information, refer to `man qm_selinux`.\n\nFor support with a specific SELinux issue, open a [QM issue](https://github.com/containers/qm/issues)\nand include the SELinux error output from a recent QM-related operation.\n\nThe following commands yield output that can help determine the root cause of the issue:\n\n```console\nausearch -m avc -ts recent | audit2why\njournalctl -t setroubleshoot\nsealert -a /var/log/audit/audit.log\n```\n\n## BlueChi\n\n- [BlueChi](https://github.com/containers/qm/pull/57)\n\nThe package configures the bluechi-agent within the QM.\n\nBlueChi is a systemd service controller intended for use in highly regulated\necosystems that feature multi-node environments with a predefined number of nodes.\nPotential use cases can be found in industries that require functional safety,\nsuch as the transportation industry in which services must be controlled across different\nedge devices and where traditional orchestration tools do not comply with\nregulatory requirements.\n\nSystems with QM installed have two systemd processes running on them. The QM\nbluechi-agent is based on the hosts `/etc/bluechi/agent.conf` file. By default, any\nchanges to the system's `agent.conf` file are reflected in the QM `/etc/bluechi/agent.conf` file.\nYou can further customize the QM bluechi-agent by adding content to the\n`/usr/lib/qm/rootfs/etc/bluechi/agent.conf.d/` directory.\n\n```console\n# dnf install -y python3-dnf-plugins-core\n# dnf config-manager --set-enabled crb\n```\n\n## RPM building dependencies\n\nTo build QM packages on CentOS Stream 9, enable the Code Ready Builder\nrepository for access to the `golang-github-cpuguy83-md2man` package.\n\n## How OOM score adjustment is used in QM\n\nThe Linux host kernel controls ASIL and QM processes. The Out-of-Memory (OOM) Killer is part of the Linux\nkernel's memory management subsystem. OOM Killer terminates processes to release RAM in memory-constrained conditions.\nThe `oom_score_adj` parameter refers to the Out-of-Memory score adjustment in Linux operating systems.\nThe OOM Killer uses the `oom_score_adj` parameter to decide which processes to terminate when the system is\ncritically low on memory.\n\nBy fine-tuning which processes are more likely to be terminated during low-memory situations,\ncritical processes can be protected, which enhances the overall stability of the system.\n\n- For example, ASIL applications are essential to maintaining functional safety in automotive systems.\nYou can set their OOM score adjustment value from *-1* to *-1000*. To prioritize their operation\neven in low-memory situations, setting the value to *-1000* makes the process immune to the OOM killer\nand ensures that ASIL applications are the last to be terminated.\n\n- The QM process has a default OOM score adjustment value set to *500*, configured via the `qm.container` file.\n\n```console\ncat /usr/share/containers/systemd/qm.container | grep OOMScoreAdjust\n# OOMScoreAdjust=500\n```\n\n- All nested containers created inside the QM have a default OOM score adjustment of *750*.\n\n```console\n$ cat /usr/share/qm/containers.conf | grep oom_score_adj\noom_score_adj = 750\n```\n\n### Adjusting OOM Score for Nested Containers\n\nYou can customize the OOM score adjustment for nested containers running inside QM. This requires both nested container configurations and QM capability adjustments.\n\n**Important Note:** To customize OOM scores for QM nested containers, you need to add the `SYS_RESOURCE` capability. The default QM configuration drops `SYS_RESOURCE` capability for security reasons. While adding this capability is not recommended, if it's absolutely necessary, the steps below demonstrate how to modify the default QM container definition.\n\n#### Step 1: Create Nested Container Configurations\n\nCreate nested container configurations in `/etc/qm/containers/systemd/`:\n\n**Create:** `/etc/qm/containers/systemd/nested.container`\n\n```ini\n[Container]\nContainerName=nested\nImage=alpine:latest\nExec=sleep 1d\nNetwork=none\n\n[Service]\nOOMScoreAdjust=1000\n```\n\n**Create:** `/etc/qm/containers/systemd/nested2.container`\n\n```ini\n[Container]\nContainerName=nested2\nImage=alpine:latest\nExec=sleep 1d\nNetwork=none\n\n[Service]\nOOMScoreAdjust=100\n```\n\n#### Step 2: Modify QM Capabilities (Required but Not Recommended)\n\nCreate a QM drop-in file to override the default capability restrictions. This adds back the `SYS_RESOURCE` capability that QM drops by default:\n\n**Create:** `/etc/containers/systemd/qm.container.d/100-AddCAPA.conf`\n\n```ini\n[Container]\nDropCapability=\nDropCapability=sys_boot\nAddCapability=sys_resource\n```\n\n#### Step 3: Verify and Apply the Configuration\n\n1. **Check the generated systemd configuration:**\n\n   ```bash\n   sudo /usr/lib/systemd/system-generators/podman-system-generator --dryrun\n   ```\n\n   Look for the ExecStart line and verify it contains:\n\n   ```text\n   --cap-drop sys_boot --cap-add all --cap-add sys_resource\n   ```\n\n2. **Apply the changes:**\n\n   ```bash\n   sudo systemctl daemon-reload\n   sudo systemctl restart qm\n   ```\n\n3. **Test the nested containers inside QM:**\n\n   ```bash\n   # Enter the QM container\n   sudo podman exec -it qm /bin/bash\n\n   # Start first nested container and check its OOM score\n   systemctl start nested\n   PID=$(podman inspect -f '{{.State.Pid}}' nested)\n   cat /proc/$PID/oom_score_adj\n   # Should output: 1000\n\n   # Start second nested container and check its OOM score\n   systemctl start nested2\n   PID=$(podman inspect -f '{{.State.Pid}}' nested2)\n   cat /proc/$PID/oom_score_adj\n   # Should output: 100\n   ```\n\nThis allows fine-grained control over OOM killer priority for different nested containers based on their importance.\n\n### Priority process of OOM killer in the QM context\n\n```txt\n+-------------------------------------------------------------+\n| The Priority Process of OOM Killer in the QM Context        |\n+-------------------------------------------------------------+\n\n------------------------------------ Kernel space -----------------------------------------------\n\n                           +--------------------------------+\n                           | Out of Memory Killer Mechanism |\n                           |          (OOM Killer)          |\n                           +--------------------------------+\n                                          |\n                                          v\n                           +--------------------------------+\n                           |       Kernel Scheduler         |\n                           +--------------------------------+\n\n------------------------------------ User space -------------------------------------------------\n\n                    +----------------------------------------+\n                    |       Out of Memory Score Adjustment   |\n                    |            (oom_score_adj)             |\n                    +----------------------------------------+\n                                    |\n                                    |\n                                    v (Processes Priority side by side)\n      +-----------------------------+--------------------------+-----------------------+\n      |                             |                          |                       |\n      v                             v                          v                       v\n+------------------+  +----------------------------+   +-----------------+     +-----------------+\n|                  |  |                            |   |                 |     |                 |\n|    QM Container  |  |  Nested Containers by QM   |   |  ASIL Apps      |     | Other Processes |\n|                  |  |                            |   |                 |     |                 |\n|     OOM Score    |  |         OOM Score          |   |   OOM Score     |     |    OOM Score    |\n|        500       |  |            750             |   |   -1 to -1000   |     |    (default: 0) |\n+------------------+  +----------------------------+   +-----------------+     +-----------------+\n          |                         |                           |                      |\n          v                         v                           v                      v\n   +----------------+      +----------------+         +--------------------+    +-----------------+\n   | Lower priority |      | Higher priority|         | Very low priority  |    | Default priority|\n   | for termination|      | for termination|         | for termination    |    | for termination |\n   +----------------+      +----------------+         +--------------------+    +-----------------+\n                                    |\n                                    |\n                                    |\n                                    v\n         +-------------------------------------------------------------+\n         |                                                             |\n         | In conclusion, all nested containers created inside QM have |\n         | their OOM score adjustment set to 750, making them more     |\n         | likely to be terminated first compared to the QM process.   |\n         |                                                             |\n         | When compared to ASIL applications, nested containers       |\n         | will have an even higher likelihood of being terminated.    |\n         |                                                             |\n         | Compared to other processes with the default adjustment     |\n         | value of 0, nested containers are still more likely to be   |\n         | terminated first, ensuring the system and ASIL apps are     |\n         | kept as safe as possible.                                   |\n         |                                                             |\n         +-------------------------------------------------------------+\n\n------------------------------------ User space -------------------------------------------------\n\n------------------------------------ Kernel space -----------------------------------------------\n```\n\n## Contributing to the QM project\n\nFor information about how to contribute to the QM project, see the [Developers documentation README](docs/devel/README.md).\n\n## Realtime\n\nTo enable real-time removal of sched_* blockage via seccomp, use the following schema:\n\n```bash\ncat \u003c\u003c EOF \u003e\u003e /etc/containers/systemd/qm.container.d/rt.conf\n\u003e [Container]\nSeccompProfile=\"\"\n\u003e EOF\n```\n\n## Talks and videos\n\nLet's spread the knowledge regarding QM. If you have interesting content pertaining to\nQM-related technology, please share it with us.\n\n## RPM mirrors\n\nLooking for a specific version of QM? Search the [CentOS Automotive SIG Stream Mirror](https://mirror.stream.centos.org/SIGs/9-stream/automotive/aarch64/packages-main/Packages/q/). The packages in CentOS Automotive SIG Stream Mirror are for experimentation only.\n\n## Configuring QM\n\nTo run QM on an immutable OSTree-based OS, we use systemd units with Podman Quadlet.\nFor more information on how `podman-systemd.unit` works, refer to the manual:\n\n`man podman-systemd.unit`\n\nThe default QM configuration drop-in file is located in `/usr/share/containers/systemd/qm.container`.\nModifying the original service file is not an option. Instead, create drop-in files to\nmodify the default configuration.\n\n**NOTE:** The configuration is built in alphabetical order of the drop-in files.\n\n### Modifying the `MemoryHigh` variable\n\nTo override the default settings, create a new drop-in `.conf` file in the\n`/etc/containers/systemd/qm.container.d/` directory. This method ensures that QM memory\nusage is controlled without modifying the base system configuration.\n\n1. Check the current memory limit:\n\n```bash\n\nsystemctl show -P MemoryHigh qm\n\ninfinity\n\n```\n\nThe command output `infinity` indicates that `MemoryHigh` is unlimited. You can\nsee this setting in `/usr/share/containers/systemd/qm.container`.\n\n1. Create a directory for the new drop-in file:\n\n```bash\n\nmkdir -p /etc/containers/systemd/qm.container.d/\n\n```\n\n1. Create a new drop-in file:\n\n```bash\nvim /etc/containers/systemd/qm.container.d/100-MemoryMax.conf\n```\n\nIn this example, the new drop-in file is named `100-MemoryMax.conf`. You can choose a different name,\nbut be aware that the configuration is built in alphabetical order of the drop-in files.\n\n1. Edit the file to add the following content:\n\n```bash\n\n[Service]\n\nMemoryHigh=2G\n\n```\n\n`MemoryHigh` is specified in gigabytes. 2G means 2 gigabytes.\n\n1. Preview the updated systemd configuration:\n\n```bash\n\n/usr/lib/systemd/system-generators/podman-system-generator {--user} --dryrun\n\n```\n\n1. Reload systemd and restart `qm.service` to apply the configuration changes:\n\n```bash\n\nsystemctl daemon-reload\n\nsystemctl restart qm.service\n\n```\n\n1. Verify the value of `MemoryHigh`:\n\n```bash\n\nsystemctl show -P MemoryHigh qm\n\n2147483648\n```\n\nMemory values are displayed in bytes; 2147483648 bytes = 2G, which confirms that `MemoryHigh` is set to 2G.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontainers%2Fqm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcontainers%2Fqm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontainers%2Fqm/lists"}