From 80f3aac62d2516975c3f39e65bfbb779a0f99bd3 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Tue, 10 Mar 2026 04:02:28 +0000 Subject: util/nvmutil: unified I/O: stdout, urandom and gbe everything is a file Signed-off-by: Leah Rowe --- util/nvmutil/nvmutil.c | 115 ++++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 63 deletions(-) (limited to 'util') diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c index fe3656cd..20f07141 100644 --- a/util/nvmutil/nvmutil.c +++ b/util/nvmutil/nvmutil.c @@ -109,8 +109,6 @@ static void set_mac_nib(size_t mac_str_pos, size_t mac_byte_pos, size_t mac_nib_pos); static uint16_t hextonum(char ch_s); static uint16_t rhex(void); -static void read_file_exact(int fd, uint8_t *mem, size_t len, - off_t off, uint8_t plesen, const char *path); static void write_mac_part(size_t partnum); static void cmd_helper_dump(void); static void print_mac_from_nvm(size_t partnum); @@ -127,6 +125,8 @@ static void set_part_modified(size_t p); static void check_nvm_bound(size_t pos16, size_t part); static void check_bin(size_t a, const char *a_name); static void write_gbe_file_part(size_t part); +static void rw_file_exact(int fd, uint8_t *mem, size_t len, + off_t off, int rw_type, const char *path, const char *rw_type_str); static off_t gbe_file_offset(size_t part, const char *f_op); static uint8_t *gbe_mem_offset(size_t part, const char *f_op); static off_t gbe_x_offset(size_t part, const char *f_op, @@ -224,6 +224,13 @@ static const char *argv0; #define ARGC_3 3 #define ARGC_4 4 +enum { + LESEN, + PLESEN, + SCHREIB, + PSCHREIB +}; + /* * Used as indices for command[] * MUST be in the same order as entries in command[] @@ -512,6 +519,9 @@ sanitize_command_index(size_t c) if (command[c].flags != O_RDONLY && command[c].flags != O_RDWR) err(EINVAL, "invalid cmd.flags setting"); + + if (!((PLESEN > LESEN) && (SCHREIB > PLESEN) && (PSCHREIB > SCHREIB))) + err(EINVAL, "some rw type integers are the same"); } static void @@ -698,9 +708,9 @@ read_gbe_file_part(size_t p) uint8_t *mem_offset = gbe_mem_offset(p ^ command[cmd_index].invert, "pread"); - read_file_exact(gbe_fd, mem_offset, + rw_file_exact(gbe_fd, mem_offset, gbe_rw_size, gbe_file_offset(p, "pread"), - 1, fname); + PLESEN, fname, "pread"); } static void @@ -938,42 +948,13 @@ rhex(void) #ifdef NVMUTIL_ARC4RANDOM_BUF arc4random_buf(rnum, n); #else - read_file_exact(urandom_fd, rnum, n, 0, 0, rname); + rw_file_exact(urandom_fd, rnum, n, 0, LESEN, rname, "read"); #endif } return (uint16_t)(rnum[--n] & 0xf); } -static void -read_file_exact(int fd, uint8_t *mem, - size_t len, off_t off, uint8_t plesen, const char *path) -{ - ssize_t rval = -1; - ssize_t rc = 0; - - if (fd == -1) - err(ECANCELED, "Trying to open bad fd: %s", path); - - for (rc = 0; rc != (ssize_t)len; rc += rval) { - if (plesen) - rval = pread(fd, mem + rc, len - rc, off + rc); - else - rval = read(fd, mem + rc, len - rc); - - if (rval > -1) { - if (!rval) /* prevent infinite loop */ - err(EIO, "%s: read of 0 bytes", path); - continue; - } - - if (errno != EINTR || rval < -1) - err(EIO, "%s", path); - - errno = 0; - } -} - static void write_mac_part(size_t partnum) { @@ -1075,12 +1056,8 @@ cmd_helper_cat(void) static void gbe_cat_buf(uint8_t *b) { - size_t wc; - ssize_t w = 0; - - for (wc = 0; wc < GBE_PART_SIZE; wc += w) - if ((w = write(STDOUT_FILENO, b + wc, GBE_PART_SIZE - wc)) < 1) - err(EIO, "%s: stdout", fname); + rw_file_exact(STDOUT_FILENO, b, GBE_PART_SIZE, 0, + SCHREIB, "stdout", "write"); } static void @@ -1222,37 +1199,49 @@ check_bin(size_t a, const char *a_name) static void write_gbe_file_part(size_t p) { - int retry; - ssize_t rval; - size_t gbe_rw_size; + size_t gbe_rw_size = command[cmd_index].rw_size; + uint8_t *mem_offset = gbe_mem_offset(p, "pwrite"); - if (gbe_fd == -1) - err(ECANCELED, "%s: Trying to write bad gbe_fd", fname); + rw_file_exact(gbe_fd, mem_offset, + gbe_rw_size, gbe_file_offset(p, "pwrite"), + PSCHREIB, fname, "pwrite"); +} + +static void +rw_file_exact(int fd, uint8_t *mem, size_t len, + off_t off, int rw_type, const char *path, + const char *rw_type_str) +{ + ssize_t rval = -1; + ssize_t rc = 0; - gbe_rw_size = command[cmd_index].rw_size; + if (fd < 0) + err(EIO, "%s: %s: Bad fd %d", path, rw_type_str, fd); + if (!len) + err(EIO, "%s: %s: Zero length", path, rw_type_str); - for (retry = 0; retry < MAX_RETRY_RW; retry++) { - rval = pwrite(gbe_fd, gbe_mem_offset(p, "pwrite"), - gbe_rw_size, gbe_file_offset(p, "pwrite")); + for (rc = 0; rc != (ssize_t)len; rc += rval) { + if (rw_type == PSCHREIB) + rval = pwrite(fd, mem + rc, len - rc, off + rc); + else if (rw_type == SCHREIB) + rval = write(fd, mem + rc, len - rc); + else if (rw_type == PLESEN) + rval = pread(fd, mem + rc, len - rc, off + rc); + else if (rw_type == LESEN) + rval = read(fd, mem + rc, len - rc); - if (rval == (ssize_t)gbe_rw_size) { - errno = 0; - printf("%s: Wrote %zu bytes to part %zu\n", - fname, gbe_rw_size, p); - return; + if (rval > -1) { + if (!rval) /* prevent infinite loop */ + err(EIO, "%s: %s: 0-byte return", + path, rw_type_str); + continue; } - if (rval != -1) - err(ECANCELED, - "%s: Short pwrite of %zd bytes", - fname, rval); + if (errno != EINTR || rval < -1) + err(EIO, "%s: %s", path, rw_type_str); - if (errno != EINTR) - err(ECANCELED, - "%s: pwrite failed on p%zu", fname, p); + errno = 0; } - - err(EINTR, "%s: pwrite: max retries exceeded on p%zu", fname, p); } /* -- cgit v1.2.1