From: Igor Ryzhov Date: Fri, 26 Jan 2024 01:08:55 +0000 (+0200) Subject: mgmtd: add ability to choose datastore to get data from X-Git-Tag: base_10.0~57^2~3 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=e13c590abe1217c8088a9493069a448d356d5c00;p=matthieu%2Ffrr.git mgmtd: add ability to choose datastore to get data from Signed-off-by: Igor Ryzhov --- diff --git a/lib/mgmt_fe_client.c b/lib/mgmt_fe_client.c index 19fbdaf1bd..c841821117 100644 --- a/lib/mgmt_fe_client.c +++ b/lib/mgmt_fe_client.c @@ -310,8 +310,8 @@ int mgmt_fe_send_regnotify_req(struct mgmt_fe_client *client, */ 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, - uint8_t defaults, const char *xpath) + uint8_t datastore, LYD_FORMAT result_type, + uint8_t flags, uint8_t defaults, const char *xpath) { struct mgmt_msg_get_data *msg; size_t xplen = strlen(xpath); @@ -325,6 +325,7 @@ int mgmt_fe_send_get_data_req(struct mgmt_fe_client *client, msg->result_type = result_type; msg->flags = flags; msg->defaults = defaults; + 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 17ec354a1a..50ebb80149 100644 --- a/lib/mgmt_fe_client.h +++ b/lib/mgmt_fe_client.h @@ -384,6 +384,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. * @@ -401,8 +404,9 @@ 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, - uint8_t defaults, const char *xpath); + uint8_t datastore, LYD_FORMAT result_type, + uint8_t flags, uint8_t defaults, + const char *xpath); /* * Destroy library and cleanup everything. diff --git a/lib/mgmt_msg_native.h b/lib/mgmt_msg_native.h index b26f07a643..ab305b125b 100644 --- a/lib/mgmt_msg_native.h +++ b/lib/mgmt_msg_native.h @@ -154,6 +154,14 @@ DECLARE_MTYPE(MSG_NATIVE_NOTIFY); #define MGMT_MSG_CODE_GET_DATA 3 #define MGMT_MSG_CODE_NOTIFY 4 +/* + * 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 { uint8_t result_type; uint8_t flags; uint8_t defaults; - uint8_t resv2[6]; + uint8_t datastore; + uint8_t resv2[4]; alignas(8) char xpath[]; }; diff --git a/lib/vty.c b/lib/vty.c index c082c8385c..c993358e5a 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -4101,17 +4101,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, uint8_t defaults, - const char *xpath) +int vty_mgmt_send_get_data_req(struct vty *vty, uint8_t datastore, + LYD_FORMAT result_type, uint8_t flags, + uint8_t defaults, 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, - defaults, xpath)) { + vty->mgmt_req_id, datastore, + intern_format, flags, defaults, 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 7244aeceed..06973da916 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -420,9 +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, uint8_t defaults, - const char *xpath); +extern int vty_mgmt_send_get_data_req(struct vty *vty, uint8_t datastore, + LYD_FORMAT result_type, uint8_t flags, + uint8_t defaults, 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 acf77f552b..5dd6a70012 100644 --- a/mgmtd/mgmt_fe_adapter.c +++ b/mgmtd/mgmt_fe_adapter.c @@ -1145,6 +1145,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; uint32_t wd_options; bool simple_xpath; @@ -1191,6 +1192,24 @@ 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); if (err) { @@ -1228,7 +1247,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, wd_options, simple_xpath, msg->xpath); if (ret) { /* destroy the just created txn */ diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c index 926b1574a1..dd2023a4fb 100644 --- a/mgmtd/mgmt_txn.c +++ b/mgmtd/mgmt_txn.c @@ -2341,9 +2341,10 @@ 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, uint32_t wd_options, - bool simple_xpath, const char *xpath) + uint64_t clients, Mgmtd__DatastoreId ds_id, + LYD_FORMAT result_type, uint8_t flags, + uint32_t wd_options, bool simple_xpath, + const char *xpath) { struct mgmt_msg_get_tree *msg; struct mgmt_txn_ctx *txn; @@ -2367,8 +2368,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) { @@ -2414,7 +2421,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 ad2e38fb0f..b7198326da 100644 --- a/mgmtd/mgmt_txn.h +++ b/mgmtd/mgmt_txn.h @@ -202,6 +202,7 @@ extern int mgmt_txn_send_get_req(uint64_t txn_id, uint64_t req_id, * txn_id: Transaction identifier. * req_id: FE client request identifier. * clients: Bitmask of clients to send get-tree to. + * ds_id: datastore ID. * result_type: LYD_FORMAT result format. * flags: option flags for the request. * wd_options: LYD_PRINT_WD_* flags for the result. @@ -212,9 +213,11 @@ 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, uint32_t wd_options, - bool simple_xpath, const char *xpath); + uint64_t clients, + Mgmtd__DatastoreId ds_id, + LYD_FORMAT result_type, uint8_t flags, + uint32_t wd_options, bool simple_xpath, + const char *xpath); /* * Notifiy backend adapter on connection. diff --git a/mgmtd/mgmt_vty.c b/mgmtd/mgmt_vty.c index 7c9c3c6fe0..12ea62ecef 100644 --- a/mgmtd/mgmt_vty.c +++ b/mgmtd/mgmt_vty.c @@ -258,11 +258,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" @@ -278,6 +282,7 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd, char *xpath = NULL; uint8_t flags = content ? GET_DATA_FLAG_CONFIG : GET_DATA_FLAG_STATE; uint8_t defaults = GET_DATA_DEFAULTS_EXPLICIT; + uint8_t datastore = MGMT_MSG_DATASTORE_OPERATIONAL; if (content && content[0] == 'w') flags |= GET_DATA_FLAG_STATE; @@ -294,6 +299,13 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd, defaults = GET_DATA_DEFAULTS_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] == '/'))) { @@ -303,7 +315,8 @@ DEFPY(show_mgmt_get_data, show_mgmt_get_data_cmd, path = xpath; } - vty_mgmt_send_get_data_req(vty, format, flags, defaults, path); + vty_mgmt_send_get_data_req(vty, datastore, format, flags, defaults, + path); if (xpath) XFREE(MTYPE_TMP, xpath);