From 4c945810da8c645eb048e5fbb3a195da855bdcf7 Mon Sep 17 00:00:00 2001
From: wujing <wujing50@huawei.com>
Date: Sat, 14 May 2022 17:13:26 +0800
Subject: [PATCH 24/30] refactor devmapper_parse_options function

Signed-off-by: wujing <wujing50@huawei.com>
---
 .../graphdriver/devmapper/deviceset.c         | 242 ++++++++++++------
 1 file changed, 157 insertions(+), 85 deletions(-)

diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c
index d90dde50..868e3086 100644
--- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c
+++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c
@@ -65,9 +65,147 @@ static char *util_trim_prefice_string(char *str, const char *prefix)
     return str;
 }
 
+typedef int (*devmapper_option_handle)(char *val, struct device_set *devset);
+
+struct devmapper_option_handler {
+    char *name;
+    devmapper_option_handle handle;
+};
+
+static int handle_dm_fs(char *val, struct device_set *devset)
+{
+    if (strcmp(val, "ext4") == 0) {
+        free(devset->filesystem);
+        devset->filesystem = util_strdup_s(val);
+    } else {
+        ERROR("Invalid filesystem: '%s': not supported", val);
+        isulad_set_error_message("Invalid filesystem: '%s': not supported", val);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int handle_dm_thinpooldev(char *val, struct device_set *devset)
+{
+    char *tmp_val = NULL;
+
+    if (!util_valid_str(val)) {
+        ERROR("Invalid thinpool device, it must not be empty");
+        isulad_set_error_message("Invalid thinpool device, it must not be empty");
+        return -1;
+    }
+    tmp_val = util_trim_prefice_string(val, "/dev/mapper/");
+    devset->thin_pool_device = util_strdup_s(tmp_val);
+
+    return 0;
+}
+
+static int handle_dm_min_free_space(char *val, struct device_set *devset)
+{
+    long converted = 0;
+    int ret = util_parse_percent_string(val, &converted);
+
+    if (ret != 0 || converted >= 100) {
+        ERROR("Invalid min free space: '%s': %s", val, strerror(-ret));
+        isulad_set_error_message("Invalid min free space: '%s': %s", val, strerror(-ret));
+        return -1;
+    }
+    devset->min_free_space_percent = (uint32_t)converted;
+
+    return 0;
+}
+
+static int handle_dm_basesize(char *val, struct device_set *devset)
+{
+    int64_t converted = 0;
+    int ret = util_parse_byte_size_string(val, &converted);
+
+    if (ret != 0) {
+        ERROR("Invalid size: '%s': %s", val, strerror(-ret));
+        isulad_set_error_message("Invalid size: '%s': %s", val, strerror(-ret));
+        return -1;
+    }
+    if (converted <= 0) {
+        ERROR("dm.basesize is lower than zero");
+        isulad_set_error_message("dm.basesize is lower than zero");
+        return -1;
+    }
+    devset->user_base_size = true;
+    devset->base_fs_size = (uint64_t)converted;
+
+    return 0;
+}
+
+static int handle_dm_mkfsarg(char *val, struct device_set *devset)
+{
+    if (!util_valid_str(val)) {
+        ERROR("Invalid dm.mkfsarg value");
+        isulad_set_error_message("Invalid dm.mkfsarg value");
+        return -1;
+    }
+    if (util_array_append(&devset->mkfs_args, val) != 0) {
+        ERROR("Out of memory");
+        return -1;
+    }
+    devset->mkfs_args_len++;
+
+    return 0;
+}
+
+static int handle_dm_mountopt(char *val, struct device_set *devset)
+{
+    if (!util_valid_str(val)) {
+        ERROR("Invalid dm.mountopt or devicemapper.mountopt value");
+        isulad_set_error_message("Invalid dm.mountopt or devicemapper.mountopt value");
+        return -1;
+    }
+    devset->mount_options = util_strdup_s(val);
+
+    return 0;
+}
+
+static int devmapper_option_exact(const char *name, char *val, struct device_set *devset)
+{
+    size_t i = 0;
+    bool found = false;
+
+    struct devmapper_option_handler handler_jump_table[] = {
+        { "dm.fs",                 handle_dm_fs             },
+        { "dm.thinpooldev",        handle_dm_thinpooldev    },
+        { "dm.min_free_space",     handle_dm_min_free_space },
+        { "dm.basesize",           handle_dm_basesize       },
+        { "dm.mkfsarg",            handle_dm_mkfsarg        },
+        { "dm.mountopt",           handle_dm_mountopt       },
+        { "devicemapper.mountopt", handle_dm_mountopt       },
+    };
+
+    for (i = 0; i < sizeof(handler_jump_table)/sizeof(handler_jump_table[0]); i++) {
+        if (strcmp(handler_jump_table[i].name, name) != 0) {
+            continue;
+        }
+        found = true;
+        if (handler_jump_table[i].handle(val, devset) != 0) {
+            ERROR("Failed to handle %s option with %s", name, val);
+            return -1;
+        }
+        break;
+    }
+
+    if (!found) {
+        ERROR("devicemapper: unknown option: '%s'", name);
+        isulad_set_error_message("devicemapper: unknown option: '%s'", name);
+        return -1;
+    }
+
+    return 0;
+}
+
 static int devmapper_parse_options(struct device_set *devset, const char **options, size_t options_len)
 {
+    int ret = 0;
     size_t i = 0;
+    char *dup_option = NULL;
 
     if (devset == NULL) {
         ERROR("Invalid input params");
@@ -75,104 +213,38 @@ static int devmapper_parse_options(struct device_set *devset, const char **optio
     }
 
     for (i = 0; options != NULL && i < options_len; i++) {
-        char *dup = NULL;
         char *val = NULL;
-        char *tmp_val = NULL;
-        int ret = 0;
-        int nret = 0;
 
-        dup = util_strdup_s(options[i]);
-        if (dup == NULL) {
+        dup_option = util_strdup_s(options[i]);
+        if (dup_option == NULL) {
             ERROR("Out of memory");
             return -1;
         }
 
-        val = strchr(dup, '=');
+        val = strchr(dup_option, '=');
         if (val == NULL) {
-            ERROR("Unable to parse key/value option: '%s'", dup);
-            isulad_set_error_message("Unable to parse key/value option: '%s'", dup);
-            free(dup);
-            return -1;
+            ERROR("Unable to parse key/value option: '%s'", dup_option);
+            isulad_set_error_message("Unable to parse key/value option: '%s'", dup_option);
+            ret = -1;
+            goto out;
         }
+
         *val = '\0';
         val++;
-        if (strcasecmp(dup, "dm.fs") == 0) {
-            if (strcmp(val, "ext4") == 0) {
-                free(devset->filesystem);
-                devset->filesystem = util_strdup_s(val);
-            } else {
-                ERROR("Invalid filesystem: '%s': not supported", val);
-                isulad_set_error_message("Invalid filesystem: '%s': not supported", val);
-                ret = -1;
-            }
-        } else if (strcasecmp(dup, "dm.thinpooldev") == 0) {
-            if (!util_valid_str(val)) {
-                ERROR("Invalid thinpool device, it must not be empty");
-                isulad_set_error_message("Invalid thinpool device, it must not be empty");
-                ret = -1;
-                goto out;
-            }
-            tmp_val = util_trim_prefice_string(val, "/dev/mapper/");
-            devset->thin_pool_device = util_strdup_s(tmp_val);
-        } else if (strcasecmp(dup, "dm.min_free_space") == 0) {
-            long converted = 0;
-            ret = util_parse_percent_string(val, &converted);
-            if (ret != 0 || converted >= 100) {
-                ERROR("Invalid min free space: '%s': %s", val, strerror(-ret));
-                isulad_set_error_message("Invalid min free space: '%s': %s", val, strerror(-ret));
-                ret = -1;
-                goto out;
-            }
-            devset->min_free_space_percent = (uint32_t)converted;
-        } else if (strcasecmp(dup, "dm.basesize") == 0) {
-            int64_t converted = 0;
-            ret = util_parse_byte_size_string(val, &converted);
-            if (ret != 0) {
-                ERROR("Invalid size: '%s': %s", val, strerror(-ret));
-                isulad_set_error_message("Invalid size: '%s': %s", val, strerror(-ret));
-                ret = -1;
-                goto out;
-            }
-            if (converted <= 0) {
-                ERROR("dm.basesize is lower than zero");
-                isulad_set_error_message("dm.basesize is lower than zero");
-                ret = -1;
-                goto out;
-            }
-            devset->user_base_size = true;
-            devset->base_fs_size = (uint64_t)converted;
-        } else if (strcasecmp(dup, "dm.mkfsarg") == 0) {
-            if (!util_valid_str(val)) {
-                ERROR("Invalid dm.mkfsarg value");
-                isulad_set_error_message("Invalid dm.mkfsarg value");
-                ret = -1;
-                goto out;
-            }
-            nret = util_array_append(&devset->mkfs_args, val);
-            if (nret != 0) {
-                ERROR("Out of memory");
-                ret = -1;
-                goto out;
-            }
-            devset->mkfs_args_len++;
-        } else if (strcasecmp(dup, "dm.mountopt") == 0 || strcasecmp(dup, "devicemapper.mountopt") == 0) {
-            if (!util_valid_str(val)) {
-                ERROR("Invalid dm.mountopt or devicemapper.mountopt value");
-                isulad_set_error_message("Invalid dm.mountopt or devicemapper.mountopt value");
-                ret = -1;
-                goto out;
-            }
-            devset->mount_options = util_strdup_s(val);
-        } else {
-            ERROR("devicemapper: unknown option: '%s'", dup);
-            isulad_set_error_message("devicemapper: unknown option: '%s'", dup);
+
+        if (devmapper_option_exact(dup_option, val, devset) != 0) {
+            ERROR("Failed to exact devmapper option: %s", dup_option);
             ret = -1;
+            goto out;
         }
+
+        free(dup_option);
+    }
+
 out:
-        free(dup);
-        if (ret != 0) {
-            return ret;
-        }
+    free(dup_option);
+    if (ret != 0) {
+        return ret;
     }
 
     return 0;
-- 
2.32.1 (Apple Git-133)

