* [PATCH V2 1/4] crc value handling and dry run mode in envfs_load
2010-07-05 13:57 reworked multiple environment support Luotao Fu
@ 2010-07-05 13:57 ` Luotao Fu
2010-07-05 13:57 ` [PATCH V2 2/4] add multi environment support Luotao Fu
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Luotao Fu @ 2010-07-05 13:57 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Luotao Fu
We add some stuffs to envfs_load for later usage in implementation of
multiple environment partitions:
* envfs_load now accepts a parameter, where the crc value of the environment
partition can be stored.
* Also added "dry run" mode to envfs_load. If the dirname is not set.
envfs_load will now only check the crc values of the partition and returns
without writing to the file system.
Signed-off-by: Luotao Fu <l.fu@pengutronix.de>
---
V2 Changes:
* fixed envfs_load call in common/startup.c
commands/loadenv.c | 4 +++-
common/environment.c | 13 +++++++++++--
common/startup.c | 4 ++--
include/environment.h | 2 +-
scripts/bareboxenv.c | 2 +-
5 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/commands/loadenv.c b/commands/loadenv.c
index 14fbf1e..3da67d9 100644
--- a/commands/loadenv.c
+++ b/commands/loadenv.c
@@ -35,12 +35,14 @@ static int do_loadenv(struct command *cmdtp, int argc, char *argv[])
dirname = "/env";
else
dirname = argv[2];
+
if (argc < 2)
filename = "/dev/env0";
else
filename = argv[1];
printf("loading environment from %s\n", filename);
- return envfs_load(filename, dirname);
+
+ return envfs_load(filename, dirname, NULL);
}
static const __maybe_unused char cmd_loadenv_help[] =
diff --git a/common/environment.c b/common/environment.c
index 0eb7e6b..e79ec99 100644
--- a/common/environment.c
+++ b/common/environment.c
@@ -159,13 +159,15 @@ EXPORT_SYMBOL(envfs_save);
/**
* Restore the last environment into the current one
* @param[in] filename from where to restore
- * @param[in] dir where to store the last content
+ * @param[in] dir where to store the last content. Function will return crc
+ * value only if dir==NULL.
+ * @param[in] crc pointer to variale, where the crc can be stored.
* @return 0 on success, anything else in case of failure
*
* Note: This function will also be used on the host! See note in the header
* of this file.
*/
-int envfs_load(char *filename, char *dir)
+int envfs_load(char *filename, char *dir, int *crc)
{
struct envfs_super super;
void *buf = NULL, *buf_free = NULL;
@@ -219,6 +221,13 @@ int envfs_load(char *filename, char *dir)
goto out;
}
+ if (crc != NULL)
+ *crc = ENVFS_32(super.crc);
+
+ /* return crc only if dir is not set */
+ if (!dir)
+ goto out;
+
while (size) {
struct envfs_inode *inode;
uint32_t inode_size, inode_namelen;
diff --git a/common/startup.c b/common/startup.c
index 2ed16fe..2190159 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -138,11 +138,11 @@ void start_barebox (void)
display_meminfo();
#ifdef CONFIG_ENV_HANDLING
- if (envfs_load("/dev/env0", "/env")) {
+ if (envfs_load("/dev/env0", "/env", NULL)) {
#ifdef CONFIG_DEFAULT_ENVIRONMENT
printf("no valid environment found on /dev/env0. "
"Using default environment\n");
- envfs_load("/dev/defaultenv", "/env");
+ envfs_load("/dev/defaultenv", "/env", NULL);
#endif
}
#endif
diff --git a/include/environment.h b/include/environment.h
index 21a7ffa..2b1f5d9 100644
--- a/include/environment.h
+++ b/include/environment.h
@@ -50,7 +50,7 @@ int setenv(const char *, const char *);
int env_pop_context(void);
int env_push_context(void);
-int envfs_load(char *filename, char *dirname);
+int envfs_load(char *filename, char *dirname, int *crc);
int envfs_save(char *filename, char *dirname);
int export(const char *);
diff --git a/scripts/bareboxenv.c b/scripts/bareboxenv.c
index 5c7f10e..af012e8 100644
--- a/scripts/bareboxenv.c
+++ b/scripts/bareboxenv.c
@@ -186,7 +186,7 @@ int main(int argc, char *argv[])
if (load) {
printf("loading env from file %s to %s\n", filename, dirname);
- envfs_load(filename, dirname);
+ envfs_load(filename, dirname, NULL);
}
if (save) {
printf("saving contents of %s to file %s\n", dirname, filename);
--
1.7.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH V2 2/4] add multi environment support
2010-07-05 13:57 reworked multiple environment support Luotao Fu
2010-07-05 13:57 ` [PATCH V2 1/4] crc value handling and dry run mode in envfs_load Luotao Fu
@ 2010-07-05 13:57 ` Luotao Fu
2010-07-05 13:57 ` [PATCH V2 3/4] Add multi env support to saveenv and loadenv commands Luotao Fu
2010-07-05 13:57 ` [PATCH V2 4/4] add general check_and_erase callback to environment handling Luotao Fu
3 siblings, 0 replies; 5+ messages in thread
From: Luotao Fu @ 2010-07-05 13:57 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Luotao Fu
We can deal with multiple environments now in our barebox. With this option
enabled barebox will scan all environment partions on start up and load the
environment from the first loadable environment partition it finds. Also it will
check the content of all environment parttions and autmotically synchronize
content of any outdated partition.
Signed-off-by: Luotao Fu <l.fu@pengutronix.de>
---
V2 Changes:
* fix envfs_load call if the multienv support is disabled
common/Kconfig | 11 ++++++
common/startup.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 92 insertions(+), 9 deletions(-)
diff --git a/common/Kconfig b/common/Kconfig
index a58f242..c33cf14 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -40,6 +40,17 @@ config LOCALVERSION_AUTO
which is done within the script "scripts/setlocalversion".)
+config MULTI_ENV_HANDLING
+ select ENV_HANDLING
+ bool "Enable handling multiple environment partitions"
+ help
+ We can have multiple environments in our barebox. With this option
+ enabled barebox will scan all environment partions on start up and
+ load the environment from the first loadable environment partition
+ it finds. Also it will check if the content of all environment
+ parttions are synchronized and autmotically synchronize content of
+ the outdated partition.
+
config BOARDINFO
string
diff --git a/common/startup.c b/common/startup.c
index 2190159..b57a712 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -110,6 +110,87 @@ static int mount_root(void)
}
fs_initcall(mount_root);
+#ifdef CONFIG_ENV_HANDLING
+#ifdef CONFIG_MULTI_ENV_HANDLING
+static int init_envfs_load(void)
+{
+ char *dirname = "/env";
+ char file[9 + 5]; /* '/dev/env.....' */
+ int i = 0, j = 0, no_more_parts = 0;
+ int crc = 0, crc_ref = 0;
+ int rc;
+ struct stat file_info;
+
+ while (1) {
+ sprintf(file, "/dev/env%d", i);
+
+ if (stat(file, &file_info) != 0) {
+ no_more_parts = 1;
+ break;
+ }
+
+ /* first loadable environment is considered to be
+ * reference */
+ if (envfs_load(file, dirname, &crc_ref) == 0)
+ break;
+
+ i++;
+ }
+
+ /* no loadable environment partition found */
+ if (no_more_parts == 1) {
+#ifdef CONFIG_DEFAULT_ENVIRONMENT
+ printf("no valid environment found. "
+ "Using default environment\n");
+ envfs_load("/dev/defaultenv", "/env", &crc_ref);
+#endif
+ goto out;
+ }
+
+ /* Now try to restore, if any, the previous failed partitions */
+ for (j = 0; j < i; j++) {
+ sprintf(file, "/dev/env%d", j);
+ if (envfs_save(file, dirname))
+ printf("failed to sync environment on %s\n", file);
+ }
+
+ /* proceed to scan further env partitions */
+ while (1) {
+ i++;
+ sprintf(file, "/dev/env%d", i);
+
+ if (stat(file, &file_info) != 0)
+ break;
+
+ /* sync partition if loading failed or crc mismatch with
+ * the reference*/
+ rc = envfs_load(file, NULL, &crc);
+ if (rc != 0 || crc != crc_ref) {
+ if (envfs_save(file, dirname))
+ printf("failed to sync environment on %s\n",
+ file);
+ }
+ }
+out:
+ return 0;
+}
+#else /* MULTI_ENV_HANDLING */
+static int init_envfs_load(void)
+{
+ if (envfs_load("/dev/env0", "/env", NULL)) {
+#ifdef CONFIG_DEFAULT_ENVIRONMENT
+ printf("no valid environment found. "
+ "Using default environment\n");
+ envfs_load("/dev/defaultenv", "/env", NULL);
+#endif
+ }
+
+ return 0;
+}
+#endif /* MULTI_ENV_HANDLING */
+late_initcall(init_envfs_load);
+#endif /* CONFIG_ENV_HANDLING */
+
void start_barebox (void)
{
initcall_t *initcall;
@@ -137,15 +218,6 @@ void start_barebox (void)
display_meminfo();
-#ifdef CONFIG_ENV_HANDLING
- if (envfs_load("/dev/env0", "/env", NULL)) {
-#ifdef CONFIG_DEFAULT_ENVIRONMENT
- printf("no valid environment found on /dev/env0. "
- "Using default environment\n");
- envfs_load("/dev/defaultenv", "/env", NULL);
-#endif
- }
-#endif
printf("running /env/bin/init...\n");
if (!stat("/env/bin/init", &s)) {
--
1.7.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH V2 3/4] Add multi env support to saveenv and loadenv commands.
2010-07-05 13:57 reworked multiple environment support Luotao Fu
2010-07-05 13:57 ` [PATCH V2 1/4] crc value handling and dry run mode in envfs_load Luotao Fu
2010-07-05 13:57 ` [PATCH V2 2/4] add multi environment support Luotao Fu
@ 2010-07-05 13:57 ` Luotao Fu
2010-07-05 13:57 ` [PATCH V2 4/4] add general check_and_erase callback to environment handling Luotao Fu
3 siblings, 0 replies; 5+ messages in thread
From: Luotao Fu @ 2010-07-05 13:57 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Luotao Fu
saveenv and loadenv commands now support multiple environments. If
CONFIG_MULTI_ENV_HANDLING is turned on. saveenv will try to save the environment
into all available environment backends, while loadenv will load the environment
from the first loadable backend it will find. Also updated the help text.
Signed-off-by: Luotao Fu <l.fu@pengutronix.de>
---
V2 Changes:
* fixed saveenv callback, removed duplicated arg parsing
* fixed loadenv handling, removed unused varaibles.
commands/loadenv.c | 48 +++++++++++++++++++++++++------
commands/saveenv.c | 80 +++++++++++++++++++++++++++++++++++----------------
2 files changed, 94 insertions(+), 34 deletions(-)
diff --git a/commands/loadenv.c b/commands/loadenv.c
index 3da67d9..122a362 100644
--- a/commands/loadenv.c
+++ b/commands/loadenv.c
@@ -26,31 +26,61 @@
#include <common.h>
#include <command.h>
#include <environment.h>
+#include <fs.h>
+#include <linux/stat.h>
static int do_loadenv(struct command *cmdtp, int argc, char *argv[])
{
- char *filename, *dirname;
+ char *dirname;
+ int rc = 0;
+#ifdef CONFIG_MULTI_ENV_HANDLING
+ char file[9 + 5]; /* '/dev/env.....' */
+ int i = 0;
+ struct stat file_info;
+#endif
if (argc < 3)
dirname = "/env";
else
dirname = argv[2];
- if (argc < 2)
- filename = "/dev/env0";
- else
- filename = argv[1];
- printf("loading environment from %s\n", filename);
+ if (argc > 1) {
+ rc = envfs_load(argv[1], dirname, NULL);
+ return rc ? 1 : 0;
+ }
+
+#ifdef CONFIG_MULTI_ENV_HANDLING
+ /* default filename, loop over all /dev/env[number] till one succeeds */
+ while (1) {
+ sprintf(file, "/dev/env%d", i);
+
+ if (stat(file, &file_info) != 0)
+ break;
+
+ rc = envfs_load(file, dirname, NULL);
+ if (!rc)
+ break;
+ i++;
+ }
+#else
+ rc = envfs_load("/dev/env0", dirname, NULL);
+#endif
- return envfs_load(filename, dirname, NULL);
+ return rc ? 1 : 0;
}
static const __maybe_unused char cmd_loadenv_help[] =
"Usage: loadenv [ENVFS] [DIRECTORY]\n"
"Load the persistent storage contained in <envfs> to the directory\n"
"<directory>.\n"
-"If ommitted <directory> defaults to /env and <envfs> defaults to /dev/env0.\n"
-"Note that envfs can only handle files. Directories are skipped silently.\n";
+#ifdef CONFIG_MULTI_ENV_HANDLING
+"If ommitted <directory> defaults the command will scan for available"
+" environment backend storages, if more than one of such storages are"
+" available, the environment will try to load the environment from the"
+" loadable backend in ascending order (env0 -> env1).\n";
+#else
+"If ommitted <directory> defaults to /env and <envfs> defaults to /dev/env0.\n";
+#endif
BAREBOX_CMD_START(loadenv)
.cmd = do_loadenv,
diff --git a/commands/saveenv.c b/commands/saveenv.c
index 42ea58f..fa81d80 100644
--- a/commands/saveenv.c
+++ b/commands/saveenv.c
@@ -29,44 +29,33 @@
#include <fs.h>
#include <fcntl.h>
#include <environment.h>
+#include <linux/stat.h>
-static int do_saveenv(struct command *cmdtp, int argc, char *argv[])
+static int saveenv(char *filename, char *dirname)
{
int ret, fd;
- char *filename, *dirname;
printf("saving environment\n");
- if (argc < 3)
- dirname = "/env";
- else
- dirname = argv[2];
- if (argc < 2)
- filename = "/dev/env0";
- else
- filename = argv[1];
fd = open(filename, O_WRONLY | O_CREAT);
if (fd < 0) {
printf("could not open %s: %s\n", filename, errno_str());
- return 1;
+ ret = -ENODEV;
+ goto out_ret;
}
ret = protect(fd, ~0, 0, 0);
-
/* ENOSYS is no error here, many devices do not need it */
if (ret && errno != -ENOSYS) {
printf("could not unprotect %s: %s\n", filename, errno_str());
- close(fd);
- return 1;
+ goto out_close;
}
ret = erase(fd, ~0, 0);
-
/* ENOSYS is no error here, many devices do not need it */
if (ret && errno != -ENOSYS) {
printf("could not erase %s: %s\n", filename, errno_str());
- close(fd);
- return 1;
+ goto out_close;
}
close(fd);
@@ -74,23 +63,58 @@ static int do_saveenv(struct command *cmdtp, int argc, char *argv[])
ret = envfs_save(filename, dirname);
if (ret) {
printf("saveenv failed\n");
- goto out;
+ goto out_ret;
}
fd = open(filename, O_WRONLY | O_CREAT);
-
ret = protect(fd, ~0, 0, 1);
-
/* ENOSYS is no error here, many devices do not need it */
if (ret && errno != -ENOSYS) {
printf("could not protect %s: %s\n", filename, errno_str());
- close(fd);
- return 1;
+ goto out_close;
}
ret = 0;
-out:
+
+out_close:
close(fd);
+out_ret:
+ return ret;
+}
+
+static int do_saveenv(struct command *cmdtp, int argc, char *argv[])
+{
+ int ret = 0;
+ char *dirname;
+#ifdef CONFIG_MULTI_ENV_HANDLING
+ int i = 0;
+ char file[9 + 5];
+ struct stat file_info;
+#endif
+
+ printf("saving environment\n");
+ if (argc < 3)
+ dirname = "/env";
+ else
+ dirname = argv[2];
+
+ if (argc > 1)
+ return saveenv(argv[1], dirname);
+#ifdef CONFIG_MULTI_ENV_HANDLING
+ /* default filename, save environment to all /dev/env[number] */
+ while (1) {
+ sprintf(file, "/dev/env%d", i);
+ if (stat(file, &file_info))
+ break;
+
+ ret |= saveenv(file, dirname);
+
+ i++;
+ }
+#else
+ ret = saveenv("/dev/env0", dirname);
+#endif
+
return ret;
}
@@ -98,8 +122,14 @@ static const __maybe_unused char cmd_saveenv_help[] =
"Usage: saveenv [<envfs>] [<directory>]\n"
"Save the files in <directory> to the persistent storage device <envfs>.\n"
"<envfs> is normally a block in flash, but could be any other file.\n"
-"If ommitted <directory> defaults to /env and <envfs> defaults to /dev/env0.\n"
-"Note that envfs can only handle files. Directories are skipped silently.\n";
+#ifdef CONFIG_MULTI_ENV_HANDLING
+"If ommitted <directory> defaults the command will scan for available"
+" environment backend storages, if more than one of such storages are"
+" available, the environment will be stored into all of them ascending"
+" order (env0 -> env1).\n";
+#else
+"If ommitted <directory> defaults to /env and <envfs> defaults to /dev/env0.\n";
+#endif
BAREBOX_CMD_START(saveenv)
.cmd = do_saveenv,
--
1.7.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH V2 4/4] add general check_and_erase callback to environment handling
2010-07-05 13:57 reworked multiple environment support Luotao Fu
` (2 preceding siblings ...)
2010-07-05 13:57 ` [PATCH V2 3/4] Add multi env support to saveenv and loadenv commands Luotao Fu
@ 2010-07-05 13:57 ` Luotao Fu
3 siblings, 0 replies; 5+ messages in thread
From: Luotao Fu @ 2010-07-05 13:57 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Luotao Fu
Checking and erasing the envfs partition prior to saving the environment is
required both in start initial environment loading and saveenv commands. Hence
we add a general callback to do this task. This callback is barebox only and
cannot be used in the script utils.
Signed-off-by: Luotao Fu <l.fu@pengutronix.de>
---
V2 Changes:
* fixed error handling in file_check_and_erase
* fixed error handling in saveenv
commands/saveenv.c | 41 +++++++++--------------------------------
common/environment.c | 36 ++++++++++++++++++++++++++++++++++++
common/startup.c | 7 +++++++
include/environment.h | 1 +
4 files changed, 53 insertions(+), 32 deletions(-)
diff --git a/commands/saveenv.c b/commands/saveenv.c
index fa81d80..2c89778 100644
--- a/commands/saveenv.c
+++ b/commands/saveenv.c
@@ -33,37 +33,17 @@
static int saveenv(char *filename, char *dirname)
{
- int ret, fd;
-
- printf("saving environment\n");
-
- fd = open(filename, O_WRONLY | O_CREAT);
- if (fd < 0) {
- printf("could not open %s: %s\n", filename, errno_str());
- ret = -ENODEV;
- goto out_ret;
- }
-
- ret = protect(fd, ~0, 0, 0);
- /* ENOSYS is no error here, many devices do not need it */
- if (ret && errno != -ENOSYS) {
- printf("could not unprotect %s: %s\n", filename, errno_str());
- goto out_close;
- }
-
- ret = erase(fd, ~0, 0);
- /* ENOSYS is no error here, many devices do not need it */
- if (ret && errno != -ENOSYS) {
- printf("could not erase %s: %s\n", filename, errno_str());
- goto out_close;
- }
+ int ret = 0;
+ int fd;
- close(fd);
+ ret = file_check_and_erase(filename);
+ if (ret)
+ return ret;
ret = envfs_save(filename, dirname);
if (ret) {
printf("saveenv failed\n");
- goto out_ret;
+ return ret;
}
fd = open(filename, O_WRONLY | O_CREAT);
@@ -71,15 +51,12 @@ static int saveenv(char *filename, char *dirname)
/* ENOSYS is no error here, many devices do not need it */
if (ret && errno != -ENOSYS) {
printf("could not protect %s: %s\n", filename, errno_str());
- goto out_close;
+ close(fd);
+ return ret;
}
- ret = 0;
-
-out_close:
close(fd);
-out_ret:
- return ret;
+ return 0;
}
static int do_saveenv(struct command *cmdtp, int argc, char *argv[])
diff --git a/common/environment.c b/common/environment.c
index e79ec99..341b1f3 100644
--- a/common/environment.c
+++ b/common/environment.c
@@ -93,6 +93,42 @@ out:
return 1;
}
+#ifdef __BAREBOX__
+int file_check_and_erase(char *filename)
+{
+ int fd;
+ int ret;
+
+ fd = open(filename, O_WRONLY | O_CREAT);
+ if (fd < 0) {
+ printf("could not open %s: %s\n", filename, errno_str());
+ ret = -ENODEV;
+ goto out_ret;
+ }
+
+ ret = protect(fd, ~0, 0, 0);
+ /* ENOSYS is no error here, many devices do not need it */
+ if (ret && errno != -ENOSYS) {
+ printf("could not unprotect %s: %s\n", filename, errno_str());
+ goto out_close;
+ }
+
+ ret = erase(fd, ~0, 0);
+ /* ENOSYS is no error here, many devices do not need it */
+ if (ret && errno != -ENOSYS) {
+ printf("could not erase %s: %s\n", filename, errno_str());
+ goto out_ret;
+ }
+
+ ret = 0;
+
+out_close:
+ close(fd);
+out_ret:
+ return ret;
+}
+#endif /* __BAREBOX__ */
+
/**
* Make the current environment persistent
* @param[in] filename where to store
diff --git a/common/startup.c b/common/startup.c
index b57a712..b8ae29a 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -150,6 +150,10 @@ static int init_envfs_load(void)
/* Now try to restore, if any, the previous failed partitions */
for (j = 0; j < i; j++) {
sprintf(file, "/dev/env%d", j);
+
+ if (file_check_and_erase(file))
+ continue;
+
if (envfs_save(file, dirname))
printf("failed to sync environment on %s\n", file);
}
@@ -166,6 +170,9 @@ static int init_envfs_load(void)
* the reference*/
rc = envfs_load(file, NULL, &crc);
if (rc != 0 || crc != crc_ref) {
+ if (file_check_and_erase(file))
+ continue;
+
if (envfs_save(file, dirname))
printf("failed to sync environment on %s\n",
file);
diff --git a/include/environment.h b/include/environment.h
index 2b1f5d9..b2b95e0 100644
--- a/include/environment.h
+++ b/include/environment.h
@@ -58,6 +58,7 @@ int export(const char *);
struct stat;
int file_size_action(const char *, struct stat *, void *, int);
int file_save_action(const char *, struct stat *, void *, int);
+int file_check_and_erase(char *filename);
#endif /* __BAREBOX__ */
--
1.7.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread