From b94566048b839227c5d3636178c30ac1fe72853b Mon Sep 17 00:00:00 2001 From: Eduard Shishkin Date: Fri, 4 Oct 2024 20:11:14 +0200 Subject: [PATCH] zipl/src: Introduce 'write simulation' mode for individual files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a write simulation operation, which doesn't write actual data and just updates the current position in the file. This allows to emulate block lists for files located on raw devices (not formatted with a file system). This is used by the next patches in the series to implement '--dry-run' zipl option for dumps of all types (not only ngdumps). Introduce a 'misc file descriptor', which allows to mark individual files as "opened in a simulation mode". Whenever bulding a bootmap file, use either real write, or write simulation depending on the mode set in the 'misc file descriptor'. Tested-by: Mikhail Zaslonko Reviewed-by: Mikhail Zaslonko Signed-off-by: Eduard Shishkin Signed-off-by: Jan Höppner --- zipl/include/bootmap.h | 6 +- zipl/include/disk.h | 9 +-- zipl/include/envblk.h | 6 +- zipl/include/install.h | 7 ++- zipl/include/misc.h | 5 ++ zipl/src/bootmap.c | 76 ++++++++++++------------ zipl/src/bootmap_header.c | 24 ++++---- zipl/src/disk.c | 26 ++++---- zipl/src/envblk.c | 20 +++---- zipl/src/install.c | 122 ++++++++++++++++++++------------------ zipl/src/job.c | 12 ++-- zipl/src/misc.c | 20 +++++++ zipl/src/zipl-editenv.c | 34 +++++------ 13 files changed, 199 insertions(+), 168 deletions(-) diff --git a/zipl/include/bootmap.h b/zipl/include/bootmap.h index d9050a34..9005f52d 100644 --- a/zipl/include/bootmap.h +++ b/zipl/include/bootmap.h @@ -49,9 +49,9 @@ struct file_signature { #define PKEY_ID_PKCS7 0x02 -int bootmap_header_init(int fd); -int bootmap_header_read(int fd, struct bootmap_header *bh); -int bootmap_header_write(int fd, struct bootmap_header *bh); +int bootmap_header_init(struct misc_fd *mfd); +int bootmap_header_read(struct misc_fd *mfd, struct bootmap_header *bh); +int bootmap_header_write(struct misc_fd *mfd, struct bootmap_header *bh); void bootmap_store_blockptr(void *buffer, disk_blockptr_t *ptr, struct disk_info *info, int fid); diff --git a/zipl/include/disk.h b/zipl/include/disk.h index 52c6fe74..ac270692 100644 --- a/zipl/include/disk.h +++ b/zipl/include/disk.h @@ -15,6 +15,7 @@ #include #include +#include "misc.h" #include "zipl.h" #include "lib/vtoc.h" @@ -113,13 +114,13 @@ int disk_head_from_blocknum(blocknum_t blocknum, struct disk_info* info); int disk_sec_from_blocknum(blocknum_t blocknum, struct disk_info* info); void disk_blockptr_from_blocknum(disk_blockptr_t* ptr, blocknum_t blocknum, struct disk_info* info); -int disk_write_block_aligned(int fd, const void* data, size_t bytecount, - disk_blockptr_t* block, struct disk_info* info); -blocknum_t disk_write_block_buffer(int fd, int fd_is_basedisk, +int disk_write_block_aligned(struct misc_fd *mfd, const void *data, size_t bytecount, + disk_blockptr_t *block, struct disk_info *info); +blocknum_t disk_write_block_buffer(struct misc_fd *fd, int fd_is_basedisk, const void* buffer, size_t bytecount, disk_blockptr_t** blocklist, struct disk_info *info); -blocknum_t disk_write_block_buffer_align(int fd, int fd_is_basedisk, +blocknum_t disk_write_block_buffer_align(struct misc_fd *mfd, int fd_is_basedisk, const void *buffer, size_t bytecount, disk_blockptr_t **blocklist, struct disk_info *info, int align, diff --git a/zipl/include/envblk.h b/zipl/include/envblk.h index 9c38c5a3..9f634f13 100644 --- a/zipl/include/envblk.h +++ b/zipl/include/envblk.h @@ -34,9 +34,9 @@ static inline size_t get_name_len(const char *p, const char *pname) return p ? strlen(pname) - strlen(p) : strlen(pname); } -int envblk_offset_get(int fd, off_t *off); -int envblk_offset_set(int fd, off_t off); -int envblk_size_get(int fd, int *size); +int envblk_offset_get(struct misc_fd *mfd, off_t *off); +int envblk_offset_set(struct misc_fd *mfd, off_t off); +int envblk_size_get(struct misc_fd *mfd, int *size); int envblk_check_name(const char *name, int len); int envblk_import(char *from, char *to, int size); char *envblk_next_line(char *s, const char *end); diff --git a/zipl/include/install.h b/zipl/include/install.h index d40971d8..04d54c87 100644 --- a/zipl/include/install.h +++ b/zipl/include/install.h @@ -14,6 +14,7 @@ #include "disk.h" #include "job.h" +#include "misc.h" #include "zipl.h" #include "boot/boot_defs.h" @@ -70,7 +71,7 @@ struct install_set { struct program_table tables[NR_PROGRAM_TABLES]; struct program_component *components[NR_PROGRAM_COMPONENTS]; int nr_menu_entries; - int fd; + struct misc_fd mfd; char *basetmp[MAX_TARGETS]; char *filename; unsigned int tmp_filename_created:1; @@ -124,10 +125,10 @@ int install_dump(const char *device, struct job_target_data *target, int install_mvdump(char* const device[], struct job_target_data* target, int device_count, uint64_t mem, uint8_t force); -int install_fba_stage1b(int fd, disk_blockptr_t **stage1b_list, +int install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, blocknum_t *stage1b_count, disk_blockptr_t *stage2_list, blocknum_t stage2_count, struct disk_info *info); -int install_eckd_stage1b(int fd, disk_blockptr_t **stage1b_list, +int install_eckd_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, blocknum_t *stage1b_count, disk_blockptr_t *stage2_list, blocknum_t stage2_count, struct disk_info *info); diff --git a/zipl/include/misc.h b/zipl/include/misc.h index d57a9c51..991e659a 100644 --- a/zipl/include/misc.h +++ b/zipl/include/misc.h @@ -24,6 +24,10 @@ struct misc_file_buffer { size_t length; }; +struct misc_fd { + int fd; + unsigned int simulate_write:1; +}; void* misc_malloc(size_t size); int misc_asprintf(char **out, const char *fmt, ...); @@ -36,6 +40,7 @@ int misc_read_file(const char* filename, char** buffer, size_t* size, int misc_read_special_file(const char* filename, char** buffer, size_t* size, int nil_terminate); int misc_write(int fd, const void* data, size_t count); +int misc_write_or_simulate(struct misc_fd *mfd, const void *data, size_t count); int misc_pwrite(int fd, void *buf, size_t size, off_t off); int misc_seek(int fd, off_t off); int misc_get_file_buffer(const char* filename, diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c index 880b93ce..f01bcb68 100644 --- a/zipl/src/bootmap.c +++ b/zipl/src/bootmap.c @@ -181,7 +181,7 @@ check_secure_boot_support(void) * of segment table blocks to the file identified by file descriptor FD. Upon * success, return 0 and set SECTION_POINTER to point to the first block in * the resulting segment table. Return non-zero otherwise. */ -static int add_segment_table(int fd, disk_blockptr_t *list, blocknum_t count, +static int add_segment_table(struct misc_fd *mfd, disk_blockptr_t *list, blocknum_t count, disk_blockptr_t *segment_pointer, struct disk_info *info, int program_table_id) { @@ -220,7 +220,7 @@ static int add_segment_table(int fd, disk_blockptr_t *list, blocknum_t count, bootmap_store_blockptr(VOID_ADD(buffer, offset * pointer_size), &next, info, program_table_id); - rc = disk_write_block_aligned(fd, buffer, info->phy_block_size, + rc = disk_write_block_aligned(mfd, buffer, info->phy_block_size, &next, info); if (rc) { free(buffer); @@ -233,7 +233,7 @@ static int add_segment_table(int fd, disk_blockptr_t *list, blocknum_t count, } -static int add_program_table(int fd, disk_blockptr_t *table, int entries, +static int add_program_table(struct misc_fd *mfd, disk_blockptr_t *table, int entries, disk_blockptr_t *pointer, struct disk_info *info, int program_table_id) { @@ -255,7 +255,7 @@ static int add_program_table(int fd, disk_blockptr_t *table, int entries, offset += get_blockptr_size(info); } /* Write program table */ - rc = disk_write_block_aligned(fd, block, PROGRAM_TABLE_BLOCK_SIZE, + rc = disk_write_block_aligned(mfd, block, PROGRAM_TABLE_BLOCK_SIZE, pointer, info); free(block); return rc; @@ -371,7 +371,7 @@ static int add_component_file_range(struct install_set *bis, } size -= trailer; /* Write buffer */ - *count = disk_write_block_buffer(bis->fd, 0, buffer, + *count = disk_write_block_buffer(&bis->mfd, 0, buffer, size, list, bis->info); free(buffer); if (*count == 0) { @@ -398,7 +398,7 @@ static int add_component_file_range(struct install_set *bis, write_segment_table: assert(*list != NULL); assert(*count != 0); - rc = add_segment_table(bis->fd, *list, *count, &segment, bis->info, + rc = add_segment_table(&bis->mfd, *list, *count, &segment, bis->info, program_table_id); if (rc == 0) create_component_entry(component, &segment, @@ -436,7 +436,7 @@ static int add_component_buffer_align(struct install_set *bis, void *buffer, /* skip the preparation work */ goto write_segment_table; /* Write buffer */ - *count = disk_write_block_buffer_align(bis->fd, 0, buffer, size, list, + *count = disk_write_block_buffer_align(&bis->mfd, 0, buffer, size, list, bis->info, align, offset); if (*count == 0) { error_text("Could not write to bootmap file"); @@ -456,7 +456,7 @@ write_segment_table: assert(*list != NULL); assert(*count != 0); - rc = add_segment_table(bis->fd, *list, *count, &segment, bis->info, + rc = add_segment_table(&bis->mfd, *list, *count, &segment, bis->info, program_table_id); if (rc == 0) create_component_entry(component, &segment, @@ -851,7 +851,7 @@ static int add_ipl_program(struct install_set *bis, char *filename, /* * finally add environment block */ - rc = envblk_offset_get(bis->fd, &envblk_off); + rc = envblk_offset_get(&bis->mfd, &envblk_off); if (rc) { free(table); return rc; @@ -879,7 +879,7 @@ static int add_ipl_program(struct install_set *bis, char *filename, * store environment block location * in the bootmap header */ - rc = envblk_offset_set(bis->fd, envblk_off); + rc = envblk_offset_set(&bis->mfd, envblk_off); if (rc) { error_text("Could not store environment block location"); free(table); @@ -914,7 +914,7 @@ static int add_ipl_program(struct install_set *bis, char *filename, (STAGE3_ENTRY | PSW_LOAD), bis->info, program_table_id); /* Write component table */ - rc = disk_write_block_aligned(bis->fd, table, + rc = disk_write_block_aligned(&bis->mfd, table, bis->info->phy_block_size, program, bis->info); free(table); @@ -963,7 +963,7 @@ static int add_segment_program(struct install_set *bis, (component_data)(uint64_t)PSW_DISABLED_WAIT, bis->info, program_table_id); /* Write component table */ - rc = disk_write_block_aligned(bis->fd, table, + rc = disk_write_block_aligned(&bis->mfd, table, bis->info->phy_block_size, program, bis->info); free(table); @@ -1139,7 +1139,7 @@ static int build_program_table(struct job_data *job, /* Add program table block */ pointer = &bis->tables[program_table_id].table; - rc = add_program_table(bis->fd, table, entries, + rc = add_program_table(&bis->mfd, table, entries, pointer, bis->info, program_table_id); } @@ -1151,7 +1151,7 @@ static int build_program_table(struct job_data *job, /* Write block of zeroes to the bootmap file FD and store the resulting * block pointer in BLOCK. Return zero on success, non-zero otherwise. */ static int -write_empty_block(int fd, disk_blockptr_t* block, struct disk_info* info) +write_empty_block(struct misc_fd *mfd, disk_blockptr_t *block, struct disk_info *info) { void* buffer; int rc; @@ -1160,14 +1160,14 @@ write_empty_block(int fd, disk_blockptr_t* block, struct disk_info* info) if (buffer == NULL) return -1; memset(buffer, 0, info->phy_block_size); - rc = disk_write_block_aligned(fd, buffer, info->phy_block_size, block, + rc = disk_write_block_aligned(mfd, buffer, info->phy_block_size, block, info); free(buffer); return rc; } -static int install_stages_dasd_fba(int fd, char *filename, +static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename, struct job_data *job, struct disk_info *info, disk_blockptr_t **stage1b_list, @@ -1188,7 +1188,7 @@ static int install_stages_dasd_fba(int fd, char *filename, */ if (boot_get_fba_stage2(&stage2_data, &stage2_size, job)) return -1; - stage2_count = disk_write_block_buffer(fd, 0, stage2_data, + stage2_count = disk_write_block_buffer(mfd, 0, stage2_data, stage2_size, &stage2_list, info); free(stage2_data); @@ -1196,7 +1196,7 @@ static int install_stages_dasd_fba(int fd, char *filename, error_text("Could not write to file '%s'", filename); return -1; } - if (install_fba_stage1b(fd, stage1b_list, stage1b_count, + if (install_fba_stage1b(mfd, stage1b_list, stage1b_count, stage2_list, stage2_count, info)) return -1; free(stage2_list); @@ -1215,7 +1215,7 @@ static int install_stages_dasd_fba(int fd, char *filename, return 0; } -static int install_stages_eckd_dasd(int fd, char *filename, +static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename, struct job_data *job, struct disk_info *info, disk_blockptr_t *program_table, @@ -1236,7 +1236,7 @@ static int install_stages_eckd_dasd(int fd, char *filename, */ if (boot_get_eckd_stage2(&stage2b_data, &stage2b_size, job)) return -1; - stage2b_count = disk_write_block_buffer(fd, 0, stage2b_data, + stage2b_count = disk_write_block_buffer(mfd, 0, stage2b_data, stage2b_size, &stage2b_list, info); @@ -1245,7 +1245,7 @@ static int install_stages_eckd_dasd(int fd, char *filename, error_text("Could not write to file '%s'", filename); return -1; } - if (install_eckd_stage1b(fd, stage1b_list, stage1b_count, + if (install_eckd_stage1b(mfd, stage1b_list, stage1b_count, stage2b_list, stage2b_count, info)) return -1; free(stage2b_list); @@ -1260,7 +1260,7 @@ static int install_stages_eckd_dasd(int fd, char *filename, if (boot_get_eckd_ld_ipl_br(&stage2b_data, &stage2b_size, program_table, info)) return -1; - stage2b_count = disk_write_block_buffer(fd, 0, stage2b_data, + stage2b_count = disk_write_block_buffer(mfd, 0, stage2b_data, stage2b_size, stage1b_list, info); @@ -1285,7 +1285,7 @@ static int bootmap_install_stages(struct job_data *job, struct install_set *bis, switch (bis->info->type) { case disk_type_fba: - rc = install_stages_dasd_fba(bis->fd, bis->filename, job, + rc = install_stages_dasd_fba(&bis->mfd, bis->filename, job, bis->info, &pt->stage1b_list, &pt->stage1b_count, @@ -1293,7 +1293,7 @@ static int bootmap_install_stages(struct job_data *job, struct install_set *bis, break; case disk_type_eckd_ldl: case disk_type_eckd_cdl: - rc = install_stages_eckd_dasd(bis->fd, bis->filename, job, + rc = install_stages_eckd_dasd(&bis->mfd, bis->filename, job, bis->info, &pt->table, &pt->stage1b_list, @@ -1310,7 +1310,7 @@ static int bootmap_install_stages(struct job_data *job, struct install_set *bis, } static int -bootmap_write_scsi_superblock(int fd, struct disk_info *info, +bootmap_write_scsi_superblock(struct misc_fd *mfd, struct disk_info *info, disk_blockptr_t *scsi_dump_sb_blockptr, ulong dump_size) { @@ -1327,7 +1327,7 @@ bootmap_write_scsi_superblock(int fd, struct disk_info *info, scsi_sb.csum_size = SCSI_DUMP_SB_CSUM_SIZE; /* Set seed because otherwise csum over zero block is 0 */ scsi_sb.csum = SCSI_DUMP_SB_SEED; - return disk_write_block_aligned(fd, &scsi_sb, + return disk_write_block_aligned(mfd, &scsi_sb, sizeof(scsi_sb), scsi_dump_sb_blockptr, info); } @@ -1451,8 +1451,8 @@ static int prepare_build_program_table_device(struct job_data *job, bis->filename = misc_strdup(job->data.dump.device); if (!bis->filename) return -1; - bis->fd = misc_open_exclusive(bis->filename); - if (bis->fd == -1) { + bis->mfd.fd = misc_open_exclusive(bis->filename); + if (bis->mfd.fd == -1) { error_text("Could not open file '%s'", bis->filename); return -1; } @@ -1476,22 +1476,22 @@ static int prepare_build_program_table_device(struct job_data *job, to expected size before end of disk */ if (estimate_scsi_dump_size(job, bis->info, &unused_size)) return -1; - if (lseek(bis->fd, unused_size, SEEK_SET) < 0) + if (lseek(bis->mfd.fd, unused_size, SEEK_SET) < 0) return -1; /* Initialize bootmap header */ - if (bootmap_header_init(bis->fd)) { + if (bootmap_header_init(&bis->mfd)) { error_text("Could not init bootmap header at '%s'", bis->filename); return -1; } /* Write empty block to be read in place of holes in files */ - if (write_empty_block(bis->fd, &empty_block, bis->info)) { + if (write_empty_block(&bis->mfd, &empty_block, bis->info)) { error_text("Could not write to file '%s'", bis->filename); return -1; } - if (bootmap_write_scsi_superblock(bis->fd, bis->info, + if (bootmap_write_scsi_superblock(&bis->mfd, bis->info, &bis->scsi_dump_sb_blockptr, unused_size)) { error_text("Could not write SCSI superblock to file '%s'", @@ -1540,8 +1540,8 @@ static int prepare_build_program_table_file(struct job_data *job, BOOTMAP_TEMPLATE_FILENAME); if (!bis->filename) return -1; - bis->fd = mkstemp(bis->filename); - if (bis->fd == -1) { + bis->mfd.fd = mkstemp(bis->filename); + if (bis->mfd.fd == -1) { error_reason(strerror(errno)); error_text("Could not create file '%s':", bis->filename); return -1; @@ -1574,13 +1574,13 @@ static int prepare_build_program_table_file(struct job_data *job, job->add_files ? " (files will be added to bootmap file)" : ""); /* Initialize bootmap header */ - if (bootmap_header_init(bis->fd)) { + if (bootmap_header_init(&bis->mfd)) { error_text("Could not init bootmap header at '%s'", bis->filename); return -1; } /* Write empty block to be read in place of holes in files */ - if (write_empty_block(bis->fd, &empty_block, bis->info)) { + if (write_empty_block(&bis->mfd, &empty_block, bis->info)) { error_text("Could not write to file '%s'", bis->filename); return -1; } @@ -1825,8 +1825,8 @@ void free_bootloader(struct install_set *bis) free(get_component(bis, i, j)->list); free(bis->components[i]); } - if (bis->fd > 0) - close(bis->fd); + if (bis->mfd.fd > 0) + close(bis->mfd.fd); if (bis->tmp_filename_created) misc_free_temp_file(bis->filename); free(bis->filename); diff --git a/zipl/src/bootmap_header.c b/zipl/src/bootmap_header.c index 84dec4a9..e1e2961a 100644 --- a/zipl/src/bootmap_header.c +++ b/zipl/src/bootmap_header.c @@ -16,7 +16,7 @@ #include "error.h" #include "misc.h" -int bootmap_header_init(int fd) +int bootmap_header_init(struct misc_fd *mfd) { struct bootmap_header bh = { .header_text = @@ -25,40 +25,40 @@ int bootmap_header_init(int fd) .version = BOOTMAP_HEADER_VERSION }; - return misc_write(fd, &bh, sizeof(bh)); + return misc_write_or_simulate(mfd, &bh, sizeof(bh)); } -static int bootmap_header_access(int fd, struct bootmap_header *bh, int read) +static int bootmap_header_access(struct misc_fd *mfd, struct bootmap_header *bh, int read) { off_t cur_off; int ret; - cur_off = lseek(fd, 0, SEEK_CUR); + cur_off = lseek(mfd->fd, 0, SEEK_CUR); if (cur_off == -1) { error_reason(strerror(errno)); return -1; } - if (lseek(fd, 0, SEEK_SET) == -1) { + if (lseek(mfd->fd, 0, SEEK_SET) == -1) { error_reason(strerror(errno)); ret = -1; goto out; } if (read) - ret = misc_read(fd, bh, sizeof(*bh)); + ret = misc_read(mfd->fd, bh, sizeof(*bh)); else - ret = misc_write(fd, bh, sizeof(*bh)); + ret = misc_write_or_simulate(mfd, bh, sizeof(*bh)); out: - if (lseek(fd, cur_off, SEEK_SET) == -1) + if (lseek(mfd->fd, cur_off, SEEK_SET) == -1) return -1; return ret; } -int bootmap_header_read(int fd, struct bootmap_header *bh) +int bootmap_header_read(struct misc_fd *mfd, struct bootmap_header *bh) { - return bootmap_header_access(fd, bh, 1); + return bootmap_header_access(mfd, bh, 1); } -int bootmap_header_write(int fd, struct bootmap_header *bh) +int bootmap_header_write(struct misc_fd *mfd, struct bootmap_header *bh) { - return bootmap_header_access(fd, bh, 0); + return bootmap_header_access(mfd, bh, 0); } diff --git a/zipl/src/disk.c b/zipl/src/disk.c index 3fc71626..bb72fdab 100644 --- a/zipl/src/disk.c +++ b/zipl/src/disk.c @@ -978,8 +978,8 @@ disk_blockptr_from_blocknum(disk_blockptr_t* ptr, blocknum_t blocknum, * otherwise. On success OFFSET contains offset of the first written byte */ static int -disk_write_block_aligned_base(int fd, int is_base_disk, const void* data, - size_t bytecount, disk_blockptr_t* block, +disk_write_block_aligned_base(struct misc_fd *mfd, int is_base_disk, const void *data, + size_t bytecount, disk_blockptr_t *block, struct disk_info *info, int align, off_t *offset) { blocknum_t current_block; @@ -989,7 +989,7 @@ disk_write_block_aligned_base(int fd, int is_base_disk, const void* data, if (align == 0) align = info->phy_block_size; - current_pos = lseek(fd, 0, SEEK_CUR); + current_pos = lseek(mfd->fd, 0, SEEK_CUR); if (current_pos == -1) { error_text(strerror(errno)); return -1; @@ -997,7 +997,7 @@ disk_write_block_aligned_base(int fd, int is_base_disk, const void* data, /* Ensure block alignment of current file pos */ if (current_pos % align != 0) { - current_pos = lseek(fd, align - current_pos % align, SEEK_CUR); + current_pos = lseek(mfd->fd, align - current_pos % align, SEEK_CUR); if (current_pos == -1) { error_text(strerror(errno)); return -1; @@ -1008,11 +1008,11 @@ disk_write_block_aligned_base(int fd, int is_base_disk, const void* data, if (bytecount > (size_t)info->phy_block_size) bytecount = info->phy_block_size; /* Write data block */ - if (misc_write(fd, data, bytecount)) + if (misc_write_or_simulate(mfd, data, bytecount)) return -1; if (block != NULL) { /* Store block pointer */ - if (disk_get_blocknum(fd, is_base_disk, current_block, + if (disk_get_blocknum(mfd->fd, is_base_disk, current_block, &blocknum, info)) return -1; disk_blockptr_from_blocknum(block, blocknum, info); @@ -1022,10 +1022,10 @@ disk_write_block_aligned_base(int fd, int is_base_disk, const void* data, return 0; } -int disk_write_block_aligned(int fd, const void *data, size_t bytecount, +int disk_write_block_aligned(struct misc_fd *mfd, const void *data, size_t bytecount, disk_blockptr_t *block, struct disk_info *info) { - return disk_write_block_aligned_base(fd, 0, data, bytecount, block, + return disk_write_block_aligned_base(mfd, 0, data, bytecount, block, info, info->phy_block_size, NULL); } @@ -1039,7 +1039,7 @@ int disk_write_block_aligned(int fd, const void *data, size_t bytecount, * otherwise. */ blocknum_t -disk_write_block_buffer_align(int fd, int fd_is_basedisk, const void *buffer, +disk_write_block_buffer_align(struct misc_fd *mfd, int fd_is_basedisk, const void *buffer, size_t bytecount, disk_blockptr_t **blocklist, struct disk_info *info, int align, off_t *offset) { @@ -1054,7 +1054,7 @@ disk_write_block_buffer_align(int fd, int fd_is_basedisk, const void *buffer, *blocklist = (disk_blockptr_t *)util_zalloc(sizeof(disk_blockptr_t) * count); if (*blocklist == NULL) { - close(fd); + close(mfd->fd); return 0; } /* Build list */ @@ -1062,7 +1062,7 @@ disk_write_block_buffer_align(int fd, int fd_is_basedisk, const void *buffer, chunk_size = bytecount - written; if (chunk_size > (size_t) info->phy_block_size) chunk_size = info->phy_block_size; - rc = disk_write_block_aligned_base(fd, fd_is_basedisk, + rc = disk_write_block_aligned_base(mfd, fd_is_basedisk, VOID_ADD(buffer, written), chunk_size, &(*blocklist)[i], info, @@ -1077,11 +1077,11 @@ disk_write_block_buffer_align(int fd, int fd_is_basedisk, const void *buffer, } blocknum_t -disk_write_block_buffer(int fd, int fd_is_basedisk, const void *buffer, +disk_write_block_buffer(struct misc_fd *mfd, int fd_is_basedisk, const void *buffer, size_t bytecount, disk_blockptr_t **blocklist, struct disk_info *info) { - return disk_write_block_buffer_align(fd, fd_is_basedisk, buffer, + return disk_write_block_buffer_align(mfd, fd_is_basedisk, buffer, bytecount, blocklist, info, info->phy_block_size, NULL); } diff --git a/zipl/src/envblk.c b/zipl/src/envblk.c index c4839f75..86b7a6d1 100644 --- a/zipl/src/envblk.c +++ b/zipl/src/envblk.c @@ -56,14 +56,14 @@ void envblk_create_blank(char *envblk, int envblk_len) /** * Find out environment block location. - * FD: bootmap file descriptor. + * MFD: bootmap file descriptor. * On success the searched location is saved in variable pointed out by OFF */ -int envblk_offset_get(int fd, off_t *off) +int envblk_offset_get(struct misc_fd *mfd, off_t *off) { struct bootmap_header bh; - if (bootmap_header_read(fd, &bh)) { + if (bootmap_header_read(mfd, &bh)) { error_reason("Could not read bootmap_header"); return -1; } @@ -73,20 +73,20 @@ int envblk_offset_get(int fd, off_t *off) /** * Save environment block location specified by OFF - * FD: bootmap file descriptor. + * MFD: bootmap file descriptor. * On success the location is saved in the bootmap header. */ -int envblk_offset_set(int fd, off_t off) +int envblk_offset_set(struct misc_fd *mfd, off_t off) { struct bootmap_header bh; - if (bootmap_header_read(fd, &bh)) { + if (bootmap_header_read(mfd, &bh)) { error_reason("Could not read bootmap header"); return -1; } bh.envblk_offset = off; - if (bootmap_header_write(fd, &bh)) { + if (bootmap_header_write(mfd, &bh)) { error_reason("Could not write bootmap header"); return -1; } @@ -95,12 +95,12 @@ int envblk_offset_set(int fd, off_t off) /** * Find out environment block size. - * FD: bootmap file descriptor. + * MFD: bootmap file descriptor. * On success the searched size is stored in RESULT */ -int envblk_size_get(int fd, int *result) +int envblk_size_get(struct misc_fd *mfd, int *result) { - if (ioctl(fd, FIGETBSZ, result) == -1) { + if (ioctl(mfd->fd, FIGETBSZ, result) == -1) { error_reason(strerror(errno)); return -1; } diff --git a/zipl/src/install.c b/zipl/src/install.c index 45530377..5e1c615d 100644 --- a/zipl/src/install.c +++ b/zipl/src/install.c @@ -170,7 +170,7 @@ install_fba_ccw(int fd, disk_blockptr_t *program_table, /* Install stage1b bootloader for ECKD type disk */ int -install_eckd_stage1b(int fd, disk_blockptr_t **stage1b_list, +install_eckd_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, blocknum_t *stage1b_count, disk_blockptr_t *stage2_list, blocknum_t stage2_count, struct disk_info *info) { @@ -186,7 +186,7 @@ install_eckd_stage1b(int fd, disk_blockptr_t **stage1b_list, memset(stage1b, 0, stage1b_size); if (boot_init_eckd_stage1b(stage1b, stage2_list, stage2_count)) goto out_free_stage1b; - *stage1b_count = disk_write_block_buffer(fd, 1, stage1b, stage1b_size, + *stage1b_count = disk_write_block_buffer(mfd, 1, stage1b, stage1b_size, stage1b_list, info); if (*stage1b_count == 0) goto out_free_stage1b; @@ -854,7 +854,7 @@ static void eckd_dump_store_param(struct eckd_dump_param *param, param->bpt = info->geo.sectors; } -static int install_svdump_eckd_ldl(int fd, struct disk_info *info, +static int install_svdump_eckd_ldl(struct misc_fd *mfd, struct disk_info *info, const struct stage2dump_parm_tail *stage2dump_parms) { disk_blockptr_t *stage2_list, *stage1b_list; @@ -872,21 +872,21 @@ static int install_svdump_eckd_ldl(int fd, struct disk_info *info, error_reason("ECKD dump record is too large"); goto out_free_stage2; } - if (overwrite_partition_start(fd, info, 0)) + if (overwrite_partition_start(mfd->fd, info, 0)) goto out_free_stage2; /* Install stage 2 and stage 1b to beginning of partition */ - if (misc_seek(fd, info->geo.start * info->phy_block_size)) + if (misc_seek(mfd->fd, info->geo.start * info->phy_block_size)) goto out_free_stage2; - stage2_count = disk_write_block_buffer(fd, 1, stage2, stage2_size, + stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size, &stage2_list, info); if (stage2_count == 0) goto out_free_stage2_list; - if (install_eckd_stage1b(fd, &stage1b_list, &stage1b_count, + if (install_eckd_stage1b(mfd, &stage1b_list, &stage1b_count, stage2_list, stage2_count, info)) goto out_free_stage2_list; /* Install stage 0 - afterwards we are at stage 1 position*/ boot_init_eckd_ldl_stage0(&stage0); - if (DRY_RUN_FUNC(misc_pwrite(fd, &stage0, sizeof(stage0), 0))) + if (DRY_RUN_FUNC(misc_pwrite(mfd->fd, &stage0, sizeof(stage0), 0))) goto out_free_stage1b_list; /* Install stage 1 and fill in dump partition parameter */ if (boot_init_eckd_stage1(&stage1, stage1b_list, stage1b_count)) @@ -895,7 +895,7 @@ static int install_svdump_eckd_ldl(int fd, struct disk_info *info, eckd_dump_store_param(¶m, info, 0); boot_get_dump_info(&stage1.boot_info, BOOT_INFO_DEV_TYPE_ECKD, ¶m); - if (DRY_RUN_FUNC(misc_pwrite(fd, &stage1, sizeof(stage1), + if (DRY_RUN_FUNC(misc_pwrite(mfd->fd, &stage1, sizeof(stage1), sizeof(stage0)))) goto out_free_stage1b_list; rc = 0; @@ -909,8 +909,9 @@ out: return rc; } -static int install_dump_eckd_cdl(int fd, struct disk_info *info, void *stage2, - size_t stage2_size, int mvdump, int force) +static int install_dump_eckd_cdl(struct misc_fd *mfd, struct disk_info *info, + void *stage2, size_t stage2_size, int mvdump, + int force) { blocknum_t count, stage2_count, stage1b_count; disk_blockptr_t *stage2_list, *stage1b_list; @@ -930,19 +931,19 @@ static int install_dump_eckd_cdl(int fd, struct disk_info *info, void *stage2, goto out; } /* Install stage 2 */ - if (misc_seek(fd, ECKD_CDL_DUMP_REC * info->phy_block_size)) + if (misc_seek(mfd->fd, ECKD_CDL_DUMP_REC * info->phy_block_size)) goto out; - stage2_count = disk_write_block_buffer(fd, 1, stage2, stage2_size, + stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size, &stage2_list, info); if (stage2_count == 0) goto out; /* Install stage 1b behind stage 2*/ - if (install_eckd_stage1b(fd, &stage1b_list, &stage1b_count, + if (install_eckd_stage1b(mfd, &stage1b_list, &stage1b_count, stage2_list, stage2_count, info)) goto out_free_stage2_list; /* Install stage 0 */ boot_init_eckd_cdl_stage0(&stage0_cdl); - if (DRY_RUN_FUNC(misc_pwrite(fd, &stage0_cdl, sizeof(stage0_cdl), 4))) + if (DRY_RUN_FUNC(misc_pwrite(mfd->fd, &stage0_cdl, sizeof(stage0_cdl), 4))) goto out_free_stage1b_list; /* Install stage 1 and fill in dump partition parameter */ if (boot_init_eckd_stage1(&stage1, stage1b_list, stage1b_count)) @@ -950,10 +951,10 @@ static int install_dump_eckd_cdl(int fd, struct disk_info *info, void *stage2, eckd_dump_store_param(¶m, info, 0); boot_get_dump_info(&stage1.boot_info, BOOT_INFO_DEV_TYPE_ECKD, ¶m); - if (DRY_RUN_FUNC(misc_pwrite(fd, &stage1, sizeof(stage1), + if (DRY_RUN_FUNC(misc_pwrite(mfd->fd, &stage1, sizeof(stage1), info->phy_block_size + 4))) goto out_free_stage1b_list; - if (!force && overwrite_partition_start(fd, info, mvdump)) + if (!force && overwrite_partition_start(mfd->fd, info, mvdump)) goto out_free_stage1b_list; rc = 0; out_free_stage1b_list: @@ -965,7 +966,7 @@ out: } static int -install_svdump_eckd_cdl(int fd, struct disk_info *info, +install_svdump_eckd_cdl(struct misc_fd *mfd, struct disk_info *info, const struct stage2dump_parm_tail *stage2dump_parms) { size_t stage2_size; @@ -974,13 +975,13 @@ install_svdump_eckd_cdl(int fd, struct disk_info *info, if (boot_get_eckd_dump_stage2(&stage2, &stage2_size, stage2dump_parms)) return -1; - rc = install_dump_eckd_cdl(fd, info, stage2, stage2_size, 0, 0); + rc = install_dump_eckd_cdl(mfd, info, stage2, stage2_size, 0, 0); free(stage2); return rc; } static int -install_mvdump_eckd_cdl(int fd, struct disk_info *info, +install_mvdump_eckd_cdl(struct misc_fd *mfd, struct disk_info *info, const struct stage2dump_parm_tail *stage2dump_parms, const struct mvdump_parm_table *mv_parm_table) { @@ -992,14 +993,14 @@ install_mvdump_eckd_cdl(int fd, struct disk_info *info, if (boot_get_eckd_mvdump_stage2(&stage2, &stage2_size, stage2dump_parms, mv_parm_table)) return -1; - rc = install_dump_eckd_cdl(fd, info, stage2, stage2_size, 1, + rc = install_dump_eckd_cdl(mfd, info, stage2, stage2_size, 1, stage2dump_parms->mvdump_force); free(stage2); return rc; } int -install_fba_stage1b(int fd, disk_blockptr_t **stage1b_list, +install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, blocknum_t *stage1b_count, disk_blockptr_t *stage2_list, blocknum_t stage2_count, struct disk_info *info) { @@ -1015,7 +1016,7 @@ install_fba_stage1b(int fd, disk_blockptr_t **stage1b_list, memset(stage1b, 0, stage1b_size); if (boot_init_fba_stage1b(stage1b, stage2_list, stage2_count)) goto out_free_stage1b; - *stage1b_count = disk_write_block_buffer(fd, 1, stage1b, stage1b_size, + *stage1b_count = disk_write_block_buffer(mfd, 1, stage1b, stage1b_size, stage1b_list, info); if (*stage1b_count == 0) goto out_free_stage1b; @@ -1027,7 +1028,7 @@ out: } static int -install_svdump_fba(int fd, struct disk_info *info, +install_svdump_fba(struct misc_fd *mfd, struct disk_info *info, const struct stage2dump_parm_tail *stage2dump_parms) { blocknum_t stage1b_count, stage2_count, blk; @@ -1039,7 +1040,7 @@ install_svdump_fba(int fd, struct disk_info *info, int rc = -1; /* Overwrite first 64k of partition */ - if (overwrite_partition_start(fd, info, 0)) + if (overwrite_partition_start(mfd->fd, info, 0)) goto out; /* Install stage 2 at end of partition */ if (boot_get_fba_dump_stage2(&stage2, &stage2_size, stage2dump_parms)) @@ -1049,17 +1050,17 @@ install_svdump_fba(int fd, struct disk_info *info, goto out_free_stage2; } blk = (info->geo.start + info->phy_blocks - blk_cnt(stage2_size, info)); - if (misc_seek(fd, blk * info->phy_block_size)) + if (misc_seek(mfd->fd, blk * info->phy_block_size)) goto out_free_stage2; - stage2_count = disk_write_block_buffer(fd, 1, stage2, stage2_size, + stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size, &stage2_list, info); if (stage2_count == 0) goto out_free_stage2; /* Install stage 1b in front of stage 2 */ blk -= blk_cnt(sizeof(struct boot_fba_stage1b), info); - if (misc_seek(fd, blk * info->phy_block_size)) + if (misc_seek(mfd->fd, blk * info->phy_block_size)) goto out_free_stage2_list; - if (install_fba_stage1b(fd, &stage1b_list, &stage1b_count, + if (install_fba_stage1b(mfd, &stage1b_list, &stage1b_count, stage2_list, stage2_count, info)) goto out_free_stage2_list; /* Install stage 0/1 fill in dump partition parameter */ @@ -1070,7 +1071,7 @@ install_svdump_fba(int fd, struct disk_info *info, param.blk_end = blk - 1; boot_get_dump_info(&stage0.boot_info, BOOT_INFO_DEV_TYPE_FBA, ¶m); - if (DRY_RUN_FUNC(misc_pwrite(fd, &stage0, sizeof(stage0), 0))) + if (DRY_RUN_FUNC(misc_pwrite(mfd->fd, &stage0, sizeof(stage0), 0))) goto out_free_stage1b_list; rc = 0; @@ -1107,32 +1108,32 @@ install_dump(const char *device, struct job_target_data *target, uint64_t mem, bool no_compress) { struct stage2dump_parm_tail stage2dump_parms = {0}; + struct misc_fd mfd = {0}; struct disk_info* info; - char* tempdev; uint64_t part_size; - int fd; + char *tempdev; int rc; stage2dump_parms.mem_upper_limit = mem; stage2dump_parms.no_compress = no_compress; - fd = misc_open_exclusive(device); - if (fd == -1) { + mfd.fd = misc_open_exclusive(device); + if (mfd.fd == -1) { error_text("Could not open dump device '%s'", device); return -1; } - if (rewind_tape(fd) == 0) { + if (rewind_tape(mfd.fd) == 0) { /* Rewind worked - this is a tape */ rc = ask_for_confirmation("Warning: All information on device " "'%s' will be lost!\nDo you want to " "continue creating a dump " "tape (y/n) ?", device); if (rc) { - close(fd); + close(mfd.fd); return rc; } if (verbose) printf("Installing tape dump record\n"); - rc = install_dump_tape(fd, &stage2dump_parms); + rc = install_dump_tape(mfd.fd, &stage2dump_parms); if (rc) { error_text("Could not install dump record on tape " "device '%s'", device); @@ -1142,10 +1143,10 @@ install_dump(const char *device, struct job_target_data *target, uint64_t mem, "tape device '%s'.\n", device); } } - close(fd); + close(mfd.fd); return rc; } - close(fd); + close(mfd.fd); /* This is a disk device */ rc = disk_get_info(device, target, &info); if (rc) { @@ -1168,8 +1169,8 @@ install_dump(const char *device, struct job_target_data *target, uint64_t mem, disk_free_info(info); return -1; } - fd = open(tempdev, O_RDWR); - if (fd == -1) { + mfd.fd = open(tempdev, O_RDWR); + if (mfd.fd == -1) { error_text("Could not open temporary device node '%s'", tempdev); misc_free_temp_dev(tempdev); @@ -1200,11 +1201,11 @@ install_dump(const char *device, struct job_target_data *target, uint64_t mem, disk_get_type_name(info->type)); } if (info->type == disk_type_eckd_ldl) - rc = install_svdump_eckd_ldl(fd, info, &stage2dump_parms); + rc = install_svdump_eckd_ldl(&mfd, info, &stage2dump_parms); else if (info->type == disk_type_eckd_cdl) - rc = install_svdump_eckd_cdl(fd, info, &stage2dump_parms); + rc = install_svdump_eckd_cdl(&mfd, info, &stage2dump_parms); else - rc = install_svdump_fba(fd, info, &stage2dump_parms); + rc = install_svdump_fba(&mfd, info, &stage2dump_parms); break; case disk_type_scsi: error_reason("%s: Unsupported disk type '%s' (try --dumptofs)", @@ -1219,9 +1220,9 @@ install_dump(const char *device, struct job_target_data *target, uint64_t mem, } misc_free_temp_dev(tempdev); disk_free_info(info); - if (fsync(fd)) + if (fsync(mfd.fd)) error_text("Could not sync device file '%s'", device); - if (close(fd)) + if (close(mfd.fd)) error_text("Could not close device file '%s'", device); return rc; } @@ -1231,13 +1232,13 @@ int install_mvdump(char* const device[], struct job_target_data* target, int count, uint64_t mem, uint8_t force) { - struct disk_info* info[MAX_DUMP_VOLUMES] = {0}; + struct disk_info *info[MAX_DUMP_VOLUMES] = {0}; struct stage2dump_parm_tail stage2dump_parms = {0}; struct mvdump_parm_table mvdump_parms; - char* tempdev; uint64_t total_size = 0; - int rc = 0, i, j, fd; struct timeval time; + int rc = 0, i, j; + char *tempdev; stage2dump_parms.mvdump_force = force; stage2dump_parms.mem_upper_limit = mem; @@ -1246,25 +1247,26 @@ install_mvdump(char* const device[], struct job_target_data* target, int count, mvdump_parms.num_param = count; mvdump_parms.timestamp = (time.tv_sec << 20) + time.tv_usec; for (i = 0; i < count; i++) { + struct misc_fd mfd = {0}; int dummy, ssid; char busid[16]; - fd = misc_open_exclusive(device[i]); - if (fd == -1) { + mfd.fd = misc_open_exclusive(device[i]); + if (mfd.fd == -1) { error_text("Could not open dump target '%s'", device[i]); rc = -1; goto out; } - if (rewind_tape(fd) == 0) { + if (rewind_tape(mfd.fd) == 0) { /* Rewind worked - this is a tape */ error_text("Dump target '%s' is a tape device", device[i]); - close(fd); + close(mfd.fd); rc = -1; goto out; } - close(fd); + close(mfd.fd); /* This is a disk device */ rc = disk_get_info(device[i], target, &info[i]); if (rc) { @@ -1340,13 +1342,15 @@ install_mvdump(char* const device[], struct job_target_data* target, int count, goto out; } for (i = 0; i < count; i++) { + struct misc_fd mfd = {0}; + rc = misc_temp_dev(info[i]->device, 1, &tempdev); if (rc) { rc = -1; goto out; } - fd = misc_open_exclusive(tempdev); - if (fd == -1) { + mfd.fd = misc_open_exclusive(tempdev); + if (mfd.fd == -1) { error_text("Could not open temporary device node '%s'", tempdev); misc_free_temp_dev(tempdev); @@ -1356,12 +1360,12 @@ install_mvdump(char* const device[], struct job_target_data* target, int count, if (verbose) printf("Installing dump record on target partition " "'%s'\n", device[i]); - rc = install_mvdump_eckd_cdl(fd, info[i], &stage2dump_parms, &mvdump_parms); + rc = install_mvdump_eckd_cdl(&mfd, info[i], &stage2dump_parms, &mvdump_parms); misc_free_temp_dev(tempdev); - if (fsync(fd)) + if (fsync(mfd.fd)) error_text("Could not sync device file '%s'", device); - if (close(fd)) + if (close(mfd.fd)) error_text("Could not close device file '%s'", device); if (rc) diff --git a/zipl/src/job.c b/zipl/src/job.c index 7ae43a70..9268a92c 100644 --- a/zipl/src/job.c +++ b/zipl/src/job.c @@ -1959,7 +1959,7 @@ get_job_from_config_file(struct command_line* cmdline, struct job_data* job) static int get_job_envblk_data(struct job_data *job, char *import_hint) { struct job_envblk_data *data = &job->envblk; - int fd; + struct misc_fd mfd = {0}; switch (job->id) { case job_ipl: @@ -1968,18 +1968,18 @@ static int get_job_envblk_data(struct job_data *job, char *import_hint) default: return 0; } - fd = open(job->target.bootmap_dir, O_RDONLY); - if (fd < 0) { + mfd.fd = open(job->target.bootmap_dir, O_RDONLY); + if (mfd.fd < 0) { error_reason(strerror(errno)); error_text("Could not open bootmap dir"); return -1; } - if (envblk_size_get(fd, &data->size)) { - close(fd); + if (envblk_size_get(&mfd, &data->size)) { + close(mfd.fd); error_text("Could not get environment block size"); return -1; } - close(fd); + close(mfd.fd); data->buf = misc_malloc(data->size); if (data->buf == NULL) { error_text("Could not allocate environment block"); diff --git a/zipl/src/misc.c b/zipl/src/misc.c index a1ecb540..b69490c0 100644 --- a/zipl/src/misc.c +++ b/zipl/src/misc.c @@ -404,6 +404,26 @@ misc_write(int fd, const void* data, size_t count) return 0; } +/** + * Instead of writing, upadte only current position in the file + */ +static int misc_simulate_write(int fd, size_t count) +{ + if (lseek(fd, count, SEEK_CUR) == (off_t)-1) { + error_reason(strerror(errno)); + error_text("Could not update position in the file"); + return -1; + } + return 0; +} + +int misc_write_or_simulate(struct misc_fd *mfd, const void *data, size_t count) +{ + return mfd->simulate_write ? + misc_simulate_write(mfd->fd, count) : + misc_write(mfd->fd, data, count); +} + int misc_seek(int fd, off_t off) { if (lseek(fd, off, SEEK_SET) == off) diff --git a/zipl/src/zipl-editenv.c b/zipl/src/zipl-editenv.c index a55e9df6..05b59a6f 100644 --- a/zipl/src/zipl-editenv.c +++ b/zipl/src/zipl-editenv.c @@ -60,7 +60,7 @@ enum op_id { static char *op_desc[LAST_OP_ID] = {"invalid", "set", "unset", "reset", "list"}; struct zipl_envblk { - int fd; + struct misc_fd mfd; char *buf; off_t offset; int size; @@ -75,7 +75,7 @@ static char *opcode2desc(enum op_id opcode) static void zipl_envblk_init(struct zipl_envblk *zeb) { memset(zeb, 0, sizeof(*zeb)); - zeb->fd = -1; + zeb->mfd.fd = -1; } static int do_list(char *envblk, unsigned int envblk_size) @@ -104,7 +104,7 @@ static int envblk_update(struct zipl_envblk *zeb) char *dev_name; int dev_fd; - if (fstat(zeb->fd, &info)) + if (fstat(zeb->mfd.fd, &info)) return -1; if (util_proc_part_get_entry(info.st_dev, &part_entry) != 0) @@ -125,7 +125,7 @@ static int envblk_update(struct zipl_envblk *zeb) /* * det disk address of the environment block */ - if (fs_map(zeb->fd, zeb->offset, &blknr, zeb->size) != 0) + if (fs_map(zeb->mfd.fd, zeb->offset, &blknr, zeb->size) != 0) goto error_close; if (lseek64(dev_fd, blknr * (uint64_t)zeb->size, SEEK_SET) < 0) { @@ -156,11 +156,11 @@ static int envblk_close(struct zipl_envblk *zeb) free(zeb->buf); zeb->buf = NULL; } - if (zeb->fd < 0) + if (zeb->mfd.fd < 0) return 0; - if (close(zeb->fd) == 0) { - zeb->fd = -1; + if (close(zeb->mfd.fd) == 0) { + zeb->mfd.fd = -1; return 0; } return -1; @@ -175,7 +175,7 @@ static int envblk_open(struct zipl_envblk *zeb) { char *bootmap_file; - if (zeb->fd >= 0) + if (zeb->mfd.fd >= 0) /* it was opened before */ return 0; bootmap_file = @@ -185,8 +185,8 @@ static int envblk_open(struct zipl_envblk *zeb) error_reason("Could not make path for bootmap file"); return -1; } - zeb->fd = open(bootmap_file, O_RDONLY); - if (zeb->fd < 0) { + zeb->mfd.fd = open(bootmap_file, O_RDONLY); + if (zeb->mfd.fd < 0) { error_reason("Could not open bootmap file %s: %s", bootmap_file, strerror(errno)); free(bootmap_file); @@ -196,11 +196,11 @@ static int envblk_open(struct zipl_envblk *zeb) if (verbose) printf("Processing bootmap file at %s\n", bootmap_file); - if (envblk_size_get(zeb->fd, &zeb->size)) { + if (envblk_size_get(&zeb->mfd, &zeb->size)) { error_reason("Could not get environment block size"); goto error; } - if (envblk_offset_get(zeb->fd, &zeb->offset)) { + if (envblk_offset_get(&zeb->mfd, &zeb->offset)) { error_reason("Could not get environment block location"); goto error; } @@ -209,9 +209,9 @@ static int envblk_open(struct zipl_envblk *zeb) goto error; } /* reopen for direct operations */ - close(zeb->fd); - zeb->fd = open(bootmap_file, O_RDWR | O_DIRECT); - if (zeb->fd < 0) { + close(zeb->mfd.fd); + zeb->mfd.fd = open(bootmap_file, O_RDWR | O_DIRECT); + if (zeb->mfd.fd < 0) { error_reason("Could not open environment block at %s", bootmap_file); goto error; @@ -224,11 +224,11 @@ static int envblk_open(struct zipl_envblk *zeb) error_reason("Could not allocate aligned memory region"); goto error; } - if (lseek(zeb->fd, zeb->offset, SEEK_SET) < 0) { + if (lseek(zeb->mfd.fd, zeb->offset, SEEK_SET) < 0) { error_reason(strerror(errno)); goto error; } - if (read(zeb->fd, zeb->buf, zeb->size) != zeb->size) { + if (read(zeb->mfd.fd, zeb->buf, zeb->size) != zeb->size) { error_reason("Could not read environment block"); goto error; }