290 lines
9.9 KiB
Diff
290 lines
9.9 KiB
Diff
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/28] 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.25.1
|
|
|