We added this helper to tune a device backing store (to set a correct
delta for a ploop device). It is executed when a group state is changed.
In this case, there is no difference where it is placed.  But now we
understand, that we need to run this helper before reporting group
states to an initiator. It will be used to sync groups with other
targets in a cluster. We have to guaranty that only one target reports
the Active/Optimize state. And in this case, it looks better if a user
helper will be set per device.

How to use:
echo -n /usr/sbin/vstorage-alua-helper > \
/sys/kernel/config/target/core/iblock_0/iqn.2014-06.com.vstorage\:test-1/alua_user_helper

Signed-off-by: Andrei Vagin <ava...@openvz.org>
---
 drivers/target/target_core_alua.c     | 49 +++++++----------------------------
 drivers/target/target_core_alua.h     |  4 +--
 drivers/target/target_core_configfs.c | 44 +++++++++++++++++++------------
 include/target/target_core_base.h     |  3 ++-
 4 files changed, 41 insertions(+), 59 deletions(-)

diff --git a/drivers/target/target_core_alua.c 
b/drivers/target/target_core_alua.c
index c59bf69..46c8beb 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -1038,20 +1038,10 @@ static int core_alua_usermode_helper(struct 
t10_alua_tg_pt_gp *tg_pt_gp,
        char *argv[8] = {}, str_id[6];
        int ret;
 
-       if (!tg_pt_gp->tg_pt_gp_usermode_helper)
+       if (!l_dev->alua_user_helper[0])
                return 0;
 
-       mutex_lock(&tg_pt_gp->tg_pt_gp_transition_mutex);
-       if (!tg_pt_gp->tg_pt_gp_usermode_helper) {
-               mutex_unlock(&tg_pt_gp->tg_pt_gp_transition_mutex);
-               return 0;
-       }
-       argv[0] = kstrdup(tg_pt_gp->tg_pt_gp_usermode_helper, GFP_KERNEL);
-       mutex_unlock(&tg_pt_gp->tg_pt_gp_transition_mutex);
-
-       if (argv[0] == NULL)
-               return -ENOMEM;
-
+       argv[0] = l_dev->alua_user_helper;
        snprintf(str_id, sizeof(str_id), "%hu", tg_pt_gp->tg_pt_gp_id);
        argv[1] = config_item_name(&tg_pt_gp->tg_pt_gp_group.cg_item);
        argv[2] = str_id;
@@ -1064,7 +1054,6 @@ static int core_alua_usermode_helper(struct 
t10_alua_tg_pt_gp *tg_pt_gp,
        ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC | 
UMH_KILLABLE);
        pr_debug("helper command: %s exit code %u (0x%x)\n",
                        argv[0], (ret >> 8) & 0xff, ret);
-       kfree(argv[0]);
        return ret;
 }
 
