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:
Eduard Shishkin
2025-07-17 16:43:45 +02:00
committed by Steffen Eiden
parent 338bea49c2
commit f375327085
6 changed files with 402 additions and 290 deletions

View File

@@ -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);

View File

@@ -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 */

View File

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

View File

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

View File

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

View File

@@ -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);