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; }