Skip to content

Software Update Backends: SWUpdate and Mender

Welma relies on existing software update frameworks as underlying mechanisms for installing update artifacts on the target. The update backend is selected through the WELMA_UPDATE Yocto variable and determines the update artifact format and the mechanism used to install it.

Welma currently supports SWUpdate and Mender. Mender can be used either in standalone mode, where updates are initiated locally through Welma, or in connected mode, where the Mender client communicates with a Mender server to retrieve and deploy updates.

#
# Software Update mechanism
#
# Supported mechanisms: swupdate, mender, mender-connected
WELMA_UPDATE ?= "swupdate"

Regardless of the selected backend, Welma keeps control of its update lifecycle, including partition management, boot selection, rollback and update confirmation.

SWUpdate

SWUpdate is the default software update backend used by Welma.

When this backend is selected:

WELMA_UPDATE = "swupdate"

Yocto generates .swu update artifacts for the modules configured for software update.

Architecture

SWUpdate runs as a daemon on the target and is responsible for writing the content of SWU artifacts to the corresponding partitions.

Welma's updated daemon remains responsible for controlling the overall update transaction.

A simplified installation sequence is (not all D-Bus exchanges are shown):

Application                        updated daemon           SWUpdate daemon
(user)                                (root)                   (root)
│                                        │                        │
├── updatectl install SWU-1 SWU-2        │                        │
│      │                                 │                        │
│      │              (D-Bus)            │                        │
│      ├─────────InstallLocalFiles──────>│                        │
│      │                                 ├── swupdate-client ────>│
│      │                                 │        SWU-1           ├── install
│      │                                 │                        │   to disk
│      │                                 ├── swupdate-client ────>│
│      │                                 │        SWU-2           ├── install
│      │                                 │                        │   to disk
│      │              (D-Bus)            │                        │
│      ├──────────SubmitUpdate──────────>│                        │
│<─────┘                                 ├── write bootflags      │
│                                        │                        │
......................... reboot ..................................
│                                        │
├── updatectl confirm                    │
│      │                                 │
│      └────────────ConfirmUpdate───────>│
│                                        ├── write bootflags

updated receives the update request through its D-Bus API, checks compatibilies and passes the SWU artifacts to SWUpdate using swupdate-client.

For more details about compatibility check, please refer to Welma Version Control

Once all artifacts have been successfully installed, updated updates the bootflags so that the newly installed A/B partitions are selected at the next boot.

After reboot, the update must be confirmed before it becomes persistent.

SWU artifacts

SWU packages generated by Welma at build time are available under:

$DEPLOY_DIR_IMAGE/$IMAGE_LINK_NAME.<partname>.swu

An SWU artifact is a CPIO archive containing:

  • sw-description file
  • Partition image (vfat, ext4 or verity)
  • Welma Binary Tag for versioned images (see Welma Version Control)

The sw-description file describes the content of the update (except the binary tag) and its installation destination.

Welma requirements

To be compatible with Welma, sw-description must:

  • use the SWUpdate default parser syntax (libconfig)
  • contain a single set of images under software.images (using board names is not supported)
  • Have target devices (software.images.[].device) under these paths:
    • /dev/disk/partitions/inactive/ for A/B modules;
    • /dev/disk/partitions/single/ for single modules.

A typical Welma sw-description entry is:

software =
{
    version = "1.0"
    hardware-compatibility = [ "1.0" ]

    images = (
        {
            device = "/dev/disk/partitions/inactive/$partname"
            filename = "$image_file"
            installed-directly = true
        }
    )
}

$partname is replaced at build time with the corresponding Welma module name.

Mender

Mender can be used as an alternative software update backend:

WELMA_UPDATE = "mender"

or:

WELMA_UPDATE = "mender-connected"

Both configurations use Mender artifacts and the Welma Mender Update Module, but differ in how updates are initiated and controlled.

In the following diagrams, /u/s/m/m/v3 is used as a shorthand for:

/usr/share/mender/modules/v3

Mender Standalone

Mender standalone mode uses Mender as a local installation mechanism while Welma remains responsible for initiating the update.

It is enabled with:

WELMA_UPDATE = "mender"

