Merge branch 'svn-trunk'

This commit is contained in:
Bart Van Assche
2019-02-21 08:08:39 -08:00
22 changed files with 1515 additions and 506 deletions
+39 -12
View File
@@ -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
+5 -4
View File
@@ -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
+7 -5
View File
@@ -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)
+102 -112
View File
@@ -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");
+117 -73
View File
@@ -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)
{
+41 -1
View File
@@ -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);
+1
View File
@@ -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);
+30 -7
View File
@@ -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 <attribute> <value>\" >mgmt\n"
" echo \"del_attribute <attribute> <value>\" >mgmt\n" : "",
@@ -5796,10 +5820,7 @@ static ssize_t scst_devt_mgmt_show(struct kobject *kobj,
" echo \"del_device_attribute device_name <attribute> <value>\" >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,
+5
View File
@@ -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.
@@ -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 <bvanassche@acm.org>.
# Copyright (c) 2011-2019 Bart Van Assche <bvanassche@acm.org>.
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;
@@ -1,6 +1,7 @@
#!perl
use strict;
use warnings;
use Test;
BEGIN {
@@ -1,6 +1,7 @@
#!perl
use strict;
use warnings;
use Test;
BEGIN {
@@ -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) {
@@ -1,6 +1,7 @@
#!perl
use strict;
use warnings;
use Test;
BEGIN {
@@ -1,6 +1,7 @@
#!perl
use strict;
use warnings;
use Test;
BEGIN {
@@ -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));
@@ -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
}
}
}
@@ -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 </dev/null"), $result);
}
# Test the scstadmin -list_* options.
sub listTest {
my $result;
$result = <<'EOS';
Collecting current configuration: done.
Handler
-------------
vcdrom
vdisk_blockio
vdisk_fileio
vdisk_nullio
All done.
EOS
ok(run("$scstadmin -list_handler"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Handler Device
-----------------------
vcdrom -
vdisk_blockio -
vdisk_fileio disk0
disk1
vdisk_nullio nodev
All done.
EOS
ok(run("$scstadmin -list_device"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
------------------------------------------------------------------------
filename /dev/scstadmin-regression-test-vdisk Yes Yes
read_only 1 No Yes
size 1048576 No Yes
All done.
EOS
ok(run("$scstadmin -list_device disk0"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Device Group
------------
dgroup1
dgroup2
All done.
EOS
ok(run("$scstadmin -list_dgrp"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Targets
-------
All done.
EOS
ok(run("$scstadmin -list_tgrp tgrp -dev_group dgroup1"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Driver
------------
copy_manager
ib_srpt
iscsi
scst_local
All done.
EOS
ok(run("$scstadmin -list_driver"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Driver Target
-----------------------------
copy_manager copy_manager_tgt
scst_local local
All done.
EOS
ok(run("$scstadmin -list_target"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Driver: copy_manager
Target: copy_manager_tgt
Assigned LUNs:
LUN Device
----------
10 disk1
8 nodev
9 disk0
Driver: scst_local
Target: local
Assigned LUNs:
LUN Device
----------
0 nodev
Group: ig
Assigned LUNs:
LUN Device
----------
0 disk0
1 disk1
Assigned Initiators:
Initiator
----
ini1
ini2
All done.
EOS
ok(run("$scstadmin -list_group"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
-----------------------------------------
(none)
All done.
EOS
ok(run("$scstadmin -list_scst_attr"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
-----------------------------------------
(none)
Device CREATE attributes available
----------------------------------
tst
All done.
EOS
ok(run("$scstadmin -list_hnd_attr vcdrom"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
-----------------------------------------
(none)
Device CREATE attributes available
----------------------------------
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
All done.
EOS
ok(run("$scstadmin -list_hnd_attr vdisk_blockio"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
-----------------------------------------
(none)
Device CREATE attributes available
----------------------------------
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
All done.
EOS
ok(run("$scstadmin -list_hnd_attr vdisk_fileio"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
-----------------------------------------
(none)
Device CREATE attributes available
----------------------------------
blocksize
cluster_mode
dif_mode
dif_static_app_tag
dif_type
dummy
numa_node_id
read_only
removable
rotational
size
size_mb
tst
All done.
EOS
ok(run("$scstadmin -list_hnd_attr vdisk_nullio"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
------------------------------------------------------------------------
filename /dev/scstadmin-regression-test-vdisk Yes Yes
read_only 1 No Yes
size 1048576 No Yes
All done.
EOS
ok(run("$scstadmin -list_dev_attr disk0"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
------------------------------------------------------------------------
filename /dev/scstadmin-regression-test-vdisk Yes Yes
nv_cache 1 No Yes
size 1048576 No Yes
All done.
EOS
ok(run("$scstadmin -list_dev_attr disk1"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
-----------------------------------------
(none)
All done.
EOS
ok(run("$scstadmin -list_drv_attr ib_srpt"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
------------------------------------------
group_id 256 Yes Yes
state active Yes Yes
All done.
EOS
ok(run("$scstadmin -list_tgrp_attr tgroup1 -dev_group dgroup1"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
-----------------------------------------
(none)
All done.
EOS
ok(run("$scstadmin -list_ttgt_attr local -tgt_group tgroup1 -dev_group dgroup1"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
-----------------------------------------
(none)
LUN CREATE attributes available
-------------------------------
read_only
All done.
EOS
ok(run("$scstadmin -list_tgt_attr local -driver scst_local"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
-----------------------------------------
(none)
LUN CREATE attributes available
-------------------------------
read_only
All done.
EOS
ok(run("$scstadmin -list_grp_attr ig -driver scst_local -target local -group ip"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
-----------------------------------------
(none)
All done.
EOS
ok(run("$scstadmin -list_lun_attr 0 -driver scst_local -target local"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Attribute Value Writable KEY
-----------------------------------------
(none)
All done.
EOS
ok(run("$scstadmin -list_lun_attr 1 -driver scst_local -target local -group ig"), $result);
$result = <<'EOS';
Collecting current configuration: done.
WARNING: Received the following error:
initiatorAttributes(): Unable to read directory '/sys/kernel/scst_tgt/targets/scst_local/local/ini_groups/ig/initiators/ini1': Bad file descriptor
All done.
EOS
ok(run("$scstadmin -list_init_attr ini1 -driver scst_local -target local -group ig"), $result);
$result = <<'EOS';
Collecting current configuration: done.
WARNING: Received the following error:
initiatorAttributes(): Unable to read directory '/sys/kernel/scst_tgt/targets/scst_local/local/ini_groups/ig/initiators/ini2': Bad file descriptor
All done.
EOS
ok(run("$scstadmin -list_init_attr ini2 -driver scst_local -target local -group ig"), $result);
$result = <<'EOS';
Collecting current configuration: done.
Driver/Target: copy_manager/copy_manager_tgt
Session: copy_manager_sess
Attribute Value Writable KEY
---------------------------------------------------------------------
active_commands 0 Yes No
bidi_cmd_count 0 Yes No
bidi_io_count_kb 0 Yes No
bidi_unaligned_cmd_count 0 Yes No
commands 0 Yes No
dif_checks_failed app ref guard Yes No
initiator_name copy_manager_sess Yes No
none_cmd_count 0 Yes No
read_cmd_count 11 Yes No
read_io_count_kb 44 Yes No
read_unaligned_cmd_count 0 Yes No
unknown_cmd_count 0 Yes No
write_cmd_count 0 Yes No
write_io_count_kb 0 Yes No
write_unaligned_cmd_count 0 Yes No
Driver/Target: scst_local/local
(no sessions)
All done.
EOS
ok(run("$scstadmin -list_sessions"), $result);
}
my $_DEBUG_ = 0;
if ($_DEBUG_) {
$redirect = ">>$redirect_file";
$redirect = ">>$redirect_file 2>&1";
open(my $logfile, '>>', $redirect_file);
select $logfile;
} else {
@@ -95,4 +622,8 @@ setup($SCST);
attributeTest(File::Spec->catfile($testdir, "07-result.conf"));
testPrompt();
listTest();
teardown();
@@ -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");
@@ -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;
@@ -1,6 +1,7 @@
#!perl
use strict;
use warnings;
use Test;
BEGIN {
File diff suppressed because it is too large Load Diff