9
0
Fork 0

environment: Add function to load envfs from buffer

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Sascha Hauer 2014-02-20 08:16:01 +01:00
parent c2428b2287
commit 0a2a8f7059
2 changed files with 118 additions and 66 deletions

View File

@ -218,79 +218,53 @@ out1:
}
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
* @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(const char *filename, const char *dir, unsigned flags)
static int envfs_check_super(struct envfs_super *super, size_t *size)
{
if (ENVFS_32(super->magic) != ENVFS_MAGIC) {
printf("envfs: wrong magic\n");
return -EIO;
}
if (crc32(0, super, sizeof(*super) - 4) != ENVFS_32(super->sb_crc)) {
printf("wrong crc on env superblock\n");
return -EIO;
}
if (super->major < ENVFS_MAJOR)
printf("envfs version %d.%d loaded into %d.%d\n",
super->major, super->minor,
ENVFS_MAJOR, ENVFS_MINOR);
*size = ENVFS_32(super->size);
return 0;
}
static int envfs_check_data(struct envfs_super *super, void *buf, size_t size)
{
uint32_t crc;
crc = crc32(0, buf, size);
if (crc != ENVFS_32(super->crc)) {
printf("wrong crc on env\n");
return -EIO;
}
return 0;
}
static int envfs_load_data(void *buf, size_t size, const char *dir, unsigned flags)
{
struct envfs_super super;
void *buf = NULL, *buf_free = NULL;
int envfd;
int fd, ret = 0;
char *str, *tmp;
int headerlen_full;
unsigned long size;
/* for envfs < 1.0 */
struct envfs_inode_end inode_end_dummy;
inode_end_dummy.mode = ENVFS_32(S_IRWXU | S_IRWXG | S_IRWXO);
inode_end_dummy.magic = ENVFS_32(ENVFS_INODE_END_MAGIC);
envfd = open(filename, O_RDONLY);
if (envfd < 0) {
printf("Open %s %s\n", filename, errno_str());
return -1;
}
/* read superblock */
ret = read(envfd, &super, sizeof(struct envfs_super));
if ( ret < sizeof(struct envfs_super)) {
perror("read");
ret = -errno;
goto out;
}
if ( ENVFS_32(super.magic) != ENVFS_MAGIC) {
printf("envfs: wrong magic on %s\n", filename);
ret = -EIO;
goto out;
}
if (crc32(0, (unsigned char *)&super, sizeof(struct envfs_super) - 4)
!= ENVFS_32(super.sb_crc)) {
printf("wrong crc on env superblock\n");
ret = -EIO;
goto out;
}
size = ENVFS_32(super.size);
buf = xmalloc(size);
buf_free = buf;
ret = read(envfd, buf, size);
if (ret < size) {
perror("read");
ret = -errno;
goto out;
}
if (crc32(0, (unsigned char *)buf, size)
!= ENVFS_32(super.crc)) {
printf("wrong crc on env\n");
ret = -EIO;
goto out;
}
if (super.major < ENVFS_MAJOR)
printf("envfs version %d.%d loaded into %d.%d\n",
super.major, super.minor,
ENVFS_MAJOR, ENVFS_MINOR);
while (size) {
struct envfs_inode *inode;
struct envfs_inode_end *inode_end;
@ -300,7 +274,7 @@ int envfs_load(const char *filename, const char *dir, unsigned flags)
buf += sizeof(struct envfs_inode);
if (ENVFS_32(inode->magic) != ENVFS_INODE_MAGIC) {
printf("envfs: wrong magic on %s\n", filename);
printf("envfs: wrong magic\n");
ret = -EIO;
goto out;
}
@ -324,7 +298,7 @@ int envfs_load(const char *filename, const char *dir, unsigned flags)
buf += headerlen_full;
if (ENVFS_32(inode_end->magic) != ENVFS_INODE_END_MAGIC) {
printf("envfs: wrong inode_end_magic on %s\n", filename);
printf("envfs: wrong inode_end_magic\n");
ret = -EIO;
goto out;
}
@ -368,11 +342,88 @@ skip:
sizeof(struct envfs_inode);
}
ret = 0;
out:
return ret;
}
int envfs_load_from_buf(void *buf, int len, const char *dir, unsigned flags)
{
int ret;
size_t size;
struct envfs_super *super = buf;
buf = super + 1;
ret = envfs_check_super(super, &size);
if (ret)
return ret;
ret = envfs_check_data(super, buf, size);
if (ret)
return ret;
ret = envfs_load_data(buf, size, dir, flags);
return ret;
}
/**
* Restore the last environment into the current one
* @param[in] filename from where to restore
* @param[in] dir where to store the last content
* @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(const char *filename, const char *dir, unsigned flags)
{
struct envfs_super super;
void *buf = NULL;
int envfd;
int ret = 0;
size_t size;
envfd = open(filename, O_RDONLY);
if (envfd < 0) {
printf("Open %s %s\n", filename, errno_str());
return -1;
}
/* read superblock */
ret = read(envfd, &super, sizeof(struct envfs_super));
if ( ret < sizeof(struct envfs_super)) {
perror("read");
ret = -errno;
goto out;
}
ret = envfs_check_super(&super, &size);
if (ret)
goto out;
buf = xmalloc(size);
ret = read(envfd, buf, size);
if (ret < size) {
perror("read");
ret = -errno;
goto out;
}
ret = envfs_check_data(&super, buf, size);
if (ret)
goto out;
ret = envfs_load_data(buf, size, dir, flags);
if (ret)
goto out;
ret = 0;
out:
close(envfd);
if (buf_free)
free(buf_free);
free(buf);
return ret;
}

View File

@ -92,6 +92,7 @@ struct envfs_super {
#define ENV_FLAG_NO_OVERWRITE (1 << 0)
int envfs_load(const char *filename, const char *dirname, unsigned flags);
int envfs_save(const char *filename, const char *dirname);
int envfs_load_from_buf(void *buf, int len, const char *dir, unsigned flags);
/* defaults to /dev/env0 */
#ifdef CONFIG_ENV_HANDLING