mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2026-01-28 01:47:18 +01:00
Reference DB: add file lock to prevent race condition when updating reference DB file
Added an exclusive file locking mechanism using `flock()` to ensure that only one process at a time can update the '/var/state/bbfdm_reference_db' file. This prevents data loss or corruption caused by concurrent access. This change improves robustness when `bbfdm_refresh_references()` is called by multiple processes in parallel.
This commit is contained in:
parent
ab5cde2c42
commit
4a3a7ca0b1
2 changed files with 42 additions and 5 deletions
|
|
@ -1921,24 +1921,26 @@ static void create_required_sections(struct dmctx *ctx)
|
|||
dmuci_rename_section_by_section(ref_s, ctx->in_value);
|
||||
} else {
|
||||
struct uci_list *uci_list = NULL;
|
||||
struct uci_element *e = NULL, *tmp = NULL;
|
||||
struct uci_element *e = NULL;
|
||||
|
||||
dmuci_get_value_by_section_list(ref_s, "reference_path", &uci_list);
|
||||
if (uci_list != NULL) {
|
||||
|
||||
uci_foreach_element_safe(uci_list, tmp, e) {
|
||||
uci_foreach_element(uci_list, e) {
|
||||
dmuci_set_value_varstate("bbfdm_reference_db", "reference_path", e->name, "");
|
||||
dmuci_del_list_value_by_section(ref_s, "reference_path", e->name);
|
||||
}
|
||||
|
||||
dmuci_set_value_by_section_varstate(ref_s, "reference_path", "");
|
||||
}
|
||||
|
||||
dmuci_get_value_by_section_list(ref_s, "reference_value", &uci_list);
|
||||
if (uci_list != NULL) {
|
||||
|
||||
uci_foreach_element_safe(uci_list, tmp, e) {
|
||||
uci_foreach_element(uci_list, e) {
|
||||
dmuci_set_value_varstate("bbfdm_reference_db", "reference_value", e->name, "");
|
||||
dmuci_del_list_value_by_section(ref_s, "reference_value", e->name);
|
||||
}
|
||||
|
||||
dmuci_set_value_by_section_varstate(ref_s, "reference_value", "");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/file.h>
|
||||
#include <libubox/blobmsg.h>
|
||||
#include <libubox/uloop.h>
|
||||
#include <libubus.h>
|
||||
|
|
@ -779,6 +782,33 @@ void bbfdm_ubus_load_data_model(DM_MAP_OBJ *DynamicObj)
|
|||
INTERNAL_ROOT_TREE = DynamicObj;
|
||||
}
|
||||
|
||||
static int bbfdm_lock_reference_db(void)
|
||||
{
|
||||
#define BBF_LOCK_FILE "/var/lock/bbfdm_reference_db.lock"
|
||||
|
||||
int fd = open(BBF_LOCK_FILE, O_CREAT | O_RDWR, 0666);
|
||||
if (fd == -1) {
|
||||
BBF_ERR("Error opening lock file %s: %s", BBF_LOCK_FILE, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flock(fd, LOCK_EX) == -1) {
|
||||
BBF_ERR("Error locking file %s: %s", BBF_LOCK_FILE, strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd; // Lock held
|
||||
}
|
||||
|
||||
static void bbfdm_unlock_reference_db(int lock_fd)
|
||||
{
|
||||
if (lock_fd >= 0) {
|
||||
flock(lock_fd, LOCK_UN);
|
||||
close(lock_fd);
|
||||
}
|
||||
}
|
||||
|
||||
int bbfdm_refresh_references(unsigned int dm_type, const char *srv_obj_name)
|
||||
{
|
||||
char hash_str[9] = {0};
|
||||
|
|
@ -791,6 +821,10 @@ int bbfdm_refresh_references(unsigned int dm_type, const char *srv_obj_name)
|
|||
.dm_type = dm_type
|
||||
};
|
||||
|
||||
int lock_fd = bbfdm_lock_reference_db();
|
||||
if (lock_fd == -1)
|
||||
return -1;
|
||||
|
||||
bbf_init(&bbf_ctx);
|
||||
int res = bbfdm_cmd_exec(&bbf_ctx, BBF_REFERENCES_DB);
|
||||
|
||||
|
|
@ -804,6 +838,7 @@ int bbfdm_refresh_references(unsigned int dm_type, const char *srv_obj_name)
|
|||
}
|
||||
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
bbfdm_unlock_reference_db(lock_fd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue