scst_vdisk: Add support for nullio "dummy" LUNs

While the SCSI specifications require presence of LUN 0 it is not always
desirable to associate storage with LUN 0. Hence allow LUN 0 (or any
other LUN) to be configured such that it does not appear at the
initiator side. This is realized by adding a "dummy" attribute in to
NULLIO vdisk devices. If that attribute is set, the PERIPHERAL QUALIFIER
field in the INQUIRY response is set to 1 and the PERIPHERAL DEVICE TYPE
is set to 0x1f. Add an example in the scst.conf(5) man page that shows
how to use the new attribute.

Signed-off-by: Bart Van Assche <bvanassche@acm.org> with some fixes and simplifications



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4874 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2013-05-22 03:48:26 +00:00
parent b0133418e3
commit 84f6cb5dae
4 changed files with 74 additions and 9 deletions

View File

@@ -914,6 +914,15 @@ Intended to be used for performance measurements at the same way as
blocksize, read_only, removable. See vdisk_fileio above for description
of those parameters.
vdisk_nullio also has extra attribute:
- dummy - if this flag is set, LUNs corresponding to this device will
not appear at the initiator side. This is because SCST will set the
PERIPHERAL QUALIFIER qualifier field to 1 (not connected) and the
PERIPHERAL DEVICE TYPE to 0x1f (no device) in the INQUIRY response.
See also SPC-4 for more information. It is designed to be used as a
"dummy" placeholder on LUN 0, if LUN 0 is not desired.
Handler vcdrom allows emulation of a virtual CDROM device using an ISO
file as backend. It doesn't have any parameters.
@@ -1007,7 +1016,7 @@ description of those parameters.
Each vdisk_nullio's device has the following attributes in
/sys/kernel/scst_tgt/devices/device_name: blocksize, read_only,
removable, size_mb, t10_dev_id, threads_num, threads_pool_type, type,
usn. See above description of those parameters.
usn, dummy. See above description of those parameters.
Each vcdrom's device has the following attributes in
/sys/kernel/scst_tgt/devices/device_name: filename, size_mb,

View File

@@ -772,6 +772,15 @@ Intended to be used for performance measurements at the same way as
blocksize, read_only, removable. See vdisk_fileio above for description
of those parameters.
vdisk_nullio also has extra attribute:
- dummy - if this flag is set, LUNs corresponding to this device will
not appear at the initiator side. This is because SCST will set the
PERIPHERAL QUALIFIER qualifier field to 1 (not connected) and the
PERIPHERAL DEVICE TYPE to 0x1f (no device) in the INQUIRY response.
See also SPC-4 for more information. It is designed to be used as a
"dummy" placeholder on LUN 0, if LUN 0 is not desired.
Handler vcdrom allows emulation of a virtual CDROM device using an ISO
file as backend. It doesn't have any parameters.
@@ -859,7 +868,7 @@ description of those parameters.
Each vdisk_nullio's device has the following attributes in
/sys/kernel/scst_tgt/devices/device_name: blocksize, read_only,
removable, size_mb, t10_dev_id, threads_num, threads_pool_type, type,
usn. See above description of those parameters.
usn, dummy. See above description of those parameters.
Each vcdrom's device has the following attributes in
/sys/kernel/scst_tgt/devices/device_name: filename, size_mb,

View File

@@ -107,6 +107,7 @@ static struct scst_trace_log vdisk_local_trace_tbl[] = {
#define DEF_WRITE_THROUGH 0
#define DEF_NV_CACHE 0
#define DEF_O_DIRECT 0
#define DEF_DUMMY 0
#define DEF_REMOVABLE 0
#define DEF_ROTATIONAL 1
#define DEF_THIN_PROVISIONED 0
@@ -155,6 +156,7 @@ struct scst_vdisk_dev {
unsigned int nullio:1;
unsigned int blockio:1;
unsigned int cdrom_empty:1;
unsigned int dummy:1;
unsigned int removable:1;
unsigned int thin_provisioned:1;
unsigned int thin_provisioned_manually_set:1;
@@ -305,6 +307,8 @@ static ssize_t vdisk_sysfs_nv_cache_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf);
static ssize_t vdisk_sysfs_o_direct_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf);
static ssize_t vdev_sysfs_dummy_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf);
static ssize_t vdisk_sysfs_removable_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf);
static ssize_t vdev_sysfs_filename_show(struct kobject *kobj,
@@ -341,6 +345,8 @@ static struct kobj_attribute vdisk_nv_cache_attr =
__ATTR(nv_cache, S_IRUGO, vdisk_sysfs_nv_cache_show, NULL);
static struct kobj_attribute vdisk_o_direct_attr =
__ATTR(o_direct, S_IRUGO, vdisk_sysfs_o_direct_show, NULL);
static struct kobj_attribute vdev_dummy_attr =
__ATTR(dummy, S_IWUSR|S_IRUGO, vdev_sysfs_dummy_show, NULL);
static struct kobj_attribute vdisk_removable_attr =
__ATTR(removable, S_IRUGO, vdisk_sysfs_removable_show, NULL);
static struct kobj_attribute vdisk_filename_attr =
@@ -397,6 +403,7 @@ static const struct attribute *vdisk_nullio_attrs[] = {
&vdev_size_attr.attr,
&vdisk_blocksize_attr.attr,
&vdisk_rd_only_attr.attr,
&vdev_dummy_attr.attr,
&vdisk_removable_attr.attr,
&vdev_t10_dev_id_attr.attr,
&vdev_usn_attr.attr,
@@ -530,7 +537,8 @@ 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, read_only, removable, rotational",
.add_device_parameters = "blocksize, read_only, dummy, removable,"
" rotational",
#endif
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
.default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
@@ -2178,7 +2186,8 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p)
goto out_put;
}
buf[0] = dev->type; /* type dev */
buf[0] = virt_dev->dummy ? SCSI_INQ_PQ_NOT_CON << 5 | 0x1f :
SCSI_INQ_PQ_CON << 5 | dev->type;
/* Vital Product */
if (cmd->cdb[1] & EVPD) {
if (0 == cmd->cdb[2]) {
@@ -4267,6 +4276,10 @@ static void vdisk_report_registering(const struct scst_vdisk_dev *virt_dev)
i += snprintf(&buf[i], sizeof(buf) - i, "%sZERO_COPY",
(j == i) ? "(" : ", ");
if (virt_dev->dummy)
i += snprintf(&buf[i], sizeof(buf) - i, "%sDUMMY",
(j == i) ? "(" : ", ");
if (j == i)
PRINT_INFO("%s", buf);
else
@@ -4342,6 +4355,7 @@ static int vdev_create(struct scst_dev_type *devt,
virt_dev->vdev_devt = devt;
virt_dev->rd_only = DEF_RD_ONLY;
virt_dev->dummy = DEF_DUMMY;
virt_dev->removable = DEF_REMOVABLE;
virt_dev->rotational = DEF_ROTATIONAL;
virt_dev->thin_provisioned = DEF_THIN_PROVISIONED;
@@ -4395,7 +4409,7 @@ static void vdev_destroy(struct scst_vdisk_dev *virt_dev)
#ifndef CONFIG_SCST_PROC
static int vdev_parse_add_dev_params(struct scst_vdisk_dev *virt_dev,
char *params, const char *allowed_params[])
char *params, const char *const allowed_params[])
{
int res = 0;
unsigned long val;
@@ -4417,7 +4431,7 @@ static int vdev_parse_add_dev_params(struct scst_vdisk_dev *virt_dev,
}
if (allowed_params != NULL) {
const char **a = allowed_params;
const char *const *a = allowed_params;
bool allowed = false;
while (*a != NULL) {
@@ -4498,6 +4512,13 @@ static int vdev_parse_add_dev_params(struct scst_vdisk_dev *virt_dev,
} else if (!strcasecmp("read_only", p)) {
virt_dev->rd_only = val;
TRACE_DBG("READ ONLY %d", virt_dev->rd_only);
} else if (!strcasecmp("dummy", p)) {
if (val > 1) {
res = -EINVAL;
goto out;
}
virt_dev->dummy = val;
TRACE_DBG("DUMMY %d", virt_dev->dummy);
} else if (!strcasecmp("removable", p)) {
virt_dev->removable = val;
TRACE_DBG("REMOVABLE %d", virt_dev->removable);
@@ -4597,7 +4618,7 @@ out_destroy:
static int vdev_blockio_add_device(const char *device_name, char *params)
{
int res = 0;
const char *allowed_params[] = { "filename", "read_only", "write_through",
const char *const allowed_params[] = { "filename", "read_only", "write_through",
"removable", "blocksize", "nv_cache",
"rotational", "thin_provisioned", NULL };
struct scst_vdisk_dev *virt_dev;
@@ -4653,8 +4674,10 @@ out_destroy:
static int vdev_nullio_add_device(const char *device_name, char *params)
{
int res = 0;
const char *allowed_params[] = { "read_only", "removable",
"blocksize", "rotational", NULL };
static const char *const allowed_params[] = {
"read_only", "dummy", "removable", "blocksize", "rotational",
NULL
};
struct scst_vdisk_dev *virt_dev;
TRACE_ENTRY();
@@ -5240,6 +5263,17 @@ static ssize_t vdisk_sysfs_o_direct_show(struct kobject *kobj,
return pos;
}
static ssize_t vdev_sysfs_dummy_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct scst_device *dev = container_of(kobj, struct scst_device,
dev_kobj);
struct scst_vdisk_dev *virt_dev = dev->dh_priv;
return sprintf(buf, "%d\n%s", virt_dev->dummy,
virt_dev->dummy != DEF_DUMMY ? SCST_SYSFS_KEY_MARK "\n" : "");
}
static ssize_t vdisk_sysfs_removable_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{

View File

@@ -149,6 +149,16 @@ HANDLER vdisk_blockio {
.br
}
.IP
HANDLER vdisk_nullio {
.br
DEVICE dummy {
.br
dummy 1
.br
}
.br
}
.IP
HANDLER vcdrom {
.br
DEVICE cdrom1 {
@@ -208,6 +218,9 @@ TARGET_DRIVER qla2x00t {
TARGET 25:00:00:f0:98:87:92:f3 {
.br
enabled 1
.br
LUN 0 dummy
.br
.IP
GROUP INI1 {
.br