public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
From: Inga Stotland <inga.stotland@intel.com>
To: linux-bluetooth@vger.kernel.org
Cc: brian.gix@intel.com, michal.lowas-rzechonek@silvair.com,
	jakub.witowski@silvair.com,
	Inga Stotland <inga.stotland@intel.com>
Subject: [PATCH BlueZ 8/9] mesh: Switch to using mesh-config routines for storage
Date: Tue,  9 Jul 2019 22:09:58 -0700	[thread overview]
Message-ID: <20190710050959.7321-9-inga.stotland@intel.com> (raw)
In-Reply-To: <20190710050959.7321-1-inga.stotland@intel.com>

This removes the assumptions of the layout of the node configuration
directory from storage.c to allow read/write of persistent node
configuration to be format agnostic.
---
 mesh/mesh.c    |  11 ++-
 mesh/storage.c | 229 +++++++++++++++++--------------------------------
 2 files changed, 87 insertions(+), 153 deletions(-)

diff --git a/mesh/mesh.c b/mesh/mesh.c
index 26acfd4dc..bdd79e6bb 100644
--- a/mesh/mesh.c
+++ b/mesh/mesh.c
@@ -22,6 +22,8 @@
 #endif
 
 #define _GNU_SOURCE
+#include <dirent.h>
+
 #include <ell/ell.h>
 
 #include "mesh/mesh-io.h"
@@ -143,6 +145,12 @@ bool mesh_init(const char *config_dir, enum mesh_io_type type, void *opts)
 	if (mesh.io)
 		return true;
 
+	if (!config_dir)
+		config_dir = MESH_STORAGEDIR;
+
+	if (strlen(config_dir) >= PATH_MAX)
+		return false;
+
 	mesh_model_init();
 	mesh_agent_init();
 
@@ -150,9 +158,6 @@ bool mesh_init(const char *config_dir, enum mesh_io_type type, void *opts)
 	mesh.prov_timeout = DEFAULT_PROV_TIMEOUT;
 	mesh.algorithms = DEFAULT_ALGORITHMS;
 
-	if (!config_dir)
-		config_dir = MESH_STORAGEDIR;
-
 	l_info("Loading node configuration from %s", config_dir);
 
 	if (!storage_load_nodes(config_dir))
diff --git a/mesh/storage.c b/mesh/storage.c
index e87b58c59..721b65904 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -47,9 +47,6 @@ struct write_info {
 	mesh_status_func_t cb;
 };
 
-static const char *cfg_name = "/node.json";
-static const char *bak_ext = ".bak";
-static const char *tmp_ext = ".tmp";
 static const char *storage_dir;
 
 static bool read_node_cb(struct mesh_config_node *db_node, void *user_data)
@@ -123,61 +120,21 @@ static bool parse_node(struct mesh_node *node, json_object *jnode)
 	return true;
 }
 
-static bool parse_config(char *in_file, char *out_dir, const uint8_t uuid[16])
+static struct mesh_node *parse_config(void *node_cfg,  const uint8_t uuid[16])
 {
-	int fd;
-	char *str;
-	struct stat st;
-	ssize_t sz;
-	json_object *jnode = NULL;
 	bool result = false;
 	struct mesh_node *node;
 
-	l_info("Loading configuration from %s", in_file);
-
-	fd = open(in_file, O_RDONLY);
-	if (fd < 0)
-		return false;
-
-	if (fstat(fd, &st) == -1) {
-		close(fd);
-		return false;
-	}
-
-	str = (char *) l_new(char, st.st_size + 1);
-	if (!str) {
-		close(fd);
-		return false;
-	}
-
-	sz = read(fd, str, st.st_size);
-	if (sz != st.st_size) {
-		l_error("Failed to read configuration file %s", in_file);
-		goto done;
-	}
-
-	jnode = json_tokener_parse(str);
-	if (!jnode)
-		goto done;
-
 	node = node_new(uuid);
 
-	result = parse_node(node, jnode);
+	result = parse_node(node, node_cfg);
 
 	if (!result) {
-		json_object_put(jnode);
 		node_remove(node);
+		return NULL;
 	}
 
-	node_config_set(node, jnode);
-	node_path_set(node, out_dir);
-
-done:
-	close(fd);
-	if (str)
-		l_free(str);
-
-	return result;
+	return node;
 }
 
 bool storage_set_ttl(struct mesh_node *node, uint8_t ttl)
@@ -360,54 +317,13 @@ bool storage_write_sequence_number(struct mesh_net *net, uint32_t seq)
 	return true;
 }
 
