From f8c7e733ef9fc3b01083cfeccb8360145d1608bc Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Fri, 26 Jan 2024 03:08:55 +0200 Subject: [PATCH] mgmtd: add ability to choose datastore to get data from Signed-off-by: Igor Ryzhov --- lib/mgmt_fe_client.c | 6 ++++-- lib/mgmt_fe_client.h | 7 +++++-- lib/mgmt_msg_native.h | 11 ++++++++++- lib/vty.c | 9 +++++---- lib/vty.h | 5 +++-- mgmtd/mgmt_fe_adapter.c | 20 +++++++++++++++++++- mgmtd/mgmt_txn.c | 17 ++++++++++++----- mgmtd/mgmt_txn.h | 7 ++++--- mgmtd/mgmt_vty.c | 16 ++++++++++++++-- 9 files changed, 76 insertions(+), 22 deletions(-) diff --git a/lib/mgmt_fe_client.c b/lib/mgmt_fe_client.c index 92619f4f7f11..1c0e25f92c5f 100644 --- a/lib/mgmt_fe_client.c +++ b/lib/mgmt_fe_client.c @@ -308,8 +308,9 @@ int mgmt_fe_send_regnotify_req(struct mgmt_fe_client *client, /* * Send get-data request. */ -int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client, uint64_t session_id, - uint64_t req_id, LYD_FORMAT result_type, +int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client, + uint64_t session_id, uint64_t req_id, + uint8_t datastore, LYD_FORMAT result_type, uint8_t flags, const char *xpath) { struct mgmt_msg_get_data *msg; @@ -323,6 +324,7 @@ int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client, uint64_t session_id msg->code = MGMT_MSG_CODE_GET_DATA; msg->result_type = result_type; msg->flags = flags; + msg->datastore = datastore; strlcpy(msg->xpath, xpath, xplen + 1); MGMTD_FE_CLIENT_DBG("Sending GET_DATA_REQ session-id %" PRIu64 diff --git a/lib/mgmt_fe_client.h b/lib/mgmt_fe_client.h index 3abe29b1cf39..9930912326ad 100644 --- a/lib/mgmt_fe_client.h +++ b/lib/mgmt_fe_client.h @@ -379,6 +379,9 @@ extern int mgmt_fe_send_regnotify_req(struct mgmt_fe_client *client, * req_id * Client request ID. * + * datastore + * Datastore for getting data. + * * result_type * The LYD_FORMAT of the result. * @@ -393,8 +396,8 @@ extern int mgmt_fe_send_regnotify_req(struct mgmt_fe_client *client, */ extern int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client, uint64_t session_id, uint64_t req_id, - LYD_FORMAT result_type, uint8_t flags, - const char *xpath); + uint8_t datastore, LYD_FORMAT result_type, + uint8_t flags, const char *xpath); /* * Destroy library and cleanup everything. diff --git a/lib/mgmt_msg_native.h b/lib/mgmt_msg_native.h index 4e4975649c8d..75f9a7118691 100644 --- a/lib/mgmt_msg_native.h +++ b/lib/mgmt_msg_native.h @@ -152,6 +152,14 @@ DECLARE_MTYPE(MSG_NATIVE_GET_DATA); #define MGMT_MSG_CODE_TREE_DATA 2 #define MGMT_MSG_CODE_GET_DATA 3 +/* + * Datastores + */ +#define MGMT_MSG_DATASTORE_STARTUP 0 +#define MGMT_MSG_DATASTORE_CANDIDATE 1 +#define MGMT_MSG_DATASTORE_RUNNING 2 +#define MGMT_MSG_DATASTORE_OPERATIONAL 3 + /** * struct mgmt_msg_header - Header common to all native messages. * @@ -262,7 +270,8 @@ struct mgmt_msg_get_data { struct mgmt_msg_header; uint8_t result_type; uint8_t flags; - uint8_t resv2[6]; + uint8_t datastore; + uint8_t resv2[5]; alignas(8) char xpath[]; }; diff --git a/lib/vty.c b/lib/vty.c index a6b4de579a4a..8769a4edd687 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -4113,16 +4113,17 @@ int vty_mgmt_send_get_req(struct vty *vty, bool is_config, return 0; } -int vty_mgmt_send_get_data_req(struct vty *vty, LYD_FORMAT result_type, - uint8_t flags, const char *xpath) +int vty_mgmt_send_get_data_req(struct vty *vty, uint8_t datastore, + LYD_FORMAT result_type, uint8_t flags, + const char *xpath) { LYD_FORMAT intern_format = result_type; vty->mgmt_req_id++; if (mgmt_fe_send_get_data_req(mgmt_fe_client, vty->mgmt_session_id, - vty->mgmt_req_id, intern_format, flags, - xpath)) { + vty->mgmt_req_id, datastore, + intern_format, flags, xpath)) { zlog_err("Failed to send GET-DATA to MGMTD session-id: %" PRIu64 " req-id %" PRIu64 ".", vty->mgmt_session_id, vty->mgmt_req_id); diff --git a/lib/vty.h b/lib/vty.h index 73e0d238ad1d..0be532f91619 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -420,8 +420,9 @@ extern int vty_mgmt_send_commit_config(struct vty *vty, bool validate_only, extern int vty_mgmt_send_get_req(struct vty *vty, bool is_config, Mgmtd__DatastoreId datastore, const char **xpath_list, int num_req); -extern int vty_mgmt_send_get_data_req(struct vty *vty, LYD_FORMAT result_type, - uint8_t flags, const char *xpath); +extern int vty_mgmt_send_get_data_req(struct vty *vty, uint8_t datastore, + LYD_FORMAT result_type, uint8_t flags, + const char *xpath); extern int vty_mgmt_send_lockds_req(struct vty *vty, Mgmtd__DatastoreId ds_id, bool lock, bool scok); extern void vty_mgmt_resume_response(struct vty *vty, int ret); diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c index 01ef83b8152d..9e0a5ef0607a 100644 --- a/mgmtd/mgmt_fe_adapter.c +++ b/mgmtd/mgmt_fe_adapter.c @@ -1146,6 +1146,7 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session, struct lysc_node **snodes = NULL; char *xpath_resolved = NULL; uint64_t req_id = msg->req_id; + Mgmtd__DatastoreId ds_id; uint64_t clients; bool simple_xpath; LY_ERR err; @@ -1171,6 +1172,23 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session, goto done; } + switch (msg->datastore) { + case MGMT_MSG_DATASTORE_CANDIDATE: + ds_id = MGMTD_DS_CANDIDATE; + break; + case MGMT_MSG_DATASTORE_RUNNING: + ds_id = MGMTD_DS_RUNNING; + break; + case MGMT_MSG_DATASTORE_OPERATIONAL: + ds_id = MGMTD_DS_OPERATIONAL; + break; + default: + fe_adapter_send_error(session, req_id, false, -EINVAL, + "Unsupported datastore %" PRIu8 + " requested from session-id: %" PRIu64, + msg->datastore, session->session_id); + goto done; + } err = yang_resolve_snode_xpath(ly_native_ctx, msg->xpath, &snodes, &simple_xpath); @@ -1209,7 +1227,7 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session, /* Create a GET-TREE request under the transaction */ ret = mgmt_txn_send_get_tree_oper(session->txn_id, req_id, clients, - msg->result_type, msg->flags, + ds_id, msg->result_type, msg->flags, simple_xpath, msg->xpath); if (ret) { /* destroy the just created txn */ diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c index 8ebf8382ae91..db1811ee5a03 100644 --- a/mgmtd/mgmt_txn.c +++ b/mgmtd/mgmt_txn.c @@ -2341,9 +2341,9 @@ int mgmt_txn_send_get_req(uint64_t txn_id, uint64_t req_id, * has registered operational state that matches the given `xpath` */ int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id, - uint64_t clients, LYD_FORMAT result_type, - uint8_t flags, bool simple_xpath, - const char *xpath) + uint64_t clients, Mgmtd__DatastoreId ds_id, + LYD_FORMAT result_type, uint8_t flags, + bool simple_xpath, const char *xpath) { struct mgmt_msg_get_tree *msg; struct mgmt_txn_ctx *txn; @@ -2383,8 +2383,14 @@ int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id, get_tree->xpath = XSTRDUP(MTYPE_MGMTD_XPATH, xpath); if (CHECK_FLAG(flags, GET_DATA_FLAG_CONFIG)) { + /* + * If the requested datastore is operational, get the config + * from running. + */ struct mgmt_ds_ctx *ds = - mgmt_ds_get_ctx_by_id(mm, MGMTD_DS_RUNNING); + mgmt_ds_get_ctx_by_id(mm, ds_id == MGMTD_DS_OPERATIONAL + ? MGMTD_DS_RUNNING + : ds_id); struct nb_config *config = mgmt_ds_get_nb_config(ds); if (config) { @@ -2430,7 +2436,8 @@ int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id, } state: /* If we are only getting config, we are done */ - if (!CHECK_FLAG(flags, GET_DATA_FLAG_STATE) || !clients) + if (!CHECK_FLAG(flags, GET_DATA_FLAG_STATE) || + ds_id != MGMTD_DS_OPERATIONAL || !clients) return txn_get_tree_data_done(txn, txn_req); msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_get_tree, slen + 1, diff --git a/mgmtd/mgmt_txn.h b/mgmtd/mgmt_txn.h index 02b2baa95fd9..aeadd8dd52b5 100644 --- a/mgmtd/mgmt_txn.h +++ b/mgmtd/mgmt_txn.h @@ -211,9 +211,10 @@ extern int mgmt_txn_send_get_req(uint64_t txn_id, uint64_t req_id, * 0 on success. */ extern int mgmt_txn_send_get_tree_oper(uint64_t txn_id, uint64_t req_id, - uint64_t clients, LYD_FORMAT result_type, - uint8_t flags, bool simple_xpath, - const char *xpath); + uint64_t clients, + Mgmtd__DatastoreId ds_id, + LYD_FORMAT result_type, uint8_t flags, + bool simple_xpath, const char *xpath); /* * Notifiy backend adapter on connection. diff --git a/mgmtd/mgmt_vty.c b/mgmtd/mgmt_vty.c index c1fcd16545cc..394b34de45d7 100644 --- a/mgmtd/mgmt_vty.c +++ b/mgmtd/mgmt_vty.c @@ -256,11 +256,15 @@ DEFPY(show_mgmt_get_config, show_mgmt_get_config_cmd, } DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd, - "show mgmt get-data WORD$path [with-config|only-config]$content [exact]$exact [with-defaults $wd] [json|xml]$fmt", + "show mgmt get-data WORD$path [datastore $ds] [with-config|only-config]$content [exact]$exact [with-defaults $wd] [json|xml]$fmt", SHOW_STR MGMTD_STR "Get a data from the operational datastore\n" "XPath expression specifying the YANG data root\n" + "Specify datastore to get data from (operational by default)\n" + "Candidate datastore\n" + "Running datastore\n" + "Operational datastore\n" "Include \"config true\" data\n" "Get only \"config true\" data\n" "Get exact node instead of the whole data tree\n" @@ -275,6 +279,7 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd, int plen = strlen(path); char *xpath = NULL; uint8_t flags = content ? GET_DATA_FLAG_CONFIG : GET_DATA_FLAG_STATE; + uint8_t datastore = MGMT_MSG_DATASTORE_OPERATIONAL; if (content && content[0] == 'w') flags |= GET_DATA_FLAG_STATE; @@ -291,6 +296,13 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd, flags |= GET_DATA_FLAG_WD_ALL; } + if (ds) { + if (ds[0] == 'c') + datastore = MGMT_MSG_DATASTORE_CANDIDATE; + else if (ds[0] == 'r') + datastore = MGMT_MSG_DATASTORE_RUNNING; + } + /* get rid of extraneous trailing slash-* or single '/' unless root */ if (plen > 2 && ((path[plen - 2] == '/' && path[plen - 1] == '*') || (path[plen - 2] != '/' && path[plen - 1] == '/'))) { @@ -300,7 +312,7 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd, path = xpath; } - vty_mgmt_send_get_data_req(vty, format, flags, path); + vty_mgmt_send_get_data_req(vty, datastore, format, flags, path); if (xpath) XFREE(MTYPE_TMP, xpath);