summaryrefslogtreecommitdiffstats
path: root/common/state/state.h
Commit message (Collapse)AuthorAgeFilesLines
* state: backend: direct: open backend in read-only mode if possibleAhmad Fatoum2023-01-161-1/+1
| | | | | | | | | | | | | | | | | We unconditionally open the device backing a direct bucket in read-write mode. We already populate struct state_backend_storage::readonly though, which we could consult at device open time. Do so. This could possibly be done for MTD as well, but until that's tested, for now, we do it only for the direct backend meant for use with block devices. This has no functional change for barebox, which calls state_new_from_node in the DT driver and in the EFI initcall always with readonly=false, but we can benefit from this in barebox_state to open a device in read-only mode when possible (e.g. when called to --dump). Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Link: https://lore.barebox.org/20230116125443.713033-1-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* Rename struct device_d to deviceSascha Hauer2023-01-101-7/+7
| | | | | | | | | | | | | The '_d' suffix was originally introduced in case we want to import Linux struct device as a separate struct into barebox. Over time it became clear that this won't happen, instead barebox struct device_d is basically the same as Linux struct device. Rename the struct name accordingly to make porting Linux code easier. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Reviewed-by: Marco Felsch <m.felsch@pengutronix.de> Link: https://lore.barebox.org/20221214123512.189688-3-s.hauer@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* treewide: add SPDX-License-Identifier for files without explicit licenseAhmad Fatoum2022-01-051-0/+2
| | | | | | | | | Record GPL-2.0-only as license for all files lacking an explicit license statement. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Link: https://lore.barebox.org/20220103120539.1730644-12-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: make first boot less verboseAhmad Fatoum2021-12-071-1/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | First boot with uninitialized state is needlessly verbose: state: New state registered 'state' state: Detected old on-storage format ERROR: state: Error, invalid header crc in raw format, calculated 0x7bd5c66f, found 0x00000000 state: Ignoring broken bucket 0@0x00000000... state: Detected old on-storage format ERROR: state: Error, invalid header crc in raw format, calculated 0x7bd5c66f, found 0x00000000 state: Ignoring broken bucket 1@0x00040000... state: Detected old on-storage format ERROR: state: Error, invalid header crc in raw format, calculated 0x7bd5c66f, found 0x00000000 state: Ignoring broken bucket 2@0x00080000... ERROR: state: Failed to find any valid state copy in any bucket ERROR: state: Failed to read state with format raw, -2 This has confused barebox-state novices more than once. Let's handle the zeroed state case specially and reduce output in that case, so it now looks like this: state: New state registered 'state' state: Detected old on-storage format state: Detected old on-storage format state: Detected old on-storage format state state.of: Fresh state detected, continuing with defaults This is only the output when CRC is zero (hinting at zeroed state partition). If crc != zero, then output is a little more verbose than before: state: New state registered 'state' state: Detected old on-storage format ERROR: state: init error: Invalid argument: header crc in raw format, calculated 0x7bd5c66f, found 0x00000000 state: Ignoring broken bucket 0@0x00000000... state: Detected old on-storage format ERROR: state: init error: Invalid argument: header crc in raw format, calculated 0x7bd5c66f, found 0x00000000 state: Ignoring broken bucket 1@0x00040000... state: Detected old on-storage format ERROR: state: init error: Invalid argument: header crc in raw format, calculated 0x7bd5c66f, found 0x00000000 state: Ignoring broken bucket 2@0x00080000... ERROR: state: init error: No such file or directory: no valid state copy in any bucket ERROR: state: init error: No such file or directory: format raw read failed WARNING: state state.of: Failed to load persistent state, continuing with defaults, -2 Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Link: https://lore.barebox.org/20211125161042.3829996-3-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: mark state init errors speciallyAhmad Fatoum2021-12-071-0/+7
| | | | | | | | | | First boot with uninitialized state is needlessly verbose. As preparation for making boot less noisy on fresh state, mark all the error messages with newly introduced dev_err_state_init(). Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Link: https://lore.barebox.org/20211125161042.3829996-2-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: remove param member from state_uint32, state_enum32, state_macChristian Eggers2020-01-271-3/+0
| | | | | | | After adding the parameter, the pointer isn't required anymore. Signed-off-by: Christian Eggers <ceggers@arri.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: remove param member from struct state_stringChristian Eggers2020-01-271-1/+0
| | | | | | | After adding the parameter, the pointer isn't required anymore. Signed-off-by: Christian Eggers <ceggers@arri.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* common: state: fix typoUlrich Ölmann2019-02-071-1/+1
| | | | | Signed-off-by: Ulrich Ölmann <u.oelmann@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* common: state: Add property to protect existing dataDaniel Schultz2018-04-161-0/+2
| | | | | | | | | | | After an update to a newer barebox version with an enabled state framework, existing data in storage memories could be overwritten. Add a new property to check in front of every write task, if the meta magic field only contains the magic number, zeros or ones. Signed-off-by: Daniel Schultz <d.schultz@phytec.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: find backend node with its reproducible nameSascha Hauer2018-02-221-0/+1
| | | | | | | | | | | | When fixing up the kernels state nodes we depended on the full node path of the input device tree. This does not work when the kernel device tree has different names. This has happened lately when the i.MX6 device trees got their leading zeroes removed from the node names. Use of_find_node_by_reproducible_name() to find the node corresponding to the storage backend node in the kernel device tree. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: Add 'init_from_defaults' parameterSascha Hauer2018-02-061-0/+2
| | | | | | | The init_from_defaults parameter allows to detect if a state has been initialized from default values, i.e. state_load failed. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* common: state: Add variable type as enumDaniel Schultz2017-11-071-0/+9
| | | | | | | | | | | The variable_type struct holds a name of its type. Checking the type of a variable with this string needs much resources. This patch introduce a enum of the variable type for better type checking. Signed-off-by: Daniel Schultz <d.schultz@phytec.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* common: state: Add variable_type to state_variableDaniel Schultz2017-11-071-3/+5
| | | | | | | | Add a pointer in state_variable to the corresponding variable_type array element. Signed-off-by: Daniel Schultz <d.schultz@phytec.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: remove unused variable typeSascha Hauer2017-04-041-11/+0
| | | | | | enum state_variable_type is never used. Remove it. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: find device node from device path, not from device node pathSascha Hauer2017-03-311-1/+1
| | | | | | | | | The device node path may change from the internal device tree to the one Linux is started with, so using this path to fixup the tree is not very robust. Instead, use of_find_node_by_devpath() which has been created for exactly this purpose. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: Allow to load without authentificationSascha Hauer2017-03-311-2/+7
| | | | | | | Sometimes it's useful to be able to load a state even when it can't be authentificated. Add an option for this. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: backend: Add more fields to struct state_backend_storageSascha Hauer2017-03-311-0/+6
| | | | | | To save a few function arguments. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: bucket: Make output more informativeSascha Hauer2017-03-311-0/+3
| | | | | | | | | | | Print offset and number of the bucket along with the bucket specific messages to give a hint which bucket a message is for. Also it's pretty much expected that buckets sometimes have no data or need cleanup, so instead of complaining loudly, only write which bucket is used and which buckets are cleaned up. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: Drop cache bucketSascha Hauer2017-03-311-3/+4
| | | | | | | | | | | | | | The cache bucket sits between the storage functions and the backend storage. We only read from the storage once, so there is no need to cache anything. The real purpose of the cache bucket is to keep the -EUCLEAN information when a NAND block needs to be rewritten and to keep the read buffers as long as the backend iterates over all buckets trying to find the one we want to use. This can be coded easier and more obvious in the backend code, so drop the cache bucket. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: Convert all bufs to void *Sascha Hauer2017-03-311-8/+8
| | | | | | | | A void * is a much better type for a buffer than a u8 * as it can be casted to any other type implicitly. Convert all buffers used by the state framework to void *. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: replace len_hint logicSascha Hauer2017-03-311-1/+1
| | | | | | | | The len_hint mechanism is rather hard to understand as it's not clear from where to where the hint is passed and also it's not clear what happens if the hint is empty or wrong. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: drop lazy_initSascha Hauer2017-03-311-4/+1
| | | | | | | | | lazy_init is an optimization that makes it possible to read only up to the first valid bucket when starting. However, when restoring consistency, immediately afterwards we have we have to initialize all buckets anyway, so being lazy doesn't give us any gain. Remove it to simplify the code. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: pass struct state * to storage functionsSascha Hauer2017-03-311-2/+1
| | | | | | | We can get a state_backend_storage * and the device * from struct state, so pass this to the storage functions rather than the two pointers. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: merge backend.c into state.cSascha Hauer2017-03-311-6/+0
| | | | | | | The code in backend.c is too small to justify an extra file. Merge it into state.c. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: Drop backend as extra struct typeSascha Hauer2017-03-311-17/+6
| | | | | | | struct state_backend is embedded into struct state. This additional indirection does not have any real gain. Drop it. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: backend: remove len_hint argument from state_storage_readSascha Hauer2017-03-311-2/+1
| | | | | | The argument is 0 in the only caller, so remove the argument. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: backend: remove .get_packed_lenSascha Hauer2017-03-311-2/+0
| | | | | | | .get_packed_len isn't implemented by any backend, so remove the hook and its potential caller. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: make locally used function staticSascha Hauer2016-09-201-1/+0
| | | | | | state_set_dirty() is only used in one file, make it static. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: Add state to state_variableSascha Hauer2016-09-201-2/+1
| | | | | | | A state variable should know which state it belongs to. Add field for it to struct state_variable. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: don't keep pointers to device tree nodesMichael Olbrich2016-09-201-1/+1
| | | | | | | | | | Caching pointers to device tree nodes or is not save. The barebox internal device tree may be changed by loading a new device tree or through fixup handlers. As a result, the node may be deleted and replaced with a new one. Keep a copy of the full path instead and resolve the node as needed. Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: copy backend of_path stringMichael Olbrich2016-09-201-1/+1
| | | | | | | | | | Caching pointers to device tree nodes or names is not safe. The barebox internal device tree may be changed by loading a new device tree or through fixup handlers. As a result, the string may be deleted. Use local copies of the full path instead. Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: Save on shutdownSascha Hauer2016-07-221-0/+1
| | | | | | | | | The state framework is meant for storing persistent variables. To make the state more persistent automatically save it on shutdown. This is now the default behaviour, but can be disabled using a 'save_on_shutdown' variable attached to the state. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: also append backend storage stridesizeMichael Grzeschik2016-07-081-0/+2
| | | | | Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* state: Refactor state frameworkMarkus Pargmann2016-07-081-0/+275
The state framework grew organically over the time. Unfortunately the architecture and abstractions disappeared during this period. This patch refactors the framework to recreate the abstractions. The main focus was the backend with its storage. The main use-case was to offer better NAND support with less erase cycles and interchangeable data formats (dtb,raw). The general architecture now has a backend which consists of a data format and storage. The storage consists of multiple storage buckets each holding exactly one copy of the state data. A data format describes a data serialization for the state framework. This can be either dtb or raw. A storage bucket is a storage location which is used to store any data. There is a (new) circular type which writes changes behind the last written data and therefore reduces the number of erases. The other type is a direct bucket which writes directly to a storage offset for all non-erase storage. Furthermore this patch splits up all classes into different files in a subdirectory. This is currently all in one patch as I can't see a good way to split the changes up without having a non-working state framework in between. The following diagram shows the new architecture roughly: .----------. | state | '----------' | | v .----------------------------. | state_backend | |----------------------------| | + state_load(*state); | | + state_save(*state); | | + state_backend_init(...); | | | | | '----------------------------' | | The format describes | | how the state data | '-------------> is serialized | .--------------------------------------------. | | state_backend_format <INTERFACE> | | |--------------------------------------------| | | + verify(*format, magic, *buf, len); | | | + pack(*format, *state, **buf, len); | | | + unpack(*format, *state, *buf, len); | | | + get_packed_len(*format, *state); | | | + free(*format); | | '--------------------------------------------' | ^ ^ | * * | * * | .--------------------. .--------------------. | | backend_format_dtb | | backend_format_raw | | '--------------------' '--------------------' | | | v .----------------------------------------------------------. | state_backend_storage | |----------------------------------------------------------| | + init(...); | | + free(*storage); | | + read(*storage, *format, magic, **buf, *len, len_hint); | | + write(*storage, *buf, len); | | + restore_consistency(*storage, *buf, len); | '----------------------------------------------------------' | The backend storage is responsible to manage multiple data copies and distribute them onto several buckets. Read data is verified against the given format to ensure that the read data is correct. | | | | | v .------------------------------------------. | state_backend_storage_bucket <INTERFACE> | |------------------------------------------| | + init(*bucket); | | + write(*bucket, *buf, len); | | + read(*bucket, **buf, len_hint); | | + free(*bucket); | '------------------------------------------' ^ ^ ^ * * * * * * A storage bucket represents*exactly one data copy at one data location. A circular b*cket writes any new data to the end of the bucket (for *educed erases on NAND). A direct bucket directly writ*s at one location. * * * * * * * * * .-----------------------. * .-------------------------. | backend_bucket_direct | * | backend_bucket_circular | '-----------------------' * '-------------------------' ^ * ^ | * | | * | | * | | .-----------------------. | '--| backend_bucket_cached |---' '-----------------------' A backend_bucket_cached is a transparent bucket that directly uses another bucket as backend device and caches all accesses. Signed-off-by: Markus Pargmann <mpa@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>