-static bool save_config(json_object *jnode, const char *config_name)
-{
-	FILE *outfile;
-	const char *str;
-	bool result = false;
-
-	outfile = fopen(config_name, "w");
-	if (!outfile) {
-		l_error("Failed to save configuration to %s", config_name);
-		return false;
-	}
-
-	str = json_object_to_json_string_ext(jnode, JSON_C_TO_STRING_PRETTY);
-
-	if (fwrite(str, sizeof(char), strlen(str), outfile) < strlen(str))
-		l_warn("Incomplete write of mesh configuration");
-	else
-		result = true;
-
-	fclose(outfile);
-
-	return result;
-}
-
 static void idle_save_config(void *user_data)
 {
 	struct write_info *info = user_data;
-	char *tmp, *bak, *cfg;
-	bool result = false;
-
-	cfg = l_strdup_printf("%s%s", info->node_path, cfg_name);
-	tmp = l_strdup_printf("%s%s", cfg, tmp_ext);
-	bak = l_strdup_printf("%s%s", cfg, bak_ext);
-	remove(tmp);
+	bool result;
 
 	l_debug("Storage-Wrote");
-	result = save_config(info->jnode, tmp);
-
-	if (result) {
-		remove(bak);
-		rename(cfg, bak);
-		rename(tmp, cfg);
-	}
-
-	remove(tmp);
-	l_free(tmp);
-	l_free(bak);
-	l_free(cfg);
+	result = mesh_config_save_config(info->node_path, info->jnode);
 
 	if (info->cb)
 		info->cb(info->user_data, result);
@@ -472,7 +388,7 @@ bool storage_load_nodes(const char *dir_name)
 {
 	DIR *dir;
 	struct dirent *entry;
-	size_t path_len = strlen(dir_name) + strlen(cfg_name) + strlen(bak_ext);
+	size_t path_len = strlen(dir_name);
 
 	create_dir(dir_name);
 	dir = opendir(dir_name);
@@ -485,84 +401,53 @@ bool storage_load_nodes(const char *dir_name)
 	storage_dir = dir_name;
 
 	while ((entry = readdir(dir)) != NULL) {
-		char *dir, *cfg, *bak;
+		char *dir;
+		void *config;
 		uint8_t uuid[16];
-		size_t node_len;
+		size_t subdir_len;
+		struct mesh_node *node;
 
 		if (entry->d_type != DT_DIR)
 			continue;
 
 		/* Check path length */
-		node_len = strlen(entry->d_name);
-		if (path_len + node_len + 1 >= PATH_MAX)
+		subdir_len = strlen(entry->d_name);
+		if (path_len + subdir_len + 1 >= PATH_MAX)
 			continue;
 
-		if (!str2hex(entry->d_name, node_len, uuid, sizeof(uuid)))
+		if (!str2hex(entry->d_name, subdir_len, uuid, sizeof(uuid)))
 			continue;
 
 		dir = l_strdup_printf("%s/%s", dir_name, entry->d_name);
-		cfg = l_strdup_printf("%s%s", dir, cfg_name);
-
-		if (!parse_config(cfg, dir, uuid)) {
-
-			/* Fall-back to Backup version */
-			bak = l_strdup_printf("%s%s", cfg, bak_ext);
-
-			if (parse_config(bak, dir, uuid)) {
-				remove(cfg);
-				rename(bak, cfg);
-			}
-			l_free(bak);
-		}
-		l_free(cfg);
-		l_free(dir);
-	}
-
-	return true;
-}
-
-bool storage_create_node_config(struct mesh_node *node, void *data)
-{
-	struct mesh_config_node *db_node = data;
-	char uuid[33];
-	char name_buf[PATH_MAX];
-	json_object *jnode;
-	size_t max_len = strlen(cfg_name) + strlen(bak_ext);
-
-	if (!storage_dir)
-		return false;
-
-	jnode = json_object_new_object();
-
-	if (!mesh_config_add_node(jnode, db_node))
-		return false;
-
-	if (!hex2str(node_uuid_get(node), 16, uuid, sizeof(uuid)))
-		goto fail;
+		config = mesh_config_get_config(dir);
+		if (!config)
+			continue;
 
-	snprintf(name_buf, PATH_MAX, "%s/%s", storage_dir, uuid);
+		node = parse_config(config, uuid);
 
-	if (strlen(name_buf) + max_len >= PATH_MAX)
-		goto fail;
+		if (!node) {
+			mesh_config_release_config(config);
 
-	/* Create a new directory and node.json file */
-	if (mkdir(name_buf, 0755) != 0)
-		goto fail;
+			/* Fall-back to Backup version */
+			config = mesh_config_get_config_backup(dir);
 
-	node_path_set(node, name_buf);
+			node = parse_config(config, uuid);
 
-	snprintf(name_buf, PATH_MAX, "%s/%s%s", storage_dir, uuid, cfg_name);
-	l_debug("New node config %s", name_buf);
+			if (node)
+				mesh_config_restore_backup(dir);
+			else
+				mesh_config_release_config(config);
+		}
 
-	if (!save_config(jnode, name_buf))
-		goto fail;
+		if (node) {
+			node_path_set(node, dir);
+			node_config_set(node, config);
+		}
 
-	node_config_set(node, jnode);
+		l_free(dir);
+	}
 
 	return true;
-fail:
-	json_object_put(jnode);
-	return false;
 }
 
 static int del_fobject(const char *fpath, const struct stat *sb, int typeflag,
@@ -596,7 +481,7 @@ void storage_remove_node_config(struct mesh_node *node)
 	/* Free the node config json object */
 	jnode = node_config_get(node);
 	if (jnode)
-		json_object_put(jnode);
+		mesh_config_release_config(jnode);
 
 	node_config_set(node, NULL);
 
@@ -614,3 +499,47 @@ void storage_remove_node_config(struct mesh_node *node)
 
 	nftw(node_path, del_fobject, 5, FTW_DEPTH | FTW_PHYS);
 }
