mirror of
https://github.com/SCST-project/scst.git
synced 2026-07-25 01:23:14 +00:00
Merge branch 'svn-trunk'
This commit is contained in:
+39
-12
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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");
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+273
-188
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user