All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonas Licht <jonas.licht@gmail.com>
To: barebox@lists.infradead.org
Cc: Jonas Licht <jonas.licht@gmail.com>
Subject: [PATCH] environment: support reading and writing of efivar
Date: Tue, 11 Mar 2025 15:17:13 +0100	[thread overview]
Message-ID: <20250311141713.30947-1-jonas.licht@gmail.com> (raw)

scripts/bareboxenv: skip file creation to allow reading the destination
file, when existing.

Signed-off-by: Jonas Licht <jonas.licht@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




             reply	other threads:[~2025-03-11 14:20 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-11 14:17 Jonas Licht [this message]
2025-03-17 10:42 ` [PATCH] environment: support reading and writing of efivar Ahmad Fatoum
2025-03-18 16:32 ` [PATCH v2] " Jonas Licht
2025-03-20  9:22 ` [PATCH v3] " Jonas Licht
2025-04-04 14:51   ` Ahmad Fatoum
2025-04-24 13:04     ` Jonas Licht
2025-04-24 12:59 ` [PATCH v4] " Jonas Licht

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250311141713.30947-1-jonas.licht@gmail.com \
    --to=jonas.licht@gmail.com \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.