From 43c8d12686846109b99a74d12bde196bb4bedfa9 Mon Sep 17 00:00:00 2001 From: Peter Rajnoha Date: Thu, 25 Mar 2021 17:54:56 +0100 Subject: [PATCH] resource: ubridge: define and use flags for _cmd_regs representing ucmd commands Define CMD_KV_IMPORT_UDEV, CMD_KV_EXPORT_UDEV, CMD_KV_EXPORT_SID, CMD_SESSION_ID to control whether certain records are imported/exported and whether the command can make use and export session ID (support for sessions is yet to be implemented). This is mainly to avoid trying to import and export records for commands which are not supposed to do so. --- src/resource/ubridge.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/src/resource/ubridge.c b/src/resource/ubridge.c index a48a6e88..aab87d16 100644 --- a/src/resource/ubridge.c +++ b/src/resource/ubridge.c @@ -290,7 +290,15 @@ struct cross_bitmap_calc_arg { }; /* - * Capability flags for scan phases. + * Generic flags for all commands. + */ +#define CMD_KV_IMPORT_UDEV UINT32_C(0x00000001) /* imports udev environment as KV_NS_UDEV records */ +#define CMD_KV_EXPORT_UDEV UINT32_C(0x00000002) /* exports KV_NS_UDEV+KV_PERSISTENT records to udev environment/db */ +#define CMD_KV_EXPORT_SID UINT32_C(0x00000004) /* exports KV_NS_+KV_PERSISTENT records to main sid db */ +#define CMD_SESSION_ID UINT32_C(0x00000008) /* supports sessions */ + +/* + * Capability flags for 'scan' command phases (phases are represented as subcommands). */ #define CMD_SCAN_CAP_RDY UINT32_C(0x00000001) /* can set ready state */ #define CMD_SCAN_CAP_RES UINT32_C(0x00000002) /* can set reserved state */ @@ -3177,11 +3185,11 @@ static int _cmd_exec_checkpoint(struct cmd_exec_arg *exec_arg) } static struct cmd_reg _cmd_regs[] = { + [USID_CMD_UNKNOWN] = {.name = NULL, .flags = 0, .exec = _cmd_exec_unknown}, [USID_CMD_ACTIVE] = {.name = NULL, .flags = 0, .exec = _cmd_exec_unknown}, - [USID_CMD_CHECKPOINT] = {.name = NULL, .flags = 0, .exec = _cmd_exec_checkpoint}, + [USID_CMD_CHECKPOINT] = {.name = NULL, .flags = CMD_KV_IMPORT_UDEV, .exec = _cmd_exec_checkpoint}, [USID_CMD_REPLY] = {.name = NULL, .flags = 0, .exec = _cmd_exec_reply}, - [USID_CMD_SCAN] = {.name = NULL, .flags = 0, .exec = _cmd_exec_scan}, - [USID_CMD_UNKNOWN] = {.name = NULL, .flags = 0, .exec = _cmd_exec_unknown}, + [USID_CMD_SCAN] = {.name = NULL, .flags = CMD_KV_IMPORT_UDEV | CMD_KV_EXPORT_UDEV | CMD_KV_EXPORT_SID | CMD_SESSION_ID, .exec = _cmd_exec_scan}, [USID_CMD_VERSION] = {.name = NULL, .flags = 0, .exec = _cmd_exec_version}, [USID_CMD_DUMP] = {.name = NULL, .flags = 0, .exec = _cmd_exec_dump}, [USID_CMD_STATS] = {.name = NULL, .flags = 0, .exec = _cmd_exec_stats}, @@ -3260,6 +3268,12 @@ static int _export_kv_store(sid_resource_t *cmd_res) // TODO: Also deal with situation if the udev namespace values are defined as vectors by chance. if (_get_ns_from_key(key) == KV_NS_UDEV) { + if (!(_cmd_regs[ucmd_ctx->request_header.cmd].flags & CMD_KV_EXPORT_UDEV)) { + log_warning(ID(cmd_res), + "Ignoring request to export record with key %s to udev.", key); + continue; + } + if (vector) { log_error(ID(cmd_res), INTERNAL_ERROR "%s: Unsupported vector value for key %s in udev namespace.", @@ -3303,6 +3317,12 @@ static int _export_kv_store(sid_resource_t *cmd_res) * Repeat 2) - 7) as long as there are keys to send. */ + if (!(_cmd_regs[ucmd_ctx->request_header.cmd].flags & CMD_KV_EXPORT_SID)) { + log_warning(ID(cmd_res), + "Ignoring request to export record with key %s to SID main KV store.", key); + continue; + } + /* FIXME: Try to reduce the "write" calls. */ if ((r_wr = write(export_fd, &flags, sizeof(flags))) == sizeof(flags)) bytes_written += r_wr; @@ -3434,9 +3454,12 @@ static int _cmd_handler(sid_resource_event_source_t *es, void *data) return -1; } - if ((r = _export_kv_store(cmd_res)) < 0) { - log_error(ID(cmd_res), "Failed to synchronize key-value store."); - goto out; + if (_cmd_regs[ucmd_ctx->request_header.cmd].flags & CMD_KV_EXPORT_UDEV || + _cmd_regs[ucmd_ctx->request_header.cmd].flags & CMD_KV_EXPORT_SID) { + if ((r = _export_kv_store(cmd_res)) < 0) { + log_error(ID(cmd_res), "Failed to synchronize key-value store."); + goto out; + } } out: if (r < 0) @@ -3642,7 +3665,7 @@ static int _init_command(sid_resource_t *res, const void *kickstart_data, void * goto fail; } - if (msg->header->cmd == USID_CMD_SCAN) { + if (_cmd_regs[msg->header->cmd].flags & CMD_KV_IMPORT_UDEV) { /* currently, we only parse udev environment for the SCAN command */ if ((r = _parse_cmd_nullstr_udev_env(ucmd_ctx, msg->header->data, msg->size - sizeof(*msg->header))) < 0) { log_error_errno(ID(res), r, "Failed to parse udev environment variables"); @@ -3655,7 +3678,8 @@ static int _init_command(sid_resource_t *res, const void *kickstart_data, void * goto fail; } - if (!_do_sid_ucmd_set_kv(NULL, + if (_cmd_regs[msg->header->cmd].flags & CMD_SESSION_ID && + !_do_sid_ucmd_set_kv(NULL, ucmd_ctx, KV_NS_UDEV, NULL,