target/iscsi_target: Add NodeACL tags for initiator group support
authorAndy Grover <agrover@redhat.com>
Wed, 12 Dec 2012 00:30:53 +0000 (16:30 -0800)
committerNicholas Bellinger <nab@linux-iscsi.org>
Thu, 13 Dec 2012 22:18:09 +0000 (14:18 -0800)
Thanks for reviews, looking a lot better.

---- 8< ----

Initiator access config could be easier. The way other storage vendors
have addressed this is to support initiator groups: the admin adds
initiator WWNs to the group, and then LUN permissions can be granted for
the entire group at once.

Instead of changing ktarget's configfs interface, this patch keeps
the configfs interface per-initiator-wwn and just adds a 'tag' field
for each. This should be enough for user tools like targetcli to group
initiator ACLs and sync their configurations.

acl_tag is not used internally, but needs to be kept in configfs so that
all user tools can avoid dependencies on each other.

Code tested to work, although userspace pieces still to be implemented.

Signed-off-by: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/iscsi/iscsi_target_configfs.c
drivers/target/target_core_tpg.c
include/target/target_core_base.h
include/target/target_core_fabric.h

index 542641c504a6d665f86bf63786245c3164eb770f..5201d5ef97007200166f9bf7a5ef742db1efa21e 100644 (file)
@@ -754,9 +754,33 @@ static ssize_t lio_target_nacl_store_cmdsn_depth(
 
 TF_NACL_BASE_ATTR(lio_target, cmdsn_depth, S_IRUGO | S_IWUSR);
 
+static ssize_t lio_target_nacl_show_tag(
+       struct se_node_acl *se_nacl,
+       char *page)
+{
+       return snprintf(page, PAGE_SIZE, "%s", se_nacl->acl_tag);
+}
+
+static ssize_t lio_target_nacl_store_tag(
+       struct se_node_acl *se_nacl,
+       const char *page,
+       size_t count)
+{
+       int ret;
+
+       ret = core_tpg_set_initiator_node_tag(se_nacl->se_tpg, se_nacl, page);
+
+       if (ret < 0)
+               return ret;
+       return count;
+}
+
+TF_NACL_BASE_ATTR(lio_target, tag, S_IRUGO | S_IWUSR);
+
 static struct configfs_attribute *lio_target_initiator_attrs[] = {
        &lio_target_nacl_info.attr,
        &lio_target_nacl_cmdsn_depth.attr,
+       &lio_target_nacl_tag.attr,
        NULL,
 };
 
index 0163309e2aba811d0a1e6e241f616aef6568d7f6..5192ac0337f736b150d7459847e38d8838e55c4c 100644 (file)
@@ -616,6 +616,29 @@ int core_tpg_set_initiator_node_queue_depth(
 }
 EXPORT_SYMBOL(core_tpg_set_initiator_node_queue_depth);
 
+/*     core_tpg_set_initiator_node_tag():
+ *
+ *     Initiator nodeacl tags are not used internally, but may be used by
+ *     userspace to emulate aliases or groups.
+ *     Returns length of newly-set tag or -EINVAL.
+ */
+int core_tpg_set_initiator_node_tag(
+       struct se_portal_group *tpg,
+       struct se_node_acl *acl,
+       const char *new_tag)
+{
+       if (strlen(new_tag) >= MAX_ACL_TAG_SIZE)
+               return -EINVAL;
+
+       if (!strncmp("NULL", new_tag, 4)) {
+               acl->acl_tag[0] = '\0';
+               return 0;
+       }
+
+       return snprintf(acl->acl_tag, MAX_ACL_TAG_SIZE, "%s", new_tag);
+}
+EXPORT_SYMBOL(core_tpg_set_initiator_node_tag);
+
 static int core_tpg_setup_virtual_lun0(struct se_portal_group *se_tpg)
 {
        /* Set in core_dev_setup_virtual_lun0() */
index 1346ee04db5ef178456274c4a3734b973f0c4d7c..7cae2360221eb0e32f9e3a19dceaec939ade7296 100644 (file)
@@ -507,6 +507,8 @@ struct se_node_acl {
        bool                    acl_stop:1;
        u32                     queue_depth;
        u32                     acl_index;
+#define MAX_ACL_TAG_SIZE 64
+       char                    acl_tag[MAX_ACL_TAG_SIZE];
        u64                     num_cmds;
        u64                     read_bytes;
        u64                     write_bytes;
index 9087b200e552494975f6a14377e5ff8c289fc688..aaa1ee6ab391caecfd4a512701c7c4875b056962 100644 (file)
@@ -142,6 +142,8 @@ int core_tpg_del_initiator_node_acl(struct se_portal_group *,
                struct se_node_acl *, int);
 int    core_tpg_set_initiator_node_queue_depth(struct se_portal_group *,
                unsigned char *, u32, int);
+int    core_tpg_set_initiator_node_tag(struct se_portal_group *,
+               struct se_node_acl *, const char *);
 int    core_tpg_register(struct target_core_fabric_ops *, struct se_wwn *,
                struct se_portal_group *, void *, int);
 int    core_tpg_deregister(struct se_portal_group *);