scripts/bareboxenv: skip file creation to allow reading the destination file, when existing.
Signed-off-by: Jonas Licht <jonas.li...@gmail.com> Fixes #29 --- common/environment.c | 62 +++++++++++++++++++++++++++++++++++++++----- scripts/bareboxenv.c | 11 +------- 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/common/environment.c b/common/environment.c index 37adb5d678..dee746a6b2 100644 --- a/common/environment.c +++ b/common/environment.c @@ -305,9 +305,10 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags) struct envfs_super *super; int envfd, size, ret; struct action_data data = {}; - void *buf = NULL, *wbuf; + void *buf = NULL, *wbuf, *bufWithEfi; struct envfs_entry *env; const char *defenv_path = default_environment_path_get(); + uint32_t magic; if (!filename) filename = defenv_path; @@ -342,7 +343,9 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags) } } - buf = xzalloc(size + sizeof(struct envfs_super)); + bufWithEfi = xzalloc(size + sizeof(struct envfs_super) + + 4); // four byte efi attributes + buf = bufWithEfi + 4; data.writep = buf + sizeof(struct envfs_super); super = buf; @@ -370,7 +373,7 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags) super->crc = ENVFS_32(crc32(0, buf + sizeof(struct envfs_super), size)); super->sb_crc = ENVFS_32(crc32(0, buf, sizeof(struct envfs_super) - 4)); - envfd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + envfd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (envfd < 0) { printf("could not open %s: %m\n", filename); ret = -errno; @@ -385,6 +388,34 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags) goto out; } + wbuf = buf; + + /* check if we writing efi vars */ + ret = pread(envfd, &magic, sizeof(uint32_t), + 4); // four byte efi var attributes + if (ret == -1 && errno == ENOENT) { + // skip as file don't exist + goto skip_efi_read; + } + if (ret < sizeof(u_int32_t)) { + perror("read of destination file failed"); + ret = -errno; + goto skip_efi_read; + } + + if (ENVFS_32(magic) == ENVFS_MAGIC) { + pr_info("looks like we writing efi vars, keep attributes\n"); + ret = pread(envfd, bufWithEfi, sizeof(uint32_t), 0); + if (ret < sizeof(uint32_t)) { + perror("read of efi attributes failed"); + ret = -errno; + goto out; + } + size += sizeof(uint32_t); + wbuf = bufWithEfi; + } + +skip_efi_read: ret = erase(envfd, ERASE_SIZE_ALL, 0, ERASE_TO_WRITE); /* ENOSYS and EOPNOTSUPP aren't errors here, many devices don't need it */ @@ -395,8 +426,6 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags) size += sizeof(struct envfs_super); - wbuf = buf; - while (size) { ssize_t now = write(envfd, wbuf, size); if (now < 0) { @@ -425,7 +454,7 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags) out: close(envfd); out1: - free(buf); + free(bufWithEfi); #ifdef __BAREBOX__ unlink_recursive(TMPDIR, NULL); #endif @@ -449,6 +478,7 @@ int envfs_load(const char *filename, const char *dir, unsigned flags) int envfd; int ret = 0; size_t size, rsize; + uint32_t magic; if (!filename) filename = default_environment_path_get(); @@ -466,6 +496,26 @@ int envfs_load(const char *filename, const char *dir, unsigned flags) return -1; } + /* check if we reading efi vars */ + ret = pread(envfd, &magic, sizeof(uint32_t), + 4); // four byte efi var attributes + if (ret < sizeof(u_int32_t)) { + perror("read"); + ret = -errno; + goto out; + } + + if (ENVFS_32(magic) == ENVFS_MAGIC) { + pr_info("looks like we reading efi vars, skip attributes\n"); + ret = read(envfd, &magic, + sizeof(uint32_t)); // simply reuse the memory + if (ret < sizeof(uint32_t)) { + perror("read"); + ret = -errno; + goto out; + } + } + /* read superblock */ ret = read(envfd, &super, sizeof(struct envfs_super)); if ( ret < sizeof(struct envfs_super)) { diff --git a/scripts/bareboxenv.c b/scripts/bareboxenv.c index e954447015..6b9b8d90c4 100644 --- a/scripts/bareboxenv.c +++ b/scripts/bareboxenv.c @@ -117,7 +117,7 @@ static void usage(char *prgname) int main(int argc, char *argv[]) { int opt; - int save = 0, load = 0, pad = 0, err = 0, fd; + int save = 0, load = 0, pad = 0, err = 0; char *filename = NULL, *dirname = NULL; unsigned envfs_flags = 0; int verbose = 0; @@ -156,15 +156,6 @@ int main(int argc, char *argv[]) exit(1); } - if (save) { - fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0644); - if (fd < 0) { - perror("open"); - exit(1); - } - close(fd); - } - if (save && pad) { if (truncate(filename, pad)) { perror("truncate"); -- 2.45.3