diff --git a/scst/README b/scst/README index 08aa28fa4..6e0a28477 100644 --- a/scst/README +++ b/scst/README @@ -1948,23 +1948,50 @@ information about ALUA support in Windows Server, see also: Active/Non-Optimized via internal redirection ............................................. -The Active-Standby configuration is simple to understand and setup, -however, it might have serious interoperability issues, because not all -initiators handle Standby state correctly. For instance, some versions -of VMware reported to have such issues. Same for Windows. +The Active-Standby configuration is simple to understand and to set up. +However, it might cause serious interoperability issues because not all +initiators handle the ALUA state 'standby' state correctly. For instance, +some versions of VMware reported to have such issues. Same for Windows. -Hence, it is better to use Non-Optimized state on the passive node -instead of Standby with internal commands redirection to the active -node. This is what the vast majority of storage vendors are doing, which -is, actually, the reason why Standby and Unavailable states have all -those initiator issues. Simply, they have had too few testing, because -only marginally used. +It is better to use the 'nonoptimized' state on the passive node instead +of 'standby' with internal commands redirection to the active node. This +is what the vast majority of storage vendors are doing. This is actually +the reason why the 'standby' and 'unavailable' states have all those +initiator interoperability issues. The latter combination has received +too few testing because it is only marginally used. -SCST has necessary support for such redirection, it just needs to be +SCST has the necessary support for such redirection, it just needs to be configured correctly. It's a little bit of effort, especially to understand how it's going to function, but then it would work MUCH more reliable for full range of initiators. Ever poor initiators, who have no -idea about ALUA (boot from SAN, e.g.) would work now. +idea about ALUA (boot from SAN, e.g.) would work now. The following +diagram illustrates this approach: + +................................................................ +. . . +. Initiator A . Initiator B . +. | . | . +................................................................ +. | . | . +. target port C . target port D . +. | . | . +. SCST . SCST . +. Instance E - target . target - Instance F . +. / \ port G . port H / \ . +. / \ \./ / \ . +. / \ /.\ / \ . +. vdisk_blockio dev_disk / . \ dev_disk vdisk_blockio . +. handler handler / . \ handler handler . +. | | / . \ | | . +. block device SCSI / . SCSI block device . +. I initiator . initiator J . +. | node K . node L | . +. |______________________ .______________________| . +................................................................ +The link between block devices I and J stands for synchronous replication. + + +Such a setup can be configured as follows: 1. Build SCST with CONFIG_SCST_FORWARD_MODE_PASS_THROUGH enabled in scst.h diff --git a/scst/include/scst.h b/scst/include/scst.h index 68027ec4b..19281a170 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -759,8 +759,6 @@ struct scst_opcode_descriptor; */ #define NO_SUCH_LUN ((uint64_t)-1) -typedef enum dma_data_direction scst_data_direction; - /* * SCST target template: defines target driver's parameters and callback * functions. @@ -1736,8 +1734,11 @@ struct scst_dev_type { /* Optional help string for mgmt_cmd commands */ const char *mgmt_cmd_help; - /* List of parameters for add_device command, if any */ - const char *add_device_parameters; + /* + * Array with parameters for add_device command, if any. NULL + * terminated. + */ + const char *const *add_device_parameters; /* * List of optional, i.e. which could be added by add_attribute command diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h index cb0caa2ea..a232de5e9 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -239,11 +239,13 @@ enum scst_cdb_flags { ** Data direction aliases. Changing it don't forget to change ** scst_to_tgt_dma_dir and SCST_DATA_DIR_MAX as well!! *************************************************************/ -#define SCST_DATA_UNKNOWN 0 -#define SCST_DATA_WRITE 1 -#define SCST_DATA_READ 2 -#define SCST_DATA_BIDI (SCST_DATA_WRITE | SCST_DATA_READ) -#define SCST_DATA_NONE 4 +typedef enum scst_data_direction { + SCST_DATA_UNKNOWN = 0, + SCST_DATA_WRITE = 1, + SCST_DATA_READ = 2, + SCST_DATA_BIDI = (SCST_DATA_WRITE | SCST_DATA_READ), + SCST_DATA_NONE = 4, +} scst_data_direction; #define SCST_DATA_DIR_MAX (SCST_DATA_NONE+1) diff --git a/scst/src/dev_handlers/scst_disk.c b/scst/src/dev_handlers/scst_disk.c index e5ede7d66..59e8bfe4f 100644 --- a/scst/src/dev_handlers/scst_disk.c +++ b/scst/src/dev_handlers/scst_disk.c @@ -42,118 +42,6 @@ #define DISK_DEF_BLOCK_SHIFT 9 -static int disk_attach(struct scst_device *dev); -static void disk_detach(struct scst_device *dev); -static int disk_parse(struct scst_cmd *cmd); -static enum scst_exec_res disk_perf_exec(struct scst_cmd *cmd); -static int disk_done(struct scst_cmd *cmd); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) -static enum scst_exec_res disk_exec(struct scst_cmd *cmd); -static bool disk_on_sg_tablesize_low(struct scst_cmd *cmd); -#endif - -static struct scst_dev_type disk_devtype = { - .name = DISK_NAME, - .type = TYPE_DISK, - .threads_num = 1, - .parse_atomic = 1, - .dev_done_atomic = 1, - .attach = disk_attach, - .detach = disk_detach, - .parse = disk_parse, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) - .exec = disk_exec, - .on_sg_tablesize_low = disk_on_sg_tablesize_low, -#endif - .dev_done = disk_done, -#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) - .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS, - .trace_flags = &trace_flag, -#endif -}; - -static struct scst_dev_type disk_devtype_perf = { - .name = DISK_PERF_NAME, - .type = TYPE_DISK, - .parse_atomic = 1, - .dev_done_atomic = 1, - .attach = disk_attach, - .detach = disk_detach, - .parse = disk_parse, - .exec = disk_perf_exec, - .dev_done = disk_done, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) - .on_sg_tablesize_low = disk_on_sg_tablesize_low, -#endif -#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) - .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS, - .trace_flags = &trace_flag, -#endif -}; - -static int __init init_scst_disk_driver(void) -{ - int res = 0; - - TRACE_ENTRY(); - - disk_devtype.module = THIS_MODULE; - - res = scst_register_dev_driver(&disk_devtype); - if (res < 0) - goto out; - - disk_devtype_perf.module = THIS_MODULE; - - res = scst_register_dev_driver(&disk_devtype_perf); - if (res < 0) - goto out_unreg; - -#ifdef CONFIG_SCST_PROC - res = scst_dev_handler_build_std_proc(&disk_devtype); - if (res != 0) - goto out_unreg1; - - res = scst_dev_handler_build_std_proc(&disk_devtype_perf); - if (res != 0) - goto out_unreg2; -#endif - -out: - TRACE_EXIT_RES(res); - return res; - -#ifdef CONFIG_SCST_PROC -out_unreg2: - scst_dev_handler_destroy_std_proc(&disk_devtype); - -out_unreg1: - scst_unregister_dev_driver(&disk_devtype_perf); -#endif - -out_unreg: - scst_unregister_dev_driver(&disk_devtype); - goto out; -} - -static void __exit exit_scst_disk_driver(void) -{ - TRACE_ENTRY(); - -#ifdef CONFIG_SCST_PROC - scst_dev_handler_destroy_std_proc(&disk_devtype_perf); - scst_dev_handler_destroy_std_proc(&disk_devtype); -#endif - scst_unregister_dev_driver(&disk_devtype_perf); - scst_unregister_dev_driver(&disk_devtype); - - TRACE_EXIT(); - return; -} - -module_init(init_scst_disk_driver); -module_exit(exit_scst_disk_driver); - static int disk_attach(struct scst_device *dev) { int res, rc; @@ -624,6 +512,108 @@ out_complete: goto out; } +static struct scst_dev_type disk_devtype = { + .name = DISK_NAME, + .type = TYPE_DISK, + .threads_num = 1, + .parse_atomic = 1, + .dev_done_atomic = 1, + .attach = disk_attach, + .detach = disk_detach, + .parse = disk_parse, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) + .exec = disk_exec, + .on_sg_tablesize_low = disk_on_sg_tablesize_low, +#endif + .dev_done = disk_done, +#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) + .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS, + .trace_flags = &trace_flag, +#endif +}; + +static struct scst_dev_type disk_devtype_perf = { + .name = DISK_PERF_NAME, + .type = TYPE_DISK, + .parse_atomic = 1, + .dev_done_atomic = 1, + .attach = disk_attach, + .detach = disk_detach, + .parse = disk_parse, + .exec = disk_perf_exec, + .dev_done = disk_done, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) + .on_sg_tablesize_low = disk_on_sg_tablesize_low, +#endif +#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) + .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS, + .trace_flags = &trace_flag, +#endif +}; + +static int __init init_scst_disk_driver(void) +{ + int res = 0; + + TRACE_ENTRY(); + + disk_devtype.module = THIS_MODULE; + + res = scst_register_dev_driver(&disk_devtype); + if (res < 0) + goto out; + + disk_devtype_perf.module = THIS_MODULE; + + res = scst_register_dev_driver(&disk_devtype_perf); + if (res < 0) + goto out_unreg; + +#ifdef CONFIG_SCST_PROC + res = scst_dev_handler_build_std_proc(&disk_devtype); + if (res != 0) + goto out_unreg1; + + res = scst_dev_handler_build_std_proc(&disk_devtype_perf); + if (res != 0) + goto out_unreg2; +#endif + +out: + TRACE_EXIT_RES(res); + return res; + +#ifdef CONFIG_SCST_PROC +out_unreg2: + scst_dev_handler_destroy_std_proc(&disk_devtype); + +out_unreg1: + scst_unregister_dev_driver(&disk_devtype_perf); +#endif + +out_unreg: + scst_unregister_dev_driver(&disk_devtype); + goto out; +} + +static void __exit exit_scst_disk_driver(void) +{ + TRACE_ENTRY(); + +#ifdef CONFIG_SCST_PROC + scst_dev_handler_destroy_std_proc(&disk_devtype_perf); + scst_dev_handler_destroy_std_proc(&disk_devtype); +#endif + scst_unregister_dev_driver(&disk_devtype_perf); + scst_unregister_dev_driver(&disk_devtype); + + TRACE_EXIT(); + return; +} + +module_init(init_scst_disk_driver); +module_exit(exit_scst_disk_driver); + MODULE_AUTHOR("Vladislav Bolkhovitin & Leonid Stoljar"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SCSI disk (type 0) dev handler for SCST"); diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 56fd89639..1ad9ef9c0 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -284,7 +284,8 @@ struct vdisk_cmd_params { }; struct scst_cmd *cmd; loff_t loff; - int fua; + unsigned int fua:1; + unsigned int execute_async:1; }; static bool vdev_saved_mode_pages_enabled = true; @@ -511,6 +512,8 @@ static ssize_t vdev_sysfs_inq_vend_specific_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); static ssize_t vdev_zero_copy_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +static ssize_t vdev_async_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count); static ssize_t vdev_async_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); static ssize_t vdev_dif_filename_show(struct kobject *kobj, @@ -612,7 +615,7 @@ static struct kobj_attribute vdev_inq_vend_specific_attr = static struct kobj_attribute vdev_zero_copy_attr = __ATTR(zero_copy, S_IRUGO, vdev_zero_copy_show, NULL); static struct kobj_attribute vdev_async_attr = - __ATTR(async, S_IRUGO, vdev_async_show, NULL); + __ATTR(async, S_IWUSR|S_IRUGO, vdev_async_show, vdev_async_store); static struct kobj_attribute vdev_dif_filename_attr = __ATTR(dif_filename, S_IRUGO, vdev_dif_filename_show, NULL); @@ -752,6 +755,28 @@ static vdisk_op_fn fileio_ops[256]; static vdisk_op_fn blockio_ops[256]; static vdisk_op_fn nullio_ops[256]; +static const char *fileio_add_dev_params[] = { + "async", + "blocksize", + "cluster_mode", + "dif_filename", + "dif_mode", + "dif_static_app_tag", + "dif_type", + "filename", + "numa_node_id", + "nv_cache", + "o_direct", + "read_only", + "removable", + "rotational", + "thin_provisioned", + "tst", + "write_through", + "zero_copy", + NULL +}; + /* * Be careful changing "name" field, since it is the name of the corresponding * /sys/kernel/scst_tgt entry, hence a part of user space ABI. @@ -784,25 +809,7 @@ static struct scst_dev_type vdisk_file_devtype = { .add_device = vdisk_add_fileio_device, .del_device = vdisk_del_device, .dev_attrs = vdisk_fileio_attrs, - .add_device_parameters = - "async, " - "blocksize, " - "cluster_mode, " - "filename, " - "numa_node_id, " - "nv_cache, " - "o_direct, " - "read_only, " - "removable, " - "rotational, " - "thin_provisioned, " - "tst, " - "write_through, " - "zero_copy, " - "dif_mode, " - "dif_type, " - "dif_static_app_tag, " - "dif_filename", + .add_device_parameters = fileio_add_dev_params, #endif #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS, @@ -816,6 +823,27 @@ static struct scst_dev_type vdisk_file_devtype = { static struct kmem_cache *blockio_work_cachep; +static const char *blockio_add_dev_params[] = { + "active", + "bind_alua_state", + "blocksize", + "cluster_mode", + "dif_filename", + "dif_mode", + "dif_static_app_tag", + "dif_type", + "filename", + "numa_node_id", + "nv_cache", + "read_only", + "removable", + "rotational", + "thin_provisioned", + "tst", + "write_through", + NULL +}; + static struct scst_dev_type vdisk_blk_devtype = { .name = "vdisk_blockio", .type = TYPE_DISK, @@ -841,24 +869,7 @@ static struct scst_dev_type vdisk_blk_devtype = { .add_device = vdisk_add_blockio_device, .del_device = vdisk_del_device, .dev_attrs = vdisk_blockio_attrs, - .add_device_parameters = - "active, " - "bind_alua_state, " - "blocksize, " - "dif_mode, " - "dif_type, " - "dif_static_app_tag, " - "dif_filename, " - "filename, " - "numa_node_id, " - "nv_cache, " - "cluster_mode, " - "read_only, " - "removable, " - "rotational, " - "thin_provisioned, " - "tst, " - "write_through", + .add_device_parameters = blockio_add_dev_params, #endif #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS, @@ -870,6 +881,23 @@ static struct scst_dev_type vdisk_blk_devtype = { #endif }; +static const char *nullio_add_dev_params[] = { + "blocksize", + "cluster_mode", + "dif_mode", + "dif_static_app_tag", + "dif_type", + "dummy", + "numa_node_id", + "read_only", + "removable", + "rotational", + "size", + "size_mb", + "tst", + NULL +}; + static struct scst_dev_type vdisk_null_devtype = { .name = "vdisk_nullio", .type = TYPE_DISK, @@ -893,20 +921,7 @@ static struct scst_dev_type vdisk_null_devtype = { .add_device = vdisk_add_nullio_device, .del_device = vdisk_del_device, .dev_attrs = vdisk_nullio_attrs, - .add_device_parameters = - "blocksize, " - "dif_mode, " - "dif_type, " - "dif_static_app_tag, " - "dummy, " - "numa_node_id, " - "cluster_mode, " - "read_only, " - "removable, " - "rotational, " - "size, " - "size_mb, " - "tst", + .add_device_parameters = nullio_add_dev_params, #endif #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS, @@ -918,6 +933,11 @@ static struct scst_dev_type vdisk_null_devtype = { #endif }; +static const char *cdrom_add_dev_params[] = { + "tst", + NULL, +}; + static struct scst_dev_type vcdrom_devtype = { .name = "vcdrom", .type = TYPE_ROM, @@ -941,7 +961,7 @@ static struct scst_dev_type vcdrom_devtype = { .add_device = vcdrom_add_device, .del_device = vcdrom_del_device, .dev_attrs = vcdrom_attrs, - .add_device_parameters = "tst", + .add_device_parameters = cdrom_add_dev_params, #endif #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS, @@ -2991,7 +3011,7 @@ static bool vdisk_parse_offset(struct vdisk_cmd_params *p, struct scst_cmd *cmd) struct scst_device *dev = cmd->dev; struct scst_vdisk_dev *virt_dev = dev->dh_priv; bool res; - int fua = 0; + bool fua = false; TRACE_ENTRY(); @@ -3352,6 +3372,8 @@ static enum compl_status_e fileio_exec_async(struct vdisk_cmd_params *p) return CMD_SUCCEEDED; } + p->execute_async = true; + kvec = p->async.kvec; length = scst_get_buf_first(cmd, &address); while (length) { @@ -3410,7 +3432,7 @@ static enum compl_status_e fileio_exec_async(struct vdisk_cmd_params *p) static void vdisk_on_free_cmd_params(const struct vdisk_cmd_params *p) { - if (!do_fileio_async(p)) { + if (!p->execute_async) { if (p->sync.iv != p->sync.small_iv) kfree(p->sync.iv); } @@ -7833,6 +7855,13 @@ static void vdev_check_node(struct scst_vdisk_dev **pvirt_dev, int orig_nodeid) } *v = *virt_dev; kfree(virt_dev); + /* + * Since the address of the virtual device changed, update all + * pointers in the virtual device that point to the virtual + * device itself. + */ + INIT_WORK(&virt_dev->vdev_inq_changed_work, + vdev_inq_changed_fn); *pvirt_dev = v; } @@ -7841,6 +7870,10 @@ out: return; } +/* + * Parse the add_device parameters. @allowed_params restricts which + * parameters can be specified at device creation time. + */ static int vdev_parse_add_dev_params(struct scst_vdisk_dev *virt_dev, char *params, const char *const allowed_params[]) { @@ -8163,14 +8196,6 @@ out_destroy: static int vdev_blockio_add_device(const char *device_name, char *params) { int res = 0; - const char *const allowed_params[] = { "filename", "read_only", "write_through", - "removable", "blocksize", "nv_cache", - "rotational", "cluster_mode", - "thin_provisioned", "tst", "active", - "bind_alua_state", "numa_node_id", - "dif_mode", - "dif_type", "dif_static_app_tag", - "dif_filename", NULL }; struct scst_vdisk_dev *virt_dev; TRACE_ENTRY(); @@ -8186,7 +8211,8 @@ static int vdev_blockio_add_device(const char *device_name, char *params) sprintf(virt_dev->t10_vend_id, "%.*s", (int)sizeof(virt_dev->t10_vend_id) - 1, SCST_BIO_VENDOR); - res = vdev_parse_add_dev_params(virt_dev, params, allowed_params); + res = vdev_parse_add_dev_params(virt_dev, params, + virt_dev->vdev_devt->add_device_parameters); if (res != 0) goto out_destroy; @@ -8234,11 +8260,6 @@ out_destroy: static int vdev_nullio_add_device(const char *device_name, char *params) { int res = 0; - static const char *const allowed_params[] = { - "read_only", "dummy", "removable", "blocksize", "rotational", - "size", "size_mb", "tst", "numa_node_id", - "cluster_mode", "dif_mode", "dif_type", "dif_static_app_tag", NULL - }; struct scst_vdisk_dev *virt_dev; TRACE_ENTRY(); @@ -8252,7 +8273,8 @@ static int vdev_nullio_add_device(const char *device_name, char *params) virt_dev->nullio = 1; virt_dev->file_size = VDISK_NULLIO_SIZE; - res = vdev_parse_add_dev_params(virt_dev, params, allowed_params); + res = vdev_parse_add_dev_params(virt_dev, params, + virt_dev->vdev_devt->add_device_parameters); if (res != 0) goto out_destroy; @@ -8411,7 +8433,6 @@ out: static ssize_t __vcdrom_add_device(const char *device_name, char *params) { int res = 0; - static const char *const allowed_params[] = { "tst", NULL }; struct scst_vdisk_dev *virt_dev; TRACE_ENTRY(); @@ -8434,7 +8455,8 @@ static ssize_t __vcdrom_add_device(const char *device_name, char *params) virt_dev->blk_shift = DEF_CDROM_BLOCK_SHIFT; - res = vdev_parse_add_dev_params(virt_dev, params, allowed_params); + res = vdev_parse_add_dev_params(virt_dev, params, + virt_dev->vdev_devt->add_device_parameters); if (res != 0) goto out_destroy; @@ -10434,6 +10456,28 @@ static ssize_t vdev_zero_copy_show(struct kobject *kobj, return pos; } +static ssize_t vdev_async_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + struct scst_device *dev = + container_of(kobj, struct scst_device, dev_kobj); + struct scst_vdisk_dev *virt_dev = dev->dh_priv; + long val; + int res; + + res = kstrtol(buf, 0, &val); + if (res) + return res; + if (val != !!val) + return -EINVAL; + + spin_lock(&virt_dev->flags_lock); + virt_dev->async = val; + spin_unlock(&virt_dev->flags_lock); + + return count; +} + static ssize_t vdev_async_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { diff --git a/scst/src/scst_pres.c b/scst/src/scst_pres.c index 1f69d1380..e1bf203cf 100644 --- a/scst/src/scst_pres.c +++ b/scst/src/scst_pres.c @@ -1549,7 +1549,44 @@ out: return res; } -/* Called with dev_pr_mutex locked, no IRQ */ +/* Add registrants for remote ports. Called with dev_pr_mutex locked, no IRQ. */ +static int scst_register_remote_ports(struct scst_cmd *cmd, uint8_t *buffer, + int buffer_size, bool spec_i_pt, struct list_head *rollback_list) +{ + struct scst_dev_group *dg; + struct scst_target_group *tg; + struct scst_tg_tgt *tgtgt; + int res = 0; + + scst_alua_lock(); + + dg = scst_lookup_dg_by_dev(cmd->dev); + if (!dg) + goto out_unlock; + + list_for_each_entry(tg, &dg->tg_list, entry) { + list_for_each_entry(tgtgt, &tg->tgt_list, entry) { + /* Skip local target ports */ + if (tgtgt->tgt) + continue; + /* To do: check the initiator port transport ID. */ + if (tgtgt->rel_tgt_id == 0) + continue; + res = scst_pr_register_on_tgt_id(cmd, tgtgt->rel_tgt_id, + buffer, buffer_size, + spec_i_pt, + rollback_list); + if (res != 0) + goto out_unlock; + } + } +out_unlock: + scst_alua_unlock(); + + return res; +} + +/* Register all target ports. Called with dev_pr_mutex locked, no IRQ. */ static int scst_pr_register_all_tg_pt(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size, bool spec_i_pt, struct list_head *rollback_list) { @@ -1594,6 +1631,9 @@ static int scst_pr_register_all_tg_pt(struct scst_cmd *cmd, uint8_t *buffer, } } + res = scst_register_remote_ports(cmd, buffer, buffer_size, spec_i_pt, + rollback_list); + out_unlock: mutex_unlock(&scst_mutex2); diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index a5bab7e9e..9e933314d 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -488,6 +488,7 @@ void scst_tg_cleanup(void); int scst_dg_add(struct kobject *parent, const char *name); int scst_dg_remove(const char *name); struct scst_dev_group *scst_lookup_dg_by_kobj(struct kobject *kobj); +struct scst_dev_group *scst_lookup_dg_by_dev(struct scst_device *dev); int scst_dg_dev_add(struct scst_dev_group *dg, const char *name); int scst_dg_dev_remove_by_name(struct scst_dev_group *dg, const char *name); int scst_dg_dev_remove_by_dev(struct scst_device *dev); diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index b41296141..dc26bc668 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -5771,6 +5771,28 @@ static struct kobj_type scst_devt_ktype = { .default_attrs = scst_devt_default_attrs, }; +static char *scst_dev_params(struct scst_dev_type *devt) +{ + char *p, *r; + const char *const *q; + bool comma = false; + + if (!devt->add_device_parameters) + return NULL; + p = kstrdup("The following parameters available: ", GFP_KERNEL); + if (!p) + return NULL; + for (q = devt->add_device_parameters; *q; q++) { + r = kasprintf(GFP_KERNEL, "%s%s%s", p, comma ? ", " : "", *q); + kfree(p); + if (!r) + return NULL; + p = r; + comma = true; + } + return p; +} + static ssize_t scst_devt_mgmt_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -5782,12 +5804,14 @@ static ssize_t scst_devt_mgmt_show(struct kobject *kobj, "\n" "where parameters are one or more " "param_name=value pairs separated by ';'\n\n" - "%s%s%s%s%s%s%s%s%s%s\n"; + "%s%s%s%s%s%s%s%s%s\n"; struct scst_dev_type *devt; + char *p; + int res; devt = container_of(kobj, struct scst_dev_type, devt_kobj); - - return scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, help, + p = scst_dev_params(devt); + res = scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, help, (devt->devt_optional_attributes != NULL) ? " echo \"add_attribute \" >mgmt\n" " echo \"del_attribute \" >mgmt\n" : "", @@ -5796,10 +5820,7 @@ static ssize_t scst_devt_mgmt_show(struct kobject *kobj, " echo \"del_device_attribute device_name \" >mgmt\n" : "", (devt->mgmt_cmd_help) ? devt->mgmt_cmd_help : "", (devt->mgmt_cmd_help) ? "\n" : "", - (devt->add_device_parameters != NULL) ? - "The following parameters available: " : "", - (devt->add_device_parameters != NULL) ? - devt->add_device_parameters : "", + p ? : "", (devt->add_device_parameters != NULL) ? "\n" : "", (devt->devt_optional_attributes != NULL) ? "The following dev handler attributes available: " : "", @@ -5811,6 +5832,8 @@ static ssize_t scst_devt_mgmt_show(struct kobject *kobj, (devt->dev_optional_attributes != NULL) ? devt->dev_optional_attributes : "", (devt->dev_optional_attributes != NULL) ? "\n" : ""); + kfree(p); + return res; } static int scst_process_devt_mgmt_store(char *buffer, diff --git a/scst/src/scst_tg.c b/scst/src/scst_tg.c index bdd8437ba..719e4d336 100644 --- a/scst/src/scst_tg.c +++ b/scst/src/scst_tg.c @@ -1403,6 +1403,11 @@ out: return dg; } +struct scst_dev_group *scst_lookup_dg_by_dev(struct scst_device *dev) +{ + return __lookup_dg_by_dev(dev); +} + /* * Target group module management. diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm b/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm index e73570395..75d14a76a 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm @@ -5,7 +5,7 @@ package SCST::SCST; # Author: Mark R. Buechler # License: GPLv2 # Copyright (c) 2005-2011 Mark R. Buechler -# Copyright (c) 2011-2015 Bart Van Assche . +# Copyright (c) 2011-2019 Bart Van Assche . use 5.005; use Fcntl ':mode'; @@ -422,7 +422,7 @@ sub scstVersion { sub scstAttributes { my $self = shift; - my %attributes; + my %attributes = ( ); my $pHandle = new IO::Handle; my $_path = SCST_ROOT_DIR(); @@ -458,7 +458,8 @@ sub scstAttributes { } my $value = <$io>; - chomp $value if (defined($value)); + $value = "" if (!defined($value)); + chomp $value; my $is_key = <$io>; $is_key = new_sysfs_interface() && !$is_static || @@ -556,6 +557,7 @@ sub drivers { push @drivers, $driver; } } + @drivers = sort(@drivers); close $dHandle; } else { return (undef, "drivers(): Unable to read directory '$_path': $!"); @@ -643,6 +645,7 @@ sub initiators { my $target = shift; my $group = shift; my @initiators; + my $errorString; return (undef, "Too few arguments") if (!defined($driver) || !defined($target) || !defined($group)); @@ -651,7 +654,6 @@ sub initiators { my $_path = make_path(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group, SCST_INITIATORS); if (!(opendir $iHandle, $_path)) { - my $errorString; if ($self->driverExists($driver) != TRUE) { $errorString = "initiators(): Driver '$driver' is not available"; } elsif ($self->targetExists($driver, $target) != TRUE) { @@ -681,6 +683,7 @@ sub luns { my $driver = shift; my $target = shift; my $group = shift; + my $errorString; return (undef, "Too few arguments") if (!defined($driver) || !defined($target)); @@ -697,7 +700,6 @@ sub luns { my $lHandle = new IO::Handle; if (!(opendir $lHandle, $_path)) { - my $errorString; if (defined($group) && $self->groupExists($driver, $target, $group) != TRUE) { $errorString = "initiators(): Group '$group' does not exist"; } elsif ($self->driverExists($driver) != TRUE) { @@ -745,7 +747,7 @@ sub luns { sub aluaAttributes { my $self = shift; - my %attributes; + my %attributes = ( ); my $pHandle = new IO::Handle; my $_path = SCST_DEV_GROUP_DIR(); @@ -767,13 +769,15 @@ sub aluaAttributes { my $io = new IO::File $pPath, O_RDONLY; if (!$io) { - return (undef, "deviceGroupsAttributes(): Unable to read device attribute '$attribute': $!"); + return (undef, "aluaAttributes(): Unable to read device attribute '$attribute': $!"); } my $value = <$io>; + $value = "" if (!defined($value)); chomp $value; my $second_line = <$io>; + $second_line = "" if (!defined($second_line)); if (new_sysfs_interface() && !$is_static || ($second_line =~ /\[key\]/)) { my $key = 0; @@ -823,13 +827,13 @@ sub deviceGroupDevices { my $self = shift; my $group = shift; my @devices; + my $errorString; return (undef, "Too few arguments") if (!defined($group)); my $dHandle = new IO::Handle; my $_path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_DEVICES); if (!(opendir $dHandle, $_path)) { - my $errorString; if ($self->deviceGroupExists($group) != TRUE) { $errorString = "deviceGroupDevices(): Device group '$group' does not exist"; } else { @@ -855,13 +859,13 @@ sub targetGroups { my $self = shift; my $group = shift; my @tgroups; + my $errorString; return (undef, "Too few arguments") if (!defined($group)); my $dHandle = new IO::Handle; my $_path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS); if (!(opendir $dHandle, $_path)) { - my $errorString; if ($self->deviceGroupExists($group) != TRUE) { $errorString = "targetGroups(): Device group '$group' does not exist"; } else { @@ -888,13 +892,13 @@ sub targetGroupTargets { my $group = shift; my $tgroup = shift; my @targets; + my $errorString; return (undef, "Too few arguments") if (!defined($group) || !defined($tgroup)); my $dHandle = new IO::Handle; my $_path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, $tgroup); if (!(opendir $dHandle, $_path)) { - my $errorString; if ($self->deviceGroupExists($group) != TRUE) { $errorString = "targetGroupTargets(): Device group '$group' does not exist"; } elsif ($self->targetGroupExists($group, $tgroup) != TRUE) { @@ -936,8 +940,9 @@ sub driverExists { sub driverDynamicAttributes { my $self = shift; my $driver = shift; - my %attributes; + my %attributes = ( ); my $available; + my $errorString; return (undef, "Too few arguments") if (!defined($driver)); @@ -956,7 +961,6 @@ sub driverDynamicAttributes { SCST_MGMT_IO), O_RDONLY; if (!$io) { - my $errorString; if ($self->driverExists($driver) != TRUE) { $errorString = "driverDynamicAttributes(): Driver '$driver' ". "is not available"; @@ -1139,11 +1143,13 @@ sub targetType { my $self = shift; my $driver = shift; my $target = shift; + my $errorString; return (undef, "Too few arguments") if (!defined($driver) || !defined($target)); if ($self->driverIsVirtualCapable($driver)) { - my ($attribs, $errorString) = $self->targetAttributes($driver, $target); + my $attribs; + ($attribs, $errorString) = $self->targetAttributes($driver, $target); if (defined($$attribs{'hw_target'}) && ($$attribs{'hw_target'}->{'value'} == TRUE)) { @@ -1217,8 +1223,9 @@ sub addVirtualTarget { sub targetDynamicAttributes { my $self = shift; my $driver = shift; - my %attributes; + my %attributes = ( ); my $available; + my $errorString; return (undef, "Too few arguments") if (!defined($driver)); @@ -1237,7 +1244,6 @@ sub targetDynamicAttributes { SCST_MGMT_IO), O_RDONLY; if (!$io) { - my $errorString; if ($self->driverExists($driver) != TRUE) { $errorString = "targetDynamicAttributes(): Driver '$driver' ". "is not available"; @@ -1723,6 +1729,8 @@ sub addDeviceGroupDevice { my $self = shift; my $group = shift; my $device = shift; + my $dgroups; + my $errorString; return SCST_C_DGRP_ADD_DEV_FAIL if (!defined($group) || !defined($device)); @@ -1761,11 +1769,11 @@ sub addDeviceGroupDevice { return $rc if ($rc > 1); # Check all device groups for this device - my ($dgroups, $errorString) = $self->deviceGroups(); - + ($dgroups, $errorString) = $self->deviceGroups(); foreach my $dgroup (@{$dgroups}) { - my ($devs, $errorString) = $self->deviceGroupDevices($dgroup); + my $devs; + ($devs, $errorString) = $self->deviceGroupDevices($dgroup); foreach my $dev (@{$devs}) { return SCST_C_DGRP_DEVICE_OTHER if ($dev eq $device); } @@ -2580,12 +2588,13 @@ sub deviceOpen { sub deviceAttributes { my $self = shift; my $device = shift; - my %attributes; + my %attributes = ( ); + my $errorString; + my $dca; my $pHandle = new IO::Handle; my $_path = make_path(SCST_DEVICES_DIR(), $device); if (!(opendir $pHandle, $_path)) { - my $errorString; if ($self->deviceOpen($device) != TRUE) { $errorString = "deviceAttributes(): Device '$device' is not open"; } else { @@ -2594,7 +2603,7 @@ sub deviceAttributes { return (undef, $errorString); } - my ($dca, $errorString) = $self->deviceCreateAttributes($self->deviceHandler($device)); + ($dca, $errorString) = $self->deviceCreateAttributes($self->deviceHandler($device)); foreach my $attribute (readdir($pHandle)) { next if ($attribute eq '.' || $attribute eq '..' || @@ -2625,6 +2634,7 @@ sub deviceAttributes { } elsif ($linked =~ /^(\.\.\/)*$t\/([^\/]+)\/([^\/]+)\/$l\/(\d+)$/) { $driver = $2; $target = $3; + $group = ""; $lun = $4; } else { print("internal error: could not parse $linked\n"); @@ -2716,12 +2726,12 @@ sub deviceAttributes { sub driverAttributes { my $self = shift; my $driver = shift; - my %attributes; + my %attributes = ( ); + my $errorString; my $pHandle = new IO::Handle; my $_path = make_path(SCST_TARGETS_DIR(), $driver); if (!(opendir $pHandle, $_path)) { - my $errorString; if ($self->driverExists($driver) != TRUE) { $errorString = "driverAttributes(): Driver '$driver' is not available"; } else { @@ -2758,6 +2768,7 @@ sub driverAttributes { } my $value = <$io>; + $value = "" if (!defined($value)); chomp $value; my $is_key = <$io>; @@ -2847,14 +2858,14 @@ sub targetAttributes { my $self = shift; my $driver = shift; my $target = shift; - my %attributes; + my %attributes = ( ); + my $errorString; return (undef, "Too few arguments") if (!defined($driver) || !defined($target)); my $pHandle = new IO::Handle; my $_path = make_path(SCST_TARGETS_DIR(), $driver, $target); if (!(opendir $pHandle, $_path)) { - my $errorString; if ($self->driverExists($driver) != TRUE) { $errorString = "targetAttributes(): Driver '$driver' is not available"; } elsif ($self->targetExists($driver, $target) != TRUE) { @@ -2914,7 +2925,8 @@ sub targetAttributes { } my $value = <$io>; - chomp $value if (defined($value)); + $value = "" if (!defined($value)); + chomp $value; my $is_key = <$io>; close $io; @@ -2999,13 +3011,13 @@ sub groupAttributes { my $driver = shift; my $target = shift; my $group = shift; - my %attributes; + my %attributes = ( ); + my $errorString; my $pHandle = new IO::Handle; my $_path = make_path(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group); if (!(opendir $pHandle, $_path)) { - my $errorString; if ($self->driverExists($driver) != TRUE) { $errorString = "groupAttributes(): Driver '$driver' is not available"; } elsif ($self->targetExists($driver, $target) != TRUE) { @@ -3048,6 +3060,7 @@ sub groupAttributes { } my $value = <$io>; + $value = "" if (!defined($value)); chomp $value; my $is_key = <$io>; @@ -3138,7 +3151,7 @@ sub lunAttributes { my $lun = shift; my $group = shift; my $errorString; - my %attributes; + my %attributes = ( ); my ($_path, $luncrattr); @@ -3203,6 +3216,7 @@ sub lunAttributes { } my $value = <$io>; + $value = "" if (!defined($value)); chomp $value; my $is_key = <$io>; @@ -3307,13 +3321,13 @@ sub initiatorAttributes { my $target = shift; my $group = shift; my $initiator = shift; - my %attributes; + my %attributes = ( ); + my $errorString; my $pHandle = new IO::Handle; my $_path = make_path(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group, SCST_INITIATORS, $initiator); if (!(opendir $pHandle, $_path)) { - my $errorString; if ($self->driverExists($driver) != TRUE) { $errorString = "initiatorAttributes(): Driver '$driver' is not available"; } elsif ($self->targetExists($driver, $target) != TRUE) { @@ -3357,6 +3371,7 @@ sub initiatorAttributes { } my $value = <$io>; + $value = "" if (!defined($value)); chomp $value; my $is_key = <$io>; @@ -3438,12 +3453,12 @@ sub setInitiatorAttribute { sub deviceGroupAttributes { my $self = shift; my $group = shift; - my %attributes; + my %attributes = ( ); + my $errorString; my $pHandle = new IO::Handle; my $_path = make_path(SCST_DEV_GROUP_DIR(), $group); if (!(opendir $pHandle, $_path)) { - my $errorString; if ($self->deviceGroupExists($group) != TRUE) { $errorString = "deviceGroupAttributes(): Device group '$group' does not exist"; } else { @@ -3479,6 +3494,7 @@ sub deviceGroupAttributes { } my $value = <$io>; + $value = "" if (!defined($value)); chomp $value; my $is_key = <$io>; @@ -3516,12 +3532,12 @@ sub targetGroupAttributes { my $self = shift; my $group = shift; my $tgroup = shift; - my %attributes; + my %attributes = ( ); + my $errorString; my $pHandle = new IO::Handle; my $_path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, $tgroup); if (!(opendir $pHandle, $_path)) { - my $errorString; if ($self->deviceGroupExists($group) != TRUE) { $errorString = "targetGroupAttributes(): Device group '$group' does not exist"; } elsif ($self->targetGroupExists($group, $tgroup) != TRUE) { @@ -3559,6 +3575,7 @@ sub targetGroupAttributes { } my $value = <$io>; + $value = "" if (!defined($value)); chomp $value; my $is_key = <$io>; @@ -3598,7 +3615,8 @@ sub targetGroupTargetAttributes { my $tgroup = shift; my $tgt = shift; my $local_tgt = shift; - my %attributes; + my %attributes = ( ); + my $errorString; my $pHandle = new IO::Handle; my $_path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, $tgroup, $tgt); @@ -3607,7 +3625,6 @@ sub targetGroupTargetAttributes { } if (!(opendir $pHandle, $_path)) { - my $errorString; if ($self->deviceGroupExists($group) != TRUE) { $errorString = "targetGroupTargetAttributes(): Device group '$group' does not exist"; } elsif ($self->targetGroupExists($group, $tgroup) != TRUE) { @@ -3648,6 +3665,7 @@ sub targetGroupTargetAttributes { } my $value = <$io>; + $value = "" if (!defined($value)); chomp $value; my $is_key = <$io>; @@ -3834,6 +3852,8 @@ sub handlers { close $hHandle; + @handlers = sort(@handlers); + return (\@handlers, undef); } @@ -3886,15 +3906,16 @@ sub setHandlerAttribute { sub handlerAttributes { my $self = shift; my $handler = shift; - my %attributes; + my %attributes = ( ); + my $errorString; + my $a; - my ($a, $errorString) = devices($self, $handler); + ($a, $errorString) = devices($self, $handler); $attributes{'devices'}->{'value'} = $a; my $hHandle = new IO::Handle; my $_path = make_path(SCST_HANDLERS_DIR(), $handler); if (!(opendir $hHandle, $_path)) { - my $errorString; if ($self->handlerExists($handler) != TRUE) { $errorString = "handlerAttributes(): Handler '$handler' is not available"; } else { @@ -3927,7 +3948,8 @@ sub handlerAttributes { } my $value = <$io>; - chomp $value if (defined($value)); + $value = "" if (!defined($value)); + chomp $value; my $is_key = <$io>; $is_key = new_sysfs_interface() && !$is_static || @@ -4035,11 +4057,11 @@ sub handlerDeviceExists { sub devicesByHandler { my $self = shift; my $handler = shift; + my $errorString; + my $attributes; - my ($attributes, $errorString) = $self->handlerAttributes($handler); - + ($attributes, $errorString) = $self->handlerAttributes($handler); if (!defined($attributes)) { - my $errorString; if ($self->handlerExists($handler) != TRUE) { $errorString = "devicesByHandler(): Handler '$handler' is not available"; } else { @@ -4086,7 +4108,8 @@ sub deviceCreateAttributes { my $self = shift; my $handler = shift; my $available; - my %attributes; + my %attributes = ( ); + my $errorString; if (new_sysfs_interface()) { my $io = new IO::File make_path(SCST_HANDLERS_DIR(), $handler, @@ -4102,7 +4125,6 @@ sub deviceCreateAttributes { SCST_MGMT_IO), O_RDONLY; if (!$io) { - my $errorString; if ($self->handlerExists($handler) != TRUE) { $errorString = "deviceCreateAttributes(): Handler '$handler' ". "is not available"; @@ -4306,7 +4328,8 @@ sub targetCreateAttributes { my $self = shift; my $driver = shift; my $available; - my %attributes; + my %attributes = ( ); + my $errorString; if (new_sysfs_interface()) { my $io = new IO::File make_path(SCST_TARGETS_DIR(), $driver, @@ -4321,7 +4344,6 @@ sub targetCreateAttributes { SCST_MGMT_IO), O_RDONLY; if (!$io) { - my $errorString; if ($self->driverExists($driver) != TRUE) { $errorString = "targetCreateAttributes(): Driver '$driver' ". "is not available"; @@ -4498,7 +4520,8 @@ sub lunCreateAttributes { my $target = shift; my $group = shift; my $available; - my %attributes; + my %attributes = ( ); + my $errorString; my $_path; @@ -4536,7 +4559,6 @@ sub lunCreateAttributes { my $io = new IO::File $_path, O_RDONLY; if (!$io) { - my $errorString; if ($self->driverExists($driver) != TRUE) { $errorString = "lunCreateAttributes(): Driver '$driver' ". "is not available"; @@ -4620,7 +4642,8 @@ sub initiatorCreateAttributes { my $target = shift; my $group = shift; my $available; - my %attributes; + my %attributes = ( ); + my $errorString; if (new_sysfs_interface()) { # Do nothing - there are no initiator attributes (yet). @@ -4631,7 +4654,6 @@ sub initiatorCreateAttributes { O_RDONLY; if (!$io) { - my $errorString; if ($self->driverExists($driver) != TRUE) { $errorString = "initiatorCreateAttributes(): Driver '$driver' ". "is not available"; @@ -4673,6 +4695,7 @@ sub sessions { my $driver = shift; my $target = shift; my %_sessions; + my $errorString; return (undef, "Too few arguments") if (!defined($driver) || !defined($target)); @@ -4680,7 +4703,6 @@ sub sessions { my $_path = make_path(SCST_TARGETS_DIR(), $driver, $target, SCST_SESSIONS); if (!(opendir $sHandle, $_path)) { - my $errorString; if ($self->driverExists($driver) != TRUE) { $errorString = "sessions(): Driver '$driver' ". "is not available"; @@ -4744,8 +4766,9 @@ sub sessions { } my $value = <$io>; - close $io; + $value = "" if (!defined($value)); chomp $value; + close $io; $_sessions{$session}->{$attribute}->{'value'} = $value; $_sessions{$session}->{$attribute}->{'static'} = $is_static; diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/01-start-scst.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/01-start-scst.t index 34bf666bb..661c968d9 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/01-start-scst.t +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/01-start-scst.t @@ -1,6 +1,7 @@ #!perl use strict; +use warnings; use Test; BEGIN { diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/02-scst-attr.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/02-scst-attr.t index 267423138..372c70e87 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/02-scst-attr.t +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/02-scst-attr.t @@ -1,6 +1,7 @@ #!perl use strict; +use warnings; use Test; BEGIN { diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/03-targets.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/03-targets.t index d07b11a34..095232154 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/03-targets.t +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/03-targets.t @@ -1,6 +1,7 @@ #!perl use strict; +use warnings; use Test; BEGIN { @@ -13,11 +14,13 @@ use SCST::SCST; sub addTargets { my $SCST = shift; + my $errorString; ok(Dumper($SCST->targets('no-such-driver')), Dumper(undef, "targets(): Driver 'no-such-driver' is not available")); - my ($drivers, $errorString) = $SCST->drivers(); + my $drivers; + ($drivers, $errorString) = $SCST->drivers(); my %drivers = map { $_ => 1 } @{$drivers}; ok(exists($drivers{'iscsi'})); ok(exists($drivers{'scst_local'})); @@ -25,7 +28,8 @@ sub addTargets { my $all_hw_tgt = 1; for my $driver (@{$drivers}) { next if $driver eq 'copy_manager'; - my ($targets, $errorString) = $SCST->targets($driver); + my $targets; + ($targets, $errorString) = $SCST->targets($driver); for my $target (@{$targets}) { if ($SCST->targetType($driver, $target) != $SCST::SCST::TGT_TYPE_HARDWARE) { diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/04-alua.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/04-alua.t index 72db337a2..04843eb67 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/04-alua.t +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/04-alua.t @@ -1,6 +1,7 @@ #!perl use strict; +use warnings; use Test; BEGIN { diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/05-dynattr.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/05-dynattr.t index d31c739bf..c4cd84585 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/05-dynattr.t +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/05-dynattr.t @@ -1,6 +1,7 @@ #!perl use strict; +use warnings; use Test; BEGIN { diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-cont-on-err.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-cont-on-err.t index 3bc6fd6b7..8027c5a68 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-cont-on-err.t +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-cont-on-err.t @@ -1,6 +1,7 @@ #!perl use strict; +use warnings; use Cwd qw(abs_path); use File::Basename; use File::Spec; @@ -10,8 +11,12 @@ my $testdir; my $scstadmin_pm_dir; my $scstadmin_dir; my $scstadmin; +my $redirect_file; +my $redirect; BEGIN { + $redirect_file = "/tmp/scstadmin-test-06-output.txt"; + unlink($redirect_file); $testdir = dirname(abs_path($0)); $scstadmin_pm_dir = dirname($testdir); $scstadmin_dir = dirname($scstadmin_pm_dir); @@ -19,7 +24,7 @@ BEGIN { unless(grep /blib/, @INC) { unshift(@INC, File::Spec->catdir($scstadmin_pm_dir, "lib")); } - plan tests => 2; + plan tests => 5; } use Data::Dumper; @@ -44,11 +49,17 @@ sub testRestoreConfig { my $diff = File::Spec->catfile(File::Spec->tmpdir(), "scstadmin-test-06-$$-diff"); - system("$scstadmin -clear_config -force -noprompt -no_lip >/dev/null"); + ok(system("$scstadmin -clear_config -force -noprompt -no_lip $redirect"), 0); system("$scstadmin -cont_on_err -no_lip -config $to_be_restored" . " >/dev/null"); - system("$scstadmin -write_config $tmpfilename1 >/dev/null"); - system("awk 'BEGIN {t = 0 } /^# Automatically generated by SCST Configurator v/ { \$0 = \"# Automatically generated by SCST Configurator v...\" } /^TARGET_DRIVER.*{\$/ { if (\$0 != \"TARGET_DRIVER scst_local {\") t = 1 } /^}\$/ { if (t == 1) t = 2 } /^\$/ { if (t == 2) { t = 3 } } /^./ { if (t == 3) { t = 0 } } { if (t == 0) print }' <$tmpfilename1 >$tmpfilename2"); + ok(system("$scstadmin -write_config $tmpfilename1 >/dev/null"), 0); + ok(system("awk 'BEGIN {t = 0 } /^# Automatically generated by SCST Configurator v/ " . + '{ $0 = "# Automatically generated by SCST Configurator v..." } ' . + '/^TARGET_DRIVER.*{$/ { if ($0 != "TARGET_DRIVER scst_local {") t = 1 } ' . + '/^}$/ { if (t == 1) t = 2 }' . + '/^$/ { if (t == 2) { t = 3 } }' . + '/^./ { if (t == 3) { t = 0 } }' . + "{ if (t == 0) print }' <$tmpfilename1 >$tmpfilename2"), 0); my $compare_result = system("diff -u $tmpfilename2 $expected >$diff"); ok($compare_result, 0); if ($compare_result == 0) { @@ -59,6 +70,13 @@ sub testRestoreConfig { } my $_DEBUG_ = 0; +if ($_DEBUG_) { + $redirect = ">>$redirect_file"; + open(my $logfile, '>>', $redirect_file); + select $logfile; +} else { + $redirect = ">/dev/null"; +} my $SCST = eval { new SCST::SCST($_DEBUG_) }; die("Creation of SCST object failed") if (!defined($SCST)); diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-result.conf b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-result.conf index 8bee55a95..01383a020 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-result.conf +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-result.conf @@ -36,3 +36,39 @@ TARGET_DRIVER scst_local { } } +DEVICE_GROUP dgroup1 { + TARGET_GROUP tgroup1 { + group_id 256 + state active + + TARGET local + } + + TARGET_GROUP tgroup2 { + group_id 257 + state active + + TARGET remote { + rel_tgt_id 11 + } + } +} + +DEVICE_GROUP dgroup2 { + TARGET_GROUP tgroup1 { + group_id 258 + state active + + TARGET local + } + + TARGET_GROUP tgroup2 { + group_id 259 + state active + + TARGET remote { + rel_tgt_id 12 + } + } +} + diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-scstadmin-args.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-scstadmin-args.t index 2178c7344..8d299cbd1 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-scstadmin-args.t +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-scstadmin-args.t @@ -1,6 +1,7 @@ #!perl use strict; +use warnings; use Cwd qw(abs_path); use File::Basename; use File::Spec; @@ -21,7 +22,7 @@ BEGIN { unless(grep /blib/, @INC) { unshift(@INC, File::Spec->catdir($scstadmin_pm_dir, "lib")); } - plan tests => 2; + plan tests => 59; } use Data::Dumper; @@ -34,7 +35,7 @@ sub setup { my ($drivers, $errorString) = $SCST->drivers(); my %drivers = map { $_ => 1 } @{$drivers}; ok(exists($drivers{'scst_local'})); - system("dd if=/dev/zero of=/dev/scstadmin-regression-test-vdisk bs=1M count=1 >/dev/null 2>&1"); + ok(system("dd if=/dev/zero of=/dev/scstadmin-regression-test-vdisk bs=1M count=1 >/dev/null 2>&1"), 0); } sub teardown { @@ -50,26 +51,55 @@ sub attributeTest { my $diff = File::Spec->catfile(File::Spec->tmpdir(), "scstadmin-test-07-$$-diff"); - system("$scstadmin -clear_config -force -noprompt -no_lip $redirect"); - system("$scstadmin -open_dev nodev -handler vdisk_nullio -attributes dummy=1 $redirect"); - system("$scstadmin -open_dev disk0 -handler vdisk_fileio -attributes filename=/dev/scstadmin-regression-test-vdisk,read_only=1 $redirect"); - system("$scstadmin -open_dev disk1 -handler vdisk_fileio -attributes filename=/dev/scstadmin-regression-test-vdisk,nv_cache=1 $redirect"); - system("$scstadmin -driver scst_local -add_target local $redirect"); - system("$scstadmin -driver scst_local -target local " . - "-add_lun 0 -device nodev $redirect"); - system("$scstadmin -driver scst_local -target local -add_group ig " . - "$redirect"); - system("$scstadmin -driver scst_local -target local -group ig " . - "-add_init ini1 $redirect"); - system("$scstadmin -driver scst_local -target local -group ig " . - "-add_init ini2 $redirect"); - system("$scstadmin -driver scst_local -target local -group ig " . - "-add_lun 0 -device disk0 $redirect"); - system("$scstadmin -driver scst_local -target local -group ig " . - "-add_lun 1 -device disk1 $redirect"); - system("$scstadmin -write_config $tmpfilename1 >/dev/null"); + ok(system("$scstadmin -clear_config -force -noprompt -no_lip $redirect"), 0); + ok(system("$scstadmin -open_dev nodev -handler vdisk_nullio -attributes dummy=1 $redirect"), 0); + ok(system("$scstadmin -open_dev disk0 -handler vdisk_fileio -attributes filename=/dev/scstadmin-regression-test-vdisk,read_only=1 $redirect"), 0); + ok(system("$scstadmin -open_dev disk1 -handler vdisk_fileio -attributes filename=/dev/scstadmin-regression-test-vdisk,nv_cache=1 $redirect"), 0); + ok(system("$scstadmin -driver scst_local -add_target local $redirect"), 0); + ok(system("$scstadmin -driver scst_local -target local " . + "-add_lun 0 -device nodev $redirect"), 0); + ok(system("$scstadmin -driver scst_local -target local -add_group ig " . + "$redirect"), 0); + ok(system("$scstadmin -driver scst_local -target local -group ig " . + "-add_init ini1 $redirect"), 0); + ok(system("$scstadmin -driver scst_local -target local -group ig " . + "-add_init ini2 $redirect"), 0); + ok(system("$scstadmin -driver scst_local -target local -group ig " . + "-add_lun 0 -device disk0 $redirect"), 0); + ok(system("$scstadmin -driver scst_local -target local -group ig " . + "-add_lun 1 -device disk1 $redirect"), 0); + + ok(system("$scstadmin -add_dgrp dgroup1 $redirect"), 0); + ok(system("$scstadmin -add_tgrp tgroup1 -dev_group dgroup1 $redirect"), 0); + ok(system("$scstadmin -noprompt -set_tgrp_attr tgroup1 -dev_group dgroup1 -attributes group_id=256 $redirect"), 0); + ok(system("$scstadmin -add_tgrp_tgt local -dev_group dgroup1 -tgt_group tgroup1 $redirect"), 0); + ok(system("$scstadmin -add_tgrp tgroup2 -dev_group dgroup1 $redirect"), 0); + ok(system("$scstadmin -noprompt -set_tgrp_attr tgroup2 -dev_group dgroup1 -attributes group_id=257 $redirect"), 0); + ok(system("$scstadmin -add_tgrp_tgt remote -dev_group dgroup1 -tgt_group tgroup2 $redirect"), 0); + ok(system("{ echo 11 > /sys/kernel/scst_tgt/device_groups/dgroup1/target_groups/tgroup2/remote/rel_tgt_id; } $redirect"), 0); + + ok(system("$scstadmin -add_dgrp dgroup2 $redirect"), 0); + ok(system("$scstadmin -add_tgrp tgroup1 -dev_group dgroup2 $redirect"), 0); + ok(system("$scstadmin -noprompt -set_tgrp_attr tgroup1 -dev_group dgroup2 -attributes group_id=258 $redirect"), 0); + ok(system("$scstadmin -add_tgrp_tgt local -dev_group dgroup2 -tgt_group tgroup1 $redirect"), 0); + ok(system("$scstadmin -add_tgrp tgroup2 -dev_group dgroup2 $redirect"), 0); + ok(system("$scstadmin -noprompt -set_tgrp_attr tgroup2 -dev_group dgroup2 -attributes group_id=259 $redirect"), 0); + ok(system("$scstadmin -noprompt -set_tgrp_attr tgroup1 -dev_group dgroup2 -attributes rel_tgt_id=2 $redirect"), 0); + ok(system("$scstadmin -add_tgrp_tgt remote -dev_group dgroup2 -tgt_group tgroup2 $redirect"), 0); + ok(system("{ echo 12 > /sys/kernel/scst_tgt/device_groups/dgroup2/target_groups/tgroup2/remote/rel_tgt_id; } $redirect"), 0); + + ok(system("$scstadmin -write_config $tmpfilename1 >/dev/null"), 0); + # Keep only the scst_local target driver information. - system("awk 'BEGIN { t = 0 } /^# Automatically generated by SCST Configurator v/ { \$0 = \"# Automatically generated by SCST Configurator v...\" } /^TARGET_DRIVER.*{\$/ { if (match(\$0, \"TARGET_DRIVER ([^ ]*) {\", d) && d[1] != \"scst_local\") t = 1 } /^}\$/ { if (t == 1) t = 2 } /^\$/ { if (t == 2) { t = 3 } } /^./ { if (t == 3) { t = 0 } } { if (t == 0) print }' <$tmpfilename1 >$tmpfilename2"); + my $cmd = "gawk 'BEGIN { t = 0 } /^# Automatically generated by SCST Configurator v/ {" . + '$0 = "# Automatically generated by SCST Configurator v..." } ' . + '/^TARGET_DRIVER.*{$/ { if (match($0, "TARGET_DRIVER ([^ ]*) {", d) && d[1] != "scst_local") t = 1 } ' . + '/^}$/ { if (t == 1) t = 2 } ' . + '/^$/ { if (t == 2) { t = 3 } } ' . + '/^./ { if (t == 3) { t = 0 } } ' . + '{ if (t == 0) print }' . + "' <$tmpfilename1 >$tmpfilename2"; + ok(system($cmd), 0); my $compare_result = system("diff -u $tmpfilename2 $expected >$diff"); ok($compare_result, 0); if ($compare_result == 0) { @@ -79,9 +109,506 @@ sub attributeTest { } } +# Run shell command $1 and return what it wrote to stdout and stderr as a +# string. +sub run { + my ($cmd) = @_; + my $tmpfile = File::Spec->catfile(File::Spec->tmpdir(), + "scstadmin-test-07-$$-3"); + my $res; + my $rc; + + $rc = system("$cmd >$tmpfile 2>&1"); + if (!open(my $file, $tmpfile)) { + $res = "failed to read $tmpfile"; + } else { + local $/ = undef; + binmode $file; + $res = <$file>; + if (!defined($res)) { + $res = ""; + } + close $file; + } + unlink($tmpfile); + return $res; +} + +# Trigger the scstadmin prompt() subroutine. +sub testPrompt { + my $result; + + $result = <<'EOS'; + +Collecting current configuration: done. + +Performing this action may result in lost or corrupt data, are you sure you wish to continue (y/[n]) ? Aborting action. + +All done. +EOS + ok(run("$scstadmin -clear_config -force >', $redirect_file); select $logfile; } else { @@ -95,4 +622,8 @@ setup($SCST); attributeTest(File::Spec->catfile($testdir, "07-result.conf")); +testPrompt(); + +listTest(); + teardown(); diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/08-scstadmin-close-dev.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/08-scstadmin-close-dev.t index cac3a5e02..45f97bb08 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/08-scstadmin-close-dev.t +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/08-scstadmin-close-dev.t @@ -1,6 +1,7 @@ #!perl use strict; +use warnings; use Cwd qw(abs_path); use File::Basename; use File::Spec; @@ -21,7 +22,7 @@ BEGIN { unless(grep /blib/, @INC) { unshift(@INC, File::Spec->catdir($scstadmin_pm_dir, "lib")); } - plan tests => 9; + plan tests => 24; } use Data::Dumper; @@ -34,7 +35,7 @@ sub setup { my ($drivers, $errorString) = $SCST->drivers(); my %drivers = map { $_ => 1 } @{$drivers}; ok(exists($drivers{'scst_local'})); - system("dd if=/dev/zero of=/dev/scstadmin-regression-test-vdisk bs=1M count=1 >/dev/null 2>&1"); + ok(system("dd if=/dev/zero of=/dev/scstadmin-regression-test-vdisk bs=1M count=1 >/dev/null 2>&1"), 0); } sub teardown { @@ -45,7 +46,13 @@ sub filterScstLocal { my $in = shift; my $out = shift; - system("awk 'BEGIN { t = 0 } /^# Automatically generated by SCST Configurator v/ { \$0 = \"# Automatically generated by SCST Configurator v...\" } /^TARGET_DRIVER.*{\$/ { if (match(\$0, \"TARGET_DRIVER ([^ ]*) {\", d) && d[1] != \"scst_local\") t = 1 } /^}\$/ { if (t == 1) t = 2 } /^\$/ { if (t == 2) { t = 3 } } /^./ { if (t == 3) { t = 0 } } { if (t == 0) print }' <" . '"' . "$in" . '" >"' . "$out" . '"'); + ok(system("awk 'BEGIN { t = 0 } /^# Automatically generated by SCST Configurator v/ " . + '{ $0 = "# Automatically generated by SCST Configurator v..." } ' . + '/^TARGET_DRIVER.*{$/ { if (match($0, "TARGET_DRIVER ([^ ]*) {", d) && d[1] != "scst_local") t = 1 } ' . + '/^}$/ { if (t == 1) t = 2 }' . + '/^$/ { if (t == 2) { t = 3 } }' . + '/^./ { if (t == 3) { t = 0 } } ' . + "{ if (t == 0) print }' <" . '"' . "$in" . '" >"' . "$out" . '"'), 0); } sub closeDevs { @@ -67,27 +74,27 @@ sub closeDevTest { "scstadmin-test-08-$$-2"); my $rc; - system("$scstadmin -clear_config -force -noprompt -no_lip $redirect"); - system("$scstadmin -open_dev nodev -handler vdisk_nullio -attributes dummy=1 $redirect"); - system("$scstadmin -open_dev disk0 -handler vdisk_fileio -attributes filename=/dev/scstadmin-regression-test-vdisk,read_only=1 $redirect"); - system("$scstadmin -open_dev disk1 -handler vdisk_fileio -attributes filename=/dev/scstadmin-regression-test-vdisk,nv_cache=1 $redirect"); - system("$scstadmin -driver scst_local -add_target local $redirect"); - system("$scstadmin -driver scst_local -target local " . - "-add_lun 0 -device nodev $redirect"); - system("$scstadmin -driver scst_local -target local -add_group ig " . - "$redirect"); - system("$scstadmin -driver scst_local -target local -group ig " . - "-add_init ini1 $redirect"); - system("$scstadmin -driver scst_local -target local -group ig " . - "-add_init ini2 $redirect"); - system("$scstadmin -driver scst_local -target local -group ig " . - "-add_lun 0 -device disk0 $redirect"); - system("$scstadmin -driver scst_local -target local -group ig " . - "-add_lun 1 -device disk1 $redirect"); - system("$scstadmin -write_config $tmpfilename1 >/dev/null"); + ok(system("$scstadmin -clear_config -force -noprompt -no_lip $redirect"), 0); + ok(system("$scstadmin -open_dev nodev -handler vdisk_nullio -attributes dummy=1 $redirect"), 0); + ok(system("$scstadmin -open_dev disk0 -handler vdisk_fileio -attributes filename=/dev/scstadmin-regression-test-vdisk,read_only=1 $redirect"), 0); + ok(system("$scstadmin -open_dev disk1 -handler vdisk_fileio -attributes filename=/dev/scstadmin-regression-test-vdisk,nv_cache=1 $redirect"), 0); + ok(system("$scstadmin -driver scst_local -add_target local $redirect"), 0); + ok(system("$scstadmin -driver scst_local -target local " . + "-add_lun 0 -device nodev $redirect"), 0); + ok(system("$scstadmin -driver scst_local -target local -add_group ig " . + "$redirect"), 0); + ok(system("$scstadmin -driver scst_local -target local -group ig " . + "-add_init ini1 $redirect"), 0); + ok(system("$scstadmin -driver scst_local -target local -group ig " . + "-add_init ini2 $redirect"), 0); + ok(system("$scstadmin -driver scst_local -target local -group ig " . + "-add_lun 0 -device disk0 $redirect"), 0); + ok(system("$scstadmin -driver scst_local -target local -group ig " . + "-add_lun 1 -device disk1 $redirect"), 0); + ok(system("$scstadmin -write_config $tmpfilename1 >/dev/null"), 0); # Keep only the scst_local target driver information. filterScstLocal("$tmpfilename1", "$tmpfilename2"); - system("cd /sys/kernel/scst_tgt && find -ls $redirect"); + ok(system("cd /sys/kernel/scst_tgt && find -ls $redirect"), 0); $rc = system("$scstadmin -dumpAttrs $redirect"); ok($rc, 0); $rc = closeDevs("nodev"); diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/09-scstadmin-invalid-args.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/09-scstadmin-invalid-args.t new file mode 100644 index 000000000..8ab2fc455 --- /dev/null +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/09-scstadmin-invalid-args.t @@ -0,0 +1,167 @@ +#!perl + +use strict; +use warnings; +use Cwd qw(abs_path); +use File::Basename; +use File::Spec; +use Test; + +my $testdir; +my $scstadmin_pm_dir; +my $scstadmin_dir; +my $scstadmin; +my $redirect_file; +my $redirect; + +BEGIN { + $redirect_file = "/tmp/scstadmin-test-06-output.txt"; + unlink($redirect_file); + $testdir = dirname(abs_path($0)); + $scstadmin_pm_dir = dirname($testdir); + $scstadmin_dir = dirname($scstadmin_pm_dir); + $scstadmin = File::Spec->catfile($scstadmin_dir, "scstadmin"); + unless(grep /blib/, @INC) { + unshift(@INC, File::Spec->catdir($scstadmin_pm_dir, "lib")); + } + plan tests => 43; +} + +use SCST::SCST; + +sub setup { + my $SCST = shift; + + my ($drivers, $errorString) = $SCST->drivers(); + my %drivers = map { $_ => 1 } @{$drivers}; + ok(exists($drivers{'ib_srpt'})); +} + +# Run shell command $1 and return what it wrote to stdout and stderr as a +# string. +sub run { + my ($cmd) = @_; + my $tmpfile = File::Spec->catfile(File::Spec->tmpdir(), + "scstadmin-test-07-$$-3"); + my $res; + my $rc; + + $rc = system("$cmd >$tmpfile 2>&1"); + if (!open(my $file, $tmpfile)) { + $res = "failed to read $tmpfile"; + } else { + local $/ = undef; + binmode $file; + $res = <$file>; + if (!defined($res)) { + $res = ""; + } + close $file; + } + unlink($tmpfile); + return $res; +} + +sub testInvalidArgs { + ok(run("$scstadmin -open_dev -handler h -set_scst_attr $redirect"), + "Please specify only one non-query operation at a time.\n"); + ok(run("$scstadmin -clear_config $redirect"), + "Please specify -force with -clear_config.\n"); + ok(run("$scstadmin -list_tgrp $redirect"), + "Please specify -dev_group with -list_tgrp.\n"); + ok(run("$scstadmin -list_tgt_attr t $redirect"), + "Please specify -driver with -list_tgt_attr.\n"); + ok(run("$scstadmin -list_grp_attr g $redirect"), + "Please specify -driver, -target and group with -list_grp_attr.\n"); + ok(run("$scstadmin -list_lun_attr l $redirect"), + "Please specify -driver and -target with -list_lun_attr.\n"); + ok(run("$scstadmin -list_init_attr i $redirect"), + "Please specify -driver, -target and -group with -list_init_attr.\n"); + ok(run("$scstadmin -list_tgrp_attr tg $redirect"), + "Please specify -dev_group with -list_tgrp_attr.\n"); + ok(run("$scstadmin -list_ttgt_attr tt $redirect"), + "Please specify -dev_group and -tgt_group with -list_ttgt_attr.\n"); + ok(run("$scstadmin -set_scst_attr $redirect"), + "Please specify -attributes with -set_scst_attr.\n"); + ok(run("$scstadmin -set_hnd_attr h $redirect"), + "Please specify -attributes with -set_hnd_attr.\n"); + ok(run("$scstadmin -set_dev_attr d $redirect"), + "Please specify -attributes with -set_dev_attr.\n"); + ok(run("$scstadmin -set_dgrp_attr dg $redirect"), + "Please specify -attributes with -set_dgrp_attr.\n"); + ok(run("$scstadmin -set_tgrp_attr tg $redirect"), + "Please specify -dev_group and -attributes with -set_tgrp_attr.\n"); + ok(run("$scstadmin -set_drv_attr d $redirect"), + "Please specify -attributes with -set_drv_attr.\n"); + ok(run("$scstadmin -set_tgt_attr t $redirect"), + "Please specify -driver and -attributes with -set_tgt_attr.\n"); + ok(run("$scstadmin -set_lun_attr l $redirect"), + "Please specify -driver -target -group and -attributes with -set_lun_attr.\n"); + ok(run("$scstadmin -set_init_attr i $redirect"), + "Please specify -driver -target -group and -attributes with -set_init_attr.\n"); + ok(run("$scstadmin -add_drv_attr d $redirect"), + "Please specify -attributes with -add_drv_attr.\n"); + ok(run("$scstadmin -add_tgt_attr t $redirect"), + "Please specify -driver and -attributes with -add_tgt_attr.\n"); + ok(run("$scstadmin -rem_drv_attr d $redirect"), + "Please specify -attributes with -rem_drv_attr.\n"); + ok(run("$scstadmin -rem_tgt_attr t $redirect"), + "Please specify -driver and -attributes with -rem_tgt_attr.\n"); + ok(run("$scstadmin -open_dev d $redirect"), + "Please specify -handler with -open_dev/-close_dev.\n"); + ok(run("$scstadmin -close_dev d $redirect"), + "Please specify -handler with -open_dev/-close_dev.\n"); + ok(run("$scstadmin -add_target t $redirect"), + "Please specify -driver with -add_target.\n"); + ok(run("$scstadmin -rem_target t $redirect"), + "Please specify -driver with -rem_target.\n"); + ok(run("$scstadmin -add_group g $redirect"), + "Please specify -driver and -target with -add_group/-rem_group.\n"); + ok(run("$scstadmin -rem_group g $redirect"), + "Please specify -driver and -target with -add_group/-rem_group.\n"); + ok(run("$scstadmin -add_init i $redirect"), + "Please specify -driver -target and -group with -add_init/-rem_init/-clear_inits.\n"); + ok(run("$scstadmin -rem_init i $redirect"), + "Please specify -driver -target and -group with -add_init/-rem_init/-clear_inits.\n"); + ok(run("$scstadmin -clear_inits $redirect"), + "Please specify -driver -target and -group with -add_init/-rem_init/-clear_inits.\n"); + ok(run("$scstadmin -move_init i $redirect"), + "Please specify -driver -target -group and -to with -move_init.\n"); + ok(run("$scstadmin -add_lun l $redirect"), + "Please specify -driver -target and -device with -add_lun/-replace_lun.\n"); + ok(run("$scstadmin -replace_lun l $redirect"), + "Please specify -driver -target and -device with -add_lun/-replace_lun.\n"); + ok(run("$scstadmin -rem_lun l $redirect"), + "Please specify -driver and -target with -rem_lun/-clear_luns.\n"); + ok(run("$scstadmin -clear_luns $redirect"), + "Please specify -driver and -target with -rem_lun/-clear_luns.\n"); + ok(run("$scstadmin -add_dgrp_dev dg $redirect"), + "Please specify -dev_group with -add_dgrp_dev/-rem_dgrp_dev.\n"); + ok(run("$scstadmin -rem_dgrp_dev dg $redirect"), + "Please specify -dev_group with -add_dgrp_dev/-rem_dgrp_dev.\n"); + ok(run("$scstadmin -add_tgrp tg $redirect"), + "Please specify -dev_group with -add_tgrp/-rem_tgrp.\n"); + ok(run("$scstadmin -rem_tgrp tg $redirect"), + "Please specify -dev_group with -add_tgrp/-rem_tgrp.\n"); + ok(run("$scstadmin -add_tgrp_tgt t $redirect"), + "Please specify -dev_group and -tgt_group with -add_tgrp_tgt/-rem_tgrp_tgt.\n"); + ok(run("$scstadmin -rem_tgrp_tgt t $redirect"), + "Please specify -dev_group and -tgt_group with -add_tgrp_tgt/-rem_tgrp_tgt.\n"); +} + +my $_DEBUG_ = 0; +if ($_DEBUG_) { + $redirect = ">>$redirect_file"; + open(my $logfile, '>>', $redirect_file); + select $logfile; +} else { + $redirect = ">/dev/null"; +} + +my $SCST = eval { new SCST::SCST($_DEBUG_) }; +die("Creation of SCST object failed") if (!defined($SCST)); + +setup($SCST); + +testInvalidArgs; + diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/99-stop-scst.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/99-stop-scst.t index c2cad55cf..b8fca3d32 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/99-stop-scst.t +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/99-stop-scst.t @@ -1,6 +1,7 @@ #!perl use strict; +use warnings; use Test; BEGIN { diff --git a/scstadmin/scstadmin.sysfs/scstadmin b/scstadmin/scstadmin.sysfs/scstadmin index 078602551..89fbe6928 100755 --- a/scstadmin/scstadmin.sysfs/scstadmin +++ b/scstadmin/scstadmin.sysfs/scstadmin @@ -1,13 +1,13 @@ #!/usr/bin/perl -$Version = 'SCST Configurator v3.3.0-pre1'; +my $Version = 'SCST Configurator v3.3.0-pre1'; # Configures SCST # # Author: Mark R. Buechler # License: GPLv2 # Copyright (c) 2005-2011 Mark R. Buechler -# Copyright (C) 2011-2015 Bart Van Assche +# Copyright (C) 2011-2019 Bart Van Assche sub usage { @@ -536,178 +536,178 @@ sub getArgs { exit 1; } - if (defined($listTargetGroup) && ($deviceGroup eq '')) { + if (defined($listTargetGroup) && !defined($deviceGroup)) { print "Please specify -dev_group with -list_tgrp.\n"; exit 1; } - if (defined($listTargetAttr) && ($driver eq '')) { + if (defined($listTargetAttr) && !defined($driver)) { print "Please specify -driver with -list_tgt_attr.\n"; exit 1; } - if (defined($listGroupAttr) && (($driver eq '') || ($target eq ''))) { + if (defined($listGroupAttr) && (!defined($driver) || !defined($target))) { print "Please specify -driver, -target and group with -list_grp_attr.\n"; exit 1; } - if (defined($listLunAttr) && (($driver eq '') || ($target eq ''))) { + if (defined($listLunAttr) && (!defined($driver) || !defined($target))) { print "Please specify -driver and -target with -list_lun_attr.\n"; exit 1; } - if (defined($listInitiatorAttr) && (($driver eq '') || ($target eq '') || ($group eq ''))) { + if (defined($listInitiatorAttr) && (!defined($driver) || !defined($target) || !defined($group))) { print "Please specify -driver, -target and -group with -list_init_attr.\n"; exit 1; } - if (defined($listTargetGroupAttr) && ($deviceGroup eq '')) { + if (defined($listTargetGroupAttr) && !defined($deviceGroup)) { print "Please specify -dev_group with -list_tgrp_attr.\n"; exit 1; } - if (defined($listTargetGroupTargetAttr) && (($deviceGroup eq '') || ($targetGroup eq ''))) { + if (defined($listTargetGroupTargetAttr) && (!defined($deviceGroup) || !defined($targetGroup))) { print "Please specify -dev_group and -tgt_group with -list_ttgt_attr.\n"; exit 1; } - if (defined($setScstAttr) && ($attributes eq '')) { + if (defined($setScstAttr) && !defined($attributes)) { print "Please specify -attributes with -set_scst_attr.\n"; exit 1; } - if (defined($setHandlerAttr) && ($attributes eq '')) { + if (defined($setHandlerAttr) && !defined($attributes)) { print "Please specify -attributes with -set_hnd_attr.\n"; exit 1; } - if (defined($setDeviceAttr) && ($attributes eq '')) { + if (defined($setDeviceAttr) && !defined($attributes)) { print "Please specify -attributes with -set_dev_attr.\n"; exit 1; } - if (defined($setDeviceGroupAttr) && ($attributes eq '')) { + if (defined($setDeviceGroupAttr) && !defined($attributes)) { print "Please specify -attributes with -set_dgrp_attr.\n"; exit 1; } - if (defined($setTargetGroupAttr) && (($deviceGroup eq '') || ($attributes eq ''))) { + if (defined($setTargetGroupAttr) && (!defined($deviceGroup) || !defined($attributes))) { print "Please specify -dev_group and -attributes with -set_tgrp_attr.\n"; exit 1; } - if (defined($setTargetGroupTargetAttr) && (($deviceGroup eq '') || ($targetGroup eq '') || ($attributes eq ''))) { + if (defined($setTargetGroupTargetAttr) && (!defined($deviceGroup) || !defined($targetGroup) || !defined($attributes))) { print "Please specify -dev_group -tgt_group and -attributes with -set_ttgt_attr.\n"; exit 1; } - if (defined($setDriverAttr) && ($attributes eq '')) { + if (defined($setDriverAttr) && !defined($attributes)) { print "Please specify -attributes with -set_drv_attr.\n"; exit 1; } - if (defined($setTargetAttr) && (($driver eq '') || ($attributes eq ''))) { + if (defined($setTargetAttr) && (!defined($driver) || !defined($attributes))) { print "Please specify -driver and -attributes with -set_tgt_attr.\n"; exit 1; } - if (defined($setGroupAttr) && (($driver eq '') || ($target eq '') || ($attributes eq ''))) { + if (defined($setGroupAttr) && (!defined($driver) || !defined($target) || !defined($attributes))) { print "Please specify -driver -target and -attributes with -set_grp_attr.\n"; exit 1; } if (defined($setLunAttr) && - (($driver eq '') || ($target eq '') || ($attributes eq ''))) { + (!defined($driver) || !defined($target) || !defined($attributes))) { print "Please specify -driver -target -group and -attributes with -set_lun_attr.\n"; exit 1; } if (defined($setInitiatorAttr) && - (($driver eq '') || ($target eq '') || ($group eq '') || ($attributes eq ''))) { + (!defined($driver) || !defined($target) || !defined($group) || !defined($attributes))) { print "Please specify -driver -target -group and -attributes with -set_init_attr.\n"; exit 1; } - if (defined($addDriverAttr) && ($attributes eq '')) { + if (defined($addDriverAttr) && !defined($attributes)) { print "Please specify -attributes with -add_drv_attr.\n"; exit 1; } if (defined($addTargetAttr) && - (($driver eq '') || ($attributes eq ''))) { + (!defined($driver) || !defined($attributes))) { print "Please specify -driver and -attributes with -add_tgt_attr.\n"; exit 1; } - if (defined($remDriverAttr) && ($attributes eq '')) { + if (defined($remDriverAttr) && !defined($attributes)) { print "Please specify -attributes with -rem_drv_attr.\n"; exit 1; } if (defined($remTargetAttr) && - (($driver eq '') || ($attributes eq ''))) { + (!defined($driver) || !defined($attributes))) { print "Please specify -driver and -attributes with -rem_tgt_attr.\n"; exit 1; } - if ((defined($openDev) || defined($closeDev)) && ($handler eq '')) { + if ((defined($openDev) || defined($closeDev)) && !defined($handler)) { print "Please specify -handler with -open_dev/-close_dev.\n"; exit 1; } - if (defined($addTarget) && ($driver eq '')) { + if (defined($addTarget) && !defined($driver)) { print "Please specify -driver with -add_target.\n"; exit 1; } - if (defined($removeTarget) && ($driver eq '')) { + if (defined($removeTarget) && !defined($driver)) { print "Please specify -driver with -rem_target.\n"; exit 1; } if ((defined($addGroup) || defined($removeGroup)) && - (($driver eq '') || ($target eq ''))) { + (!defined($driver) || !defined($target))) { print "Please specify -driver and -target with -add_group/-rem_group.\n"; exit 1; } if ((defined($addInitiator) || defined($removeInitiator) || defined($clearInitiators)) && - (($target eq '') || ($driver eq '') || ($group eq ''))) { + (!defined($target) || !defined($driver) || !defined($group))) { print "Please specify -driver -target and -group with ". "-add_init/-rem_init/-clear_inits.\n"; exit 1; } if (defined($moveInitiator) && - (($driver eq '') || ($target eq '') || ($group eq '') || ($to eq ''))) { + (!defined($driver) || !defined($target) || !defined($group) || !defined($to))) { print "Please specify -driver -target -group and -to with -move_init.\n"; exit 1; } if ((defined($addLun) || defined($replaceLun)) && - (($driver eq '') || ($target eq '') || ($device eq ''))) { + (!defined($driver) || !defined($target) || !defined($device))) { print "Please specify -driver -target and -device with -add_lun/-replace_lun.\n"; exit 1; } - if ((defined($clearLuns) || defined($removeLun)) && (($driver eq '') || ($target eq ''))) { + if ((defined($clearLuns) || defined($removeLun)) && (!defined($driver) || !defined($target))) { print "Please specify -driver and -target with -rem_lun/-clear_luns.\n"; exit 1; } - if ((defined($addDevGroupDevice) || defined($removeDevGroupDevice)) && ($deviceGroup eq '')) { + if ((defined($addDevGroupDevice) || defined($removeDevGroupDevice)) && !defined($deviceGroup)) { print "Please specify -dev_group with -add_dgrp_dev/-rem_dgrp_dev.\n"; exit 1; } - if ((defined($addTargetGroup) || defined($removeTargetGroup)) && ($deviceGroup eq '')) { + if ((defined($addTargetGroup) || defined($removeTargetGroup)) && !defined($deviceGroup)) { print "Please specify -dev_group with -add_tgrp/-rem_tgrp.\n"; exit 1; } if ((defined($addTargetGroupTarget) || defined($removeTargetGroupTarget)) && - (($deviceGroup eq '') || ($targetGroup eq ''))) { - print "Please specify -dev_group and -tgt_group with -add_tgrp_init/-rem_tgrp_init.\n"; + (!defined($deviceGroup) || !defined($targetGroup))) { + print "Please specify -dev_group and -tgt_group with -add_tgrp_tgt/-rem_tgrp_tgt.\n"; exit 1; } @@ -831,8 +831,6 @@ sub getArgs { } sub main { - my $rc = 0; - STDOUT->autoflush(1); # We need to run as root @@ -1358,6 +1356,7 @@ sub main { sub readWorkingConfig { my $force = shift; + my $errorString; print "\nCollecting current configuration: "; @@ -1365,57 +1364,69 @@ sub readWorkingConfig { # Get current handlers/devices - my ($handlers, $errorString) = $SCST->handlers(); + my $handlers; + ($handlers, $errorString) = $SCST->handlers(); immediateExit($errorString); foreach my $handler (@{$handlers}) { - my ($devices, $errorString) = $SCST->devicesByHandler($handler); + my $devices; + + ($devices, $errorString) = $SCST->devicesByHandler($handler); immediateExit($errorString); $CURRENT{'handler'}->{$handler} = $devices; } # Get current assignments - my ($drivers, $errorString) = $SCST->drivers(); + my $drivers; + ($drivers, $errorString) = $SCST->drivers(); immediateExit($errorString); foreach my $driver (@{$drivers}) { my %empty; $CURRENT{'assign'}->{$driver} = \%empty; - my ($targets, $errorString) = $SCST->targets($driver); + my $targets; + ($targets, $errorString) = $SCST->targets($driver); immediateExit($errorString); foreach my $target (@{$targets}) { my %empty; $CURRENT{'assign'}->{$driver}->{$target} = \%empty; - my ($luns, $errorString) = $SCST->luns($driver, $target); + my $luns; + ($luns, $errorString) = $SCST->luns($driver, $target); $CURRENT{'assign'}->{$driver}->{$target}->{'LUN'} = $luns if (defined($luns)); - my ($groups, $errorString) = $SCST->groups($driver, $target); + my $groups; + ($groups, $errorString) = $SCST->groups($driver, $target); immediateExit($errorString); foreach my $group (@{$groups}) { - my ($initiators, $errorString) = $SCST->initiators($driver, $target, $group); + my $initiators; + ($initiators, $errorString) = $SCST->initiators($driver, $target, $group); immediateExit($errorString); $CURRENT{'assign'}->{$driver}->{$target}->{'GROUP'}->{$group}->{'INITIATORS'} = $initiators; - my ($luns, $errorString) = $SCST->luns($driver, $target, $group); + ($luns, $errorString) = $SCST->luns($driver, $target, $group); $CURRENT{'assign'}->{$driver}->{$target}->{'GROUP'}->{$group}->{'LUN'} = $luns; immediateExit($errorString); } } } - my ($dgroups, $errorString) = $SCST->deviceGroups(); + my $dgroups; + ($dgroups, $errorString) = $SCST->deviceGroups(); immediateExit($errorString); foreach my $dgroup (@{$dgroups}) { - my ($dgd, $errorString) = $SCST->deviceGroupDevices($dgroup); + my $dgd; + ($dgd, $errorString) = $SCST->deviceGroupDevices($dgroup); immediateExit($errorString); $CURRENT{'dgroups'}->{$dgroup}->{'devices'} = $dgd; - my ($tgroups, $errorString) = $SCST->targetGroups($dgroup); + my $tgroups; + ($tgroups, $errorString) = $SCST->targetGroups($dgroup); immediateExit($errorString); foreach my $tgroup (@{$tgroups}) { - my ($tgt, $errorString) = $SCST->targetGroupTargets($dgroup, $tgroup); + my $tgt; + ($tgt, $errorString) = $SCST->targetGroupTargets($dgroup, $tgroup); $CURRENT{'dgroups'}->{$dgroup}->{'tgroups'}->{$tgroup}->{'targets'} = $tgt; } } @@ -1455,7 +1466,7 @@ sub readWorkingConfig { sub escapeMeta { my $value = shift; - $value =~ s/([\\\#])/\\\1/g; + $value =~ s/([\\\#])/\\$1/g; if ($value =~ / /) { $value = "\"$value\""; } @@ -1471,7 +1482,7 @@ sub serializeKeyAttr { my $prefix = shift; my $attributes = shift; my $attr_filter = shift; - my $result; + my $result = ""; foreach my $attribute (sort keys %{$attributes}) { next if defined($$attributes{$attribute}->{'set'}); @@ -1507,7 +1518,7 @@ sub serializeNkAttr { my $prefix = shift; my $attributes = shift; my $attr_filter = shift; - my $result; + my $result = ""; foreach my $attribute (sort keys %{$attributes}) { if (!defined($$attributes{$attribute}->{'set'}) @@ -1532,13 +1543,16 @@ sub serializeNkAttr { sub isPassthroughDev { my $dev = shift; my $pt = FALSE; + my $errorString; foreach my $handler (keys %{$CURRENT{'handler'}}) { - my ($ha, $errorString) = $SCST->handlerAttributes($handler); - next if ($ha->{'mgmt'} !~ 'echo "add_device H:C:I:L"'); + my $ha; + ($ha, $errorString) = $SCST->handlerAttributes($handler); + next if (defined($ha->{'mgmt'}) && + $ha->{'mgmt'} !~ 'echo "add_device H:C:I:L"'); my @devs = @{$CURRENT{'handler'}->{$handler}}; for my $i (0 .. $#devs) { - if ($dev eq @devs[$i]) { + if ($dev eq $devs[$i]) { $pt = TRUE; last; } @@ -1550,6 +1564,7 @@ sub isPassthroughDev { # Returns 0 upon success and 1 upon error. sub writeConfiguration { my $nonkey = shift; + my $errorString; my $io = new IO::File $CONFIGFILE, O_CREAT|O_WRONLY|O_TRUNC; @@ -1563,7 +1578,8 @@ sub writeConfiguration { print $io "# Automatically generated by $Version.\n\n"; { - my ($attributes, $errorString) = $SCST->scstAttributes(); + my $attributes; + ($attributes, $errorString) = $SCST->scstAttributes(); immediateExit($errorString); print $io serializeKeyAttr("", $attributes); @@ -1578,26 +1594,27 @@ sub writeConfiguration { } foreach my $handler (sort keys %{$CURRENT{'handler'}}) { - my $handler_buff; - my $handler_buff_nk; - - my ($handler_attrs, $errorString) = $SCST->deviceCreateAttributes($handler); - my ($attributes, $errorString) = $SCST->handlerAttributes($handler); + my $handler_buff = ""; + my $handler_buff_nk = ""; + my $handler_attrs; + my $attributes; + ($handler_attrs, $errorString) = $SCST->deviceCreateAttributes($handler); + ($attributes, $errorString) = $SCST->handlerAttributes($handler); $handler_buff = serializeKeyAttr("\t", $attributes); $handler_buff_nk = serializeNkAttr("\t", $attributes) if ($nonkey); my $devices = $CURRENT{'handler'}->{$handler}; - my $device_buff; + my $device_buff = ""; foreach my $device (sort @{$devices}) { $device_buff .= "\tDEVICE $device"; - my ($attributes, $errorString) = $SCST->deviceAttributes($device); - - my $attribute_buff; - my $attribute_buff_nk; + my $attributes; + my $attribute_buff = ""; + my $attribute_buff_nk = ""; + ($attributes, $errorString) = $SCST->deviceAttributes($device); $attribute_buff = serializeKeyAttr("\t\t", $attributes, $handler_attrs); $attribute_buff_nk = serializeNkAttr("\t\t", $attributes, $handler_attrs) if ($nonkey); $attribute_buff .= "\n" if ($attribute_buff); @@ -1636,30 +1653,31 @@ sub writeConfiguration { } foreach my $driver (sort keys %{$CURRENT{'assign'}}) { - my $driver_buff; + my $driver_buff = ""; - my ($drv_attrs, $errorString) = $SCST->driverAttributes($driver); - - my $drv_attr_buff; - my $drv_attr_buff_nk; + my $drv_attrs; + my $drv_attr_buff = ""; + my $drv_attr_buff_nk = ""; + ($drv_attrs, $errorString) = $SCST->driverAttributes($driver); $drv_attr_buff = serializeKeyAttr("\t", $drv_attrs); $drv_attr_buff_nk = serializeNkAttr("\t", $drv_attrs) if ($nonkey); $drv_attr_buff .= "\n" if ($drv_attr_buff); $drv_attr_buff_nk .= "\n" if ($drv_attr_buff_nk); my $targets = $CURRENT{'assign'}->{$driver}; - my ($tgt_attrs, $errorString) = $SCST->targetCreateAttributes($driver); + my $tgt_attrs; + ($tgt_attrs, $errorString) = $SCST->targetCreateAttributes($driver); - my $target_buff; + my $target_buff = ""; foreach my $target (sort keys %{$targets}) { $target_buff .= "\tTARGET $target"; - my ($attributes, $errorString) = $SCST->targetAttributes($driver, $target); - - my $attribute_buff; - my $attribute_buff_nk; + my $attributes; + my $attribute_buff = ""; + my $attribute_buff_nk = ""; + ($attributes, $errorString) = $SCST->targetAttributes($driver, $target); if (defined($$attributes{'hw_target'}) && ($$attributes{'hw_target'}->{'value'} == TRUE)) { $attribute_buff = "\t\tHW_TARGET\n\n"; @@ -1671,9 +1689,10 @@ sub writeConfiguration { $attribute_buff_nk .= "\n" if ($attribute_buff_nk); my $luns = $CURRENT{'assign'}->{$driver}->{$target}->{'LUN'}; - my ($lun_attrs, $errorString) = $SCST->lunCreateAttributes($driver, $target); + my $lun_attrs; + ($lun_attrs, $errorString) = $SCST->lunCreateAttributes($driver, $target); - my $t_lun_buff; + my $t_lun_buff = ""; foreach my $lun (sort numerically keys %{$luns}) { my $lun_dev = $$luns{$lun}; @@ -1685,7 +1704,8 @@ sub writeConfiguration { $t_lun_buff .= "\t\tLUN $lun $lun_dev"; - my ($attributes, $errorString) = $SCST->lunAttributes($driver, $target, $lun); + my $attributes; + ($attributes, $errorString) = $SCST->lunAttributes($driver, $target, $lun); my $l_attribute_buff = serializeKeyAttr("\t\t\t", $attributes, @@ -1714,22 +1734,25 @@ sub writeConfiguration { my $groups = $CURRENT{'assign'}->{$driver}->{$target}->{'GROUP'}; - my $group_buff; + my $group_buff = ""; foreach my $group (sort keys %{$groups}) { - my ($lun_attrs, $errorString) = $SCST->lunCreateAttributes($driver, $target, $group); - my ($ini_attrs, $errorString) = $SCST->initiatorCreateAttributes($driver, $target, $group); + my $lun_attrs; + my $ini_attrs; + ($lun_attrs, $errorString) = $SCST->lunCreateAttributes($driver, $target, $group); + ($ini_attrs, $errorString) = $SCST->initiatorCreateAttributes($driver, $target, $group); $group_buff .= "\t\tGROUP $group"; my $luns = $CURRENT{'assign'}->{$driver}->{$target}->{'GROUP'}->{$group}->{'LUN'}; - my $lun_buff; + my $lun_buff = ""; foreach my $lun (sort numerically keys %{$luns}) { my $lun_dev = $$luns{$lun}; $lun_buff .= "\t\t\tLUN $lun $lun_dev"; - my ($attributes, $errorString) = $SCST->lunAttributes($driver, $target, $lun, $group); + my $attributes; + ($attributes, $errorString) = $SCST->lunAttributes($driver, $target, $lun, $group); my $l_attribute_buff = serializeKeyAttr("\t\t\t\t", @@ -1757,11 +1780,12 @@ sub writeConfiguration { my $inits = $CURRENT{'assign'}->{$driver}->{$target}->{'GROUP'}->{$group}->{'INITIATORS'}; - my $init_buff; + my $init_buff = ""; foreach my $init (sort @{$inits}) { $init_buff .= "\n\t\t\tINITIATOR " . escapeMeta($init); - my ($attributes, $errorString) = $SCST->initiatorAttributes($driver, $target, $group, $init); + my $attributes; + ($attributes, $errorString) = $SCST->initiatorAttributes($driver, $target, $group, $init); my $i_attribute_buff = serializeKeyAttr("\t\t\t\t", @@ -1787,7 +1811,8 @@ sub writeConfiguration { } } - my ($grp_attributes, $errorString) = $SCST->groupAttributes($driver, $target, $group); + my $grp_attributes; + ($grp_attributes, $errorString) = $SCST->groupAttributes($driver, $target, $group); my $g_attribute_buff = serializeKeyAttr("\t\t\t", $grp_attributes); @@ -1858,7 +1883,8 @@ sub writeConfiguration { } } - my ($dga, $errorString) = $SCST->aluaAttributes(); + my $dga; + ($dga, $errorString) = $SCST->aluaAttributes(); my $dga_buff = serializeKeyAttr("\t", $dga); my $dga_buff_nk = serializeNkAttr("\t", $dga) if ($nonkey); if ($dga_buff_nk) { @@ -1872,19 +1898,18 @@ sub writeConfiguration { } foreach my $dgroup (sort keys %{$CURRENT{'dgroups'}}) { - my $dgroup_buff; - - my ($dgroup_attrs, $errorString) = $SCST->deviceGroupAttributes($dgroup); - - my $dgrp_attr_buff; - my $dgrp_attr_buff_nk; + my $dgroup_buff = ""; + my $dgroup_attrs; + my $dgrp_attr_buff = ""; + my $dgrp_attr_buff_nk = ""; + ($dgroup_attrs, $errorString) = $SCST->deviceGroupAttributes($dgroup); $dgrp_attr_buff = serializeKeyAttr("\t", $dgroup_attrs); $dgrp_attr_buff_nk = serializeNkAttr("\t", $dgroup_attrs) if ($nonkey); $dgrp_attr_buff .= "\n" if ($dgrp_attr_buff); $dgrp_attr_buff_nk .= "\n" if ($dgrp_attr_buff_nk); - my $devices_buff; + my $devices_buff = ""; my $devices = $CURRENT{'dgroups'}->{$dgroup}->{'devices'}; @@ -1896,16 +1921,16 @@ sub writeConfiguration { my $tgroups = $CURRENT{'dgroups'}->{$dgroup}->{'tgroups'}; - my $tgroup_buff; + my $tgroup_buff = ""; foreach my $tgroup (sort keys %{$tgroups}) { $tgroup_buff .= "\tTARGET_GROUP $tgroup"; - my ($attributes, $errorString) = $SCST->targetGroupAttributes($dgroup, $tgroup); - - my $attribute_buff; - my $attribute_buff_nk; + my $attributes; + my $attribute_buff = ""; + my $attribute_buff_nk = ""; + ($attributes, $errorString) = $SCST->targetGroupAttributes($dgroup, $tgroup); $attribute_buff .= serializeKeyAttr("\t\t", $attributes); $attribute_buff_nk .= serializeNkAttr("\t\t", $attributes) if ($nonkey); $attribute_buff .= "\n" if ($attribute_buff); @@ -1913,11 +1938,13 @@ sub writeConfiguration { my $tgts = $CURRENT{'dgroups'}->{$dgroup}->{'tgroups'}->{$tgroup}->{'targets'}; - my $tgt_buff; + my $tgt_buff = ""; foreach my $tgt (@{$tgts}) { $tgt_buff .= "\t\tTARGET $tgt"; - my ($tgt_attrs, $errorString) = $SCST->targetGroupTargetAttributes($dgroup, $tgroup, $tgt); + my $tgt_attrs; + + ($tgt_attrs, $errorString) = $SCST->targetGroupTargetAttributes($dgroup, $tgroup, $tgt); my $t_attribute_buff = serializeKeyAttr("\t\t\t", $tgt_attrs); @@ -2211,14 +2238,16 @@ sub applyConfigDevices { my $config = shift; my $deletions = shift; my $changes = 0; + my $errorString; my $handlers = $CURRENT{'handler'}; foreach my $handler (keys %{$handlers}) { foreach my $device (@{$$handlers{$handler}}) { if (!defined($$config{'HANDLER'}->{$handler}->{'DEVICE'}->{$device})) { - my ($attributes, $errorString) = $SCST->deviceAttributes($device); + my $attributes; + ($attributes, $errorString) = $SCST->deviceAttributes($device); if ($deletions) { closeDevice($handler, $device, $deletions); $changes++; @@ -2244,13 +2273,15 @@ sub applyConfigDevices { my $attributes = configToAttr(\%_attributes); my $create_attrs = configToAttr(\%_attributes); - my ($possible, $errorString) = $SCST->deviceCreateAttributes($handler); + my $possible; + ($possible, $errorString) = $SCST->deviceCreateAttributes($handler); condExit($errorString); filterCreateAttributes($possible, $create_attrs, FALSE); filterCreateAttributes($possible, $attributes, TRUE); if (handlerHasDevice($handler, $device)) { - my ($old_create_attrs, $errorString) = $SCST->deviceAttributes($device); + my $old_create_attrs; + ($old_create_attrs, $errorString) = $SCST->deviceAttributes($device); condExit($errorString); filterCreateAttributes($possible, $old_create_attrs, FALSE); @@ -2308,6 +2339,7 @@ sub applyConfigAssignments { my $deletions = shift; my $only_del = shift; my $changes = 0; + my $errorString; my $assignments = $CURRENT{'assign'}; @@ -2330,9 +2362,11 @@ sub applyConfigAssignments { } } else { my $c_attrs = configToAttr($$config{'TARGET_DRIVER'}->{$driver}->{'TARGET'}->{$target}->{'LUN'}->{$lun}->{$device}); - my ($o_attrs, $errorString) = $SCST->lunAttributes($driver, $target, $lun); + my $o_attrs; + ($o_attrs, $errorString) = $SCST->lunAttributes($driver, $target, $lun); condExit($errorString); - my ($possible, $errorString) = $SCST->lunCreateAttributes($driver, $target); + my $possible; + ($possible, $errorString) = $SCST->lunCreateAttributes($driver, $target); condExit($errorString); filterCreateAttributes($possible, $c_attrs, FALSE); @@ -2373,9 +2407,11 @@ sub applyConfigAssignments { } } else { my $c_attrs = configToAttr($$config{'TARGET_DRIVER'}->{$driver}->{'TARGET'}->{$target}->{'GROUP'}->{$group}->{'LUN'}->{$lun}->{$device}); - my ($o_attrs, $errorString) = $SCST->lunAttributes($driver, $target, $lun, $group); + my $o_attrs; + ($o_attrs, $errorString) = $SCST->lunAttributes($driver, $target, $lun, $group); condExit($errorString); - my ($possible, $errorString) = $SCST->lunCreateAttributes($driver, $target, $group); + my $possible; + ($possible, $errorString) = $SCST->lunCreateAttributes($driver, $target, $group); condExit($errorString); filterCreateAttributes($possible, $c_attrs, FALSE); @@ -2445,6 +2481,7 @@ sub applyConfigEnableDrivers { my $config = shift; my $deletions = shift; my $changes = 0; + my $errorString; my $assignments = $$config{'TARGET_DRIVER'}; @@ -2457,7 +2494,8 @@ sub applyConfigEnableDrivers { } my $attributes = configToAttr(\%_attributes); - my ($d_attributes, $errorString) = $SCST->driverAttributes($driver); + my $d_attributes; + ($d_attributes, $errorString) = $SCST->driverAttributes($driver); if (defined($$d_attributes{'enabled'}) && ($$d_attributes{'enabled'}->{'value'} != $$attributes{'enabled'})) { @@ -2762,6 +2800,7 @@ sub applyConfigEnableTargets { my $config = shift; my $deletions = shift; my $changes = 0; + my $errorString; my $assignments = $$config{'TARGET_DRIVER'}; @@ -2778,7 +2817,8 @@ sub applyConfigEnableTargets { } my $attributes = configToAttr(\%_attributes); - my ($t_attributes, $errorString) = $SCST->targetAttributes($driver, $target); + my $t_attributes; + ($t_attributes, $errorString) = $SCST->targetAttributes($driver, $target); if (defined($$t_attributes{'enabled'}) && ($$t_attributes{'enabled'}->{'value'} != $$attributes{'enabled'})) { @@ -2898,6 +2938,7 @@ sub compareToKeyAttribute { sub clearConfiguration { my $dgroups = $CURRENT{'dgroups'}; my $assignments = $CURRENT{'assign'}; + my $errorString; print "-> Clearing running configuration.\n"; @@ -2937,18 +2978,22 @@ sub clearConfiguration { foreach my $handler (sort keys %{$handlers}) { foreach my $device (@{$$handlers{$handler}}) { - my ($attributes, $errorString) = $SCST->deviceAttributes($device); + my $attributes; + + ($attributes, $errorString) = $SCST->deviceAttributes($device); closeDevice($handler, $device, TRUE); } } # Todo - check return code - my ($drivers, $errorString) = $SCST->drivers(); + my $drivers; + ($drivers, $errorString) = $SCST->drivers(); foreach my $driver (@{$drivers}) { - my ($targets, $errorString) = $SCST->targets($driver); + my $targets; + ($targets, $errorString) = $SCST->targets($driver); foreach my $target (@{$targets}) { disableTarget($driver, $target); } @@ -2965,13 +3010,15 @@ sub addVirtualTarget { my $driver = shift; my $target = shift; my $attributes = shift; + my $errorString; + my $targets; # Enable all hardware targets before creating virtual ones - my ($targets, $errorString) = $SCST->targets($driver); - + ($targets, $errorString) = $SCST->targets($driver); foreach my $_target (@{$targets}) { - my ($attributes, $errorString) = $SCST->targetAttributes($driver, $_target); + my $attributes; + ($attributes, $errorString) = $SCST->targetAttributes($driver, $_target); if (defined($$attributes{'hw_target'}) && !$$attributes{'enabled'}->{'value'}) { enableTarget($driver, $_target); @@ -3005,7 +3052,7 @@ sub listHandlers { my ($handlers, $errorString) = $SCST->handlers(); - my $l_handler; + my $l_handler = 0; foreach my $handler (@{$handlers}) { $l_handler = length($handler) if ($l_handler < length($handler)); } @@ -3028,12 +3075,11 @@ sub listHandler { my $handler = shift; my %toprint; - my $got_handler = ($handler ne ''); + my $got_handler = defined($handler); my ($handlers, $errorString) = $SCST->handlers(); - my $l_device; - my $l_handler; - + my $l_device = 0; + my $l_handler = 0; foreach my $_handler (@{$handlers}) { $handler = $_handler if (!$got_handler); @@ -3042,8 +3088,9 @@ sub listHandler { $l_handler = length($handler) if ($l_handler < length($handler)); - my ($devices, $errorString) = $SCST->devicesByHandler($handler); + my $devices; + ($devices, $errorString) = $SCST->devicesByHandler($handler); if ($#{$devices} == -1) { push @{$devices}, '-'; } @@ -3062,15 +3109,16 @@ sub listHandler { }; print "\n"; - foreach my $handler (keys %toprint) { - my ($devices, $errorString) = $SCST->devicesByHandler($handler); + foreach my $handler (sort keys %toprint) { + my $devices; my $first = TRUE; + ($devices, $errorString) = $SCST->devicesByHandler($handler); if ($#{$devices} == -1) { push @{$devices}, '-'; } - foreach my $device (@{$devices}) { + foreach my $device (sort @{$devices}) { if ($first) { printf("\t%-*s %-*s\n", $l_handler, $handler, $l_device, $device); $first = FALSE; @@ -3118,7 +3166,7 @@ sub listDeviceGroups { my ($groups, $errorString) = $SCST->deviceGroups(); - my $l_group; + my $l_group = 0; foreach my $group (@{$groups}) { $l_group = length($group) if ($l_group < length($group)); } @@ -3142,10 +3190,11 @@ sub listDeviceGroups { sub listDeviceGroup { my $group = shift; + my $errorString; + my $devices; + my $l_device = 0; - my ($devices, $errorString) = $SCST->deviceGroupDevices($group); - - my $l_device; + ($devices, $errorString) = $SCST->deviceGroupDevices($group); foreach my $device (@{$devices}) { $l_device = length($device) if ($l_device < length($device)); } @@ -3163,9 +3212,10 @@ sub listDeviceGroup { print "\t$device\n"; } - my ($tgroups, $errorString) = $SCST->targetGroups($group); + my $tgroups; + my $l_tgroup = 0; - my $l_tgroup; + ($tgroups, $errorString) = $SCST->targetGroups($group); foreach my $tgroup (@{$tgroups}) { $l_tgroup = length($tgroup) if ($l_tgroup < length($tgroup)); } @@ -3196,7 +3246,7 @@ sub listTargetGroups { my ($tgroups, $errorString) = $SCST->targetGroups($group); - my $l_tgroup; + my $l_tgroup = 0; foreach my $tgroup (@{$tgroups}) { $l_tgroup = length($tgroup) if ($l_tgroup < length($tgroup)); } @@ -3227,7 +3277,7 @@ sub listTargetGroup { my ($targets, $errorString) = $SCST->targetGroupTargets($group, $tgroup); - my $l_tgt; + my $l_tgt = 0; foreach my $tgt (@{$targets}) { $l_tgt = length($tgt) if ($l_tgt < length($tgt)); } @@ -3256,7 +3306,7 @@ sub listDeviceGroupDevices { my ($devices, $errorString) = $SCST->deviceGroupDevices($group); - my $l_device; + my $l_device = 0; foreach my $device (@{$devices}) { $l_device = length($device) if ($l_device < length($device)); } @@ -3284,7 +3334,7 @@ sub listDrivers { my ($drivers, $errorString) = $SCST->drivers(); - my $l_driver; + my $l_driver = 0; foreach my $driver (@{$drivers}) { $l_driver = length($driver) if ($l_driver < length($driver)); } @@ -3310,13 +3360,12 @@ sub listTargets { return listGroups($driver, $target, undef) if (($target ne '') && ($driver ne '')); - my $got_driver = ($driver ne ''); + my $got_driver = defined($driver); my ($drivers, $errorString) = $SCST->drivers(); - my $l_driver; - my $l_target; - + my $l_driver = 0; + my $l_target = 0; foreach my $_driver (@{$drivers}) { $driver = $_driver if (!$got_driver); @@ -3325,7 +3374,8 @@ sub listTargets { $l_driver = length($driver) if ($l_driver < length($driver)); - my ($targets, $errorString) = $SCST->targets($driver); + my $targets; + ($targets, $errorString) = $SCST->targets($driver); foreach my $target (@{$targets}) { $l_target = length($target) if ($l_target < length($target)); @@ -3343,9 +3393,10 @@ sub listTargets { my %p; - foreach my $driver (keys %toprint) { - my ($targets, $errorString) = $SCST->targets($driver); + foreach my $driver (sort keys %toprint) { + my $targets; + ($targets, $errorString) = $SCST->targets($driver); foreach my $target (@{$targets}) { if (!defined($p{$driver})) { printf("\t%-*s %-*s\n", $l_driver, $driver, $l_target, $target); @@ -3366,18 +3417,20 @@ sub listSessions { my ($drivers, $errorString) = $SCST->drivers(); foreach my $driver (@{$drivers}) { - my ($targets, $errorString) = $SCST->targets($driver); + my $targets; + ($targets, $errorString) = $SCST->targets($driver); foreach my $target (@{$targets}) { my $had_sessions = FALSE; + my $sessions; print "Driver/Target: $driver/$target\n\n"; - my ($sessions, $errorString) = $SCST->sessions($driver, $target); + ($sessions, $errorString) = $SCST->sessions($driver, $target); foreach my $session (keys %{$sessions}) { print "\tSession: $session\n\n"; - my %attributes; + my %attributes = ( ); foreach my $attr (keys %{$$sessions{$session}}) { if ($attr eq 'luns') { foreach my $lun (keys %{$$sessions{$session}->{'luns'}}) { @@ -3414,19 +3467,18 @@ sub listGroup { my $errorString; ($luns, $errorString) = $SCST->luns($driver, $target, $group) if (!$luns); - if (($initiators eq '') && ($group ne '')) { + if (!defined($initiators) && defined($group)) { ($initiators, $errorString) = $SCST->initiators($driver, $target, $group); return TRUE if issueWarning($errorString); } if ((keys %{$luns}) || ($#{$initiators} > -1)) { - my $l_device; - my $l_initiator; - + my $l_device = 0; foreach my $lun (keys %{$luns}) { $l_device = length($$luns{$lun}) if (length($$luns{$lun}) > $l_device); } + my $l_initiator = 0; foreach my $initiator (@{$initiators}) { $l_initiator = length($initiator) if (length($initiator) > $l_initiator); } @@ -3499,7 +3551,9 @@ sub listGroups { $driver = $_driver if (!$got_driver); if ($driver eq $_driver) { - my ($targets, $errorString) = $SCST->targets($driver); + my $targets; + + ($targets, $errorString) = $SCST->targets($driver); foreach my $_target (@{$targets}) { $target = $_target if (!$got_target); @@ -3512,7 +3566,9 @@ sub listGroups { print "\n"; - my ($groups, $errorString) = $SCST->groups($driver, $target); + my $groups; + + ($groups, $errorString) = $SCST->groups($driver, $target); foreach my $_group (@{$groups}) { $group = $_group if (!$got_group); @@ -3613,8 +3669,8 @@ sub listAttributes { } } - printf("\t%-*s %-*s %-*s %-*s\n", $l_attr, 'Attribute', $l_value, - 'Value', 9, 'Writable', 3, 'KEY'); + printf("\t%-*s %-*s %-*s %-*s\n", $l_attr, 'Attribute', + $l_value, 'Value', 9, 'Writable', 3, 'KEY'); print "\t"; for (my $x = 0; $x < ($l_attr + $l_value + 27); $x++) { print "-"; @@ -3739,7 +3795,7 @@ sub listHandlerAttributes { print "\n\tDevice CREATE attributes available\n"; print "\t----------------------------------\n"; - foreach my $attribute (keys %{$attributes}) { + foreach my $attribute (sort keys %{$attributes}) { print "\t$attribute\n"; } @@ -3765,20 +3821,21 @@ sub listDriverAttributes { print "\n\tDynamic attributes available\n"; print "\t----------------------------\n"; - foreach my $attribute (keys %{$attributes}) { + foreach my $attribute (sort keys %{$attributes}) { print "\t$attribute\n"; } } - my ($attributes, $errorString) = $SCST->targetCreateAttributes($driver); + my $attributes; + ($attributes, $errorString) = $SCST->targetCreateAttributes($driver); return TRUE if issueWarning($errorString); return TRUE if (!scalar keys %{$attributes}); print "\n\tTarget CREATE attributes available:\n"; print "\t-----------------------------------\n"; - foreach my $attribute (keys %{$attributes}) { + foreach my $attribute (sort keys %{$attributes}) { print "\t$attribute\n"; } } @@ -3811,7 +3868,7 @@ sub listTargetAttributes { print "\n\tDynamic attributes available\n"; print "\t----------------------------\n"; - foreach my $attribute (keys %{$attributes}) { + foreach my $attribute (sort keys %{$attributes}) { print "\t$attribute\n"; } } @@ -3825,7 +3882,7 @@ sub listTargetAttributes { print "\n\tLUN CREATE attributes available\n"; print "\t-------------------------------\n"; - foreach my $attribute (keys %{$attributes}) { + foreach my $attribute (sort keys %{$attributes}) { print "\t$attribute\n"; } @@ -3858,7 +3915,7 @@ sub listGroupAttributes { print "\n\tLUN CREATE attributes available\n"; print "\t-------------------------------\n"; - foreach my $attribute (keys %{$attributes}) { + foreach my $attribute (sort keys %{$attributes}) { print "\t$attribute\n"; } @@ -4827,11 +4884,14 @@ sub addTargetGroupTarget { sub removeDeviceGroup { my $group = shift; my $force = shift; + my $errorString; if (!$force) { - my ($devices, $errorString) = $SCST->deviceGroupDevices($group); - my ($tgroups, $errorString) = $SCST->targetGroups($group); + my $devices; + my $tgroups; + ($devices, $errorString) = $SCST->deviceGroupDevices($group); + ($tgroups, $errorString) = $SCST->targetGroups($group); if (($#{$devices} > -1) || ($#{$tgroups} > -1)) { print "\n"; listDeviceGroup($group); @@ -4854,10 +4914,12 @@ sub removeTargetGroup { my $group = shift; my $tgroup = shift; my $force = shift; + my $errorString; if (!$force) { - my ($tgts, $errorString) = $SCST->targetGroupTargets($group, $tgroup); + my $tgts; + ($tgts, $errorString) = $SCST->targetGroupTargets($group, $tgroup); if ($#{$tgts} > -1) { print "\n"; listTargetGroup($group, $tgroup); @@ -4912,14 +4974,17 @@ sub removeDeviceGroupDevice { my $group = shift; my $device = shift; my $force = shift; + my $errorString; if (!$force) { my $found = FALSE; - my ($tgroups, $errorString) = $SCST->targetGroups($group); + my $tgroups; + ($tgroups, $errorString) = $SCST->targetGroups($group); foreach my $tgroup (@{$tgroups}) { - my ($targets, $errorString) = $SCST->targetGroupTargets($group, $tgroup); + my $targets; + ($targets, $errorString) = $SCST->targetGroupTargets($group, $tgroup); if ($#{$targets} > -1) { print "\n"; listTargetGroup($group, $tgroup); @@ -4966,11 +5031,14 @@ sub removeGroup { my $target = shift; my $group = shift; my $force = shift; + my $errorString; if (!$force) { - my ($luns, $errorString) = $SCST->luns($driver, $target, $group); - my ($initiators, $errorString) = $SCST->initiators($driver, $target, $group); + my $luns; + my $initiators; + ($luns, $errorString) = $SCST->luns($driver, $target, $group); + ($initiators, $errorString) = $SCST->initiators($driver, $target, $group); if ((keys %{$luns}) || ($#{$initiators} > -1)) { listGroup($driver, $target, $group, $luns, $initiators); immediateExit("Group is still in use, aborting. Use -force to override."); @@ -5172,14 +5240,17 @@ sub clearLuns { sub clearDriverDynamicAttributes { my $driver = shift; + my $errorString; return TRUE if (!$SCST->driverIsVirtualCapable($driver)); print "\t-> Removing all dynamic attributes from driver '$driver': "; - my ($attributes, $errorString) = $SCST->driverAttributes($driver); - my ($dynamic, $errorString) = $SCST->driverDynamicAttributes($driver); + my $attributes; + my $dynamic; + ($attributes, $errorString) = $SCST->driverAttributes($driver); + ($dynamic, $errorString) = $SCST->driverDynamicAttributes($driver); foreach my $attribute (keys %{$attributes}) { if (defined($$dynamic{$attribute})) { if (defined($$attributes{$attribute}->{'keys'})) { @@ -5201,14 +5272,17 @@ sub clearDriverDynamicAttributes { sub clearTargetDynamicAttributes { my $driver = shift; my $target = shift; + my $errorString; return TRUE if (!$SCST->driverIsVirtualCapable($driver)); print "\t-> Removing all dynamic attributes from driver/target '$driver/$target': "; - my ($attributes, $errorString) = $SCST->targetAttributes($driver, $target); - my ($dynamic, $errorString) = $SCST->targetDynamicAttributes($driver); + my $attributes; + my $dynamic; + ($attributes, $errorString) = $SCST->targetAttributes($driver, $target); + ($dynamic, $errorString) = $SCST->targetDynamicAttributes($driver); foreach my $attribute (keys %{$attributes}) { if (defined($$dynamic{$attribute})) { if (defined($$attributes{$attribute}->{'keys'})) { @@ -5273,15 +5347,18 @@ sub issueLip { my $driver = shift; my $target = shift; my $warn = shift; + my $errorString; if (defined($driver) && defined($target)) { return _issueLip($driver, $target, $warn); } else { - my ($drivers, $errorString) = $SCST->drivers(); + my $drivers; + ($drivers, $errorString) = $SCST->drivers(); foreach my $driver(@{$drivers}) { - my ($targets, $errorString) = $SCST->targets($driver); + my $targets; + ($targets, $errorString) = $SCST->targets($driver); foreach my $target (@{$targets}) { my $rc = _issueLip($driver, $target, $warn); @@ -5376,7 +5453,7 @@ sub readConfigFile { } } - $line =~ s/\\(.)/\1/g; + $line =~ s/\\(.)/$1/g; $buffer .= $line; } @@ -5415,8 +5492,11 @@ sub parseStanza { if ($char eq "\n") { my %empty; - parseLine($line, \%hash, \%empty); - $line = undef; + + if ($line) { + parseLine($line, \%hash, \%empty); + $line = undef; + } } else { $line .= $char; } @@ -5439,9 +5519,9 @@ sub parseLine { push @elements, defined($1) ? $1:$3; } - my $attribute = @elements[0]; - my $value = @elements[1]; - my $value2 = @elements[2]; + my $attribute = $elements[0]; + my $value = $elements[1]; + my $value2 = $elements[2]; if (defined($attribute) && defined($value) && defined($value2)) { $$hash{$attribute}->{$value}->{$value2} = $child; @@ -5560,8 +5640,9 @@ sub readOldConfigFile { my($device, $lun) = split(/\,/, $device); foreach my $driver (@{$drivers}) { - my ($targets, $errorString) = $SCST->targets($driver); + my $targets; + ($targets, $errorString) = $SCST->targets($driver); foreach my $target (@{$targets}) { $new{'TARGET_DRIVER'}->{$driver}->{'TARGET'}->{$target}->{'LUN'}->{$lun}->{$device} = {}; } @@ -5573,8 +5654,9 @@ sub readOldConfigFile { my $found_t = FALSE; # Find the associated target foreach my $driver (@{$drivers}) { - my ($targets, $errorString) = $SCST->targets($driver); + my $targets; + ($targets, $errorString) = $SCST->targets($driver); foreach my $target (@{$targets}) { if ($target eq $group_t) { foreach my $device (@{$config{'ASSIGNMENT'}->{$group}->{'DEVICE'}}) { @@ -5625,8 +5707,9 @@ sub readOldConfigFile { # Fill in with known targets, all disabled. foreach my $driver (@{$drivers}) { - my ($targets, $errorString) = $SCST->targets($driver); + my $targets; + ($targets, $errorString) = $SCST->targets($driver); foreach my $target (@{$targets}) { addAllGroupsToTarget(\%config, \%new, $driver, $target); } @@ -5644,8 +5727,9 @@ sub readOldConfigFile { foreach my $driver (keys %{$new{'TARGET_DRIVER'}}) { next if ($driver =~ /^qla/); - my ($attributes, $errorString) = $SCST->driverAttributes($driver); + my $attributes; + ($attributes, $errorString) = $SCST->driverAttributes($driver); if (defined($$attributes{'enabled'})) { $new{'TARGET_DRIVER'}->{$driver}->{'enabled'}->{'1'} = {}; } @@ -5757,7 +5841,7 @@ sub arrayHasValue { sub configToAttr { my $config = shift; - my %attributes; + my %attributes = ( ); foreach my $attr (keys %{$config}) { if (!scalar keys %{$$config{$attr}}) { @@ -5851,7 +5935,8 @@ sub prompt { "are you sure you wish to continue (y/[n]) ? "; my $answer = ; - if (($answer =~ /^y$/i) || ($answer =~ /^yes$/i)) { + if (defined($answer) && + (($answer =~ /^y$/i) || ($answer =~ /^yes$/i))) { return FALSE; }