if the provided name in argument is not null this could lead to un
undefined behavior.
Use strnlen to make this safe
Signed-off-by: Riadh Ghaddab <rghaddab@baylibre.com>
Add a function to get the value's length of a Key. If it doesn't exist
returns 0.
Add ZMS implementation for csi_get_val_len() and a default implementation
for the other storage systems.
Add some functional tests to verify it.
Signed-off-by: Riadh Ghaddab <rghaddab@baylibre.com>
When a power off happens after writing the settings name and before
writing the linked list node we cannot write the settings name again in
the future.
Fix this by writing the linked list node before writing the name.
When loading all settings, we already delete linked list node that do
not have any name or value written.
Adds as well a recover path if a power down happens in the middle of
unlinking an LL node after a delete.
Signed-off-by: Riadh Ghaddab <rghaddab@baylibre.com>
Add a a function settings_load_one that allows to load only one settings
entry instead of a complete subtree.
Add as well its implementation for ZMS backend.
This will allow a faster return if the Settings entry doesn't exist in
the persistent storage.
Signed-off-by: Riadh Ghaddab <rghaddab@baylibre.com>
Increase the load performance by adding an optional cache for the linked
list hashes.
This is used only when the settings_load is called with NULL parameter
and we need to load all Settings that exist in the persistent storage.
Cache is enabled using SETTINGS_ZMS_LL_CACHE and the size of the cache
is set using SETTINGS_ZMS_LL_CACHE_SIZE.
Each cache entry will add 8 bytes of RAM usage.
Signed-off-by: Riadh Ghaddab <rghaddab@baylibre.com>
If the subtree argument is not NULL in the settings_load function, load
only the setting entry that corresponds to that subtree.
If the subtree argument is NULL or it is not found in the storage, load
all the existing entries in the storage.
Signed-off-by: Riadh Ghaddab <rghaddab@baylibre.com>
When deleting a settings entry the linked list is updated by removing
the deleted node. This operation is time consuming and add some delays.
For applications that use almost the same set of Setting entries, add an
option to make this operation faster at a cost of having some empty
nodes in the linked list.
These empty nodes can be used later when the deleted entry is written
again.
Each empty node occupies 16B of storage.
Signed-off-by: Riadh Ghaddab <rghaddab@baylibre.com>
The settings shell returned an unhelpful message when provided
the incorrect arguments. This changes the returned message to
provide the correct usage message.
Signed-off-by: Tim Gibson <timmaxgibson@gmail.com>
Make reading and writing string values more flexible:
1. Eliminate the intermediate buffer when saving a string
setting. This needlessly limited the maximum string
length that could be saved using the shell command.
2. Do not add nor assume that a string saved in the settings
includes the null-terminator. The settings subsystem uses
metadata for encoding the value length, so there it is
redundant to also store the null-terminator in flash.
By the way, also make sure the command handlers only return
-EINVAL and -ENOEXEC error codes as documented in the
handler type description.
Signed-off-by: Damian Krolik <damian.krolik@nordicsemi.no>
To avoid collisions between IDs used by settings and IDs used directly
by subsystems using ZMS API, the MSB is always set to 1 for Setting's
name ID written to ZMS backend
Add as well a recovery path if the hash linked list is broken.
Signed-off-by: Riadh Ghaddab <rghaddab@baylibre.com>
`CONFIG_CONFIG_SETTINGS_FS` has been deprecated for
more than 2 releases, remove it and its associated source
code.
Signed-off-by: Yong Cong Sin <ycsin@meta.com>
Replace flash_area_erase with flash_area_flatten to allow FCB
Settings backend to work on devices that do not provide erase
callback.
Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
When running multiple subsystems or applications on a MCU, the usual
strategy is to use different settings subtrees.
The API provides a way to load or commit a subtree, to avoid adding
dependencies between subsystems or applications, but lacks the way to
save a subtree only. Fix that by adding a settings_save_subtree()
function.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Issue:
When the setting nvs cache is disabled and `settings_nvs_save` is
called, the function reads all stored setting name entries from NVS
until either finds the desired setting name entry or reaches the last
stored setting name entry.
With the settings nvs cache enabled, `settings_nvs_save` runs through
the cached setting name entries first. If the cached entry matches with
the desired one, it immediately writes the new setting value to NVS
that corresponds to the cached setting name entry.
However, if the setting name entry is not found in the cache (which is
the case for a new entry), `settings_nvs_save` reads all stored setting
name entries from NVS again. This means that even if the number of
stored entries in the settings is less than the cache size, for each
new setting entry to be stored `settings_nvs_save` will first run
through the cache, then read all stored setting name entries from NVS
and only then will pick the next free name id for this new setting name
entry and will finally store the new setting entry.
This makes the cache ineffiсient for every new entry to be stored even
when the cache size is always able to keep all setting entries that will
be stored in NVS.
Use-case:
In the Bluetooth mesh there is a Replay Protection List which keeps
sequence numbers of all nodes it received messages from. The RPL is
stored persistently in NVS. The setting name entry is the source
address of the node and the setting value entry is the sequence number.
The common use case is when RPL is quite big (for example, 255 entries).
With the current settings nvs cache implementation, every time the node
stores a new RPL entry in settings (which is the first received message
from a particular source address), `settings_nvs_save` will always check
the cache first, then also read all stored entries in NVS and only then
will figure out that this is a new entry. With every new RPL entry to be
stored this search time increases. This behavior results in much worse
performance in comparison with when the corresponding entry was already
stored. E.g. on nRF52840, with bare minimal mesh stack configuration,
when the cache is bigger than number of stored entries or close to it,
storing of 255 RPL entries takes ~25 seconds. The time of subsequent
store of 255 RPL entires is ~2 seconds with the cache.
Solution:
This commit improves the behavior of the first write by bypassing the
reading from NVS if the following conditions are met:
1. `settings_nvs_load` was called,
2. the cache was not overflowed (bigger than the number of stored
entries).
As long as these 2 conditiones are met, it is safe to skip reading from
NVS, pick the next free name id and write the value immediately.
Signed-off-by: Pavel Vasilyev <pavel.vasilyev@nordicsemi.no>
Settings NVS adds entry into Settings NVS cache after writing it
into flash. Previously, the entry was added into cache only
on the second writing attempt that caused very huge timing
despite cache was enabled since it was still empty.
Signed-off-by: Aleksandr Khromykh <aleksandr.khromykh@nordicsemi.no>
fs_rename can handle the file move atomically without unlinking
the file first if the filesystem supports that. This change makes
the settings file more power cut resilient so that the whole
settings file is not lost with poorly timed power cut.
Signed-off-by: Miika Karanki <miika.karanki@vaisala.com>
Improved the updates to the name ID metadata (NVS_NAMECNT_ID) item
in the Settings NVS backend implementation. The improvements should
make the implementation more robust in handling edge cases such as:
power downs, resets or a case in which the storage partition is
full. In the last case, the NVS backend could return an ENOSPC error
in the context of the settings_delete API. This change also fixes
this issue.
Signed-off-by: Kamil Piszczek <Kamil.Piszczek@nordicsemi.no>
Until now iterable sections APIs have been part of the toolchain
(common) headers. They are not strictly related to a toolchain, they
just rely on linker providing support for sections. Most files relied on
indirect includes to access the API, now, it is included as needed.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Multiple components may use the settings subsystem, so ensure
settings_subsys_init() is thread safe.
Signed-off-by: Stig Bjørlykke <stig.bjorlykke@nordicsemi.no>
Devices with write block size greater than 16 could not use settings_fcb
due to small buffer size.
Update value in test as well.
Signed-off-by: Nicolas VINCENT <nicolas.vincent@vossloh.com>
Prototypes of those functions are already in header files in
subsys/settings/include/settings/ directory, so no reason to have
duplicates in C files.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
There is already CONFIG_SETTINGS_FILE_PATH, which is set to full file path,
while CONFIG_SETTINGS_FILE_DIR is required to be set to its parent
directory. This is redundant, as parent directory path can be easily found
out either during runtime or optionally during buildtime by CMake.
CONFIG_SETTINGS_FILE_DIR was actually introduced recently after Zephyr 3.2
release as a replacement of deprecated CONFIG_SETTINGS_FS_DIR. This means,
that there is no need to deprecate it for 3.3 release and dropping it
should be fine. Adjust 3.3 release notes accordingly, so that
CONFIG_SETTINGS_FILE_PATH will be used directly.
This patch stops using deprecated CONFIG_SETTINGS_FS_DIR. There is actually
no value in respecting it, as setting anything other than parent directory
of CONFIG_SETTINGS_FS_FILE makes no sense.
There is actually one use of CONFIG_SETTINGS_FILE_DIR in file backend
tests, to derive directory for files containing tested settings.
CONFIG_SETTINGS_FILE_PATH is not used there, so it makes little sense to
derive directory name from it. Instead, just use hardcoded "/settings"
subdirectory, as this was the default value of CONFIG_SETTINGS_FILE_DIR.
Deriving parent directory can be done either in runtime or in
buildtime (e.g. using some helper CMake function). Doing it in runtime
however allows to create directory recursively (which this patch actually
implements), e.g. for some more nested FS tree structure. Additionally it
will simplify migration of settings configuration from Kconfig to
device-tree (yet to be developed feature).
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
There is little reason to panic on settings backend initialization error.
Such behavior was introduced with initial settings subsystem support, which
was adapted from MyNewt. This is not the usual way how Zephyr handles
errors, so it is time to change that.
There is already handling of some errors by simply returning / propagating
them to caller. Rework all the paths that resulted in k_panic() to also
return error codes.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
File backend can be read-only with the use of `settings_file_src()` API. It
makes no sense to create file when `settings_load()` is called and
registered file backend won't be used for saving files (because
`settings_file_dst()` was not used).
Do not create file during `settings_load()` if it does not exist yet. This
just requires to remove FS_O_CREATE flag in `fs_open()` invocation.
Open file with read-only access, which is now possible after removal of
`FS_O_CREATE` flag.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
`settings_fcb_save_priv()` already takes `const char *value`, so there is
no reason to cast to `char *` before passing.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
`settings_file_save_priv()` already takes `const char *value`, so there is
no reason to cast to `char *` before passing.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
This function was refactored several times due to many features (like
base64 encoding), which got deprecated over time. Simplify it a bit now.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
This macro is not used anymore and is strictly a leftover, which should be
removed as part of commit 55be783c85 ("settings: Remove deprecated
SETTINGS_USE_BASE64 support").
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
Put all options under one `if SETTINGS` block, so that `depends on
SETTINGS` does not need to be repeated every time.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
Use CONTAINER_OF() macro to access outer backend-specific structure. This
removes the requirement to keep `struct settings_store` as the first item
in outer structure.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
Currently there is inconsistency in repository file names, APIs, Kconfig
options and documentation around file / file-system backend for settings
storage, as both "file" and "FS (file system)" are used. As an example,
there is `CONFIG_SETTINGS_FS` Kconfig option, but the file that implements
this settings backend is called `settings_file.c`. Another example are
names of static functions that implement settings storage API:
`settings_file_load()`, `settings_file_save()` and
`settings_fs_storage_get()`.
This backend is actually storing all settings in a single file, so it makes
sense to use "File" as the name of backend, instead of a more general
"FS" (which would make sense if several files would be used to store
settings).
Fix inconsistency in used wording in the tree and unify it to "settings
file backend". This naming is more precise to how the implementation looks.
It will also make it easier to grep through the codebase and analyze
existing code.
Deprecate settings_mount_fs_backend() function and all Kconfig options
starting with `CONFIG_SETTINGS_FS`.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
The commit switches flash area access from FLASH_AREA_ macros
to FIXED_PARTITION_ macros and to usage of DTS node labels,
to identify partitions, instead of label property.
Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
As of today <zephyr/zephyr.h> is 100% equivalent to <zephyr/kernel.h>.
This patch proposes to then include <zephyr/kernel.h> instead of
<zephyr/zephyr.h> since it is more clear that you are including the
Kernel APIs and (probably) nothing else. <zephyr/zephyr.h> sounds like a
catch-all header that may be confusing. Most applications need to
include a bunch of other things to compile, e.g. driver headers or
subsystem headers like BT, logging, etc.
The idea of a catch-all header in Zephyr is probably not feasible
anyway. Reason is that Zephyr is not a library, like it could be for
example `libpython`. Zephyr provides many utilities nowadays: a kernel,
drivers, subsystems, etc and things will likely grow. A catch-all header
would be massive, difficult to keep up-to-date. It is also likely that
an application will only build a small subset. Note that subsystem-level
headers may use a catch-all approach to make things easier, though.
NOTE: This patch is **NOT** removing the header, just removing its usage
in-tree. I'd advocate for its deprecation (add a #warning on it), but I
understand many people will have concerns.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
On MCU with bank swap capabilities, the offset of the storage area is
not the same before and after a bank swap. This commit introduce a weak
function which returns the default flash area of the storage partition.
On MCU with the bank swap capability the user can define its own
function to get the proper flash area depending on which bank the fw is
run from.
This commit is a workaround for #47732
Signed-off-by: Nicolas VINCENT <nicolas.vincent@vossloh.com>