Update Raspberry from 32-bit to 64-bit kernel

We are testing the procedure to update some raspberry Pi devices from a 32-bit to a 64-bit build.

I realize that after the update and reboot is done, the “mender-store” file cannot be read anymore by the mender-client. I suppose that the reason for this is that the original file was created on the 32-bit build and then stored on the persistent /data partition.

The only solution I see to launch the mender-client is to delete the “mender-store” file before before. Obviously this is not ideal because some information is lost and as a consequence the update is not committed properly to the server.

Is there any other option to make this work?

Hi @raphaelzaugg that does seem like a bug to me. I can’t imagine why the mender-store file would differ in this case. @lluiscampos any ideas?

At least I get this error message after the update when using the mender-store file that has been created with the 32-bit version before…

“Failed to open DB environment: mdb_env_open: MDB_INVALID: File is not an LMDB file”

LMDB database are not compatible across different architectures.

I have a workaround for you: Attach a state script to the update with the following content:

#!/bin/sh

if [ "$(uname -m)" = "arm" ]; then
    rm -f /data/mender/mender-store*
fi

This has one caveat, namely that the update will be applied twice. What it does is a two pass update, essentially. It starts by applying the update while running on 32-bit. At the end of that, it deletes the database and reboots, causing it to forget that it was doing an update. Because of that, it starts downloading it again as soon as it boots, which in itself is useless, but since we are checking the architecture in the state scripts, we are not deleting the database on the second pass, allowing it to succeed after this.

Note also, that this will mess with rollback, after the second pass has started, the rollback will be unreliable.

1 Like

Hello.

This is the approach that I tested using a state script “ArtifactInstall_Leave_*”
But after the reboot mender-client does not start to download the update again.
The status of the deployment on the server shows “Already Installed” instead when the mender-client connects again to the server after the reboot.

So, yes this somehow works and we can verify the installed reported by the device to confirm this.
It is just that the status reported by the deployment is misleading…

Yes, and in this case you may get an unintentional rollback if the device reboots by itself, because the bootloader is still in the upgrade phase, and will try to roll back.

But I think I know the reason: We need to change the name inside /etc/mender/artifact_info, which is used as a fallback when the second phase starts. This name needs to be different from the name of the artifact, or you will get the “Already installed” message.

Try this:

echo "artifact_name=dummy-name" > artifact_info
mender-artifact cp artifact_info <PATH-TO-ARTIFACT>:/etc/mender/artifact_info

And then deploy that.

I tested this and it seems to work, after the second update it committed correctly to the server.

Do you see any drawback regarding the “wrong” artifact_name that remains in the /etc/mender/artifact_info file? Will that be used somehow by the mender-client?

Great!

The wrong artifact name is of no concern. That file is deprecated, and will only be used when no artifact has ever been installed (which Mender thinks, since you deleted the database). After any artifact has been installed, even an empty one, the database is used to store the name from that point on.

We may remove the file entirely in a future release.

Hello,

We have discussed this a while ago… But we are still using the same process to upgrade from 32-bit to 64-bit Linux distribution.

The workaround we discussed here three years ago does not work anymore. Now, when the device boots on its 64-bit version (after deleting the mender-store file and therefore not remembering that it in the middle up an upgrade) it contracts the serve to check for an update and gets the response “409 Conflict”.

As a consequence the update is marked as failed on the server side and never committed on the client side.

Do you have any new idea how we could handle this regarding this server response that seems to have changed?

Thanks