9
0
Fork 0

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>
This commit is contained in:
Sascha Hauer 2014-10-08 14:56:13 +02:00
parent eb3ef18c8c
commit 70e718baa1
2 changed files with 108 additions and 14 deletions

View File

@ -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;

View File

@ -78,17 +78,12 @@ void __noreturn start_barebox(void)
pr_debug("initcalls done\n");
if (IS_ENABLED(CONFIG_ENV_HANDLING)) {
int ret;
char *default_environment_path = default_environment_path_get();
ret = envfs_load(default_environment_path, "/env", 0);
if (ret && IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT)) {
pr_err("no valid environment found on %s. "
"Using default environment\n",
default_environment_path);
if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT))
defaultenv_load("/env", 0);
}
envfs_load(default_environment_path, "/env", 0);
}
if (IS_ENABLED(CONFIG_COMMAND_SUPPORT)) {