diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2014-10-08 14:56:13 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2014-11-06 10:58:54 +0100 |
commit | 70e718baa1b2ae8e478df67397e759457acddcd4 (patch) | |
tree | 1bcff8b517c1df5b4c230684f4904bf5fffdcd85 /common/environment.c | |
parent | eb3ef18c8cac32bee1b59865c6b29847882f9f85 (diff) | |
download | barebox-70e718baa1b2ae8e478df67397e759457acddcd4.tar.gz barebox-70e718baa1b2ae8e478df67397e759457acddcd4.tar.xz |
environment: Only save changes to the defaultenv
Instead of storing the complete files with a 'saveenv' command
only store the files that have changes to the default environment.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common/environment.c')
-rw-r--r-- | common/environment.c | 111 |
1 files changed, 105 insertions, 6 deletions
diff --git a/common/environment.c b/common/environment.c index 985adc11f6..a04b1fadc1 100644 --- a/common/environment.c +++ b/common/environment.c @@ -36,6 +36,8 @@ #include <libbb.h> #include <libgen.h> #include <environment.h> +#include <globalvar.h> +#include <libfile.h> #else # define errno_str(x) ("void") #define EXPORT_SYMBOL(x) @@ -57,6 +59,9 @@ struct action_data { #define PAD4(x) ((x + 3) & ~3) #ifdef __BAREBOX__ + +#define TMPDIR "/.defaultenv" + static char *default_environment_path = "/dev/env0"; void default_environment_path_set(char *path) @@ -68,6 +73,21 @@ char *default_environment_path_get(void) { return default_environment_path; } + +static int do_compare_file(const char *filename, const char *base) +{ + int ret; + char *cmp; + const char *relname = filename + strlen(base) + 1; + + cmp = asprintf("%s/%s", TMPDIR, relname); + ret = compare_file(cmp, filename); + + free(cmp); + + return ret; +} + #else static inline int protect(int fd, size_t count, unsigned long offset, int prot) { @@ -78,6 +98,11 @@ static inline int erase(int fd, size_t count, unsigned long offset) { return 0; } + +static int do_compare_file(const char *filename, const char *base) +{ + return 1; +} #endif static int file_action(const char *filename, struct stat *statbuf, @@ -87,6 +112,9 @@ static int file_action(const char *filename, struct stat *statbuf, struct envfs_entry *env; int fd, ret; + if (!do_compare_file(filename, data->base)) + return 1; + env = xzalloc(sizeof(*env)); env->name = strdup(filename + strlen(data->base)); env->size = statbuf->st_size; @@ -153,6 +181,60 @@ static void envfs_save_inode(struct action_data *data, struct envfs_entry *env) data->writep += PAD4(env->size); } +#ifdef __BAREBOX__ +static int file_remove_action(const char *filename, struct stat *statbuf, + void *userdata, int depth) +{ + struct action_data *data = userdata; + char *envname; + struct stat s; + int ret; + struct envfs_entry *env; + + filename += sizeof(TMPDIR) - 1; + + envname = asprintf("%s/%s", data->base, filename); + + ret = stat(envname, &s); + if (ret) { + char *base; + + base = basename(envname); + + env = xzalloc(sizeof(*env)); + env->name = strdup(filename); + env->size = strlen(base) + 1; + + env->buf = strdup(base); + if (!env->buf) + goto out; + + env->mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFLNK; + + env->next = data->env; + data->env = env; + } +out: + free(envname); + + return 1; +} +#else +static int file_remove_action(const char *filename, struct stat *statbuf, + void *userdata, int depth) +{ + return 0; +} +#endif + +static int dir_remove_action(const char *filename, struct stat *statbuf, + void *userdata, int depth) +{ + rmdir(filename); + + return 1; +} + /** * Make the current environment persistent * @param[in] filename where to store @@ -174,12 +256,18 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags) data.writep = NULL; data.base = dirname; +#ifdef __BAREBOX__ + defaultenv_load(TMPDIR, 0); +#endif + if (flags & ENVFS_FLAGS_FORCE_BUILT_IN) { size = 0; /* force no content */ } else { /* first pass: calculate size */ recursive_action(dirname, ACTION_RECURSE, file_action, NULL, &data, 0); + recursive_action("/.defaultenv", ACTION_RECURSE, + file_remove_action, NULL, &data, 0); size = 0; for (env = data.env; env; env = env->next) { @@ -270,6 +358,9 @@ out: close(envfd); out1: free(buf); +#ifdef __BAREBOX__ + unlink_recursive(TMPDIR, NULL); +#endif return ret; } EXPORT_SYMBOL(envfs_save); @@ -346,9 +437,6 @@ static int envfs_load_data(struct envfs_super *super, void *buf, size_t size, inode_size, namelen, inode_headerlen); str = concat_path_file(dir, inode->data); - tmp = strdup(str); - make_directory(dirname(tmp)); - free(tmp); headerlen_full = PAD4(inode_headerlen); buf += headerlen_full; @@ -359,11 +447,19 @@ static int envfs_load_data(struct envfs_super *super, void *buf, size_t size, goto out; } + tmp = strdup(str); + make_directory(dirname(tmp)); + free(tmp); + if (S_ISLNK(ENVFS_32(inode_end->mode))) { debug("symlink: %s -> %s\n", str, (char*)buf); - if (symlink(buf, str) < 0) { - printf("symlink: %s -> %s :", str, (char*)buf); - perror(""); + if (!strcmp(buf, basename(str))) { + unlink(str); + } else { + ret = symlink(buf, str); + if (ret < 0) + printf("symlink: %s -> %s : %s\n", + str, (char*)buf, strerror(-errno)); } free(str); } else { @@ -398,6 +494,9 @@ skip: sizeof(struct envfs_inode); } + recursive_action(dir, ACTION_RECURSE | ACTION_DEPTHFIRST, NULL, + dir_remove_action, NULL, 0); + ret = 0; out: return ret; |