+
+bool storage_create_node_config(struct mesh_node *node, void *data)
+{
+	struct mesh_config_node *db_node = data;
+	char uuid[33];
+	char node_dir[PATH_MAX];
+	json_object *jnode;
+
+	if (!storage_dir)
+		return false;
+
+	jnode = mesh_config_create_config();
+
+	if (!jnode || !mesh_config_add_node(jnode, db_node))
+		return false;
+
+	if (!hex2str(node_uuid_get(node), 16, uuid, sizeof(uuid)))
+		goto fail;
+
+	snprintf(node_dir, PATH_MAX, "%s/%s", storage_dir, uuid);
+
+	if (strlen(node_dir) >= PATH_MAX)
+		goto fail;
+
+	/* Create a new node config directory */
+	if (mkdir(node_dir, 0755) != 0)
+		goto fail;
+
+	if (!mesh_config_save_config(node_dir, jnode)) {
+		nftw(node_dir, del_fobject, 5, FTW_DEPTH | FTW_PHYS);
+		goto fail;
+	}
+
+	l_debug("New node config %s", node_dir);
+	node_path_set(node, node_dir);
+	node_config_set(node, jnode);
+
+	return true;
+fail:
+	mesh_config_release_config(jnode);
+	node_config_set(node, NULL);
+
+	return false;
+}
-- 
2.21.0


  parent reply	other threads:[~2019-07-10  5:10 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-10  5:09 [PATCH BlueZ 0/9] mesh: Configuration storage re-org Inga Stotland
2019-07-10  5:09 ` [PATCH BlueZ 1/9] mesh: Move network config setup from storage.c to node.c Inga Stotland
2019-07-10  5:09 ` [PATCH BlueZ 2/9] mesh: Rename mesh-db.c to mesh-config-json.c Inga Stotland
2019-07-10  5:09 ` [PATCH BlueZ 3/9] mesh: Change mesh_db prefix to mesh_config Inga Stotland
2019-07-10  5:09 ` [PATCH BlueZ 4/9] mesh: Generalize mesh-config APIs Inga Stotland
2019-07-10  7:38   ` Michał Lowas-Rzechonek
2019-07-10 15:01     ` Michał Lowas-Rzechonek
2019-07-10 15:58       ` Stotland, Inga
2019-07-10  5:09 ` [PATCH BlueZ 5/9] mesh: Change variable prefix "jconfig" to "config" Inga Stotland
2019-07-10  8:29   ` Michał Lowas-Rzechonek
2019-07-10  5:09 ` [PATCH BlueZ 6/9] mesh: Define storage format specific read/write routines Inga Stotland
2019-07-10  7:52   ` Michał Lowas-Rzechonek
2019-07-10 16:53     ` Stotland, Inga
2019-07-10 17:00       ` michal.lowas-rzechonek
2019-07-10 17:20     ` Gix, Brian
2019-07-10 19:32       ` Michal Lowas-Rzechonek
2019-07-10  5:09 ` [PATCH BlueZ 7/9] mesh: Implement config read/write for mesh json format Inga Stotland
2019-07-10  5:09 ` Inga Stotland [this message]
2019-07-10  5:09 ` [PATCH BlueZ 9/9] mesh: Make storage.c json-c agnostic Inga Stotland

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190710050959.7321-9-inga.stotland@intel.com \
    --to=inga.stotland@intel.com \
    --cc=brian.gix@intel.com \
    --cc=jakub.witowski@silvair.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=michal.lowas-rzechonek@silvair.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox