mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zipl/src: Introduce 'write simulation' mode for individual files
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 <zaslonko@linux.ibm.com> Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com> Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
85a232a711
commit
b94566048b
@@ -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);
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user