mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zipl/src: Support multiple disk_info structures per logical device
Replace struct disk_info with new 2 types.
Old type:
struct disk_info {
A; /* logical device info */
B; /* basedisk info */
};
New types:
struct disk_info {
B; /* basedisk info */
};
and
struct device_info {
A; /* logical device info */
struct disk_info C [MAX_TARGETS]; /* array of base disks */
};
Here A (logical device info) is the following:
dev_t device; /* logical device for bootmap creation */
char *name; /* name of logical device as reetrieved from
"/proc/partitions" */
char *drv_name; /* name of the driver managing the logical
device as retrieved from "/proc/devices",
or evaluated */
int fs_block_size;
Refactor the code respectively, to use only the first element of
the array C, so that this patch represents an equivalent transform.
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
committed by
Steffen Eiden
parent
338bea49c2
commit
f375327085
@@ -68,24 +68,33 @@ typedef enum {
|
||||
undefined
|
||||
} definition_t;
|
||||
|
||||
/* Disk information type */
|
||||
/* Physical disk information type */
|
||||
struct disk_info {
|
||||
dev_t disk;
|
||||
disk_type_t type;
|
||||
dev_t device; /* logical device for bootmap creation */
|
||||
dev_t partition;
|
||||
int devno;
|
||||
int partnum;
|
||||
int phy_block_size;
|
||||
int fs_block_size;
|
||||
uint64_t phy_blocks;
|
||||
struct hd_geometry geo;
|
||||
char* name;
|
||||
char* drv_name;
|
||||
definition_t targetbase_def;
|
||||
int is_nvme;
|
||||
dev_t basedisks[MAX_TARGETS]; /* array of physical disks for
|
||||
* bootstrap blocks recording
|
||||
*/
|
||||
};
|
||||
|
||||
/* Logical device information type */
|
||||
struct device_info {
|
||||
dev_t device; /* logical device for bootmap creation */
|
||||
char *name; /* name of the logical device as retrieved
|
||||
* from "/proc/partitions"
|
||||
*/
|
||||
char *drv_name; /* name of the driver managing the logical device
|
||||
* as retrieved from "/proc/devices", or evaluated
|
||||
*/
|
||||
int fs_block_size;
|
||||
struct disk_info base[MAX_TARGETS]; /* array of physical disks for
|
||||
* bootstrap blocks recording
|
||||
*/
|
||||
};
|
||||
|
||||
struct file_range {
|
||||
@@ -95,51 +104,55 @@ struct file_range {
|
||||
|
||||
struct job_target_data;
|
||||
|
||||
int disk_get_info(const char *device, struct job_target_data *target,
|
||||
struct disk_info **info);
|
||||
int disk_get_ext_type(const char *device, struct disk_ext_type *ext_type);
|
||||
int device_get_info(const char *device, struct job_target_data *target,
|
||||
struct device_info **info);
|
||||
int disk_get_ext_type(const char *device, struct disk_ext_type *ext_type,
|
||||
int disk_id);
|
||||
int disk_is_tape(const char *device);
|
||||
int disk_type_is_scsi(struct disk_ext_type *ext_type);
|
||||
int disk_type_is_eckd_ldl(struct disk_ext_type *ext_type);
|
||||
int disk_type_is_nvme(struct disk_ext_type *ext_type);
|
||||
int disk_type_is_eckd(disk_type_t type);
|
||||
|
||||
int disk_info_set_fs_block(const char *filename, struct disk_info *info);
|
||||
int disk_get_info_from_file(const char* filename,
|
||||
struct job_target_data* target,
|
||||
struct disk_info** info);
|
||||
void disk_free_info(struct disk_info* info);
|
||||
char* disk_get_type_name(disk_type_t type);
|
||||
int device_info_set_fs_block(const char *filename, struct device_info *info);
|
||||
int device_get_info_from_file(const char *filename,
|
||||
struct job_target_data *target,
|
||||
struct device_info **info);
|
||||
void device_free_info(struct device_info *info);
|
||||
char *disk_get_type_name(disk_type_t type);
|
||||
char *disk_get_ipl_type(disk_type_t type, int is_dump);
|
||||
int disk_is_large_volume(struct disk_info* info);
|
||||
int disk_cyl_from_blocknum(blocknum_t blocknum, struct disk_info* info);
|
||||
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(struct misc_fd *mfd, const void *data, size_t bytecount,
|
||||
disk_blockptr_t *block, struct disk_info *info);
|
||||
struct disk_info *info);
|
||||
int disk_write_block_aligned(struct misc_fd *mfd, const void *data,
|
||||
size_t bytecount, disk_blockptr_t *block,
|
||||
int fs_block_size, 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);
|
||||
int fs_block_size, struct disk_info *info);
|
||||
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,
|
||||
int fs_block_size,
|
||||
struct disk_info *info, int align,
|
||||
off_t *offset);
|
||||
void disk_print_devt(dev_t d);
|
||||
void disk_print_devname(dev_t d);
|
||||
void prepare_footnote_ptr(int source, char *ptr);
|
||||
void print_footnote_ref(int source, const char *prefix);
|
||||
void disk_print_info(struct disk_info *info, int source);
|
||||
int disk_is_zero_block(disk_blockptr_t* block, struct disk_info* info);
|
||||
void device_print_info(struct device_info *info, int source);
|
||||
int disk_is_zero_block(disk_blockptr_t *block, struct disk_info *info);
|
||||
blocknum_t disk_compact_blocklist(disk_blockptr_t* list, blocknum_t count,
|
||||
struct disk_info* info);
|
||||
struct disk_info *info);
|
||||
blocknum_t disk_get_blocklist_from_file(const char* filename,
|
||||
struct file_range *reg,
|
||||
disk_blockptr_t** blocklist,
|
||||
struct disk_info* pinfo);
|
||||
disk_blockptr_t **blocklist,
|
||||
int fs_block_size,
|
||||
struct disk_info *info);
|
||||
int disk_check_subchannel_set(int devno, dev_t device, char* dev_name);
|
||||
int fs_map(int fd, uint64_t offset, blocknum_t *mapped, int fs_block_size);
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ struct install_set {
|
||||
unsigned int tmp_filename_created:1;
|
||||
unsigned int skip_prepare:1;
|
||||
unsigned int print_details:1;
|
||||
struct disk_info *info;
|
||||
struct device_info *info;
|
||||
disk_blockptr_t scsi_dump_sb_blockptr;
|
||||
};
|
||||
|
||||
@@ -127,11 +127,13 @@ int install_mvdump(char* const device[], struct job_target_data* target,
|
||||
|
||||
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);
|
||||
blocknum_t stage2_count, int fs_block_size,
|
||||
struct disk_info *info);
|
||||
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);
|
||||
blocknum_t stage2_count, int fs_block_size,
|
||||
struct disk_info *info);
|
||||
int rewind_tape(int fd);
|
||||
|
||||
#endif /* INSTALL_H */
|
||||
|
||||
@@ -45,7 +45,7 @@ static bool secure_boot_supported;
|
||||
|
||||
/* Get size of a bootmap block pointer for disk with given INFO. */
|
||||
static int
|
||||
get_blockptr_size(struct disk_info* info)
|
||||
get_blockptr_size(struct disk_info *info)
|
||||
{
|
||||
switch (info->type) {
|
||||
case disk_type_scsi:
|
||||
@@ -69,8 +69,7 @@ get_blockptr_size(struct disk_info* info)
|
||||
* defined by FORMAT_ID (relevant only for ECKD disk types)
|
||||
*/
|
||||
void bootmap_store_blockptr(void *buffer, disk_blockptr_t *ptr,
|
||||
struct disk_info *info,
|
||||
int format_id)
|
||||
struct disk_info *info, int format_id)
|
||||
{
|
||||
struct eckd_blockptr_legacy *eckd_legacy;
|
||||
struct eckd_blockptr *eckd;
|
||||
@@ -121,7 +120,7 @@ void bootmap_store_blockptr(void *buffer, disk_blockptr_t *ptr,
|
||||
/* Calculate the maximum number of entries in the program table. INFO
|
||||
* specifies the type of disk. */
|
||||
static int
|
||||
get_program_table_size(struct disk_info* info)
|
||||
get_program_table_size(struct disk_info *info)
|
||||
{
|
||||
return PROGRAM_TABLE_BLOCK_SIZE / get_blockptr_size(info) - 1;
|
||||
}
|
||||
@@ -130,7 +129,7 @@ get_program_table_size(struct disk_info* info)
|
||||
|
||||
static int
|
||||
check_menu_positions(struct job_menu_data* menu, char* name,
|
||||
struct disk_info* info)
|
||||
struct disk_info *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -181,9 +180,10 @@ 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(struct misc_fd *mfd, disk_blockptr_t *list, blocknum_t count,
|
||||
disk_blockptr_t *segment_pointer,
|
||||
struct disk_info *info, int program_table_id)
|
||||
static int add_segment_table(struct misc_fd *mfd, disk_blockptr_t *list,
|
||||
blocknum_t count, disk_blockptr_t *segment_pointer,
|
||||
int fs_block_size, struct disk_info *info,
|
||||
int program_table_id)
|
||||
{
|
||||
disk_blockptr_t next;
|
||||
void* buffer;
|
||||
@@ -221,7 +221,7 @@ static int add_segment_table(struct misc_fd *mfd, disk_blockptr_t *list, blocknu
|
||||
&next, info,
|
||||
program_table_id);
|
||||
rc = disk_write_block_aligned(mfd, buffer, info->phy_block_size,
|
||||
&next, info);
|
||||
&next, fs_block_size, info);
|
||||
if (rc) {
|
||||
free(buffer);
|
||||
return rc;
|
||||
@@ -233,8 +233,9 @@ static int add_segment_table(struct misc_fd *mfd, disk_blockptr_t *list, blocknu
|
||||
}
|
||||
|
||||
|
||||
static int add_program_table(struct misc_fd *mfd, disk_blockptr_t *table, int entries,
|
||||
disk_blockptr_t *pointer, struct disk_info *info,
|
||||
static int add_program_table(struct misc_fd *mfd, disk_blockptr_t *table,
|
||||
int entries, disk_blockptr_t *pointer,
|
||||
int fs_block_size, struct disk_info *info,
|
||||
int program_table_id)
|
||||
{
|
||||
void* block;
|
||||
@@ -256,7 +257,7 @@ static int add_program_table(struct misc_fd *mfd, disk_blockptr_t *table, int en
|
||||
}
|
||||
/* Write program table */
|
||||
rc = disk_write_block_aligned(mfd, block, PROGRAM_TABLE_BLOCK_SIZE,
|
||||
pointer, info);
|
||||
pointer, fs_block_size, info);
|
||||
free(block);
|
||||
return rc;
|
||||
}
|
||||
@@ -307,16 +308,16 @@ create_component_header(void* buffer, component_header_type type)
|
||||
* Return 0, if auto-detection succeeded, and it is proven that the
|
||||
* file does NOT locate on DISK. Otherwise, return 1.
|
||||
*/
|
||||
static int file_is_on_disk(const char *filename, struct disk_info *where)
|
||||
static int file_is_on_device(const char *filename, struct device_info *where)
|
||||
{
|
||||
/*
|
||||
* Retrieve info of the underlying disk without any user hints
|
||||
*/
|
||||
struct job_target_data tmp = {.source = source_unknown};
|
||||
struct disk_info *info;
|
||||
struct device_info *info;
|
||||
int rc;
|
||||
|
||||
rc = disk_get_info_from_file(filename, &tmp, &info);
|
||||
rc = device_get_info_from_file(filename, &tmp, &info);
|
||||
free_target_data(&tmp);
|
||||
if (rc) {
|
||||
/*
|
||||
@@ -332,11 +333,11 @@ static int file_is_on_disk(const char *filename, struct disk_info *where)
|
||||
"Warning: Preparing a logical device for boot might fail\n");
|
||||
return 1;
|
||||
}
|
||||
if (info->basedisks[0] != where->basedisks[0]) {
|
||||
disk_free_info(info);
|
||||
if (info->base[0].disk != where->base[0].disk) {
|
||||
device_free_info(info);
|
||||
return 0;
|
||||
}
|
||||
disk_free_info(info);
|
||||
device_free_info(info);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -350,6 +351,7 @@ static int add_component_file_range(struct install_set *bis,
|
||||
int program_table_id)
|
||||
{
|
||||
struct program_component *pc = get_component(bis, comp_id, menu_idx);
|
||||
struct disk_info *info = &bis->info->base[0];
|
||||
struct component_loc *location = &pc->loc;
|
||||
disk_blockptr_t **list = &pc->list;
|
||||
blocknum_t *count = &pc->count;
|
||||
@@ -372,39 +374,44 @@ static int add_component_file_range(struct install_set *bis,
|
||||
size -= trailer;
|
||||
/* Write buffer */
|
||||
*count = disk_write_block_buffer(&bis->mfd, 0, buffer,
|
||||
size, list, bis->info);
|
||||
size, list,
|
||||
bis->info->fs_block_size,
|
||||
info);
|
||||
free(buffer);
|
||||
if (*count == 0) {
|
||||
error_text("Could not write to bootmap file");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (!file_is_on_disk(filename, bis->info)) {
|
||||
if (!file_is_on_device(filename, bis->info)) {
|
||||
error_reason("File is not on target device");
|
||||
return -1;
|
||||
}
|
||||
/* Get block list from existing file */
|
||||
*count = disk_get_blocklist_from_file(filename, reg,
|
||||
list, bis->info);
|
||||
list,
|
||||
bis->info->fs_block_size,
|
||||
info);
|
||||
if (*count == 0)
|
||||
return -1;
|
||||
*count -= DIV_ROUND_UP(trailer, bis->info->phy_block_size);
|
||||
*count -= DIV_ROUND_UP(trailer, info->phy_block_size);
|
||||
}
|
||||
/* Fill in component location */
|
||||
location->addr = load_address;
|
||||
location->size = *count * bis->info->phy_block_size;
|
||||
location->size = *count * info->phy_block_size;
|
||||
/* Try to compact list */
|
||||
*count = disk_compact_blocklist(*list, *count, bis->info);
|
||||
*count = disk_compact_blocklist(*list, *count, info);
|
||||
write_segment_table:
|
||||
assert(*list != NULL);
|
||||
assert(*count != 0);
|
||||
rc = add_segment_table(&bis->mfd, *list, *count, &segment, bis->info,
|
||||
rc = add_segment_table(&bis->mfd, *list, *count, &segment,
|
||||
bis->info->fs_block_size, info,
|
||||
program_table_id);
|
||||
if (rc == 0)
|
||||
create_component_entry(component, &segment,
|
||||
component_type_by_id(comp_id),
|
||||
(component_data)load_address,
|
||||
bis->info, program_table_id);
|
||||
info, program_table_id);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -426,6 +433,7 @@ static int add_component_buffer_align(struct install_set *bis, void *buffer,
|
||||
int program_table_id)
|
||||
{
|
||||
struct program_component *pc = get_component(bis, comp_id, menu_idx);
|
||||
struct disk_info *info = &bis->info->base[0];
|
||||
struct component_loc *location = &pc->loc;
|
||||
disk_blockptr_t **list = &pc->list;
|
||||
blocknum_t *count = &pc->count;
|
||||
@@ -437,7 +445,8 @@ static int add_component_buffer_align(struct install_set *bis, void *buffer,
|
||||
goto write_segment_table;
|
||||
/* Write buffer */
|
||||
*count = disk_write_block_buffer_align(&bis->mfd, 0, buffer, size, list,
|
||||
bis->info, align, offset);
|
||||
bis->info->fs_block_size,
|
||||
info, align, offset);
|
||||
if (*count == 0) {
|
||||
error_text("Could not write to bootmap file");
|
||||
return -1;
|
||||
@@ -445,23 +454,24 @@ static int add_component_buffer_align(struct install_set *bis, void *buffer,
|
||||
if (component_type_by_id(comp_id) == COMPONENT_TYPE_LOAD) {
|
||||
/* Fill in component location */
|
||||
location->addr = data.load_address;
|
||||
location->size = *count * bis->info->phy_block_size;
|
||||
location->size = *count * info->phy_block_size;
|
||||
} else {
|
||||
location->addr = 0;
|
||||
location->size = 0;
|
||||
}
|
||||
/* Try to compact list */
|
||||
*count = disk_compact_blocklist(*list, *count, bis->info);
|
||||
*count = disk_compact_blocklist(*list, *count, info);
|
||||
write_segment_table:
|
||||
assert(*list != NULL);
|
||||
assert(*count != 0);
|
||||
|
||||
rc = add_segment_table(&bis->mfd, *list, *count, &segment, bis->info,
|
||||
rc = add_segment_table(&bis->mfd, *list, *count, &segment,
|
||||
bis->info->fs_block_size, info,
|
||||
program_table_id);
|
||||
if (rc == 0)
|
||||
create_component_entry(component, &segment,
|
||||
component_type_by_id(comp_id),
|
||||
data, bis->info, program_table_id);
|
||||
data, info, program_table_id);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -470,8 +480,10 @@ static int add_component_buffer(struct install_set *bis, void *buffer,
|
||||
void *component, int comp_id, int menu_idx,
|
||||
int program_table_id)
|
||||
{
|
||||
struct disk_info *info = &bis->info->base[0];
|
||||
|
||||
return add_component_buffer_align(bis, buffer, size, data, component,
|
||||
bis->info->phy_block_size, NULL,
|
||||
info->phy_block_size, NULL,
|
||||
comp_id, menu_idx, program_table_id);
|
||||
}
|
||||
|
||||
@@ -579,6 +591,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
int verbose, int add_files, component_header_type type,
|
||||
int is_secure, int menu_idx, int program_table_id)
|
||||
{
|
||||
struct disk_info *info = &bis->info->base[0];
|
||||
struct signature_header sig_head;
|
||||
size_t ramdisk_size, image_size;
|
||||
size_t stage3_params_size;
|
||||
@@ -593,7 +606,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
int rc;
|
||||
|
||||
memset(&sig_head, 0, sizeof(sig_head));
|
||||
table = util_zalloc(bis->info->phy_block_size);
|
||||
table = util_zalloc(info->phy_block_size);
|
||||
if (table == NULL)
|
||||
return -1;
|
||||
/* Create component table */
|
||||
@@ -622,7 +635,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
}
|
||||
}
|
||||
ramdisk_size = stats.st_size;
|
||||
if (bis->info->type == disk_type_scsi) {
|
||||
if (info->type == disk_type_scsi) {
|
||||
flags |= STAGE3_FLAG_SCSI;
|
||||
/*
|
||||
* Add dummy components for stage 3 heap and stack to block the
|
||||
@@ -715,7 +728,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
ramdisk_size,
|
||||
ipl->is_kdump ? IMAGE_ENTRY_KDUMP :
|
||||
IMAGE_ENTRY,
|
||||
(bis->info->type == disk_type_scsi) ? 0 : 1,
|
||||
(info->type == disk_type_scsi) ? 0 : 1,
|
||||
flags, ipl->common.image_addr, image_size,
|
||||
ipl->envblk_addr,
|
||||
add_envblk ? envblk->size : 0);
|
||||
@@ -760,7 +773,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
}
|
||||
offset += sizeof(struct component_entry);
|
||||
free(signature);
|
||||
check_remaining_filesize(image_size, signature_size, bis->info,
|
||||
check_remaining_filesize(image_size, signature_size, info,
|
||||
ipl->common.image);
|
||||
} else if (is_secure == SECURE_BOOT_ENABLED) {
|
||||
/*
|
||||
@@ -830,8 +843,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
offset += sizeof(struct component_entry);
|
||||
free(signature);
|
||||
check_remaining_filesize(ramdisk_size, signature_size,
|
||||
bis->info,
|
||||
ipl->common.ramdisk);
|
||||
info, ipl->common.ramdisk);
|
||||
}
|
||||
rc = add_component_file(bis, ipl->common.ramdisk,
|
||||
ipl->common.ramdisk_addr,
|
||||
@@ -912,11 +924,11 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
COMPONENT_TYPE_EXECUTE,
|
||||
(component_data) (uint64_t)
|
||||
(STAGE3_ENTRY | PSW_LOAD),
|
||||
bis->info, program_table_id);
|
||||
info, program_table_id);
|
||||
/* Write component table */
|
||||
rc = disk_write_block_aligned(&bis->mfd, table,
|
||||
bis->info->phy_block_size,
|
||||
program, bis->info);
|
||||
info->phy_block_size, program,
|
||||
bis->info->fs_block_size, info);
|
||||
free(table);
|
||||
return rc;
|
||||
}
|
||||
@@ -927,11 +939,12 @@ static int add_segment_program(struct install_set *bis,
|
||||
int add_files, component_header_type type,
|
||||
int program_table_id)
|
||||
{
|
||||
struct disk_info *info = &bis->info->base[0];
|
||||
void *table;
|
||||
int offset;
|
||||
int rc;
|
||||
|
||||
table = util_zalloc(bis->info->phy_block_size);
|
||||
table = util_zalloc(info->phy_block_size);
|
||||
if (table == NULL)
|
||||
return -1;
|
||||
/* Create component table */
|
||||
@@ -961,11 +974,11 @@ static int add_segment_program(struct install_set *bis,
|
||||
create_component_entry(VOID_ADD(table, offset), NULL,
|
||||
COMPONENT_TYPE_EXECUTE,
|
||||
(component_data)(uint64_t)PSW_DISABLED_WAIT,
|
||||
bis->info, program_table_id);
|
||||
info, program_table_id);
|
||||
/* Write component table */
|
||||
rc = disk_write_block_aligned(&bis->mfd, table,
|
||||
bis->info->phy_block_size,
|
||||
program, bis->info);
|
||||
info->phy_block_size, program,
|
||||
bis->info->fs_block_size, info);
|
||||
free(table);
|
||||
return rc;
|
||||
}
|
||||
@@ -998,13 +1011,14 @@ static int add_dump_program(struct install_set *bis,
|
||||
static int build_program_table(struct job_data *job,
|
||||
struct install_set *bis, int program_table_id)
|
||||
{
|
||||
struct disk_info *info = &bis->info->base[0];
|
||||
int entries, component_header;
|
||||
disk_blockptr_t *table;
|
||||
int is_secure;
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
entries = get_program_table_size(bis->info);
|
||||
entries = get_program_table_size(info);
|
||||
/* Get some memory for the program table */
|
||||
table = (disk_blockptr_t *) misc_malloc(sizeof(disk_blockptr_t) *
|
||||
entries);
|
||||
@@ -1140,7 +1154,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->mfd, table, entries,
|
||||
pointer, bis->info,
|
||||
pointer, bis->info->fs_block_size, info,
|
||||
program_table_id);
|
||||
}
|
||||
free(table);
|
||||
@@ -1151,7 +1165,8 @@ 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(struct misc_fd *mfd, disk_blockptr_t *block, struct disk_info *info)
|
||||
write_empty_block(struct misc_fd *mfd, disk_blockptr_t *block,
|
||||
int fs_block_size, struct disk_info *info)
|
||||
{
|
||||
void* buffer;
|
||||
int rc;
|
||||
@@ -1161,7 +1176,7 @@ write_empty_block(struct misc_fd *mfd, disk_blockptr_t *block, struct disk_info
|
||||
return -1;
|
||||
memset(buffer, 0, info->phy_block_size);
|
||||
rc = disk_write_block_aligned(mfd, buffer, info->phy_block_size, block,
|
||||
info);
|
||||
fs_block_size, info);
|
||||
free(buffer);
|
||||
return rc;
|
||||
}
|
||||
@@ -1169,6 +1184,7 @@ write_empty_block(struct misc_fd *mfd, disk_blockptr_t *block, struct disk_info
|
||||
|
||||
static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename,
|
||||
struct job_data *job,
|
||||
int fs_block_size,
|
||||
struct disk_info *info,
|
||||
disk_blockptr_t **stage1b_list,
|
||||
blocknum_t *stage1b_count,
|
||||
@@ -1190,14 +1206,17 @@ static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename,
|
||||
return -1;
|
||||
stage2_count = disk_write_block_buffer(mfd, 0, stage2_data,
|
||||
stage2_size,
|
||||
&stage2_list, info);
|
||||
&stage2_list,
|
||||
fs_block_size,
|
||||
info);
|
||||
free(stage2_data);
|
||||
if (stage2_count == 0) {
|
||||
error_text("Could not write to file '%s'", filename);
|
||||
return -1;
|
||||
}
|
||||
if (install_fba_stage1b(mfd, stage1b_list, stage1b_count,
|
||||
stage2_list, stage2_count, info))
|
||||
stage2_list, stage2_count,
|
||||
fs_block_size, info))
|
||||
return -1;
|
||||
free(stage2_list);
|
||||
break;
|
||||
@@ -1217,6 +1236,7 @@ static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename,
|
||||
|
||||
static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename,
|
||||
struct job_data *job,
|
||||
int fs_block_size,
|
||||
struct disk_info *info,
|
||||
disk_blockptr_t *program_table,
|
||||
disk_blockptr_t **stage1b_list,
|
||||
@@ -1239,6 +1259,7 @@ static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename,
|
||||
stage2b_count = disk_write_block_buffer(mfd, 0, stage2b_data,
|
||||
stage2b_size,
|
||||
&stage2b_list,
|
||||
fs_block_size,
|
||||
info);
|
||||
free(stage2b_data);
|
||||
if (stage2b_count == 0) {
|
||||
@@ -1246,7 +1267,8 @@ static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename,
|
||||
return -1;
|
||||
}
|
||||
if (install_eckd_stage1b(mfd, stage1b_list, stage1b_count,
|
||||
stage2b_list, stage2b_count, info))
|
||||
stage2b_list, stage2b_count,
|
||||
fs_block_size, info))
|
||||
return -1;
|
||||
free(stage2b_list);
|
||||
break;
|
||||
@@ -1263,6 +1285,7 @@ static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename,
|
||||
stage2b_count = disk_write_block_buffer(mfd, 0, stage2b_data,
|
||||
stage2b_size,
|
||||
stage1b_list,
|
||||
fs_block_size,
|
||||
info);
|
||||
free(stage2b_data);
|
||||
if (stage2b_count == 0) {
|
||||
@@ -1281,12 +1304,14 @@ static int bootmap_install_stages(struct job_data *job, struct install_set *bis,
|
||||
int program_table_id)
|
||||
{
|
||||
struct program_table *pt = &bis->tables[program_table_id];
|
||||
struct disk_info *info = &bis->info->base[0];
|
||||
int rc = 0;
|
||||
|
||||
switch (bis->info->type) {
|
||||
switch (info->type) {
|
||||
case disk_type_fba:
|
||||
rc = install_stages_dasd_fba(&bis->mfd, bis->filename, job,
|
||||
bis->info,
|
||||
bis->info->fs_block_size,
|
||||
info,
|
||||
&pt->stage1b_list,
|
||||
&pt->stage1b_count,
|
||||
program_table_id);
|
||||
@@ -1294,7 +1319,8 @@ static int bootmap_install_stages(struct job_data *job, struct install_set *bis,
|
||||
case disk_type_eckd_ldl:
|
||||
case disk_type_eckd_cdl:
|
||||
rc = install_stages_eckd_dasd(&bis->mfd, bis->filename, job,
|
||||
bis->info,
|
||||
bis->info->fs_block_size,
|
||||
info,
|
||||
&pt->table,
|
||||
&pt->stage1b_list,
|
||||
&pt->stage1b_count,
|
||||
@@ -1310,7 +1336,8 @@ static int bootmap_install_stages(struct job_data *job, struct install_set *bis,
|
||||
}
|
||||
|
||||
static int
|
||||
bootmap_write_scsi_superblock(struct misc_fd *mfd, struct disk_info *info,
|
||||
bootmap_write_scsi_superblock(struct misc_fd *mfd, int fs_block_size,
|
||||
struct disk_info *info,
|
||||
disk_blockptr_t *scsi_dump_sb_blockptr,
|
||||
ulong dump_size)
|
||||
{
|
||||
@@ -1327,9 +1354,9 @@ bootmap_write_scsi_superblock(struct misc_fd *mfd, 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(mfd, &scsi_sb,
|
||||
sizeof(scsi_sb),
|
||||
scsi_dump_sb_blockptr, info);
|
||||
return disk_write_block_aligned(mfd, &scsi_sb, sizeof(scsi_sb),
|
||||
scsi_dump_sb_blockptr, fs_block_size,
|
||||
info);
|
||||
}
|
||||
|
||||
|
||||
@@ -1438,6 +1465,7 @@ check_dump_device(struct job_data *job, const struct disk_info *info,
|
||||
static int prepare_build_program_table_device(struct job_data *job,
|
||||
struct install_set *bis)
|
||||
{
|
||||
struct disk_info *info;
|
||||
ulong unused_size;
|
||||
|
||||
if (bis->skip_prepare)
|
||||
@@ -1452,16 +1480,17 @@ static int prepare_build_program_table_device(struct job_data *job,
|
||||
return -1;
|
||||
}
|
||||
/* Retrieve target device information */
|
||||
if (disk_get_info(bis->filename, &job->target, &bis->info))
|
||||
if (device_get_info(bis->filename, &job->target, &bis->info))
|
||||
return -1;
|
||||
|
||||
if (verbose) {
|
||||
printf("Target device information\n");
|
||||
disk_print_info(bis->info, job->target.source);
|
||||
device_print_info(bis->info, job->target.source);
|
||||
}
|
||||
if (misc_temp_dev(bis->info->basedisks[0], 1, &bis->basetmp[0]))
|
||||
info = &bis->info->base[0];
|
||||
if (misc_temp_dev(info->disk, 1, &bis->basetmp[0]))
|
||||
return -1;
|
||||
if (check_dump_device(job, bis->info, bis->basetmp[0]))
|
||||
if (check_dump_device(job, info, bis->basetmp[0]))
|
||||
return -1;
|
||||
printf("Building bootmap directly on partition '%s'%s\n",
|
||||
bis->filename,
|
||||
@@ -1469,7 +1498,7 @@ static int prepare_build_program_table_device(struct job_data *job,
|
||||
: "");
|
||||
/* For partition dump set raw partition offset
|
||||
to expected size before end of disk */
|
||||
if (estimate_scsi_dump_size(job, bis->info, &unused_size))
|
||||
if (estimate_scsi_dump_size(job, info, &unused_size))
|
||||
return -1;
|
||||
if (lseek(bis->mfd.fd, unused_size, SEEK_SET) < 0)
|
||||
return -1;
|
||||
@@ -1481,12 +1510,14 @@ static int prepare_build_program_table_device(struct job_data *job,
|
||||
return -1;
|
||||
}
|
||||
/* Write empty block to be read in place of holes in files */
|
||||
if (write_empty_block(&bis->mfd, &empty_block, bis->info)) {
|
||||
if (write_empty_block(&bis->mfd, &empty_block,
|
||||
bis->info->fs_block_size, info)) {
|
||||
error_text("Could not write to file '%s'",
|
||||
bis->filename);
|
||||
return -1;
|
||||
}
|
||||
if (bootmap_write_scsi_superblock(&bis->mfd, bis->info,
|
||||
if (bootmap_write_scsi_superblock(&bis->mfd,
|
||||
bis->info->fs_block_size, info,
|
||||
&bis->scsi_dump_sb_blockptr,
|
||||
unused_size)) {
|
||||
error_text("Could not write SCSI superblock to file '%s'",
|
||||
@@ -1525,6 +1556,7 @@ static int prepare_bootloader_device(struct job_data *job,
|
||||
static int prepare_build_program_table_file(struct job_data *job,
|
||||
struct install_set *bis)
|
||||
{
|
||||
struct disk_info *info;
|
||||
int i;
|
||||
|
||||
if (bis->skip_prepare)
|
||||
@@ -1561,36 +1593,36 @@ static int prepare_build_program_table_file(struct job_data *job,
|
||||
* Retrieve file system block size from the proxy
|
||||
* file system
|
||||
*/
|
||||
if (disk_get_info(job->data.dump.device,
|
||||
&job->target, &bis->info))
|
||||
if (device_get_info(job->data.dump.device,
|
||||
&job->target, &bis->info))
|
||||
return -1;
|
||||
if (disk_info_set_fs_block(bis->filename, bis->info))
|
||||
if (device_info_set_fs_block(bis->filename, bis->info))
|
||||
return -1;
|
||||
} else {
|
||||
/*
|
||||
* ngdump or ipl job.
|
||||
*/
|
||||
if (disk_get_info_from_file(bis->filename,
|
||||
&job->target,
|
||||
&bis->info))
|
||||
if (device_get_info_from_file(bis->filename,
|
||||
&job->target,
|
||||
&bis->info))
|
||||
return -1;
|
||||
}
|
||||
if (!disk_is_appropriate(job, bis->info))
|
||||
info = &bis->info->base[0];
|
||||
|
||||
if (!disk_is_appropriate(job, info))
|
||||
return -1;
|
||||
if (verbose) {
|
||||
printf("Target device information\n");
|
||||
disk_print_info(bis->info, job->target.source);
|
||||
device_print_info(bis->info, job->target.source);
|
||||
}
|
||||
for (i = 0; i < job_get_nr_targets(job); i++) {
|
||||
if (misc_temp_dev(bis->info->basedisks[i],
|
||||
1,
|
||||
&bis->basetmp[i]))
|
||||
if (misc_temp_dev(bis->info->base[i].disk, 1, &bis->basetmp[i]))
|
||||
return -1;
|
||||
}
|
||||
/* Check configuration number limits */
|
||||
if (job->id == job_menu) {
|
||||
if (check_menu_positions(&job->data.menu, job->name,
|
||||
bis->info))
|
||||
info))
|
||||
return -1;
|
||||
}
|
||||
printf("Building bootmap in '%s'%s\n", job->target.bootmap_dir,
|
||||
@@ -1603,7 +1635,8 @@ static int prepare_build_program_table_file(struct job_data *job,
|
||||
return -1;
|
||||
}
|
||||
/* Write empty block to be read in place of holes in files */
|
||||
if (write_empty_block(&bis->mfd, &empty_block, bis->info)) {
|
||||
if (write_empty_block(&bis->mfd, &empty_block,
|
||||
bis->info->fs_block_size, info)) {
|
||||
error_text("Could not write to file '%s'", bis->filename);
|
||||
return -1;
|
||||
}
|
||||
@@ -1760,12 +1793,14 @@ static char *build_mount_point_pathname(void)
|
||||
static int prepare_bootloader_ngdump(struct job_data *job,
|
||||
struct install_set *bis)
|
||||
{
|
||||
struct device_info *dev_info;
|
||||
struct disk_info *info;
|
||||
|
||||
/* Retrieve target device information */
|
||||
if (disk_get_info(job->data.dump.device, &job->target, &info))
|
||||
if (device_get_info(job->data.dump.device, &job->target, &dev_info))
|
||||
return -1;
|
||||
if (misc_temp_dev(info->basedisks[0], 1, &bis->basetmp[0]))
|
||||
info = &dev_info->base[0];
|
||||
if (misc_temp_dev(info->disk, 1, &bis->basetmp[0]))
|
||||
return -1;
|
||||
if (check_dump_device(job, info, bis->basetmp[0]))
|
||||
return -1;
|
||||
@@ -1810,6 +1845,8 @@ static int prepare_bootloader_ngdump(struct job_data *job,
|
||||
*/
|
||||
static int prepare_bootloader_ipl(struct job_data *job, struct install_set *bis)
|
||||
{
|
||||
struct disk_info *info;
|
||||
|
||||
/*
|
||||
* Build a program table for List-Directed IPL from
|
||||
* SCSI or ECKD DASD
|
||||
@@ -1817,7 +1854,9 @@ static int prepare_bootloader_ipl(struct job_data *job, struct install_set *bis)
|
||||
bis->print_details = 1;
|
||||
if (bootmap_create_file(job, bis, BLKPTR_FORMAT_ID))
|
||||
return -1;
|
||||
if (bis->info->type == disk_type_scsi)
|
||||
|
||||
info = &bis->info->base[0];
|
||||
if (info->type == disk_type_scsi)
|
||||
/* only one table to be installed per device */
|
||||
return 0;
|
||||
/*
|
||||
@@ -1917,5 +1956,5 @@ void free_bootloader(struct install_set *bis)
|
||||
if (bis->basetmp[i])
|
||||
misc_free_temp_dev(bis->basetmp[i]);
|
||||
}
|
||||
disk_free_info(bis->info);
|
||||
device_free_info(bis->info);
|
||||
}
|
||||
|
||||
280
zipl/src/disk.c
280
zipl/src/disk.c
@@ -104,9 +104,10 @@ read_block_by_offset(int fd, int blksize, uint64_t offset, char *buffer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int determine_virtblk_type(struct disk_info *data,
|
||||
static int determine_virtblk_type(struct device_info *dev_info,
|
||||
const struct stat *stats)
|
||||
{
|
||||
struct disk_info *data = &dev_info->base[0];
|
||||
char *device;
|
||||
char *buffer;
|
||||
int fd, rc, shift, sb;
|
||||
@@ -131,9 +132,9 @@ static int determine_virtblk_type(struct disk_info *data,
|
||||
if (data->geo.heads == 15) {
|
||||
/* assume DASD */
|
||||
data->partnum = stats->st_rdev & DASD_PARTN_MASK;
|
||||
data->device = stats->st_rdev & ~DASD_PARTN_MASK;
|
||||
dev_info->device = stats->st_rdev & ~DASD_PARTN_MASK;
|
||||
|
||||
rc = misc_temp_dev(data->device, 1, &device);
|
||||
rc = misc_temp_dev(dev_info->device, 1, &device);
|
||||
if (rc)
|
||||
goto out_err;
|
||||
|
||||
@@ -167,7 +168,7 @@ static int determine_virtblk_type(struct disk_info *data,
|
||||
} else {
|
||||
data->type = disk_type_scsi;
|
||||
data->partnum = stats->st_rdev & SCSI_PARTN_MASK;
|
||||
data->device = stats->st_rdev & ~SCSI_PARTN_MASK;
|
||||
dev_info->device = stats->st_rdev & ~SCSI_PARTN_MASK;
|
||||
}
|
||||
|
||||
out_err:
|
||||
@@ -309,40 +310,40 @@ static void print_base_disk_params(struct job_target_data *td, int index)
|
||||
* Set disk info using ready target parameters provided either by
|
||||
* user, or by script
|
||||
*/
|
||||
static int disk_set_info_by_hint(struct job_target_data *td,
|
||||
struct disk_info *data, int fd)
|
||||
static int device_set_info_by_hint(struct job_target_data *td,
|
||||
struct device_info *data, int fd)
|
||||
{
|
||||
int majnum, minnum;
|
||||
struct stat stats;
|
||||
int i;
|
||||
/*
|
||||
* Currently multiple base disks with different parameters
|
||||
* are not supported
|
||||
*/
|
||||
data->devno = -1;
|
||||
data->phy_block_size = get_targetblocksize(td, 0);
|
||||
data->type = get_targettype(td, 0);
|
||||
|
||||
assert(td->nr_targets != 0);
|
||||
for (i = 1; i < td->nr_targets; i++) {
|
||||
if (data->type != get_targettype(td, i) ||
|
||||
data->phy_block_size != get_targetblocksize(td, i)) {
|
||||
/* set devno, type, phy_block_size */
|
||||
for (i = 0; i < td->nr_targets; i++) {
|
||||
data->base[i].devno = -1;
|
||||
data->base[i].type = get_targettype(td, i);
|
||||
data->base[i].phy_block_size = get_targetblocksize(td, i);
|
||||
|
||||
if (data->base[0].type !=
|
||||
data->base[i].type ||
|
||||
data->base[0].phy_block_size !=
|
||||
data->base[i].phy_block_size) {
|
||||
/*
|
||||
* Currently multiple base disks with different
|
||||
* parameters are not supported
|
||||
*/
|
||||
print_base_disk_params(td, 0);
|
||||
print_base_disk_params(td, i);
|
||||
error_reason("Inconsistent base disk geometry in target device");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
data->partnum = 0;
|
||||
data->targetbase_def = undefined;
|
||||
|
||||
/* set disk, targetbase_def, partnum, is_nvme */
|
||||
for (i = 0; i < td->nr_targets; i++) {
|
||||
definition_t defined_as;
|
||||
|
||||
if (sscanf(get_targetbase(td, i),
|
||||
"%d:%d", &majnum, &minnum) == 2) {
|
||||
data->basedisks[i] = makedev(majnum, minnum);
|
||||
defined_as = defined_as_device;
|
||||
data->base[i].disk = makedev(majnum, minnum);
|
||||
data->base[i].targetbase_def = defined_as_device;
|
||||
} else {
|
||||
if (stat(get_targetbase(td, i), &stats)) {
|
||||
error_reason(strerror(errno));
|
||||
@@ -356,47 +357,51 @@ static int disk_set_info_by_hint(struct job_target_data *td,
|
||||
get_targetbase(td, i));
|
||||
return -1;
|
||||
}
|
||||
data->basedisks[i] = stats.st_rdev;
|
||||
defined_as = defined_as_name;
|
||||
data->base[i].disk = stats.st_rdev;
|
||||
data->base[i].targetbase_def = defined_as_name;
|
||||
}
|
||||
if (data->targetbase_def != undefined &&
|
||||
data->targetbase_def != defined_as) {
|
||||
if (data->base[i].targetbase_def !=
|
||||
data->base[0].targetbase_def) {
|
||||
error_reason("Target base disks are defined by different ways");
|
||||
return -1;
|
||||
}
|
||||
data->targetbase_def = defined_as;
|
||||
data->base[i].partnum = 0;
|
||||
if (data->base[i].type == disk_type_scsi &&
|
||||
ioctl(fd, NVME_IOCTL_ID) >= 0)
|
||||
data->base[i].is_nvme = 1;
|
||||
}
|
||||
if (data->type == disk_type_scsi && ioctl(fd, NVME_IOCTL_ID) >= 0)
|
||||
data->is_nvme = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate target parameters in the case when no hints were provided
|
||||
*/
|
||||
static int disk_set_info_auto(struct disk_info *data,
|
||||
static int disk_set_info_auto(struct device_info *dev_info,
|
||||
const struct stat *stats, int fd)
|
||||
{
|
||||
struct disk_info *data = &dev_info->base[0];
|
||||
struct dasd_information dasd_info;
|
||||
|
||||
if (ioctl(fd, BLKSSZGET, &data->phy_block_size)) {
|
||||
error_reason("Could not get blocksize");
|
||||
return -1;
|
||||
}
|
||||
if (!data->drv_name) {
|
||||
if (!dev_info->drv_name) {
|
||||
/* Driver name cannot be read */
|
||||
if (ioctl(fd, BIODASDINFO, &dasd_info)) {
|
||||
data->devno = -1;
|
||||
if (data->geo.start) {
|
||||
/* SCSI partition */
|
||||
data->type = disk_type_scsi;
|
||||
data->partnum = stats->st_rdev & SCSI_PARTN_MASK;
|
||||
data->device = stats->st_rdev & ~SCSI_PARTN_MASK;
|
||||
data->partnum =
|
||||
stats->st_rdev & SCSI_PARTN_MASK;
|
||||
dev_info->device =
|
||||
stats->st_rdev & ~SCSI_PARTN_MASK;
|
||||
} else {
|
||||
/* SCSI disk */
|
||||
data->type = disk_type_scsi;
|
||||
data->partnum = 0;
|
||||
data->device = stats->st_rdev;
|
||||
dev_info->device = stats->st_rdev;
|
||||
}
|
||||
} else {
|
||||
/* DASD */
|
||||
@@ -404,9 +409,9 @@ static int disk_set_info_auto(struct disk_info *data,
|
||||
if (disk_determine_dasd_type(data, dasd_info))
|
||||
return -1;
|
||||
data->partnum = stats->st_rdev & DASD_PARTN_MASK;
|
||||
data->device = stats->st_rdev & ~DASD_PARTN_MASK;
|
||||
dev_info->device = stats->st_rdev & ~DASD_PARTN_MASK;
|
||||
}
|
||||
} else if (strcmp(data->drv_name, UTIL_PROC_DEV_ENTRY_DASD) == 0) {
|
||||
} else if (strcmp(dev_info->drv_name, UTIL_PROC_DEV_ENTRY_DASD) == 0) {
|
||||
/* Driver name is 'dasd' */
|
||||
if (ioctl(fd, BIODASDINFO, &dasd_info)) {
|
||||
error_reason("Could not determine DASD type");
|
||||
@@ -416,27 +421,29 @@ static int disk_set_info_auto(struct disk_info *data,
|
||||
if (disk_determine_dasd_type(data, dasd_info))
|
||||
return -1;
|
||||
data->partnum = stats->st_rdev & DASD_PARTN_MASK;
|
||||
data->device = stats->st_rdev & ~DASD_PARTN_MASK;
|
||||
} else if (strcmp(data->drv_name, UTIL_PROC_DEV_ENTRY_SD) == 0) {
|
||||
dev_info->device = stats->st_rdev & ~DASD_PARTN_MASK;
|
||||
} else if (strcmp(dev_info->drv_name, UTIL_PROC_DEV_ENTRY_SD) == 0) {
|
||||
/* Driver name is 'sd' */
|
||||
data->devno = -1;
|
||||
data->type = disk_type_scsi;
|
||||
data->partnum = stats->st_rdev & SCSI_PARTN_MASK;
|
||||
data->device = stats->st_rdev & ~SCSI_PARTN_MASK;
|
||||
dev_info->device = stats->st_rdev & ~SCSI_PARTN_MASK;
|
||||
|
||||
} else if (strcmp(data->drv_name, UTIL_PROC_DEV_ENTRY_VIRTBLK) == 0) {
|
||||
} else if (strcmp(dev_info->drv_name,
|
||||
UTIL_PROC_DEV_ENTRY_VIRTBLK) == 0) {
|
||||
/* Driver name is 'virtblk' */
|
||||
if (ioctl(fd, HDIO_GETGEO, &data->geo) != 0)
|
||||
perror("Could not retrieve disk geometry information.");
|
||||
if (ioctl(fd, BLKSSZGET, &data->phy_block_size) != 0)
|
||||
perror("Could not retrieve blocksize information.");
|
||||
|
||||
if (determine_virtblk_type(data, stats)) {
|
||||
if (determine_virtblk_type(dev_info, stats)) {
|
||||
error_reason("Virtblk device type not clearly "
|
||||
"determined.");
|
||||
return -1;
|
||||
}
|
||||
} else if (strcmp(data->drv_name, UTIL_PROC_DEV_ENTRY_BLKEXT) == 0 &&
|
||||
} else if (strcmp(dev_info->drv_name,
|
||||
UTIL_PROC_DEV_ENTRY_BLKEXT) == 0 &&
|
||||
ioctl(fd, NVME_IOCTL_ID) >= 0) {
|
||||
/* NVMe path, driver name is 'blkext' */
|
||||
data->devno = -1;
|
||||
@@ -444,18 +451,20 @@ static int disk_set_info_auto(struct disk_info *data,
|
||||
data->is_nvme = 1;
|
||||
|
||||
if (util_sys_dev_is_partition(stats->st_rdev)) {
|
||||
if (util_sys_get_base_dev(stats->st_rdev, &data->device))
|
||||
if (util_sys_get_base_dev(stats->st_rdev,
|
||||
&dev_info->device))
|
||||
return -1;
|
||||
data->partnum = util_sys_get_partnum(stats->st_rdev);
|
||||
if (data->partnum == -1)
|
||||
return -1;
|
||||
} else {
|
||||
data->device = stats->st_rdev;
|
||||
dev_info->device = stats->st_rdev;
|
||||
data->partnum = 0;
|
||||
}
|
||||
} else {
|
||||
/* Driver name is unknown */
|
||||
error_reason("Unsupported device driver '%s'", data->drv_name);
|
||||
error_reason("Unsupported device driver '%s'",
|
||||
dev_info->drv_name);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@@ -488,7 +497,7 @@ static void set_source_type(struct job_target_data *td,
|
||||
td->source = source_auto;
|
||||
}
|
||||
|
||||
static void set_driver_name(int fd, struct disk_info *info, dev_t device)
|
||||
static void set_driver_name(int fd, struct device_info *info, dev_t device)
|
||||
{
|
||||
struct util_proc_dev_entry dev_entry;
|
||||
|
||||
@@ -555,25 +564,26 @@ static int run_targetbase_script(struct job_target_data *td,
|
||||
* Note: geo.start contains a sector number offset measured in
|
||||
* physical blocks, not sectors (512 bytes)
|
||||
*/
|
||||
static int disk_set_geometry_by_hint(struct job_target_data *td,
|
||||
struct disk_info *data)
|
||||
static int device_set_geometry_by_hint(struct job_target_data *td,
|
||||
struct device_info *data)
|
||||
{
|
||||
int i;
|
||||
/*
|
||||
* Currently multiple base disks with different parameters
|
||||
* are not supported
|
||||
*/
|
||||
data->geo.heads = get_targetheads(td, 0);
|
||||
data->geo.sectors = get_targetsectors(td, 0);
|
||||
data->geo.cylinders = get_targetcylinders(td, 0);
|
||||
data->geo.start = get_targetoffset(td, 0);
|
||||
|
||||
assert(td->nr_targets != 0);
|
||||
for (i = 1; i < td->nr_targets; i++) {
|
||||
if (data->geo.heads != get_targetheads(td, i) ||
|
||||
data->geo.sectors != get_targetsectors(td, i) ||
|
||||
data->geo.cylinders != get_targetcylinders(td, i) ||
|
||||
data->geo.start != get_targetoffset(td, i)) {
|
||||
for (i = 0; i < td->nr_targets; i++) {
|
||||
data->base[i].geo.heads = get_targetheads(td, i);
|
||||
data->base[i].geo.sectors = get_targetsectors(td, i);
|
||||
data->base[i].geo.cylinders = get_targetcylinders(td, i);
|
||||
data->base[i].geo.start = get_targetoffset(td, i);
|
||||
|
||||
if (data->base[i].geo.heads != data->base[0].geo.heads ||
|
||||
data->base[i].geo.sectors != data->base[0].geo.sectors ||
|
||||
data->base[i].geo.cylinders != data->base[0].geo.cylinders ||
|
||||
data->base[i].geo.start != data->base[0].geo.start) {
|
||||
/*
|
||||
* Currently multiple base disks with different
|
||||
* parameters are not supported
|
||||
*/
|
||||
print_base_disk_params(td, 0);
|
||||
print_base_disk_params(td, i);
|
||||
error_reason("Inconsistent base disk geometry in target device");
|
||||
@@ -600,9 +610,10 @@ static int disk_set_geometry_auto(int fd, struct disk_info *info)
|
||||
* Pre-condition: disk type is already known and set at DATA->type
|
||||
*/
|
||||
static int disk_set_info_complete(struct job_target_data *td,
|
||||
struct disk_info *data,
|
||||
struct device_info *dev_info,
|
||||
struct stat *stats, int fd)
|
||||
{
|
||||
struct disk_info *data = &dev_info->base[0];
|
||||
struct util_proc_part_entry part_entry;
|
||||
long devsize;
|
||||
|
||||
@@ -632,14 +643,14 @@ static int disk_set_info_complete(struct job_target_data *td,
|
||||
if (data->partnum != 0)
|
||||
data->partition = stats->st_rdev;
|
||||
/* Try to get device name */
|
||||
if (util_proc_part_get_entry(data->device, &part_entry) == 0) {
|
||||
data->name = misc_strdup(part_entry.name);
|
||||
if (util_proc_part_get_entry(dev_info->device, &part_entry) == 0) {
|
||||
dev_info->name = misc_strdup(part_entry.name);
|
||||
util_proc_part_free_entry(&part_entry);
|
||||
if (data->name == NULL)
|
||||
if (!dev_info->name)
|
||||
return -1;
|
||||
}
|
||||
/* Initialize file system block size with invalid value */
|
||||
data->fs_block_size = -1;
|
||||
dev_info->fs_block_size = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -666,11 +677,11 @@ static int disk_set_info_complete(struct job_target_data *td,
|
||||
* DEVICE: logical, or physical device, optionally formatted with a
|
||||
* file system.
|
||||
*/
|
||||
int disk_get_info(const char *device, struct job_target_data *td,
|
||||
struct disk_info **info)
|
||||
int device_get_info(const char *device, struct job_target_data *td,
|
||||
struct device_info **info)
|
||||
{
|
||||
char *script_file = NULL;
|
||||
struct disk_info *data;
|
||||
struct device_info *data;
|
||||
struct stat stats;
|
||||
int fd;
|
||||
|
||||
@@ -683,10 +694,10 @@ int disk_get_info(const char *device, struct job_target_data *td,
|
||||
error_reason(strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
data = (struct disk_info *)misc_malloc(sizeof(struct disk_info));
|
||||
data = (struct device_info *)misc_malloc(sizeof(struct device_info));
|
||||
if (!data)
|
||||
goto error;
|
||||
memset((void *)data, 0, sizeof(struct disk_info));
|
||||
memset((void *)data, 0, sizeof(struct device_info));
|
||||
set_driver_name(fd, data, stats.st_rdev);
|
||||
set_source_type(td, data->drv_name, &script_file);
|
||||
switch (td->source) {
|
||||
@@ -696,9 +707,9 @@ int disk_get_info(const char *device, struct job_target_data *td,
|
||||
/* target parameters were set by the script output */
|
||||
assert(target_parameters_are_set(td));
|
||||
|
||||
if (disk_set_geometry_by_hint(td, data))
|
||||
if (device_set_geometry_by_hint(td, data))
|
||||
goto error;
|
||||
if (disk_set_info_by_hint(td, data, fd))
|
||||
if (device_set_info_by_hint(td, data, fd))
|
||||
goto error;
|
||||
data->device = stats.st_rdev;
|
||||
break;
|
||||
@@ -709,20 +720,20 @@ int disk_get_info(const char *device, struct job_target_data *td,
|
||||
*/
|
||||
assert(target_parameters_are_set(td));
|
||||
|
||||
if (disk_set_geometry_by_hint(td, data))
|
||||
if (device_set_geometry_by_hint(td, data))
|
||||
goto error;
|
||||
if (disk_set_info_by_hint(td, data, fd))
|
||||
if (device_set_info_by_hint(td, data, fd))
|
||||
goto error;
|
||||
/*
|
||||
* multiple base disks are not supported
|
||||
* with this source type
|
||||
*/
|
||||
assert(td->nr_targets == 1);
|
||||
data->device = data->basedisks[0];
|
||||
data->device = data->base[0].disk;
|
||||
break;
|
||||
case source_auto:
|
||||
/* no ready target parameters are available */
|
||||
if (disk_set_geometry_auto(fd, data))
|
||||
if (disk_set_geometry_auto(fd, &data->base[0]))
|
||||
goto error;
|
||||
if (disk_set_info_auto(data, &stats, fd))
|
||||
goto error;
|
||||
@@ -730,7 +741,7 @@ int disk_get_info(const char *device, struct job_target_data *td,
|
||||
* multiple base disks are not supported
|
||||
* with this source type
|
||||
*/
|
||||
data->basedisks[0] = data->device;
|
||||
data->base[0].disk = data->device;
|
||||
td->nr_targets = 1;
|
||||
break;
|
||||
default:
|
||||
@@ -772,17 +783,20 @@ disk_is_tape(const char* device)
|
||||
* partition, etc). In case of success the resulted disk type is
|
||||
* stored in EXT_TYPE.
|
||||
*/
|
||||
int disk_get_ext_type(const char *device, struct disk_ext_type *ext_type)
|
||||
int disk_get_ext_type(const char *device, struct disk_ext_type *ext_type,
|
||||
int disk_idx)
|
||||
{
|
||||
struct job_target_data tmp = {.source = source_unknown};
|
||||
struct device_info *dev_info;
|
||||
struct disk_info *info;
|
||||
|
||||
if (disk_get_info(device, &tmp, &info))
|
||||
if (device_get_info(device, &tmp, &dev_info))
|
||||
return -1;
|
||||
info = &dev_info->base[disk_idx];
|
||||
ext_type->type = info->type;
|
||||
ext_type->is_nvme = info->is_nvme;
|
||||
|
||||
disk_free_info(info);
|
||||
device_free_info(dev_info);
|
||||
free_target_data(&tmp);
|
||||
return 0;
|
||||
}
|
||||
@@ -811,7 +825,7 @@ int disk_type_is_eckd(disk_type_t type)
|
||||
/**
|
||||
* Retrieve and set block size of the file system which contains FILENAME
|
||||
*/
|
||||
int disk_info_set_fs_block(const char *filename, struct disk_info *info)
|
||||
int device_info_set_fs_block(const char *filename, struct device_info *dinfo)
|
||||
{
|
||||
int blocksize;
|
||||
int fd;
|
||||
@@ -830,7 +844,7 @@ int disk_info_set_fs_block(const char *filename, struct disk_info *info)
|
||||
filename);
|
||||
return -1;
|
||||
}
|
||||
info->fs_block_size = blocksize;
|
||||
dinfo->fs_block_size = blocksize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -838,9 +852,9 @@ int disk_info_set_fs_block(const char *filename, struct disk_info *info)
|
||||
* Retrieve disk info of the device which contains FILENAME
|
||||
* and set the filesystem block size
|
||||
*/
|
||||
int disk_get_info_from_file(const char *filename,
|
||||
struct job_target_data *target,
|
||||
struct disk_info **info)
|
||||
int device_get_info_from_file(const char *filename,
|
||||
struct job_target_data *target,
|
||||
struct device_info **info)
|
||||
{
|
||||
struct stat stats;
|
||||
char *device;
|
||||
@@ -851,15 +865,15 @@ int disk_get_info_from_file(const char *filename,
|
||||
}
|
||||
if (misc_temp_dev(stats.st_dev, 1, &device))
|
||||
return -1;
|
||||
if (disk_get_info(device, target, info)) {
|
||||
if (device_get_info(device, target, info)) {
|
||||
misc_free_temp_dev(device);
|
||||
return -1;
|
||||
}
|
||||
misc_free_temp_dev(device);
|
||||
return disk_info_set_fs_block(filename, *info);
|
||||
return device_info_set_fs_block(filename, *info);
|
||||
}
|
||||
|
||||
void disk_free_info(struct disk_info *info)
|
||||
void device_free_info(struct device_info *info)
|
||||
{
|
||||
if (!info)
|
||||
return;
|
||||
@@ -877,28 +891,29 @@ void disk_free_info(struct disk_info *info)
|
||||
* otherwise. */
|
||||
static int
|
||||
disk_get_blocknum(int fd, int fd_is_basedisk, blocknum_t logical,
|
||||
blocknum_t* physical, struct disk_info* info)
|
||||
blocknum_t *physical, int fs_block_size,
|
||||
struct disk_info *disk_info)
|
||||
{
|
||||
blocknum_t phy_per_fs;
|
||||
blocknum_t mapped;
|
||||
int subblock;
|
||||
|
||||
/* No file system: partition or raw disk */
|
||||
if (info->fs_block_size == -1) {
|
||||
if (fs_block_size == -1) {
|
||||
if (fd_is_basedisk)
|
||||
*physical = logical;
|
||||
else
|
||||
*physical = logical + info->geo.start;
|
||||
*physical = logical + disk_info->geo.start;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Get mapping in file system blocks
|
||||
*/
|
||||
phy_per_fs = info->fs_block_size / info->phy_block_size;
|
||||
phy_per_fs = fs_block_size / disk_info->phy_block_size;
|
||||
subblock = logical % phy_per_fs;
|
||||
|
||||
if (fs_map(fd, logical * info->phy_block_size,
|
||||
&mapped, info->fs_block_size) != 0)
|
||||
if (fs_map(fd, logical * disk_info->phy_block_size,
|
||||
&mapped, fs_block_size) != 0)
|
||||
return -1;
|
||||
if (mapped == 0) {
|
||||
/* This is a hole in the file */
|
||||
@@ -907,7 +922,7 @@ disk_get_blocknum(int fd, int fd_is_basedisk, blocknum_t logical,
|
||||
/* Convert file system block to physical */
|
||||
*physical = mapped * phy_per_fs + subblock;
|
||||
/* Add partition start */
|
||||
*physical += info->geo.start;
|
||||
*physical += disk_info->geo.start;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -916,7 +931,7 @@ disk_get_blocknum(int fd, int fd_is_basedisk, blocknum_t logical,
|
||||
/* Return the cylinder on which the block number BLOCKNUM is stored on the
|
||||
* CHS device identified by INFO. */
|
||||
int
|
||||
disk_cyl_from_blocknum(blocknum_t blocknum, struct disk_info* info)
|
||||
disk_cyl_from_blocknum(blocknum_t blocknum, struct disk_info *info)
|
||||
{
|
||||
return blocknum / (info->geo.heads * info->geo.sectors);
|
||||
}
|
||||
@@ -925,7 +940,7 @@ disk_cyl_from_blocknum(blocknum_t blocknum, struct disk_info* info)
|
||||
/* Return the head on which the block number BLOCKNUM is stored on the
|
||||
* CHS device identified by INFO. */
|
||||
int
|
||||
disk_head_from_blocknum(blocknum_t blocknum, struct disk_info* info)
|
||||
disk_head_from_blocknum(blocknum_t blocknum, struct disk_info *info)
|
||||
{
|
||||
return (blocknum / info->geo.sectors) % info->geo.heads;
|
||||
}
|
||||
@@ -934,7 +949,7 @@ disk_head_from_blocknum(blocknum_t blocknum, struct disk_info* info)
|
||||
/* Return the sector on which the block number BLOCKNUM is stored on the
|
||||
* CHS device identified by INFO. */
|
||||
int
|
||||
disk_sec_from_blocknum(blocknum_t blocknum, struct disk_info* info)
|
||||
disk_sec_from_blocknum(blocknum_t blocknum, struct disk_info *info)
|
||||
{
|
||||
return blocknum % info->geo.sectors + 1;
|
||||
}
|
||||
@@ -945,7 +960,7 @@ disk_sec_from_blocknum(blocknum_t blocknum, struct disk_info* info)
|
||||
* layout. */
|
||||
void
|
||||
disk_blockptr_from_blocknum(disk_blockptr_t* ptr, blocknum_t blocknum,
|
||||
struct disk_info* info)
|
||||
struct disk_info *info)
|
||||
{
|
||||
switch (info->type) {
|
||||
case disk_type_scsi:
|
||||
@@ -986,8 +1001,9 @@ 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(struct misc_fd *mfd, 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, int fs_block_size,
|
||||
struct disk_info *info, int align, off_t *offset)
|
||||
{
|
||||
blocknum_t current_block;
|
||||
@@ -1021,7 +1037,7 @@ disk_write_block_aligned_base(struct misc_fd *mfd, int is_base_disk, const void
|
||||
if (block != NULL) {
|
||||
/* Store block pointer */
|
||||
if (disk_get_blocknum(mfd->fd, is_base_disk, current_block,
|
||||
&blocknum, info))
|
||||
&blocknum, fs_block_size, info))
|
||||
return -1;
|
||||
disk_blockptr_from_blocknum(block, blocknum, info);
|
||||
}
|
||||
@@ -1030,11 +1046,13 @@ disk_write_block_aligned_base(struct misc_fd *mfd, int is_base_disk, const void
|
||||
return 0;
|
||||
}
|
||||
|
||||
int disk_write_block_aligned(struct misc_fd *mfd, const void *data, size_t bytecount,
|
||||
disk_blockptr_t *block, struct disk_info *info)
|
||||
int disk_write_block_aligned(struct misc_fd *mfd, const void *data,
|
||||
size_t bytecount, disk_blockptr_t *block,
|
||||
int fs_block_size, struct disk_info *info)
|
||||
{
|
||||
return disk_write_block_aligned_base(mfd, 0, data, bytecount, block,
|
||||
info, info->phy_block_size, NULL);
|
||||
fs_block_size, info,
|
||||
info->phy_block_size, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1047,8 +1065,9 @@ int disk_write_block_aligned(struct misc_fd *mfd, const void *data, size_t bytec
|
||||
* otherwise.
|
||||
*/
|
||||
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,
|
||||
disk_write_block_buffer_align(struct misc_fd *mfd, int fd_is_basedisk,
|
||||
const void *buffer, size_t bytecount,
|
||||
disk_blockptr_t **blocklist, int fs_block_size,
|
||||
struct disk_info *info, int align, off_t *offset)
|
||||
{
|
||||
blocknum_t count;
|
||||
@@ -1074,6 +1093,7 @@ disk_write_block_buffer_align(struct misc_fd *mfd, int fd_is_basedisk, const voi
|
||||
rc = disk_write_block_aligned_base(mfd, fd_is_basedisk,
|
||||
VOID_ADD(buffer, written),
|
||||
chunk_size, &(*blocklist)[i],
|
||||
fs_block_size,
|
||||
info,
|
||||
i == 0 ? align : info->phy_block_size,
|
||||
&pos);
|
||||
@@ -1086,12 +1106,14 @@ disk_write_block_buffer_align(struct misc_fd *mfd, int fd_is_basedisk, const voi
|
||||
}
|
||||
|
||||
blocknum_t
|
||||
disk_write_block_buffer(struct misc_fd *mfd, int fd_is_basedisk, const void *buffer,
|
||||
size_t bytecount, disk_blockptr_t **blocklist,
|
||||
disk_write_block_buffer(struct misc_fd *mfd, int fd_is_basedisk,
|
||||
const void *buffer, size_t bytecount,
|
||||
disk_blockptr_t **blocklist, int fs_block_size,
|
||||
struct disk_info *info)
|
||||
{
|
||||
return disk_write_block_buffer_align(mfd, fd_is_basedisk, buffer,
|
||||
bytecount, blocklist, info,
|
||||
bytecount, blocklist,
|
||||
fs_block_size, info,
|
||||
info->phy_block_size, NULL);
|
||||
}
|
||||
|
||||
@@ -1168,7 +1190,7 @@ char *disk_get_ipl_type(disk_type_t type, int is_dump)
|
||||
|
||||
/* Return non-zero for ECKD large volumes. */
|
||||
int
|
||||
disk_is_large_volume(struct disk_info* info)
|
||||
disk_is_large_volume(struct disk_info *info)
|
||||
{
|
||||
return (info->type == disk_type_eckd_ldl ||
|
||||
info->type == disk_type_eckd_cdl) &&
|
||||
@@ -1177,13 +1199,14 @@ disk_is_large_volume(struct disk_info* info)
|
||||
|
||||
|
||||
/* Print textual representation of INFO contents. */
|
||||
void disk_print_info(struct disk_info *info, int source)
|
||||
void device_print_info(struct device_info *this, int source)
|
||||
{
|
||||
struct disk_info *info = &this->base[0];
|
||||
char footnote[4] = "";
|
||||
|
||||
prepare_footnote_ptr(source, footnote);
|
||||
printf(" Device..........................: ");
|
||||
disk_print_devt(info->device);
|
||||
disk_print_devt(this->device);
|
||||
if (info->targetbase_def == defined_as_device)
|
||||
printf("%s", footnote);
|
||||
printf("\n");
|
||||
@@ -1192,16 +1215,16 @@ void disk_print_info(struct disk_info *info, int source)
|
||||
disk_print_devt(info->partition);
|
||||
printf("\n");
|
||||
}
|
||||
if (info->name) {
|
||||
if (this->name) {
|
||||
printf(" Device name.....................: %s",
|
||||
info->name);
|
||||
this->name);
|
||||
if (info->targetbase_def == defined_as_name)
|
||||
printf("%s", footnote);
|
||||
printf("\n");
|
||||
}
|
||||
if (info->drv_name) {
|
||||
if (this->drv_name) {
|
||||
printf(" Device driver name..............: %s\n",
|
||||
info->drv_name);
|
||||
this->drv_name);
|
||||
}
|
||||
if (((info->type == disk_type_fba) ||
|
||||
(info->type == disk_type_diag) ||
|
||||
@@ -1231,9 +1254,9 @@ void disk_print_info(struct disk_info *info, int source)
|
||||
}
|
||||
printf(" Geometry - start................: %ld%s\n",
|
||||
info->geo.start, footnote);
|
||||
if (info->fs_block_size >= 0)
|
||||
if (this->fs_block_size >= 0)
|
||||
printf(" File system block size..........: %d\n",
|
||||
info->fs_block_size);
|
||||
this->fs_block_size);
|
||||
printf(" Physical block size.............: %d%s\n",
|
||||
info->phy_block_size, footnote);
|
||||
printf(" Device size in physical blocks..: %ld\n",
|
||||
@@ -1244,7 +1267,7 @@ void disk_print_info(struct disk_info *info, int source)
|
||||
/* Check whether a block is a zero block which identifies a hole in a file.
|
||||
* Return non-zero if BLOCK is a zero block, 0 otherwise. */
|
||||
int
|
||||
disk_is_zero_block(disk_blockptr_t* block, struct disk_info* info)
|
||||
disk_is_zero_block(disk_blockptr_t *block, struct disk_info *info)
|
||||
{
|
||||
switch (info->type) {
|
||||
case disk_type_scsi:
|
||||
@@ -1270,7 +1293,7 @@ disk_is_zero_block(disk_blockptr_t* block, struct disk_info* info)
|
||||
* blocks can be merged, 0 otherwise. */
|
||||
static int
|
||||
can_merge_blocks(disk_blockptr_t* first, disk_blockptr_t* second,
|
||||
struct disk_info* info)
|
||||
struct disk_info *info)
|
||||
{
|
||||
int max_count;
|
||||
|
||||
@@ -1316,7 +1339,7 @@ can_merge_blocks(disk_blockptr_t* first, disk_blockptr_t* second,
|
||||
* type. */
|
||||
static void
|
||||
merge_blocks(disk_blockptr_t* first, disk_blockptr_t* second,
|
||||
struct disk_info* info)
|
||||
struct disk_info *info)
|
||||
{
|
||||
switch (info->type) {
|
||||
case disk_type_scsi:
|
||||
@@ -1339,7 +1362,7 @@ merge_blocks(disk_blockptr_t* first, disk_blockptr_t* second,
|
||||
* number of elements in the list. */
|
||||
blocknum_t
|
||||
disk_compact_blocklist(disk_blockptr_t* list, blocknum_t count,
|
||||
struct disk_info* info)
|
||||
struct disk_info *info)
|
||||
{
|
||||
blocknum_t i;
|
||||
blocknum_t last;
|
||||
@@ -1366,8 +1389,8 @@ disk_compact_blocklist(disk_blockptr_t* list, blocknum_t count,
|
||||
*/
|
||||
blocknum_t
|
||||
disk_get_blocklist_from_file(const char *filename, struct file_range *reg,
|
||||
disk_blockptr_t **blocklist,
|
||||
struct disk_info* info)
|
||||
disk_blockptr_t **blocklist, int fs_block_size,
|
||||
struct disk_info *info)
|
||||
{
|
||||
struct stat stats;
|
||||
int fd;
|
||||
@@ -1420,7 +1443,8 @@ disk_get_blocklist_from_file(const char *filename, struct file_range *reg,
|
||||
}
|
||||
/* Build list */
|
||||
for (i = 0; i < blk_count; i++) {
|
||||
if (disk_get_blocknum(fd, 0, blk_off + i, &blocknum, info)) {
|
||||
if (disk_get_blocknum(fd, 0, blk_off + i, &blocknum,
|
||||
fs_block_size, info)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -172,7 +172,8 @@ install_fba_ccw(int fd, disk_blockptr_t *program_table,
|
||||
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)
|
||||
blocknum_t stage2_count, int fs_block_size,
|
||||
struct disk_info *info)
|
||||
{
|
||||
struct boot_eckd_stage1b *stage1b;
|
||||
int stage1b_size, rc = -1;
|
||||
@@ -187,7 +188,8 @@ install_eckd_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list,
|
||||
if (boot_init_eckd_stage1b(stage1b, stage2_list, stage2_count))
|
||||
goto out_free_stage1b;
|
||||
*stage1b_count = disk_write_block_buffer(mfd, 1, stage1b, stage1b_size,
|
||||
stage1b_list, info);
|
||||
stage1b_list, fs_block_size,
|
||||
info);
|
||||
if (*stage1b_count == 0)
|
||||
goto out_free_stage1b;
|
||||
rc = 0;
|
||||
@@ -430,7 +432,7 @@ static int install_bootloader_dump(struct program_table *tables,
|
||||
int install_bootloader(struct job_data *job, struct install_set *bis)
|
||||
{
|
||||
disk_blockptr_t *scsi_dump_sb_blockptr = &bis->scsi_dump_sb_blockptr;
|
||||
struct disk_info *info = bis->info;
|
||||
struct disk_info *info = &bis->info->base[0];
|
||||
char footnote[4];
|
||||
int rc;
|
||||
int i;
|
||||
@@ -444,15 +446,15 @@ int install_bootloader(struct job_data *job, struct install_set *bis)
|
||||
disk_get_ipl_type(info->type,
|
||||
job->id == job_dump_partition),
|
||||
job->id == job_dump_partition ? "dump" : "IPL");
|
||||
if (info->name) {
|
||||
printf("%s", info->name);
|
||||
if (bis->info->name) {
|
||||
printf("%s", bis->info->name);
|
||||
if (info->devno >= 0)
|
||||
printf(" (%04x)", info->devno);
|
||||
printf(".\n");
|
||||
} else if (info->devno >= 0) {
|
||||
printf("%04x.\n", info->devno);
|
||||
} else {
|
||||
disk_print_devt(info->device);
|
||||
disk_print_devt(bis->info->device);
|
||||
printf(".\n");
|
||||
}
|
||||
/* Install independently on each physical target base */
|
||||
@@ -462,7 +464,7 @@ int install_bootloader(struct job_data *job, struct install_set *bis)
|
||||
|
||||
if (verbose) {
|
||||
printf("Installing on base disk: ");
|
||||
disk_print_devname(info->basedisks[i]);
|
||||
disk_print_devname(bis->info->base[i].disk);
|
||||
printf("%s.\n", footnote);
|
||||
}
|
||||
/* Open device file */
|
||||
@@ -488,12 +490,14 @@ int install_bootloader(struct job_data *job, struct install_set *bis)
|
||||
* picture in comments above)
|
||||
*/
|
||||
if (job->id == job_dump_partition) {
|
||||
rc = install_bootloader_dump(bis->tables, info,
|
||||
rc = install_bootloader_dump(bis->tables,
|
||||
&bis->info->base[i],
|
||||
scsi_dump_sb_blockptr,
|
||||
job_dump_is_ngdump(job),
|
||||
fd);
|
||||
} else {
|
||||
rc = install_bootloader_ipl(bis->tables, info,
|
||||
rc = install_bootloader_ipl(bis->tables,
|
||||
&bis->info->base[i],
|
||||
fd);
|
||||
}
|
||||
if (fsync(fd))
|
||||
@@ -512,13 +516,16 @@ int install_bootloader(struct job_data *job, struct install_set *bis)
|
||||
if (info->devno >= 0)
|
||||
syslog(LOG_INFO, "Boot loader written to %s (%04x) - "
|
||||
"%02x:%02x",
|
||||
(info->name ? info->name : "-"), info->devno,
|
||||
major(info->device), minor(info->device));
|
||||
(bis->info->name ? bis->info->name : "-"),
|
||||
info->devno,
|
||||
major(bis->info->device),
|
||||
minor(bis->info->device));
|
||||
else
|
||||
syslog(LOG_INFO, "Boot loader written to %s - "
|
||||
"%02x:%02x",
|
||||
(info->name ? info->name : "-"),
|
||||
major(info->device), minor(info->device));
|
||||
(bis->info->name ? bis->info->name : "-"),
|
||||
major(bis->info->device),
|
||||
minor(bis->info->device));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -793,7 +800,7 @@ install_tapeloader(const char* device, const char* image, const char* parmline,
|
||||
/* Write 64k null bytes with dump signature at offset 512 to
|
||||
* start of dump partition */
|
||||
static int
|
||||
overwrite_partition_start(int fd, struct disk_info* info, int mv_dump_magic)
|
||||
overwrite_partition_start(int fd, struct disk_info *info, int mv_dump_magic)
|
||||
{
|
||||
int rc;
|
||||
unsigned int bytes = 65536;
|
||||
@@ -826,7 +833,7 @@ overwrite_partition_start(int fd, struct disk_info* info, int mv_dump_magic)
|
||||
* Force block size of 4KiB because otherwise there is not enough space
|
||||
* to write the dump tool.
|
||||
*/
|
||||
static int check_eckd_dump_partition(struct disk_info* info)
|
||||
static int check_eckd_dump_partition(struct disk_info *info)
|
||||
{
|
||||
unsigned long long end_blk = info->geo.start + info->phy_blocks - 1;
|
||||
|
||||
@@ -856,8 +863,10 @@ static void eckd_dump_store_param(struct eckd_dump_param *param,
|
||||
param->bpt = info->geo.sectors;
|
||||
}
|
||||
|
||||
static int install_svdump_eckd_ldl(struct misc_fd *mfd, struct disk_info *info,
|
||||
const struct stage2dump_parm_tail *stage2dump_parms)
|
||||
static int
|
||||
install_svdump_eckd_ldl(struct misc_fd *mfd, int fs_block_size,
|
||||
struct disk_info *info,
|
||||
const struct stage2dump_parm_tail *stage2dump_parms)
|
||||
{
|
||||
disk_blockptr_t *stage2_list, *stage1b_list;
|
||||
blocknum_t stage2_count, stage1b_count;
|
||||
@@ -880,11 +889,13 @@ static int install_svdump_eckd_ldl(struct misc_fd *mfd, struct disk_info *info,
|
||||
if (misc_seek(mfd->fd, info->geo.start * info->phy_block_size))
|
||||
goto out_free_stage2;
|
||||
stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size,
|
||||
&stage2_list, info);
|
||||
&stage2_list,
|
||||
fs_block_size, info);
|
||||
if (stage2_count == 0)
|
||||
goto out_free_stage2_list;
|
||||
if (install_eckd_stage1b(mfd, &stage1b_list, &stage1b_count,
|
||||
stage2_list, stage2_count, info))
|
||||
stage2_list, stage2_count, fs_block_size,
|
||||
info))
|
||||
goto out_free_stage2_list;
|
||||
/* Install stage 0 - afterwards we are at stage 1 position*/
|
||||
boot_init_eckd_ldl_stage0(&stage0);
|
||||
@@ -911,8 +922,9 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int install_dump_eckd_cdl(struct misc_fd *mfd, struct disk_info *info,
|
||||
void *stage2, size_t stage2_size, int mvdump,
|
||||
static int install_dump_eckd_cdl(struct misc_fd *mfd, int fs_block_size,
|
||||
struct disk_info *info, void *stage2,
|
||||
size_t stage2_size, int mvdump,
|
||||
int force)
|
||||
{
|
||||
blocknum_t count, stage2_count, stage1b_count;
|
||||
@@ -936,12 +948,14 @@ static int install_dump_eckd_cdl(struct misc_fd *mfd, struct disk_info *info,
|
||||
if (misc_seek(mfd->fd, ECKD_CDL_DUMP_REC * info->phy_block_size))
|
||||
goto out;
|
||||
stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size,
|
||||
&stage2_list, info);
|
||||
&stage2_list, fs_block_size,
|
||||
info);
|
||||
if (stage2_count == 0)
|
||||
goto out;
|
||||
/* Install stage 1b behind stage 2*/
|
||||
if (install_eckd_stage1b(mfd, &stage1b_list, &stage1b_count,
|
||||
stage2_list, stage2_count, info))
|
||||
stage2_list, stage2_count, fs_block_size,
|
||||
info))
|
||||
goto out_free_stage2_list;
|
||||
/* Install stage 0 */
|
||||
boot_init_eckd_cdl_stage0(&stage0_cdl);
|
||||
@@ -968,7 +982,8 @@ out:
|
||||
}
|
||||
|
||||
static int
|
||||
install_svdump_eckd_cdl(struct misc_fd *mfd, struct disk_info *info,
|
||||
install_svdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size,
|
||||
struct disk_info *info,
|
||||
const struct stage2dump_parm_tail *stage2dump_parms)
|
||||
{
|
||||
size_t stage2_size;
|
||||
@@ -977,13 +992,15 @@ install_svdump_eckd_cdl(struct misc_fd *mfd, struct disk_info *info,
|
||||
|
||||
if (boot_get_eckd_dump_stage2(&stage2, &stage2_size, stage2dump_parms))
|
||||
return -1;
|
||||
rc = install_dump_eckd_cdl(mfd, info, stage2, stage2_size, 0, 0);
|
||||
rc = install_dump_eckd_cdl(mfd, fs_block_size,
|
||||
info, stage2, stage2_size, 0, 0);
|
||||
free(stage2);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
install_mvdump_eckd_cdl(struct misc_fd *mfd, struct disk_info *info,
|
||||
install_mvdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size,
|
||||
struct disk_info *info,
|
||||
const struct stage2dump_parm_tail *stage2dump_parms,
|
||||
const struct mvdump_parm_table *mv_parm_table)
|
||||
{
|
||||
@@ -995,7 +1012,8 @@ install_mvdump_eckd_cdl(struct misc_fd *mfd, 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(mfd, info, stage2, stage2_size, 1,
|
||||
rc = install_dump_eckd_cdl(mfd, fs_block_size, info, stage2,
|
||||
stage2_size, 1,
|
||||
stage2dump_parms->mvdump_force);
|
||||
free(stage2);
|
||||
return rc;
|
||||
@@ -1004,7 +1022,8 @@ install_mvdump_eckd_cdl(struct misc_fd *mfd, struct disk_info *info,
|
||||
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)
|
||||
blocknum_t stage2_count, int fs_block_size,
|
||||
struct disk_info *info)
|
||||
{
|
||||
struct boot_fba_stage1b *stage1b;
|
||||
int stage1b_size, rc = -1;
|
||||
@@ -1019,7 +1038,8 @@ install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list,
|
||||
if (boot_init_fba_stage1b(stage1b, stage2_list, stage2_count))
|
||||
goto out_free_stage1b;
|
||||
*stage1b_count = disk_write_block_buffer(mfd, 1, stage1b, stage1b_size,
|
||||
stage1b_list, info);
|
||||
stage1b_list, fs_block_size,
|
||||
info);
|
||||
if (*stage1b_count == 0)
|
||||
goto out_free_stage1b;
|
||||
rc = 0;
|
||||
@@ -1030,7 +1050,8 @@ out:
|
||||
}
|
||||
|
||||
static int
|
||||
install_svdump_fba(struct misc_fd *mfd, struct disk_info *info,
|
||||
install_svdump_fba(struct misc_fd *mfd, int fs_block_size,
|
||||
struct disk_info *info,
|
||||
const struct stage2dump_parm_tail *stage2dump_parms)
|
||||
{
|
||||
blocknum_t stage1b_count, stage2_count, blk;
|
||||
@@ -1055,7 +1076,8 @@ install_svdump_fba(struct misc_fd *mfd, struct disk_info *info,
|
||||
if (misc_seek(mfd->fd, blk * info->phy_block_size))
|
||||
goto out_free_stage2;
|
||||
stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size,
|
||||
&stage2_list, info);
|
||||
&stage2_list, fs_block_size,
|
||||
info);
|
||||
if (stage2_count == 0)
|
||||
goto out_free_stage2;
|
||||
/* Install stage 1b in front of stage 2 */
|
||||
@@ -1063,7 +1085,7 @@ install_svdump_fba(struct misc_fd *mfd, struct disk_info *info,
|
||||
if (misc_seek(mfd->fd, blk * info->phy_block_size))
|
||||
goto out_free_stage2_list;
|
||||
if (install_fba_stage1b(mfd, &stage1b_list, &stage1b_count,
|
||||
stage2_list, stage2_count, info))
|
||||
stage2_list, stage2_count, fs_block_size, info))
|
||||
goto out_free_stage2_list;
|
||||
/* Install stage 0/1 fill in dump partition parameter */
|
||||
if (boot_init_fba_stage0(&stage0, stage1b_list, stage1b_count))
|
||||
@@ -1111,7 +1133,8 @@ install_dump(const char *device, struct job_target_data *target, uint64_t mem,
|
||||
{
|
||||
struct stage2dump_parm_tail stage2dump_parms = {0};
|
||||
struct misc_fd mfd = {0};
|
||||
struct disk_info* info;
|
||||
struct device_info *dev_info;
|
||||
struct disk_info *info;
|
||||
uint64_t part_size;
|
||||
char *tempdev;
|
||||
int rc;
|
||||
@@ -1151,32 +1174,33 @@ install_dump(const char *device, struct job_target_data *target, uint64_t mem,
|
||||
}
|
||||
close(mfd.fd);
|
||||
/* This is a disk device */
|
||||
rc = disk_get_info(device, target, &info);
|
||||
rc = device_get_info(device, target, &dev_info);
|
||||
if (rc) {
|
||||
error_text("Could not get information for dump target "
|
||||
"'%s'", device);
|
||||
return rc;
|
||||
}
|
||||
info = &dev_info->base[0];
|
||||
if (info->partnum == 0) {
|
||||
error_reason("Dump target '%s' is not a disk partition",
|
||||
device);
|
||||
disk_free_info(info);
|
||||
device_free_info(dev_info);
|
||||
return -1;
|
||||
}
|
||||
if (verbose) {
|
||||
printf("Target device information\n");
|
||||
disk_print_info(info, target->source);
|
||||
device_print_info(dev_info, target->source);
|
||||
}
|
||||
rc = misc_temp_dev(info->device, 1, &tempdev);
|
||||
rc = misc_temp_dev(dev_info->device, 1, &tempdev);
|
||||
if (rc) {
|
||||
disk_free_info(info);
|
||||
device_free_info(dev_info);
|
||||
return -1;
|
||||
}
|
||||
if (misc_open_device(tempdev, &mfd, dry_run) == -1) {
|
||||
error_text("Could not open temporary device node '%s'",
|
||||
tempdev);
|
||||
misc_free_temp_dev(tempdev);
|
||||
disk_free_info(info);
|
||||
device_free_info(dev_info);
|
||||
return -1;
|
||||
}
|
||||
switch (info->type) {
|
||||
@@ -1203,11 +1227,16 @@ 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(&mfd, info, &stage2dump_parms);
|
||||
rc = install_svdump_eckd_ldl(&mfd,
|
||||
dev_info->fs_block_size,
|
||||
info, &stage2dump_parms);
|
||||
else if (info->type == disk_type_eckd_cdl)
|
||||
rc = install_svdump_eckd_cdl(&mfd, info, &stage2dump_parms);
|
||||
rc = install_svdump_eckd_cdl(&mfd,
|
||||
dev_info->fs_block_size,
|
||||
info, &stage2dump_parms);
|
||||
else
|
||||
rc = install_svdump_fba(&mfd, info, &stage2dump_parms);
|
||||
rc = install_svdump_fba(&mfd, dev_info->fs_block_size,
|
||||
info, &stage2dump_parms);
|
||||
break;
|
||||
case disk_type_scsi:
|
||||
error_reason("%s: Unsupported disk type '%s' (try --dumptofs)",
|
||||
@@ -1221,7 +1250,7 @@ install_dump(const char *device, struct job_target_data *target, uint64_t mem,
|
||||
break;
|
||||
}
|
||||
misc_free_temp_dev(tempdev);
|
||||
disk_free_info(info);
|
||||
device_free_info(dev_info);
|
||||
if (fsync(mfd.fd))
|
||||
error_text("Could not sync device file '%s'", device);
|
||||
if (close(mfd.fd))
|
||||
@@ -1234,8 +1263,9 @@ 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 device_info *dev_info[MAX_DUMP_VOLUMES] = {0};
|
||||
struct stage2dump_parm_tail stage2dump_parms = {0};
|
||||
struct disk_info *info[MAX_DUMP_VOLUMES] = {0};
|
||||
struct mvdump_parm_table mvdump_parms;
|
||||
uint64_t total_size = 0;
|
||||
struct timeval time;
|
||||
@@ -1269,12 +1299,13 @@ install_mvdump(char* const device[], struct job_target_data* target, int count,
|
||||
}
|
||||
close(mfd.fd);
|
||||
/* This is a disk device */
|
||||
rc = disk_get_info(device[i], target, &info[i]);
|
||||
rc = device_get_info(device[i], target, &dev_info[i]);
|
||||
if (rc) {
|
||||
error_text("Could not get information for dump target "
|
||||
"'%s'", device[i]);
|
||||
goto out;
|
||||
}
|
||||
info[i] = &dev_info[i]->base[0];
|
||||
if (info[i]->partnum == 0) {
|
||||
error_reason("Dump target '%s' is not a disk partition",
|
||||
device[i]);
|
||||
@@ -1323,7 +1354,7 @@ install_mvdump(char* const device[], struct job_target_data* target, int count,
|
||||
if (verbose) {
|
||||
for (i = 0; i < count; i++) {
|
||||
printf("Multi-volume dump target %d:\n", i + 1);
|
||||
disk_print_info(info[i], target->source);
|
||||
device_print_info(dev_info[i], target->source);
|
||||
printf("-------------------------------------------\n");
|
||||
}
|
||||
}
|
||||
@@ -1345,7 +1376,7 @@ install_mvdump(char* const device[], struct job_target_data* target, int count,
|
||||
for (i = 0; i < count; i++) {
|
||||
struct misc_fd mfd = {0};
|
||||
|
||||
rc = misc_temp_dev(info[i]->device, 1, &tempdev);
|
||||
rc = misc_temp_dev(dev_info[i]->device, 1, &tempdev);
|
||||
if (rc) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
@@ -1360,7 +1391,9 @@ 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(&mfd, info[i], &stage2dump_parms, &mvdump_parms);
|
||||
rc = install_mvdump_eckd_cdl(&mfd, dev_info[i]->fs_block_size,
|
||||
info[i], &stage2dump_parms,
|
||||
&mvdump_parms);
|
||||
misc_free_temp_dev(tempdev);
|
||||
|
||||
if (fsync(mfd.fd))
|
||||
@@ -1374,6 +1407,6 @@ install_mvdump(char* const device[], struct job_target_data* target, int count,
|
||||
out:
|
||||
for (i = 0; i < count; i++)
|
||||
if (info[i] != NULL)
|
||||
disk_free_info(info[i]);
|
||||
device_free_info(dev_info[i]);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -174,7 +174,8 @@ main(int argc, char* argv[])
|
||||
/* Do it */
|
||||
switch (job->id) {
|
||||
case job_dump_partition:
|
||||
rc = disk_get_ext_type(job->data.dump.device, &ext_type);
|
||||
rc = disk_get_ext_type(job->data.dump.device, &ext_type,
|
||||
0 /* disk index */);
|
||||
if (rc)
|
||||
break;
|
||||
job_dump_check_set_ngdump(job, &ext_type);
|
||||
|
||||
Reference in New Issue
Block a user