Updates are installed locally using updatectl, similarly to the SWUpdate backend.

Architecture

A simplified update sequence is (not all D-Bus exchanges are shown):

Application                               updated daemon
(user)                                       (root)
│                                               │
├── updatectl install MENDER1 MENDER2           │
│      │                                        │
│      ├───────────InstallLocalFiles───────────>│
│      │                                        ├── mender install MENDER1
│      │                                        │   └── /u/s/m/m/v3/welma
│      │                                        │       └── write to disk
│      │                                        │
│      │                                        ├── mender install MENDER2
│      │                                        │   └── /u/s/m/m/v3/welma
│      │                                        │       └── write to disk
│      │                                        │
│      ├─────────────SubmitUpdate──────────────>│
│<─────┘                                        ├── write bootflags
│                                               │
└── reboot                                      │
...................... reboot ...................
│                                               │
├── updatectl confirm                           │
│      │                                        │
│      └────────────ConfirmUpdate──────────────>│
│                                               ├── write bootflags

In this mode, updated invokes mender install for each artifact. The Welma Mender Update Module is then responsible for writing the module image to its target partition.

Mender artifacts

Welma uses Mender artifacts containing a payload of type welma.

Conceptually, a Mender artifact has the following structure:

Mender Artifact
│
├── header
│
├── payload 0000
│   └── files
│       └── ...
│
├── payload 0001
│   └── files
│       └── ...
│
└── ...

To be compatible with Welma update, a Mender artifact for Welma should comply with the following:

  • Have exactly one payload of type welma
  • The payload shall have:
    • One file for each partition to be installed:
      • The file name indicates the name of the partition where it should be installed
      • The content indicates the name of the image file to be installed
    • One Welma tag for each versioned partition image
    • The image file(s) referenced by the above

Note

Mender extracts its payloads under /var/lib before installation. The filesystem containing /var/lib must therefore have enough free space to temporarily store the extracted update data.

Mender Connected

In connected mode, the Mender daemon drives the installation while the Welma Mender Update Module communicates with updated to keep Welma informed of the modified partitions and update state.

A simplified sequence (not all D-Bus exchanges are shown) is:

Mender daemon                                     updated daemon
(root)                                               (root)
  │                                                    │
  ├── download artifact                                │
  │                                                    │
  ├── /u/s/m/m/v3/welma ArtifactInstall                │
  │   │                                                │
  │   ├── write BOOT to disk                           │
  │   ├──────────── MarkSlotUpdated BOOT ─────────────>│
  │   │                                                │
  │   ├── write SYSRO to disk                          │
  │   ├──────────── MarkSlotUpdated SYSRO ────────────>│
  │   │                                                │
  │   ├── write APPRO to disk                          │
  │   ├──────────── MarkSlotUpdated APPRO ────────────>│
  │   │                                                │
  │   └──────────────── SubmitUpdate ─────────────────>│
  │                                                    ├── write bootflags
  │                                                    │
  └── reboot                                           │
  ......................... reboot .....................
  │                                                    │
  ├── /u/s/m/m/v3/welma ArtifactVerifyReboot           │
  │                                                    │
  ├── /u/s/m/m/v3/welma ArtifactCommit                 │
  │   └──────────────── ConfirmUpdate ────────────────>│
  │                                                    ├── write bootflags

Unlike standalone mode, InstallLocalFile() and InstallLocalFiles() are not used because Mender itself performs the installation.

The Welma Update Module instead calls MarkSlotUpdated() for each modified partition. Once installation is complete, SubmitUpdate() schedules the new partitions for the next boot.

After reboot, the Mender artifact commit phase triggers ConfirmUpdate().

Yocto configuration

