Azure / iot-hub-device-update

Device Update for IoT Hub agent
MIT License
52 stars 41 forks source link

Proxy update with reboot: update restarts instead of continuing #646

Open D-r-P-3-p-p-3-r opened 1 month ago

D-r-P-3-p-p-3-r commented 1 month ago

We're planning to use Device Update for IoT Hub for an embedded device (ARM) which is running a custom-built Linux.

To evaluate the build, deployment, and operation of the device update agent, I've created a "manual" build of DUA 1.1.0 in a Debian 11 VM. I.e. I did not use apt packages for the installation, but I built the device agent in the VM (including its dependencies).

As we're planning to use proxy updates I've written

The update package contains 6 steps

After step 1 a reboot is required, because it's an A/B update and we have to switch slots.

The custom flash update handler requests a reboot after the install step by calling workflow_request_immediate_reboot(workflowData->WorkflowHandle);

Setting the return value of ADUC_Result flash_update_handler::Install([[maybe_unused]]const tagADUC_WorkflowData* workflowData); to ADUC_Result_Install_RequiredImmediateReboot doesn't seem to be enough and doesn't trigger a reboot. I find this weird because I have to implement an interface, but the correct behavior of the extension relies on side effects and not just the contract defined by the interface. But that's a different story.

Unfortunately, the reboot seems to interrupt the logging. The last line I see in the journal is

Jul 31 12:01:25 AducIotAgent[2571]: 2024-07-31T10:01:25.4072Z 2571[2589] [I] Loading extension 'foo/flash:1'. Reg file : /var/lib/adu/extensions/update_content_handlers/foo_flash_1/content_handler.json [LoadExtensionLibrary:85]

So I'm not quite sure what happens after the install step and before rebooting.

After the VM reboots the DUA restarts. But it doesn't seem to continue the update where it left off, but restarts enumerating all components again and checks if they are installed. Now, step 0 (the flashed component) reports that it is already installed. The other components of course do not and thus get installed. In the end, all components are updated.

In the device twin, the device now reports that it is updated to the latest version:

{
    "__t": "c",
    "agent": {
        "deviceProperties": {
            "manufacturer": "foo",
            "model": "bar",
            "contractModelId": "dtmi:azure:iot:deviceUpdateContractModel;3",
            "aduVer": "DU;agent/1.1.0"
        },
        "compatPropertyNames": "manufacturer,model",
        "lastInstallResult": {
            "resultCode": 700,
            "extendedResultCodes": "00000000,A0000FFF",
            "stepResults": {
                "step_0": {
                    "resultCode": 603,
                    "extendedResultCodes": "00000000",
                    "resultDetails": ""
                },
                "step_1": {
                    "resultCode": 700,
                    "extendedResultCodes": "00000000",
                    "resultDetails": ""
                },
                "step_2": {
                    "resultCode": 700,
                    "extendedResultCodes": "00000000",
                    "resultDetails": ""
                },
                "step_3": {
                    "resultCode": 700,
                    "extendedResultCodes": "00000000",
                    "resultDetails": ""
                },
                "step_4": {
                    "resultCode": 700,
                    "extendedResultCodes": "00000000",
                    "resultDetails": ""
                },
                "step_5": {
                    "resultCode": 700,
                    "extendedResultCodes": "00000000",
                    "resultDetails": ""
                }
            },
            "resultDetails": ""
        },
        "state": 0,
        "workflow": {
            "action": 3,
            "id": "f64ab3bb-8796-4ea4-b993-9a559ef7d1c9"
        },
        "installedUpdateId": "{\"provider\":\"foo\",\"name\":\"bar\",\"version\":\"17.0.0.1\"}"
    }
}

The state of the device is correct now, but the ugly thing is, that step_0's resultCode is 603 (already installed). The reason for this is, that the update restarted and did not continue.

Is this normal/expected behavior or am I doing something wrong? E.g. in the custom flash extension or the DUA configuration.

Nox-MSFT commented 3 weeks ago

@D-r-P-3-p-p-3-r , first, thank you for your feedback and detailed information.

If the step_0 resultCode is 603 (already installed), this probably mean that the 'Is_Installed' logic for the step_0, returned '900' (ADUC_Result_IsInstalled_Installed). Please double check your logic in IsInstalled function.

If you need to perform additional tasks (in step_0) after the firmware has been updated, and device rebooted, you should make sure that the IsInstalled doesn't return 900 until all tasks has been completed successfully.

Please let me know