@@ -1727,7 +1716,6 @@ struct t10_alua_tg_pt_gp 
*core_alua_allocate_tg_pt_gp(struct se_device *dev,
        tg_pt_gp->tg_pt_gp_nonop_delay_msecs = ALUA_DEFAULT_NONOP_DELAY_MSECS;
        tg_pt_gp->tg_pt_gp_trans_delay_msecs = ALUA_DEFAULT_TRANS_DELAY_MSECS;
        tg_pt_gp->tg_pt_gp_implicit_trans_secs = 
ALUA_DEFAULT_IMPLICIT_TRANS_SECS;
-       tg_pt_gp->tg_pt_gp_usermode_helper = NULL;
 
        /*
         * Enable all supported states
@@ -1885,8 +1873,6 @@ void core_alua_free_tg_pt_gp(
        }
        spin_unlock(&tg_pt_gp->tg_pt_gp_lock);
 
-       kfree(tg_pt_gp->tg_pt_gp_usermode_helper);
-
        kmem_cache_free(t10_alua_tg_pt_gp_cache, tg_pt_gp);
 }
 
@@ -2216,41 +2202,26 @@ ssize_t core_alua_store_trans_delay_msecs(
 }
 
 ssize_t core_alua_show_user_helper(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
+       struct se_device *dev,
        char *page)
 {
-       ssize_t len;
-
-       mutex_lock(&tg_pt_gp->tg_pt_gp_transition_mutex);
-       if (!tg_pt_gp->tg_pt_gp_usermode_helper)
-               len = 0;
-       else
-               len = sprintf(page, "%s\n", tg_pt_gp->tg_pt_gp_usermode_helper);
-       mutex_unlock(&tg_pt_gp->tg_pt_gp_transition_mutex);
-
-       return len;
+       return sprintf(page, "%s\n", dev->alua_user_helper);
 }
 
 ssize_t core_alua_store_user_helper(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
+       struct se_device *dev,
        const char *page,
        size_t count)
 {
-       char *h;
-
        if (count == 1 && page[0] == '-') {
-               h = NULL;
+               dev->alua_user_helper[0] = 0;
+       } else if (count > ALUA_USER_HELPER_LEN - 1) {
+               return -EINVAL;
        } else {
-               h = kstrndup(page, count, GFP_KERNEL);
-               if (h == NULL)
-                       return -ENOMEM;
+               memcpy(dev->alua_user_helper, page, count);
+               dev->alua_user_helper[count] = 0;
        }
 
-       mutex_lock(&tg_pt_gp->tg_pt_gp_transition_mutex);
-       kfree(tg_pt_gp->tg_pt_gp_usermode_helper);
-       tg_pt_gp->tg_pt_gp_usermode_helper = h;
-       mutex_unlock(&tg_pt_gp->tg_pt_gp_transition_mutex);
-
        return count;
 }
 
diff --git a/drivers/target/target_core_alua.h 
b/drivers/target/target_core_alua.h
index 7673ffe..df1cf49 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -137,9 +137,9 @@ extern ssize_t core_alua_show_trans_delay_msecs(struct 
t10_alua_tg_pt_gp *,
                                        char *);
 extern ssize_t core_alua_store_trans_delay_msecs(struct t10_alua_tg_pt_gp *,
                                        const char *, size_t);
-extern ssize_t core_alua_show_user_helper(struct t10_alua_tg_pt_gp *,
+extern ssize_t core_alua_show_user_helper(struct se_device *,
                                        char *);
-extern ssize_t core_alua_store_user_helper(struct t10_alua_tg_pt_gp *,
+extern ssize_t core_alua_store_user_helper(struct se_device *,
                                        const char *, size_t);
 extern ssize_t core_alua_show_implicit_trans_secs(struct t10_alua_tg_pt_gp *,
                                        char *);
diff --git a/drivers/target/target_core_configfs.c 
b/drivers/target/target_core_configfs.c
index 7596801..7e7de7c 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -1478,6 +1478,32 @@ static struct target_core_configfs_attribute 
target_core_attr_dev_enable = {
        .store  = target_core_store_dev_enable,
 };
 
+static ssize_t target_core_show_attr_dev_user_helper(void *p,
+       char *page)
+{
+       struct se_device *dev = p;
+
+       return core_alua_show_user_helper(dev, page);
+}
+
+static ssize_t target_core_store_attr_dev_user_helper(
+       void *p,
+       const char *page,
+       size_t count)
+{
+       struct se_device *dev = p;
+
+       return core_alua_store_user_helper(dev, page, count);
+}
+
+static struct target_core_configfs_attribute target_core_attr_dev_user_helper 
= {
+       .attr   = { .ca_owner = THIS_MODULE,
+                   .ca_name = "alua_user_helper",
+                   .ca_mode =  S_IRUGO | S_IWUSR },
+       .show   = target_core_show_attr_dev_user_helper,
+       .store  = target_core_store_attr_dev_user_helper,
+};
+
 static ssize_t target_core_show_alua_lu_gp(void *p, char *page)
 {
        struct se_device *dev = p;
@@ -1770,6 +1796,7 @@ static struct configfs_attribute *target_core_dev_attrs[] 
= {
        &target_core_attr_dev_enable.attr,
        &target_core_attr_dev_alua_lu_gp.attr,
        &target_core_attr_dev_lba_map.attr,
+       &target_core_attr_dev_user_helper.attr,
        NULL,
 };
 
@@ -2323,22 +2350,6 @@ static ssize_t 
target_core_alua_tg_pt_gp_store_attr_trans_delay_msecs(
 
 SE_DEV_ALUA_TG_PT_ATTR(trans_delay_msecs, S_IRUGO | S_IWUSR);
 
-static ssize_t target_core_alua_tg_pt_gp_show_attr_user_helper(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       char *page)
-{
-       return core_alua_show_user_helper(tg_pt_gp, page);
-}
-
-static ssize_t target_core_alua_tg_pt_gp_store_attr_user_helper(
-       struct t10_alua_tg_pt_gp *tg_pt_gp,
-       const char *page,
-       size_t count)
-{
-       return core_alua_store_user_helper(tg_pt_gp, page, count);
-}
-
-SE_DEV_ALUA_TG_PT_ATTR(user_helper, S_IRUGO | S_IWUSR);
 /*
  * implicit_trans_secs
  */
@@ -2490,7 +2501,6 @@ static struct configfs_attribute 
*target_core_alua_tg_pt_gp_attrs[] = {
        &target_core_alua_tg_pt_gp_alua_write_metadata.attr,
        &target_core_alua_tg_pt_gp_nonop_delay_msecs.attr,
        &target_core_alua_tg_pt_gp_trans_delay_msecs.attr,
-       &target_core_alua_tg_pt_gp_user_helper.attr,
        &target_core_alua_tg_pt_gp_implicit_trans_secs.attr,
        &target_core_alua_tg_pt_gp_preferred.attr,
        &target_core_alua_tg_pt_gp_tg_pt_gp_id.attr,
diff --git a/include/target/target_core_base.h 
b/include/target/target_core_base.h
index 12415c4..e94b784 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -328,7 +328,6 @@ struct t10_alua_tg_pt_gp {
        struct list_head tg_pt_gp_mem_list;
        struct se_port *tg_pt_gp_alua_port;
        struct se_node_acl *tg_pt_gp_alua_nacl;
-       char *tg_pt_gp_usermode_helper;
 };
 
 struct t10_alua_tg_pt_gp_member {
@@ -810,6 +809,8 @@ struct se_device {
        unsigned char           dev_alias[SE_DEV_ALIAS_LEN];
 #define SE_UDEV_PATH_LEN 512           /* must be less than PAGE_SIZE */
        unsigned char           udev_path[SE_UDEV_PATH_LEN];
+#define ALUA_USER_HELPER_LEN 512       /* must be less than PAGE_SIZE */
+       char                    alua_user_helper[ALUA_USER_HELPER_LEN];
        /* Pointer to template of function pointers for transport */
        struct se_subsystem_api *transport;
        /* Linked list for struct se_hba struct se_device list */
-- 
1.8.3.1

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to