mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Subject: [PATCH 2/6] nv: Save nv variables on shutdown
Date: Fri, 22 Jul 2016 12:39:15 +0200	[thread overview]
Message-ID: <1469183959-9002-3-git-send-email-s.hauer@pengutronix.de> (raw)
In-Reply-To: <1469183959-9002-1-git-send-email-s.hauer@pengutronix.de>

With this patch nv variables are automatically saved whenever barebox
shuts down (that is 'reset' is executed or a kernel is started). With
this the additional 'saveenv' step becomes unnecessary.

The nv variables are stored in the environment and the estasblished
behaviour is that files in the environment must be manually saved
using 'saveenv'. This behaviour shall be kept for now, so this patch
cannot just call 'saveenv' since that would save the modified
environment files aswell. Instead we read the environment from the
device, modifiy the nv variables and save the environment back.

Since this changes a long existing behaviour messages are printed the
first time a nv variable is modified and during shutdown when the
variables are actually saved.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/environment.c |  4 +++
 common/globalvar.c   | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 include/globalvar.h  |  3 ++
 3 files changed, 85 insertions(+), 3 deletions(-)

diff --git a/common/environment.c b/common/environment.c
index c3ad252..db127d7 100644
--- a/common/environment.c
+++ b/common/environment.c
@@ -364,6 +364,10 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags)
 
 	ret = 0;
 
+#ifdef CONFIG_NVVAR
+	if (!strcmp(filename, default_environment_path_get()))
+	    nv_var_set_clean();
+#endif
 out:
 	close(envfd);
 out1:
diff --git a/common/globalvar.c b/common/globalvar.c
index be08231..4110a06 100644
--- a/common/globalvar.c
+++ b/common/globalvar.c
@@ -9,6 +9,9 @@
 #include <fcntl.h>
 #include <libfile.h>
 #include <generated/utsrelease.h>
+#include <envfs.h>
+
+static int nv_dirty;
 
 struct device_d global_device = {
 	.name = "global",
@@ -20,6 +23,11 @@ struct device_d nv_device = {
 	.id = DEVICE_ID_SINGLE,
 };
 
+void nv_var_set_clean(void)
+{
+	nv_dirty = 0;
+}
+
 int globalvar_add(const char *name,
 		int (*set)(struct device_d *dev, struct param_d *p, const char *val),
 		const char *(*get)(struct device_d *, struct param_d *p),
@@ -43,16 +51,16 @@ void globalvar_remove(const char *name)
 	dev_remove_param(param);
 }
 
-static int nv_save(const char *name, const char *val)
+static int __nv_save(const char *prefix, const char *name, const char *val)
 {
 	int fd, ret;
 	char *fname;
 
-	ret = make_directory("/env/nv");
+	ret = make_directory(prefix);
 	if (ret)
 		return ret;
 
-	fname = basprintf("/env/nv/%s", name);
+	fname = basprintf("%s/%s", prefix, name);
 
 	fd = open(fname, O_CREAT | O_WRONLY | O_TRUNC);
 
@@ -68,6 +76,25 @@ static int nv_save(const char *name, const char *val)
 	return 0;
 }
 
+static int nv_save(const char *name, const char *val)
+{
+	int ret;
+	static int once = 1;
+
+	ret = __nv_save("/env/nv", name, val);
+	if (ret)
+		return ret;
+
+	if (once) {
+		pr_info("nv variable modified, will save nv variables on shutdown\n");
+		once = 0;
+	}
+
+	nv_dirty = 1;
+
+	return 0;
+}
+
 /**
  * dev_param_init_from_nv - initialize a device parameter from nv variable
  * @dev: The device
@@ -423,3 +450,51 @@ static int globalvar_init(void)
 pure_initcall(globalvar_init);
 
 BAREBOX_MAGICVAR_NAMED(global_version, global.version, "The barebox version");
+
+/**
+ * nvvar_save - save NV variables to persistent environment
+ *
+ * This saves the NV variables to the persisitent environment without saving
+ * the other files in the environment that might be changed.
+ */
+int nvvar_save(void)
+{
+	struct param_d *param;
+	const char *env = default_environment_path_get();
+	int ret;
+#define TMPDIR "/.env.tmp"
+	if (!nv_dirty || !env)
+		return 0;
+
+	if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT))
+		defaultenv_load(TMPDIR, 0);
+
+	envfs_load(env, TMPDIR, 0);
+
+	list_for_each_entry(param, &nv_device.parameters, list) {
+		ret = __nv_save(TMPDIR "/nv", param->name,
+				dev_get_param(&nv_device, param->name));
+		if (ret) {
+			pr_err("Cannot save NV var: %s\n", strerror(-ret));
+			goto out;
+		}
+	}
+
+	envfs_save(env, TMPDIR, 0);
+out:
+	unlink_recursive(TMPDIR, NULL);
+
+	if (!ret)
+		nv_dirty = 0;
+
+	return ret;
+}
+
+static void nv_exit(void)
+{
+	if (nv_dirty)
+		pr_info("nv variables modified, saving them\n");
+
+	nvvar_save();
+}
+predevshutdown_exitcall(nv_exit);
diff --git a/include/globalvar.h b/include/globalvar.h
index 67b97de..1cd8d21 100644
--- a/include/globalvar.h
+++ b/include/globalvar.h
@@ -173,4 +173,7 @@ static inline void dev_param_init_from_nv(struct device_d *dev, const char *name
 
 #endif
 
+void nv_var_set_clean(void);
+int nvvar_save(void);
+
 #endif /* __GLOBALVAR_H */
-- 
2.8.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2016-07-22 10:39 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-22 10:39 nv variable changes Sascha Hauer
2016-07-22 10:39 ` [PATCH 1/6] nv: Do not save nv variables while loading Sascha Hauer
2016-07-22 10:39 ` Sascha Hauer [this message]
2016-07-22 10:39 ` [PATCH 3/6] nv: Add option to explicitly save nv variables Sascha Hauer
2016-07-22 10:39 ` [PATCH 4/6] nv: Allow to set/remove multiple variables with one command Sascha Hauer
2016-07-22 10:39 ` [PATCH 5/6] nv: Use dev_remove_param to delete nv variable Sascha Hauer
2016-07-22 10:39 ` [PATCH 6/6] nv: Allow wildcards when removing NV vars Sascha Hauer

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=1469183959-9002-3-git-send-email-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /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