aboutsummaryrefslogtreecommitdiff
path: root/sys/cam
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2014-10-10 19:41:09 +0000
committerAlexander Motin <mav@FreeBSD.org>2014-10-10 19:41:09 +0000
commit19720f4113964e8a7e1c122471d469b9c02322db (patch)
treed1a00a90a72ae29ed58f4ac2ec1e1c0ee65c9ea7 /sys/cam
parente33dfddd037c2a84f69facb426cee2b03ba5479b (diff)
downloadsrc-19720f4113964e8a7e1c122471d469b9c02322db.tar.gz
src-19720f4113964e8a7e1c122471d469b9c02322db.zip
Make ctld start even if some LUNs are unable to open backing storage.
Such LUNs will be visible to initiators, but return "not ready" status on media access commands. If backing storage become available later, `ctladm modify ...` or `service ctld reload` can trigger its reopen.
Notes
Notes: svn path=/head/; revision=272911
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ctl/ctl.c3
-rw-r--r--sys/cam/ctl/ctl_backend.h5
-rw-r--r--sys/cam/ctl/ctl_backend_block.c160
-rw-r--r--sys/cam/ctl/ctl_cmd_table.c22
-rw-r--r--sys/cam/ctl/ctl_ioctl.h3
5 files changed, 107 insertions, 86 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 7edf582534ae..622aeee9c2f0 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -4599,6 +4599,9 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
be_lun->ctl_lun = lun;
be_lun->lun_id = lun_number;
atomic_add_int(&be_lun->be->num_luns, 1);
+ if (be_lun->flags & CTL_LUN_FLAG_OFFLINE)
+ lun->flags |= CTL_LUN_OFFLINE;
+
if (be_lun->flags & CTL_LUN_FLAG_POWERED_OFF)
lun->flags |= CTL_LUN_STOPPED;
diff --git a/sys/cam/ctl/ctl_backend.h b/sys/cam/ctl/ctl_backend.h
index d8e78ab477ad..fab34adb47fa 100644
--- a/sys/cam/ctl/ctl_backend.h
+++ b/sys/cam/ctl/ctl_backend.h
@@ -73,6 +73,8 @@
* The DEV_TYPE flag tells us that the device_type field is filled in.
*
* The UNMAP flag tells us that this LUN supports UNMAP.
+ *
+ * The OFFLINE flag tells us that this LUN can not access backing store.
*/
typedef enum {
CTL_LUN_FLAG_ID_REQ = 0x01,
@@ -82,7 +84,8 @@ typedef enum {
CTL_LUN_FLAG_SERIAL_NUM = 0x10,
CTL_LUN_FLAG_DEVID = 0x20,
CTL_LUN_FLAG_DEV_TYPE = 0x40,
- CTL_LUN_FLAG_UNMAP = 0x80
+ CTL_LUN_FLAG_UNMAP = 0x80,
+ CTL_LUN_FLAG_OFFLINE = 0x100
} ctl_backend_lun_flags;
#ifdef _KERNEL
diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c
index eb16474a247b..e9852348513c 100644
--- a/sys/cam/ctl/ctl_backend_block.c
+++ b/sys/cam/ctl/ctl_backend_block.c
@@ -151,6 +151,7 @@ typedef void (*cbb_dispatch_t)(struct ctl_be_block_lun *be_lun,
* and a backend block LUN, and between a backend block LUN and a CTL LUN.
*/
struct ctl_be_block_lun {
+ struct ctl_lun_create_params params;
struct ctl_block_disk *disk;
char lunname[32];
char *dev_path;
@@ -1521,7 +1522,7 @@ ctl_be_block_ioctl(struct cdev *dev, u_long cmd, caddr_t addr,
default:
lun_req->status = CTL_LUN_ERROR;
snprintf(lun_req->error_str, sizeof(lun_req->error_str),
- "%s: invalid LUN request type %d", __func__,
+ "invalid LUN request type %d",
lun_req->reqtype);
break;
}
@@ -1545,7 +1546,7 @@ ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
error = 0;
file_data = &be_lun->backend.file;
- params = &req->reqdata.create;
+ params = &be_lun->params;
be_lun->dev_type = CTL_BE_BLOCK_FILE;
be_lun->dispatch = ctl_be_block_dispatch_file;
@@ -1628,7 +1629,7 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
int error;
off_t ps, pss, po, pos;
- params = &req->reqdata.create;
+ params = &be_lun->params;
be_lun->dev_type = CTL_BE_BLOCK_DEV;
be_lun->backend.dev.cdev = be_lun->vn->v_rdev;
@@ -1646,8 +1647,8 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
error = VOP_GETATTR(be_lun->vn, &vattr, NOCRED);
if (error) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: error getting vnode attributes for device %s",
- __func__, be_lun->dev_path);
+ "error getting vnode attributes for device %s",
+ be_lun->dev_path);
return (error);
}
@@ -1655,7 +1656,7 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
devsw = dev->si_devsw;
if (!devsw->d_ioctl) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: no d_ioctl for device %s!", __func__,
+ "no d_ioctl for device %s!",
be_lun->dev_path);
return (ENODEV);
}
@@ -1665,8 +1666,8 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
curthread);
if (error) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: error %d returned for DIOCGSECTORSIZE ioctl "
- "on %s!", __func__, error, be_lun->dev_path);
+ "error %d returned for DIOCGSECTORSIZE ioctl "
+ "on %s!", error, be_lun->dev_path);
return (error);
}
@@ -1688,9 +1689,9 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
be_lun->blocksize = params->blocksize_bytes;
} else {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: requested blocksize %u is not an even "
+ "requested blocksize %u is not an even "
"multiple of backing device blocksize %u",
- __func__, params->blocksize_bytes,
+ params->blocksize_bytes,
be_lun->blocksize);
return (EINVAL);
@@ -1698,8 +1699,8 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
} else if ((params->blocksize_bytes != 0)
&& (params->blocksize_bytes != be_lun->blocksize)) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: requested blocksize %u < backing device "
- "blocksize %u", __func__, params->blocksize_bytes,
+ "requested blocksize %u < backing device "
+ "blocksize %u", params->blocksize_bytes,
be_lun->blocksize);
return (EINVAL);
}
@@ -1709,8 +1710,8 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
curthread);
if (error) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: error %d returned for DIOCGMEDIASIZE "
- " ioctl on %s!", __func__, error,
+ "error %d returned for DIOCGMEDIASIZE "
+ " ioctl on %s!", error,
be_lun->dev_path);
return (error);
}
@@ -1718,8 +1719,8 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
if (params->lun_size_bytes != 0) {
if (params->lun_size_bytes > be_lun->size_bytes) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: requested LUN size %ju > backing device "
- "size %ju", __func__,
+ "requested LUN size %ju > backing device "
+ "size %ju",
(uintmax_t)params->lun_size_bytes,
(uintmax_t)be_lun->size_bytes);
return (EINVAL);
@@ -1792,6 +1793,7 @@ ctl_be_block_close(struct ctl_be_block_lun *be_lun)
panic("Unexpected backend type.");
break;
}
+ be_lun->dev_type = CTL_BE_BLOCK_NONE;
}
PICKUP_GIANT();
@@ -1814,7 +1816,7 @@ ctl_be_block_open(struct ctl_be_block_softc *softc,
if (rootvnode == NULL) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: Root filesystem is not mounted", __func__);
+ "Root filesystem is not mounted");
return (1);
}
@@ -1858,7 +1860,7 @@ ctl_be_block_open(struct ctl_be_block_softc *softc,
}
}
snprintf(req->error_str, sizeof(req->error_str),
- "%s: error opening %s", __func__, be_lun->dev_path);
+ "error opening %s: %d", be_lun->dev_path, error);
return (error);
}
@@ -1902,11 +1904,13 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
params = &req->reqdata.create;
retval = 0;
+ req->status = CTL_LUN_OK;
num_threads = cbb_num_threads;
be_lun = malloc(sizeof(*be_lun), M_CTLBLK, M_ZERO | M_WAITOK);
+ be_lun->params = req->reqdata.create;
be_lun->softc = softc;
STAILQ_INIT(&be_lun->input_queue);
STAILQ_INIT(&be_lun->config_write_queue);
@@ -1922,7 +1926,7 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
if (be_lun->lun_zone == NULL) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: error allocating UMA zone", __func__);
+ "error allocating UMA zone");
goto bailout_error;
}
@@ -1935,26 +1939,18 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
value = ctl_get_opt(&be_lun->ctl_be_lun.options, "file");
if (value == NULL) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: no file argument specified", __func__);
+ "no file argument specified");
goto bailout_error;
}
be_lun->dev_path = strdup(value, M_CTLBLK);
+ be_lun->blocksize = 512;
+ be_lun->blocksize_shift = fls(be_lun->blocksize) - 1;
retval = ctl_be_block_open(softc, be_lun, req);
if (retval != 0) {
retval = 0;
- goto bailout_error;
+ req->status = CTL_LUN_WARNING;
}
-
- /*
- * Tell the user the size of the file/device.
- */
- params->lun_size_bytes = be_lun->size_bytes;
-
- /*
- * The maximum LBA is the size - 1.
- */
- be_lun->ctl_be_lun.maxlba = be_lun->size_blocks - 1;
} else {
/*
* For processor devices, we don't have any size.
@@ -1965,7 +1961,6 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
be_lun->size_blocks = 0;
be_lun->size_bytes = 0;
be_lun->ctl_be_lun.maxlba = 0;
- params->lun_size_bytes = 0;
/*
* Default to just 1 thread for processor devices.
@@ -1988,8 +1983,8 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
*/
if (tmp_num_threads < 1) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: invalid number of threads %s",
- __func__, num_thread_str);
+ "invalid number of threads %s",
+ num_thread_str);
goto bailout_error;
}
num_threads = tmp_num_threads;
@@ -2001,16 +1996,22 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
be_lun->flags = CTL_BE_BLOCK_LUN_UNCONFIGURED;
be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY;
+ if (be_lun->vn == NULL)
+ be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_OFFLINE;
if (unmap)
be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_UNMAP;
- if (be_lun->dispatch == ctl_be_block_dispatch_zvol)
- be_lun->ctl_be_lun.atomicblock = CTLBLK_MAX_IO_SIZE /
- be_lun->blocksize;
be_lun->ctl_be_lun.be_lun = be_lun;
+ be_lun->ctl_be_lun.maxlba = (be_lun->size_blocks == 0) ?
+ 0 : (be_lun->size_blocks - 1);
be_lun->ctl_be_lun.blocksize = be_lun->blocksize;
be_lun->ctl_be_lun.pblockexp = be_lun->pblockexp;
be_lun->ctl_be_lun.pblockoff = be_lun->pblockoff;
+ if (be_lun->dispatch == ctl_be_block_dispatch_zvol &&
+ be_lun->blocksize != 0)
+ be_lun->ctl_be_lun.atomicblock = CTLBLK_MAX_IO_SIZE /
+ be_lun->blocksize;
/* Tell the user the blocksize we ended up using */
+ params->lun_size_bytes = be_lun->size_bytes;
params->blocksize_bytes = be_lun->blocksize;
if (params->flags & CTL_LUN_FLAG_ID_REQ) {
be_lun->ctl_be_lun.req_lun_id = params->req_lun_id;
@@ -2062,7 +2063,7 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
if (be_lun->io_taskqueue == NULL) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: Unable to create taskqueue", __func__);
+ "unable to create taskqueue");
goto bailout_error;
}
@@ -2105,8 +2106,8 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
softc->num_luns--;
mtx_unlock(&softc->lock);
snprintf(req->error_str, sizeof(req->error_str),
- "%s: ctl_add_lun() returned error %d, see dmesg for "
- "details", __func__, retval);
+ "ctl_add_lun() returned error %d, see dmesg for "
+ "details", retval);
retval = 0;
goto bailout_error;
}
@@ -2128,8 +2129,7 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
if (be_lun->flags & CTL_BE_BLOCK_LUN_CONFIG_ERR) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: LUN configuration error, see dmesg for details",
- __func__);
+ "LUN configuration error, see dmesg for details");
STAILQ_REMOVE(&softc->lun_list, be_lun, ctl_be_block_lun,
links);
softc->num_luns--;
@@ -2148,9 +2148,6 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
| DEVSTAT_TYPE_IF_OTHER,
DEVSTAT_PRIORITY_OTHER);
-
- req->status = CTL_LUN_OK;
-
return (retval);
bailout_error:
@@ -2192,8 +2189,8 @@ ctl_be_block_rm(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
if (be_lun == NULL) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: LUN %u is not managed by the block backend",
- __func__, params->lun_id);
+ "LUN %u is not managed by the block backend",
+ params->lun_id);
goto bailout_error;
}
@@ -2201,8 +2198,8 @@ ctl_be_block_rm(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
if (retval != 0) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: error %d returned from ctl_disable_lun() for "
- "LUN %d", __func__, retval, params->lun_id);
+ "error %d returned from ctl_disable_lun() for "
+ "LUN %d", retval, params->lun_id);
goto bailout_error;
}
@@ -2210,8 +2207,8 @@ ctl_be_block_rm(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
retval = ctl_invalidate_lun(&be_lun->ctl_be_lun);
if (retval != 0) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: error %d returned from ctl_invalidate_lun() for "
- "LUN %d", __func__, retval, params->lun_id);
+ "error %d returned from ctl_invalidate_lun() for "
+ "LUN %d", retval, params->lun_id);
goto bailout_error;
}
@@ -2229,8 +2226,7 @@ ctl_be_block_rm(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
if ((be_lun->flags & CTL_BE_BLOCK_LUN_UNCONFIGURED) == 0) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: interrupted waiting for LUN to be freed",
- __func__);
+ "interrupted waiting for LUN to be freed");
mtx_unlock(&softc->lock);
goto bailout_error;
}
@@ -2274,9 +2270,7 @@ ctl_be_block_modify_file(struct ctl_be_block_lun *be_lun,
{
struct vattr vattr;
int error;
- struct ctl_lun_modify_params *params;
-
- params = &req->reqdata.modify;
+ struct ctl_lun_create_params *params = &be_lun->params;
if (params->lun_size_bytes != 0) {
be_lun->size_bytes = params->lun_size_bytes;
@@ -2303,16 +2297,13 @@ ctl_be_block_modify_dev(struct ctl_be_block_lun *be_lun,
{
struct ctl_be_block_devdata *dev_data;
int error;
- struct ctl_lun_modify_params *params;
+ struct ctl_lun_create_params *params = &be_lun->params;
uint64_t size_bytes;
- params = &req->reqdata.modify;
-
dev_data = &be_lun->backend.dev;
if (!dev_data->csw->d_ioctl) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: no d_ioctl for device %s!", __func__,
- be_lun->dev_path);
+ "no d_ioctl for device %s!", be_lun->dev_path);
return (ENODEV);
}
@@ -2321,16 +2312,16 @@ ctl_be_block_modify_dev(struct ctl_be_block_lun *be_lun,
curthread);
if (error) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: error %d returned for DIOCGMEDIASIZE ioctl "
- "on %s!", __func__, error, be_lun->dev_path);
+ "error %d returned for DIOCGMEDIASIZE ioctl "
+ "on %s!", error, be_lun->dev_path);
return (error);
}
if (params->lun_size_bytes != 0) {
if (params->lun_size_bytes > size_bytes) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: requested LUN size %ju > backing device "
- "size %ju", __func__,
+ "requested LUN size %ju > backing device "
+ "size %ju",
(uintmax_t)params->lun_size_bytes,
(uintmax_t)size_bytes);
return (EINVAL);
@@ -2355,9 +2346,7 @@ ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
params = &req->reqdata.modify;
mtx_lock(&softc->lock);
-
be_lun = NULL;
-
STAILQ_FOREACH(be_lun, &softc->lun_list, links) {
if (be_lun->ctl_be_lun.lun_id == params->lun_id)
break;
@@ -2366,29 +2355,22 @@ ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
if (be_lun == NULL) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: LUN %u is not managed by the block backend",
- __func__, params->lun_id);
+ "LUN %u is not managed by the block backend",
+ params->lun_id);
goto bailout_error;
}
- if (params->lun_size_bytes != 0) {
- if (params->lun_size_bytes < be_lun->blocksize) {
- snprintf(req->error_str, sizeof(req->error_str),
- "%s: LUN size %ju < blocksize %u", __func__,
- params->lun_size_bytes, be_lun->blocksize);
- goto bailout_error;
- }
- }
+ be_lun->params.lun_size_bytes = params->lun_size_bytes;
- oldsize = be_lun->size_bytes;
- if (be_lun->vn->v_type == VREG)
+ oldsize = be_lun->size_blocks;
+ if (be_lun->vn == NULL)
+ error = ctl_be_block_open(softc, be_lun, req);
+ else if (be_lun->vn->v_type == VREG)
error = ctl_be_block_modify_file(be_lun, req);
else
error = ctl_be_block_modify_dev(be_lun, req);
- if (error != 0)
- goto bailout_error;
- if (be_lun->size_bytes != oldsize) {
+ if (error == 0 && be_lun->size_blocks != oldsize) {
be_lun->size_blocks = be_lun->size_bytes >>
be_lun->blocksize_shift;
@@ -2398,14 +2380,24 @@ ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
* XXX: Note that this field is being updated without locking,
* which might cause problems on 32-bit architectures.
*/
- be_lun->ctl_be_lun.maxlba = be_lun->size_blocks - 1;
+ be_lun->ctl_be_lun.maxlba = (be_lun->size_blocks == 0) ?
+ 0 : (be_lun->size_blocks - 1);
+ be_lun->ctl_be_lun.blocksize = be_lun->blocksize;
+ be_lun->ctl_be_lun.pblockexp = be_lun->pblockexp;
+ be_lun->ctl_be_lun.pblockoff = be_lun->pblockoff;
+ if (be_lun->dispatch == ctl_be_block_dispatch_zvol &&
+ be_lun->blocksize != 0)
+ be_lun->ctl_be_lun.atomicblock = CTLBLK_MAX_IO_SIZE /
+ be_lun->blocksize;
ctl_lun_capacity_changed(&be_lun->ctl_be_lun);
+ if (oldsize == 0 && be_lun->size_blocks != 0)
+ ctl_lun_online(&be_lun->ctl_be_lun);
}
/* Tell the user the exact size we ended up using */
params->lun_size_bytes = be_lun->size_bytes;
- req->status = CTL_LUN_OK;
+ req->status = error ? CTL_LUN_WARNING : CTL_LUN_OK;
return (0);
diff --git a/sys/cam/ctl/ctl_cmd_table.c b/sys/cam/ctl/ctl_cmd_table.c
index e2323a2cb342..f1093005d28b 100644
--- a/sys/cam/ctl/ctl_cmd_table.c
+++ b/sys/cam/ctl/ctl_cmd_table.c
@@ -70,6 +70,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5e[32] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
@@ -81,6 +82,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5e[32] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
@@ -92,6 +94,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5e[32] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
@@ -103,6 +106,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5e[32] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
@@ -120,6 +124,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_OUT |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
@@ -131,6 +136,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_OUT |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
@@ -142,6 +148,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_OUT |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
@@ -153,6 +160,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_OUT |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
@@ -164,6 +172,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_OUT |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
@@ -178,6 +187,7 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_OUT |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
@@ -460,6 +470,7 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
{ctl_report_tagret_port_groups, CTL_SERIDX_INQ, CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN,
CTL_LUN_PAT_NONE,
@@ -472,6 +483,7 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
{ctl_report_supported_opcodes, CTL_SERIDX_INQ, CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
@@ -482,6 +494,7 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
{ctl_report_supported_tmf, CTL_SERIDX_INQ, CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
@@ -495,6 +508,7 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
{ctl_report_timestamp, CTL_SERIDX_INQ, CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN,
CTL_LUN_PAT_NONE,
@@ -601,6 +615,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
{ctl_mode_select, CTL_SERIDX_MD_SEL, CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_OUT,
CTL_LUN_PAT_NONE, 6, {0x11, 0, 0, 0xff, 0x07}},
@@ -610,6 +625,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_OUT,
CTL_LUN_PAT_NONE, 6, {0, 0, 0, 0, 0x07}},
@@ -619,6 +635,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_NONE,
CTL_LUN_PAT_NONE, 6, {0, 0, 0, 0, 0x07}},
@@ -633,6 +650,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
{ctl_mode_sense, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
@@ -855,6 +873,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
{ctl_mode_select, CTL_SERIDX_MD_SEL, CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_OUT,
CTL_LUN_PAT_NONE, 10, {0x11, 0, 0, 0, 0, 0, 0xff, 0xff, 0x07} },
@@ -864,6 +883,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_OUT,
CTL_LUN_PAT_NONE, 10, {0x02, 0, 0xff, 0, 0, 0, 0xff, 0xff, 0x07} },
@@ -873,6 +893,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_OUT,
CTL_LUN_PAT_NONE, 10, {0x02, 0, 0xff, 0, 0, 0, 0xff, 0xff, 0x07} },
@@ -887,6 +908,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
{ctl_mode_sense, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_BOTH |
CTL_CMD_FLAG_OK_ON_STOPPED |
CTL_CMD_FLAG_OK_ON_INOPERABLE |
+ CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
diff --git a/sys/cam/ctl/ctl_ioctl.h b/sys/cam/ctl/ctl_ioctl.h
index a90475b8fcf5..7640313a61f9 100644
--- a/sys/cam/ctl/ctl_ioctl.h
+++ b/sys/cam/ctl/ctl_ioctl.h
@@ -363,7 +363,8 @@ struct ctl_port_list {
typedef enum {
CTL_LUN_NOSTATUS,
CTL_LUN_OK,
- CTL_LUN_ERROR
+ CTL_LUN_ERROR,
+ CTL_LUN_WARNING
} ctl_lun_status;
#define CTL_ERROR_STR_LEN 160