Mender Connected requires:

  1. Setup Mender Connected in your conf/local.conf:

    WELMA_UPDATE = "mender-connected"
    MENDER_SERVER_URL = "https://eu.hosted.mender.io"
    MENDER_TENANT_TOKEN = "<organization-token>"
    

    • MENDER_SERVER_URL: US instance (https://hosted.mender.io) or EU instance (https://eu.hosted.mender.io).
    • MENDER_TENANT_TOKEN: can be found in the web page of the hosted Mender platform ("My organization" > "Organization token").
  2. Be sure to have meta-mender-core in your conf/bblayers.conf

  3. The generated output files will be:

    • An SD card image with the whole partitioning (with extensions .wic or .wic.gz) suitable for the first bare-metal installation of the device.
    • Module files with extension .mender for remote updates.

Note

When designing the partition layout, ensure that updateable partitions are large enough to accommodate future software versions.

Runtime configuration

The Mender server can alternatively be configured directly on the running device.

Edit /var/lib/mender/mender.conf and configure:

/var/lib/mender/mender.conf
{
    "ServerURL": "https://eu.hosted.mender.io",
    "TenantToken": "<organization-token>"
}

Then restart the Mender client:

systemctl restart mender-client

The device should then appear as pending on the configured Mender server and can be accepted through the Mender web interface.

Deployment

To deploy an update using Mender Connected:

  1. Create a deployment for the target device from the Mender web interface and upload the Mender artifact generated by Welma.
  2. Wait for the Mender client to detect the deployment, or restart mender-client to trigger communication immediately (this is to avoid waiting for 30 minutes which is the default UpdatePollIntervalSeconds)..
  3. You should see progress of the deployment on the web page of the hosted Mender platform.

    Note: Sometimes the progress bar on the webpage hangs and does not reflect progress in realtime. The current Welma update state can be inspected using:

  4. To enable updates to be initiated by the user, our local agent requires clearance for both downloading and installing updates

    • Run updatectl clearance-notify ready to accept the download of the artifact
    • After few seconds, on Mender's web page, you will notice that the deployment process is waiting to start the installation of the artifact. Run the same command again updatectl clearance-notify ready on your target to accept the installation.
  5. The system will then restart once the installation is over and the Mender daemon will confirm the installation after it has reached the Mender server.

  6. Check update status using updatectl status. Example:

    $ updatectl status
    state               normal
    partitions-active   /dev/mmcblk0p3 /dev/mmcblk0p5 /dev/mmcblk0p7
    partitions-inactive /dev/mmcblk0p4 /dev/mmcblk0p6 /dev/mmcblk0p8
    

Clearance mechanism

Mender Connected integrates with the Welma clearance mechanism so that the embedded application can decide when an update may be downloaded or installed.

Two clearance points are used:

Mender daemon                  updated daemon          application
    │                              │                        │
  detects that a package           │                        │
  is ready for download            │                        │
    │                              │                        │
    ├── Download_Enter_01          │                        │
    │   │                          │                        │
    │   ├── RequestClearance ─────>│                        │
    │   │       "download"         ├─ ClearanceRequested ──>│
    │   │                          │       "download"       │
    │   │                          │                        │
    │   │                          │<─── NotifyClearance ───┤
    │   │                          │        "ready"         │
    │   │<──── reply "ready" ──────┤                        │
    │   │                          │                        │
    │<──┘ exit code 0              │                        │
    │                              │                        │
    ├── download artifact          │                        │
    │                              │                        │
    ├── Download_Leave_01          │                        │
    │   │                          │                        │
    │   ├── RequestClearance ─────>│                        │
    │   │       "install"          ├─ ClearanceRequested ──>│
    │   │                          │       "install"        │
    │   │                          │                        │
    │   │                          │<─── NotifyClearance ───┤
    │   │                          │        "ready"         │
    │   │<──── reply "ready" ──────┤                        │
    │   │                          │                        │
    │<──┘ exit code 0              │                        │
    │                              │                        │
    ├── install artifact           │                        │

Troubleshooting

Mender client logs can be inspected through the system journal:

journalctl -u mender-client

If the Mender client can not connect to the server, typically the first time it tries, and emits messages like the following to syslog at the device:

... level=error msg="authorize failed: transient error: authorization request failed: failed to execute authorization request"

Most commonly this is caused by incorrect time setting on the device which runs the Mender client. Check this by running date on the device, and make sure it is correct.

To determine the status of your time synchronization, execute the following:

timedatectl status

Also verify:

  • the configured Mender server URL;
  • the tenant token;
  • network connectivity;
  • that the device has been accepted by the Mender server;
  • that sufficient storage is available under /var/lib.

See also