From dc1e3d786ab629dc391d27be6578f5c35078bf47 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Tue, 8 Dec 2020 17:06:40 +0000 Subject: [PATCH] Problem statement: Applications that are capable of running as Fibre Transport Target mode server need to able to function when running in containerized form factor in a secure and multi-tenant platform. Solution: Such applications when containerized can run in any container based platform such as Kubernetes/OpenShift or a custom one. These applications are generic in nature and all they need is access to SCST user storage device driver (/dev/scst_user). The security policy of the platform may not allow these applications to manage Fibre Channel (FC) port and /sys file-system. The platform, however, can manage the FC ports on behalf of these applications. The containerized applications can remain generic in nature and run on any containerized platforms. The sequence of operations would be 1. The platform converts the desired FC ports to target mode prior to starting the containerized application 2. The application does device registration using exported the SCST user storage device driver 3. The platform, at this point, asynchronously adds FC port LUNs to the user device registered by the application. As the application inside the container can auto or manual restart asynchronously, the platform would add the LUNs every time the application does device registration. Patch description: The SCST event mechanism is leveraged to achieve the asynchronous LUN additions when application does device registration. The current set of SCST events is extended to send a new event whenever there is a virtual user device registration happens. The platform can watch for the specific event and make business logic decisions to allow target mode applications function securely. By extending the set of event, the SCST module will be friendly to containerized applications and platforms. Signed-off-by: Vikas Goel git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9210 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/include/scst_event.h | 5 +++++ scst/src/scst_event.c | 39 +++++++++++++++++++++++++++++++++++++++ scst/src/scst_main.c | 1 + scst/src/scst_priv.h | 1 + usr/events/events.c | 10 ++++++++++ 5 files changed, 56 insertions(+) diff --git a/scst/include/scst_event.h b/scst/include/scst_event.h index ebcbd80c9..f18b1ea91 100644 --- a/scst/include/scst_event.h +++ b/scst/include/scst_event.h @@ -156,4 +156,9 @@ struct scst_event_stpg_payload { struct scst_event_stpg_descr stpg_descriptors[0]; }; +#define SCST_EVENT_REG_VIRT_DEV 6 +struct scst_event_reg_vdev_payload { + uint8_t device_name[SCST_MAX_NAME+10]; +}; + #endif /* __SCST_EVENT_H */ diff --git a/scst/src/scst_event.c b/scst/src/scst_event.c index 99fd3fd60..f86e5ca4e 100644 --- a/scst/src/scst_event.c +++ b/scst/src/scst_event.c @@ -484,6 +484,45 @@ out: return res; } +/* No locks */ +int scst_event_queue_reg_vdev(const char *dev_name) +{ + int res = 0, event_entry_len; + struct scst_event_entry *event_entry; + struct scst_event *event; + struct scst_event_reg_vdev_payload *payload; + + TRACE_ENTRY(); + + event_entry_len = sizeof(*event_entry) + sizeof(*payload); + event_entry = kzalloc(event_entry_len, GFP_ATOMIC); + if (event_entry == NULL) { + PRINT_ERROR("Unable to allocate event (size %d). Virtual " + "device registration event is lost (device name %s)!", + event_entry_len, dev_name); + res = -ENOMEM; + goto out; + } + + TRACE_MEM("event_entry %p (len %d) allocated", event_entry, + event_entry_len); + + event = &event_entry->event; + + event->payload_len = sizeof(*payload); + payload = (struct scst_event_reg_vdev_payload *)event->payload; + + strlcpy(payload->device_name, dev_name, + sizeof(payload->device_name)); + + scst_event_queue(SCST_EVENT_REG_VIRT_DEV, + SCST_EVENT_SCST_CORE_ISSUER, event_entry); + +out: + TRACE_EXIT_RES(res); + return res; +} + /* scst_event_mutex supposed to be held. Can release/reacquire it inside */ static void scst_release_event_entry(struct scst_event_entry *e) { diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index ac4474cee..f4f942a18 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -1383,6 +1383,7 @@ int scst_register_virtual_device_node(struct scst_dev_type *dev_handler, res = dev->virt_id; + scst_event_queue_reg_vdev(dev_name); PRINT_INFO("Attached to virtual device %s (id %d)", dev_name, res); out: diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index b2226fad8..21061c7a1 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -872,6 +872,7 @@ int scst_event_queue_negative_luns_inquiry(const struct scst_tgt *tgt, const char *initiator_name); int scst_event_queue_ext_blocking_done(struct scst_device *dev, void *data, int len); int scst_event_queue_tm_fn_received(struct scst_mgmt_cmd *mcmd); +int scst_event_queue_reg_vdev(const char *dev_name); typedef void __printf(2, 3) (*scst_show_fn)(void *arg, const char *fmt, ...); void scst_trace_cmds(scst_show_fn show, void *arg); diff --git a/usr/events/events.c b/usr/events/events.c index 5f0151e05..4e1f73425 100644 --- a/usr/events/events.c +++ b/usr/events/events.c @@ -85,6 +85,14 @@ static void usage(void) #endif } +static void handle_reg_vdev_received(struct scst_event_user *event_user) +{ + struct scst_event_reg_vdev_payload *p = (struct scst_event_reg_vdev_payload *)event_user->out_event.payload; + printf("Virtual device %s registration received.\n", p->device_name); + + return; +} + static void handle_tm_received(struct scst_event_user *event_user) { struct scst_event_tm_fn_received_payload *p = (struct scst_event_tm_fn_received_payload *)event_user->out_event.payload; @@ -278,6 +286,8 @@ again_poll: if (res != 0) PRINT_ERROR("SCST_EVENT_NOTIFY_DONE failed: %s " "(res %d)", strerror(errno), res); + } else if (event_user->out_event.event_code == SCST_EVENT_REG_VIRT_DEV) { + handle_reg_vdev_received(event_user); } else if (event_user->out_event.event_code == SCST_EVENT_TM_FN_RECEIVED) handle_tm_received(event_user); else if (event_user->out_event.event_code == SCST_EVENT_TM_FN_RECEIVED) {