If node configuration is completely removed from the system, remove all pending writes to the configuration file. Fixes the segfault below: mesh/cfgmod-server.c:node_reset() Node Reset mesh/mesh-config-json.c:mesh_config_destroy() Delete node config /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c mesh/util.c:del_fobject() RM /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c/rpl/00000000/0001 mesh/util.c:del_fobject() RMDIR /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c/rpl/00000000 mesh/util.c:del_fobject() RMDIR /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c/rpl mesh/util.c:del_fobject() RM /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c/node.json.bak mesh/util.c:del_fobject() RM /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c/node.json mesh/util.c:del_fobject() RMDIR /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c Segmentation fault Program terminated with signal SIGSEGV, Segmentation fault. 0x0000563a35df2ed0 in ?? () 0x00007fd6b131689f in json_object_to_json_string_length (jso=jso@entry=0x563a35dd8d30, flags=flags@entry=2, --- mesh/mesh-config-json.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/mesh/mesh-config-json.c b/mesh/mesh-config-json.c index 172e0e355..97267b6c3 100644 --- a/mesh/mesh-config-json.c +++ b/mesh/mesh-config-json.c @@ -54,6 +54,7 @@ struct mesh_config { uint8_t uuid[16]; uint32_t write_seq; struct timeval write_time; + struct l_queue *idles; }; struct write_info { @@ -1677,6 +1678,7 @@ static struct mesh_config *create_config(const char *cfg_path, memcpy(cfg->uuid, uuid, 16); cfg->node_dir_path = l_strdup(cfg_path); cfg->write_seq = node->seq_number; + cfg->idles = l_queue_new(); gettimeofday(&cfg->write_time, NULL); return cfg; @@ -2104,6 +2106,7 @@ static bool load_node(const char *fname, const uint8_t uuid[16], memcpy(cfg->uuid, uuid, 16); cfg->node_dir_path = l_strdup(fname); cfg->write_seq = node.seq_number; + cfg->idles = l_queue_new(); gettimeofday(&cfg->write_time, NULL); result = cb(&node, uuid, cfg, user_data); @@ -2130,17 +2133,26 @@ done: return result; } +static void release_idle(void *data) +{ + struct l_idle *idle = data; + + l_idle_remove(idle); +} + void mesh_config_release(struct mesh_config *cfg) { if (!cfg) return; + l_queue_destroy(cfg->idles, release_idle); + l_free(cfg->node_dir_path); json_object_put(cfg->jnode); l_free(cfg); } -static void idle_save_config(void *user_data) +static void idle_save_config(struct l_idle *idle, void *user_data) { struct write_info *info = user_data; char *fname_tmp, *fname_bak, *fname_cfg; @@ -2169,6 +2181,11 @@ static void idle_save_config(void *user_data) if (info->cb) info->cb(info->user_data, result); + if (idle) { + l_queue_remove(info->cfg->idles, idle); + l_idle_remove(idle); + } + l_free(info); } @@ -2186,10 +2203,14 @@ bool mesh_config_save(struct mesh_config *cfg, bool no_wait, info->cb = cb; info->user_data = user_data; - if (no_wait) - idle_save_config(info); - else - l_idle_oneshot(idle_save_config, info, NULL); + if (no_wait) { + idle_save_config(NULL, info); + } else { + struct l_idle *idle; + + idle = l_idle_create(idle_save_config, info, NULL); + l_queue_push_tail(cfg->idles, idle); + } return true; } -- 2.21.1