Skip to content

Configuring IPC and shared memory between containers in QM and root partitions

Cross-environment communication enables containers in the root partition to communicate with containers in the quality-managed (QM) partition using both UNIX domain sockets for inter-process communication (IPC) and shared memory for efficient data sharing. This configuration requires mounting shared volumes in both partitions and configuring appropriate SELinux security labels to enable IPC and shared memory access between the containers.

About the demo code

The demo code uses a pair of C applications packaged as containers — a server running in the root partition and a client running in the QM partition — that communicate over a UNIX domain socket at /run/ipc/ipc_server.socket and share data through shared memory.

To configure the AutoSD OS image build, the Automotive Image Builder (AIB) manifest file specifies:

  • The server container image to add to the root partition
  • The client container image to add to the QM partition
  • The Quadlet unit configurations for both applications
  • A shared volume mount at /run/ipc for socket communication
  • A shared memory mount configuration to enable data sharing between partitions
  • A custom SELinux policy to enable shared memory access

When the built AutoSD system starts, the server creates and binds to the UNIX domain socket, creates shared memory segments, and the client connects to both, enabling IPC and shared memory access between the two applications running in separate partitions.

The sample Containerfiles and C source code available in the demo directory illustrate how to create these containerized applications with proper socket and shared memory handling.

Prerequisites

A custom aib.yml Automotive Image Builder (AIB) manifest file, such as the manifest file that you created in Configuring communication between containers in the root partition.

Procedure

  1. Using Podman, create local containerized versions of the server and client applications using the sample code located in the demo code.

    Note

    The demo code includes C source files (server.c and client.c) and Containerfiles for building the applications. You can use the provided build.sh script to build both container images locally. For AIB to find the the built container images during the build process, you must run the build script as a user with elevated privileges: sudo bash build.sh builds both the application containers and the AutoSD OS image from the AIB manifest, and sudo bash build.sh --noimage builds only the application containers.

  2. Build the custom SELinux policy RPM that enables shared memory access. The demo includes a policy package in the policy/ directory:

    #!/bin/sh
    # Copyright 2019 Red Hat Inc.
    # Copyright 2022 Collabora Ltd.
    # SPDX-License-Identifier: LGPL-2.1-or-later
    
    set -eu
    
    output_dir=$1
    
    TMP=$(mktemp -d selinux-build-XXXXXX)
    cp -t "$TMP/" shm-policy.te shm-policy.fc shm-policy.if
    
    make -C "$TMP" -f /usr/share/selinux/devel/Makefile shm-policy.pp
    bzip2 -9 "$TMP/shm-policy.pp"
    cp "$TMP/shm-policy.pp.bz2" "$output_dir"/shm-policy.pp.bz2
    rm -fr "$TMP"
    

    Note

    This custom policy is required to fix container mount issues with shared memory. For more information, see issue #912.

  3. To copy the local container images to their respective partitions in the OS image, add the following sections to your manifest file:

    1. Add the server container image to the root partition in the content section:

      content:
      ...
          container_images:
            # Get the auto-apps container image from gitlab
            - source: "localhost/server"
              tag: latest
              name: "localhost/server"
              containers-transport: containers-storage
      
    2. Add the custom SELinux policy RPM to the root partition:

      content:
          rpms:
            # For testing the image only:
            - openssh-server
            - openssh-clients
      
            # Install custom policy to fix container mount issue
            # see https://github.com/containers/qm/issues/912
            - shm-policy
      
    3. Add the client container image to the QM partition in the qm section:

      qm:
        content:
      ...
          container_images:
            # Get the auto-apps container image from gitlab
            - source: "localhost/client"
              tag: latest
              name: "localhost/client"
              containers-transport: containers-storage
      
  4. Create Quadlet unit files for both the server and client containers:

    1. Create a server.container Quadlet unit file for the server running in the root partition:

      [Unit]
      Description=Demo server service container
      
      [Container]
      Image=localhost/server
      Volume=/run/ipc:/run/ipc
      Volume=/dev/shm/qm:/dev/shm/qm
      SecurityLabelType=ipc_t
      
      [Service]
      Restart=no
      
      [Install]
      WantedBy=multi-user.target
      
    2. Create a client.container Quadlet unit file for the client running in the QM partition:

      [Unit]
      Description=Demo client service container
      
      [Container]
      Image=localhost/client
      Volume=/run/ipc:/run/ipc
      Volume=/dev/shm/qm:/dev/shm/qm
      SecurityLabelType=qm_container_ipc_t
      
      [Service]
      Restart=no
      
      [Install]
      WantedBy=multi-user.target
      

    Note

    Both containers mount the same volume /dev/shm/qm:/dev/shm/qm for IPC and shared memory, but they use different SELinux security label types:

    • Server (root partition): SecurityLabelType=ipc_t
    • Client (QM partition): SecurityLabelType=qm_container_ipc_t
  5. Create a Quadlet drop-in configuration file for the QM container to ensure the shared volumes are mounted. Create a 10-shm-demo.conf file:

    [Container]
    Volume=/run/ipc:/run/ipc
    Volume=/dev/shm/qm:/dev/shm/qm
    

    Note

    QM configuration is built into the partition and should not be changed. By using drop-in files, you can make additional modifications to the QM partition without overwriting the built-in configuration settings.

  6. Configure the manifest file to copy the Quadlet files and create necessary directories:

    1. Add the directory for the QM container drop-in configuration:

      content:
      ...
          make_dirs:
            - path: /etc/containers/systemd/qm.container.d
              mode: 0755
              parents: true
              exist_ok: true
      
    2. Add the file copying configuration for all Quadlet files and configurations:

      content:
      ...
          add_files:
            - path: /etc/containers/systemd/qm.container.d/10-shm-demo.conf
              source_path: ./10-shm-demo.conf
            - path: /etc/containers/systemd/server.container
              source_path: ./server.container
            - path: /usr/lib/tmpfiles.d/qm_ipc.conf
              source_path: ./qm_ipc.conf
            - path: /usr/lib/tmpfiles.d/shm_qm.conf
              source_path: ./shm_qm.conf
      
    3. Copy the client Quadlet file to the QM partition:

      qm:
        content:
      ...
          add_files:
            - path: /etc/containers/systemd/client.container
              source_path: ./client.container
      
  7. Configure the runtime directory creation by adding a systemd tmpfiles configuration. The demo includes a qm_ipc.conf file that creates the /run/ipc directory:

    D! /run/ipc 0755 root root
    

    This file is copied to /usr/lib/tmpfiles.d/qm_ipc.conf as shown in the manifest file above.

Sample code

The following is a fully functioning demo code sample of an AIB manifest so that two containerized C applications will be added to separate partitions and will automatically start communicating through an IPC Unix domain socket and shared memory.

Sample shared_memory_qm_root.aib.yml file
# Example manifest building an image with two applications talking to each
# other over IPC (here an unix domain socket) between the QM and root
# partition and sharing data via Shared Memory

name: shared_memory_qm_root

content:
    rpms:
      # For testing the image only:
      - openssh-server
      - openssh-clients

      # Install custom policy to fix container mount issue
      # see https://github.com/containers/qm/issues/912
      - shm-policy

    container_images:
      # Get the auto-apps container image from gitlab
      - source: "localhost/server"
        tag: latest
        name: "localhost/server"
        containers-transport: containers-storage

    make_dirs:
      - path: /etc/containers/systemd/qm.container.d
        mode: 0755
        parents: true
        exist_ok: true

    add_files:
      - path: /etc/containers/systemd/qm.container.d/10-shm-demo.conf
        source_path: ./10-shm-demo.conf
      - path: /etc/containers/systemd/server.container
        source_path: ./server.container
      - path: /usr/lib/tmpfiles.d/qm_ipc.conf
        source_path: ./qm_ipc.conf
      - path: /usr/lib/tmpfiles.d/shm_qm.conf
        source_path: ./shm_qm.conf

    systemd:
      enabled_services:
        # Enable ssh daemon - Required for testing the image only
        - sshd.service

qm:
  content:
    repos:
      - id: epel
        baseurl: https://dl.fedoraproject.org/pub/epel/10/Everything/$arch/
    rpms:
      - podman
      - vsomeip3-routingmanager
      - dlt-daemon
      # For testing the image only:
      - openssh-server
      - openssh-clients

    container_images:
      # Get the auto-apps container image from gitlab
      - source: "localhost/client"
        tag: latest
        name: "localhost/client"
        containers-transport: containers-storage

    add_files:
      - path: /etc/containers/systemd/client.container
        source_path: ./client.container

    systemd:
      enabled_services:
        # Enable the dlt daemon
        - dlt

auth:
  # "password"
  root_password: $6$xoLqEUz0cGGJRx01$H3H/bFm0myJPULNMtbSsOFd/2BnHqHkMD92Sfxd.EKM9hXTWSmELG8cf205l6dktomuTcgKGGtGDgtvHVXSWU.
  # Required for testing the image only:
  sshd_config:
    PasswordAuthentication: true
    PermitRootLogin: true

Next steps

  • Now that you have configured the manifest and Quadlet unit files to set up communication between containers in different partitions using both IPC and shared memory, you can build your AutoSD OS image. For more information, see Building an image from a custom manifest.
  • Alternatively, you can continue customizing your image. For more information, see Containerized applications.

Additional resources


© Red Hat