Reading mender storage database

December 18, 2023: Getting to know your mender-store

I recently had to debug how mender finds out what you are actually running via the mender show-artifact command. I always thought that it just reads the artifact_info/etc/mender/artifact_info file and outputs whatever it contains.

Turns out that this is NOT, or no longer the case if you use mender 3 and upwards.

We use mender 2.6.1 in our project, as that is what our supplier has chosen and is well supported by our dunfell yocto branchYocto releases . Drilling down from the cli/cli.go file down to “device/device.go” we find following artifact info retrieval code.

func (d *DeviceManager) GetCurrentArtifactName() (string, error) {
	if d.Store != nil {
		dbname, err := d.Store.ReadAll(datastore.ArtifactNameKey)
		if err == nil {
			name := string(dbname)
			log.Debugf("Returning artifact name %s from database.", name)
			return name, nil
		} else if err != os.ErrNotExist {
			log.Errorf("Could not read artifact name from database: %s", err.Error())
		}
	}
	log.Debugf("Returning artifact name from %s file.", d.ArtifactInfoFile)
	return GetManifestData("artifact_name", d.ArtifactInfoFile" %})
}

So mender actually asks some database if it knows the current artifact name. It turns out that the artifact_info file is deprecatedsee here . So what kind of database is this and where is it located?

The mender-store

mender uses a databaase format I never encountered before, the Lightning Memory-Mapped database. Unfortunately the database is architecture dependent, so you can generally not just copy it from your Embedded Linux to your desktop PC and debug it.
You can however “dump” it via some lmdb tools. The database is normally located or at least symlinked to /var/lib/mendersee Github .

The database format is interesting, incorporating a B+ Tree and is very memory efficient and fast.

Reading the lmdb store

By installing the bitabake lmdb package in our image we have access to the lmdb tools, namely mdb_dump and mdb_stat.

We can now dump the content of the mender store.

$ mdb_dump -n /var/lib/mender/mender-store -p
VERSION=3
format=print
type=btree
mapsize=1048576
maxreaders=126
db_pagesize=4096
HEADER=END
artifact-name
ImageCustomer
artifact-provides
{"rootfs-image.checksum":"b61ca0ca0115057ad4206256dab66ea3a02715cf810b0ba0f1505d4216aeedbd","rootfs-image.version":"ImageCustomer"}
DATA=END

$ mdb_stat -n /var/lib/mender/mender-store
Status of Main DB
Tree depth: 1
Branch pages: 0
Leaf pages: 1
Overflow pages: 0
Entries: 2

So there is not a lot saved in the datbase, at least in mender version 2.6.

The artifact-provides gets written by app/standalone.go cleanup functionsee the different mender states

While the rootfs-image.checksum gets used during installation, I have not found any indication that it is actually still used afterwards, e.g. to ensure that we boot a valid partition or something like that.

Reading mender storage database - December 18, 2023 - S. Egli