1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * MGMTD Frontend Client Connection Adapter
5 * Copyright (C) 2021 Vmware, Inc.
6 * Pushpasis Sarkar <spushpasis@vmware.com>
13 #include "mgmt_fe_client.h"
18 #include "mgmtd/mgmt.h"
19 #include "mgmtd/mgmt_memory.h"
20 #include "mgmtd/mgmt_fe_adapter.h"
22 #ifdef REDIRECT_DEBUG_TO_STDERR
23 #define MGMTD_FE_ADAPTER_DBG(fmt, ...) \
24 fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__)
25 #define MGMTD_FE_ADAPTER_ERR(fmt, ...) \
26 fprintf(stderr, "%s: ERROR, " fmt "\n", __func__, ##__VA_ARGS__)
27 #else /* REDIRECT_DEBUG_TO_STDERR */
28 #define MGMTD_FE_ADAPTER_DBG(fmt, ...) \
31 zlog_debug("%s: " fmt, __func__, ##__VA_ARGS__); \
33 #define MGMTD_FE_ADAPTER_ERR(fmt, ...) \
34 zlog_err("%s: ERROR: " fmt, __func__, ##__VA_ARGS__)
35 #endif /* REDIRECT_DEBUG_TO_STDERR */
37 #define FOREACH_ADAPTER_IN_LIST(adapter) \
38 frr_each_safe (mgmt_fe_adapters, &mgmt_fe_adapters, (adapter))
40 enum mgmt_session_event
{
41 MGMTD_FE_SESSION_CFG_TXN_CLNUP
= 1,
42 MGMTD_FE_SESSION_SHOW_TXN_CLNUP
,
45 struct mgmt_fe_session_ctx
{
46 struct mgmt_fe_client_adapter
*adapter
;
51 uint8_t ds_write_locked
[MGMTD_DS_MAX_ID
];
52 uint8_t ds_read_locked
[MGMTD_DS_MAX_ID
];
53 uint8_t ds_locked_implict
[MGMTD_DS_MAX_ID
];
54 struct event
*proc_cfg_txn_clnp
;
55 struct event
*proc_show_txn_clnp
;
57 struct mgmt_fe_sessions_item list_linkage
;
60 DECLARE_LIST(mgmt_fe_sessions
, struct mgmt_fe_session_ctx
, list_linkage
);
62 #define FOREACH_SESSION_IN_LIST(adapter, session) \
63 frr_each_safe (mgmt_fe_sessions, &(adapter)->fe_sessions, (session))
65 static struct event_loop
*mgmt_fe_adapter_tm
;
66 static struct mgmt_master
*mgmt_fe_adapter_mm
;
68 static struct mgmt_fe_adapters_head mgmt_fe_adapters
;
70 static struct hash
*mgmt_fe_sessions
;
71 static uint64_t mgmt_fe_next_session_id
;
73 /* Forward declarations */
75 mgmt_fe_adapter_register_event(struct mgmt_fe_client_adapter
*adapter
,
76 enum mgmt_fe_event event
);
78 mgmt_fe_adapter_disconnect(struct mgmt_fe_client_adapter
*adapter
);
80 mgmt_fe_session_register_event(struct mgmt_fe_session_ctx
*session
,
81 enum mgmt_session_event event
);
84 mgmt_fe_session_write_lock_ds(Mgmtd__DatastoreId ds_id
,
85 struct mgmt_ds_ctx
*ds_ctx
,
86 struct mgmt_fe_session_ctx
*session
)
88 if (!session
->ds_write_locked
[ds_id
]) {
89 if (mgmt_ds_write_lock(ds_ctx
) != 0) {
91 "Failed to lock the DS %u for Sessn: %p from %s!",
92 ds_id
, session
, session
->adapter
->name
);
96 session
->ds_write_locked
[ds_id
] = true;
98 "Write-Locked the DS %u for Sessn: %p from %s!", ds_id
,
99 session
, session
->adapter
->name
);
106 mgmt_fe_session_read_lock_ds(Mgmtd__DatastoreId ds_id
,
107 struct mgmt_ds_ctx
*ds_ctx
,
108 struct mgmt_fe_session_ctx
*session
)
110 if (!session
->ds_read_locked
[ds_id
]) {
111 if (mgmt_ds_read_lock(ds_ctx
) != 0) {
112 MGMTD_FE_ADAPTER_DBG(
113 "Failed to lock the DS %u for Sessn: %p from %s!",
114 ds_id
, session
, session
->adapter
->name
);
118 session
->ds_read_locked
[ds_id
] = true;
119 MGMTD_FE_ADAPTER_DBG(
120 "Read-Locked the DS %u for Sessn: %p from %s!", ds_id
,
121 session
, session
->adapter
->name
);
127 static int mgmt_fe_session_unlock_ds(Mgmtd__DatastoreId ds_id
,
128 struct mgmt_ds_ctx
*ds_ctx
,
129 struct mgmt_fe_session_ctx
*session
,
130 bool unlock_write
, bool unlock_read
)
132 if (unlock_write
&& session
->ds_write_locked
[ds_id
]) {
133 session
->ds_write_locked
[ds_id
] = false;
134 session
->ds_locked_implict
[ds_id
] = false;
135 if (mgmt_ds_unlock(ds_ctx
) != 0) {
136 MGMTD_FE_ADAPTER_DBG(
137 "Failed to unlock the DS %u taken earlier by Sessn: %p from %s!",
138 ds_id
, session
, session
->adapter
->name
);
142 MGMTD_FE_ADAPTER_DBG(
143 "Unlocked DS %u write-locked earlier by Sessn: %p from %s",
144 ds_id
, session
, session
->adapter
->name
);
145 } else if (unlock_read
&& session
->ds_read_locked
[ds_id
]) {
146 session
->ds_read_locked
[ds_id
] = false;
147 session
->ds_locked_implict
[ds_id
] = false;
148 if (mgmt_ds_unlock(ds_ctx
) != 0) {
149 MGMTD_FE_ADAPTER_DBG(
150 "Failed to unlock the DS %u taken earlier by Sessn: %p from %s!",
151 ds_id
, session
, session
->adapter
->name
);
155 MGMTD_FE_ADAPTER_DBG(
156 "Unlocked DS %u read-locked earlier by Sessn: %p from %s",
157 ds_id
, session
, session
->adapter
->name
);
164 mgmt_fe_session_cfg_txn_cleanup(struct mgmt_fe_session_ctx
*session
)
166 Mgmtd__DatastoreId ds_id
;
167 struct mgmt_ds_ctx
*ds_ctx
;
170 * Ensure any uncommitted changes in Candidate DS
173 mgmt_ds_copy_dss(mm
->running_ds
, mm
->candidate_ds
, false);
175 for (ds_id
= 0; ds_id
< MGMTD_DS_MAX_ID
; ds_id
++) {
176 ds_ctx
= mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
, ds_id
);
178 if (session
->ds_locked_implict
[ds_id
])
179 mgmt_fe_session_unlock_ds(
180 ds_id
, ds_ctx
, session
, true, false);
185 * Destroy the actual transaction created earlier.
187 if (session
->cfg_txn_id
!= MGMTD_TXN_ID_NONE
)
188 mgmt_destroy_txn(&session
->cfg_txn_id
);
192 mgmt_fe_session_show_txn_cleanup(struct mgmt_fe_session_ctx
*session
)
194 Mgmtd__DatastoreId ds_id
;
195 struct mgmt_ds_ctx
*ds_ctx
;
197 for (ds_id
= 0; ds_id
< MGMTD_DS_MAX_ID
; ds_id
++) {
198 ds_ctx
= mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
, ds_id
);
200 mgmt_fe_session_unlock_ds(ds_id
, ds_ctx
, session
,
206 * Destroy the transaction created recently.
208 if (session
->txn_id
!= MGMTD_TXN_ID_NONE
)
209 mgmt_destroy_txn(&session
->txn_id
);
213 mgmt_fe_adapter_compute_set_cfg_timers(struct mgmt_setcfg_stats
*setcfg_stats
)
215 setcfg_stats
->last_exec_tm
= timeval_elapsed(setcfg_stats
->last_end
,
216 setcfg_stats
->last_start
);
217 if (setcfg_stats
->last_exec_tm
> setcfg_stats
->max_tm
)
218 setcfg_stats
->max_tm
= setcfg_stats
->last_exec_tm
;
220 if (setcfg_stats
->last_exec_tm
< setcfg_stats
->min_tm
)
221 setcfg_stats
->min_tm
= setcfg_stats
->last_exec_tm
;
223 setcfg_stats
->avg_tm
=
224 (((setcfg_stats
->avg_tm
* (setcfg_stats
->set_cfg_count
- 1))
225 + setcfg_stats
->last_exec_tm
)
226 / setcfg_stats
->set_cfg_count
);
230 mgmt_fe_session_compute_commit_timers(struct mgmt_commit_stats
*cmt_stats
)
232 cmt_stats
->last_exec_tm
=
233 timeval_elapsed(cmt_stats
->last_end
, cmt_stats
->last_start
);
234 if (cmt_stats
->last_exec_tm
> cmt_stats
->max_tm
) {
235 cmt_stats
->max_tm
= cmt_stats
->last_exec_tm
;
236 cmt_stats
->max_batch_cnt
= cmt_stats
->last_batch_cnt
;
239 if (cmt_stats
->last_exec_tm
< cmt_stats
->min_tm
) {
240 cmt_stats
->min_tm
= cmt_stats
->last_exec_tm
;
241 cmt_stats
->min_batch_cnt
= cmt_stats
->last_batch_cnt
;
245 static void mgmt_fe_cleanup_session(struct mgmt_fe_session_ctx
**session
)
247 if ((*session
)->adapter
) {
248 mgmt_fe_session_cfg_txn_cleanup((*session
));
249 mgmt_fe_session_show_txn_cleanup((*session
));
250 mgmt_fe_session_unlock_ds(MGMTD_DS_CANDIDATE
,
251 mgmt_fe_adapter_mm
->candidate_ds
,
252 *session
, true, true);
253 mgmt_fe_session_unlock_ds(MGMTD_DS_RUNNING
,
254 mgmt_fe_adapter_mm
->running_ds
,
255 *session
, true, true);
257 mgmt_fe_sessions_del(&(*session
)->adapter
->fe_sessions
,
259 mgmt_fe_adapter_unlock(&(*session
)->adapter
);
262 hash_release(mgmt_fe_sessions
, *session
);
263 XFREE(MTYPE_MGMTD_FE_SESSION
, *session
);
267 static struct mgmt_fe_session_ctx
*
268 mgmt_fe_find_session_by_client_id(struct mgmt_fe_client_adapter
*adapter
,
271 struct mgmt_fe_session_ctx
*session
;
273 FOREACH_SESSION_IN_LIST (adapter
, session
) {
274 if (session
->client_id
== client_id
)
281 static unsigned int mgmt_fe_session_hash_key(const void *data
)
283 const struct mgmt_fe_session_ctx
*session
= data
;
285 return jhash2((uint32_t *) &session
->session_id
,
286 sizeof(session
->session_id
) / sizeof(uint32_t), 0);
289 static bool mgmt_fe_session_hash_cmp(const void *d1
, const void *d2
)
291 const struct mgmt_fe_session_ctx
*session1
= d1
;
292 const struct mgmt_fe_session_ctx
*session2
= d2
;
294 return (session1
->session_id
== session2
->session_id
);
297 static void mgmt_fe_session_hash_free(void *data
)
299 struct mgmt_fe_session_ctx
*session
= data
;
301 mgmt_fe_cleanup_session(&session
);
304 static void mgmt_fe_session_hash_destroy(void)
306 if (mgmt_fe_sessions
== NULL
)
309 hash_clean(mgmt_fe_sessions
,
310 mgmt_fe_session_hash_free
);
311 hash_free(mgmt_fe_sessions
);
312 mgmt_fe_sessions
= NULL
;
315 static inline struct mgmt_fe_session_ctx
*
316 mgmt_session_id2ctx(uint64_t session_id
)
318 struct mgmt_fe_session_ctx key
= {0};
319 struct mgmt_fe_session_ctx
*session
;
321 if (!mgmt_fe_sessions
)
324 key
.session_id
= session_id
;
325 session
= hash_lookup(mgmt_fe_sessions
, &key
);
330 static struct mgmt_fe_session_ctx
*
331 mgmt_fe_create_session(struct mgmt_fe_client_adapter
*adapter
,
334 struct mgmt_fe_session_ctx
*session
;
336 session
= mgmt_fe_find_session_by_client_id(adapter
, client_id
);
338 mgmt_fe_cleanup_session(&session
);
340 session
= XCALLOC(MTYPE_MGMTD_FE_SESSION
,
341 sizeof(struct mgmt_fe_session_ctx
));
343 session
->client_id
= client_id
;
344 session
->adapter
= adapter
;
345 session
->txn_id
= MGMTD_TXN_ID_NONE
;
346 session
->cfg_txn_id
= MGMTD_TXN_ID_NONE
;
347 mgmt_fe_adapter_lock(adapter
);
348 mgmt_fe_sessions_add_tail(&adapter
->fe_sessions
, session
);
349 if (!mgmt_fe_next_session_id
)
350 mgmt_fe_next_session_id
++;
351 session
->session_id
= mgmt_fe_next_session_id
++;
352 hash_get(mgmt_fe_sessions
, session
, hash_alloc_intern
);
358 mgmt_fe_cleanup_sessions(struct mgmt_fe_client_adapter
*adapter
)
360 struct mgmt_fe_session_ctx
*session
;
362 FOREACH_SESSION_IN_LIST (adapter
, session
)
363 mgmt_fe_cleanup_session(&session
);
367 mgmt_fe_adapter_sched_msg_write(struct mgmt_fe_client_adapter
*adapter
)
369 if (!CHECK_FLAG(adapter
->flags
, MGMTD_FE_ADAPTER_FLAGS_WRITES_OFF
))
370 mgmt_fe_adapter_register_event(adapter
,
371 MGMTD_FE_CONN_WRITE
);
375 mgmt_fe_adapter_writes_on(struct mgmt_fe_client_adapter
*adapter
)
377 MGMTD_FE_ADAPTER_DBG("Resume writing msgs for '%s'", adapter
->name
);
378 UNSET_FLAG(adapter
->flags
, MGMTD_FE_ADAPTER_FLAGS_WRITES_OFF
);
379 mgmt_fe_adapter_sched_msg_write(adapter
);
383 mgmt_fe_adapter_writes_off(struct mgmt_fe_client_adapter
*adapter
)
385 SET_FLAG(adapter
->flags
, MGMTD_FE_ADAPTER_FLAGS_WRITES_OFF
);
386 MGMTD_FE_ADAPTER_DBG("Paused writing msgs for '%s'", adapter
->name
);
390 mgmt_fe_adapter_send_msg(struct mgmt_fe_client_adapter
*adapter
,
391 Mgmtd__FeMessage
*fe_msg
)
393 if (adapter
->conn_fd
== -1) {
394 MGMTD_FE_ADAPTER_DBG("can't send message on closed connection");
398 int rv
= mgmt_msg_send_msg(
399 &adapter
->mstate
, fe_msg
,
400 mgmtd__fe_message__get_packed_size(fe_msg
),
401 (size_t(*)(void *, void *))mgmtd__fe_message__pack
,
403 mgmt_fe_adapter_sched_msg_write(adapter
);
408 mgmt_fe_send_session_reply(struct mgmt_fe_client_adapter
*adapter
,
409 struct mgmt_fe_session_ctx
*session
,
410 bool create
, bool success
)
412 Mgmtd__FeMessage fe_msg
;
413 Mgmtd__FeSessionReply session_reply
;
415 mgmtd__fe_session_reply__init(&session_reply
);
416 session_reply
.create
= create
;
418 session_reply
.has_client_conn_id
= 1;
419 session_reply
.client_conn_id
= session
->client_id
;
421 session_reply
.session_id
= session
->session_id
;
422 session_reply
.success
= success
;
424 mgmtd__fe_message__init(&fe_msg
);
425 fe_msg
.message_case
= MGMTD__FE_MESSAGE__MESSAGE_SESSION_REPLY
;
426 fe_msg
.session_reply
= &session_reply
;
428 MGMTD_FE_ADAPTER_DBG(
429 "Sending SESSION_REPLY message to MGMTD Frontend client '%s'",
432 return mgmt_fe_adapter_send_msg(adapter
, &fe_msg
);
435 static int mgmt_fe_send_lockds_reply(struct mgmt_fe_session_ctx
*session
,
436 Mgmtd__DatastoreId ds_id
,
437 uint64_t req_id
, bool lock_ds
,
438 bool success
, const char *error_if_any
)
440 Mgmtd__FeMessage fe_msg
;
441 Mgmtd__FeLockDsReply lockds_reply
;
443 assert(session
->adapter
);
445 mgmtd__fe_lock_ds_reply__init(&lockds_reply
);
446 lockds_reply
.session_id
= session
->session_id
;
447 lockds_reply
.ds_id
= ds_id
;
448 lockds_reply
.req_id
= req_id
;
449 lockds_reply
.lock
= lock_ds
;
450 lockds_reply
.success
= success
;
452 lockds_reply
.error_if_any
= (char *)error_if_any
;
454 mgmtd__fe_message__init(&fe_msg
);
455 fe_msg
.message_case
= MGMTD__FE_MESSAGE__MESSAGE_LOCKDS_REPLY
;
456 fe_msg
.lockds_reply
= &lockds_reply
;
458 MGMTD_FE_ADAPTER_DBG(
459 "Sending LOCK_DS_REPLY message to MGMTD Frontend client '%s'",
460 session
->adapter
->name
);
462 return mgmt_fe_adapter_send_msg(session
->adapter
, &fe_msg
);
465 static int mgmt_fe_send_setcfg_reply(struct mgmt_fe_session_ctx
*session
,
466 Mgmtd__DatastoreId ds_id
,
467 uint64_t req_id
, bool success
,
468 const char *error_if_any
,
469 bool implicit_commit
)
471 Mgmtd__FeMessage fe_msg
;
472 Mgmtd__FeSetConfigReply setcfg_reply
;
474 assert(session
->adapter
);
476 if (implicit_commit
&& session
->cfg_txn_id
)
477 mgmt_fe_session_register_event(
478 session
, MGMTD_FE_SESSION_CFG_TXN_CLNUP
);
480 mgmtd__fe_set_config_reply__init(&setcfg_reply
);
481 setcfg_reply
.session_id
= session
->session_id
;
482 setcfg_reply
.ds_id
= ds_id
;
483 setcfg_reply
.req_id
= req_id
;
484 setcfg_reply
.success
= success
;
486 setcfg_reply
.error_if_any
= (char *)error_if_any
;
488 mgmtd__fe_message__init(&fe_msg
);
489 fe_msg
.message_case
= MGMTD__FE_MESSAGE__MESSAGE_SETCFG_REPLY
;
490 fe_msg
.setcfg_reply
= &setcfg_reply
;
492 MGMTD_FE_ADAPTER_DBG(
493 "Sending SET_CONFIG_REPLY message to MGMTD Frontend client '%s'",
494 session
->adapter
->name
);
496 if (implicit_commit
) {
497 if (mm
->perf_stats_en
)
498 gettimeofday(&session
->adapter
->cmt_stats
.last_end
, NULL
);
499 mgmt_fe_session_compute_commit_timers(
500 &session
->adapter
->cmt_stats
);
503 if (mm
->perf_stats_en
)
504 gettimeofday(&session
->adapter
->setcfg_stats
.last_end
, NULL
);
505 mgmt_fe_adapter_compute_set_cfg_timers(&session
->adapter
->setcfg_stats
);
507 return mgmt_fe_adapter_send_msg(session
->adapter
, &fe_msg
);
510 static int mgmt_fe_send_commitcfg_reply(
511 struct mgmt_fe_session_ctx
*session
, Mgmtd__DatastoreId src_ds_id
,
512 Mgmtd__DatastoreId dst_ds_id
, uint64_t req_id
, enum mgmt_result result
,
513 bool validate_only
, const char *error_if_any
)
515 Mgmtd__FeMessage fe_msg
;
516 Mgmtd__FeCommitConfigReply commcfg_reply
;
518 assert(session
->adapter
);
520 mgmtd__fe_commit_config_reply__init(&commcfg_reply
);
521 commcfg_reply
.session_id
= session
->session_id
;
522 commcfg_reply
.src_ds_id
= src_ds_id
;
523 commcfg_reply
.dst_ds_id
= dst_ds_id
;
524 commcfg_reply
.req_id
= req_id
;
525 commcfg_reply
.success
=
526 (result
== MGMTD_SUCCESS
|| result
== MGMTD_NO_CFG_CHANGES
)
529 commcfg_reply
.validate_only
= validate_only
;
531 commcfg_reply
.error_if_any
= (char *)error_if_any
;
533 mgmtd__fe_message__init(&fe_msg
);
534 fe_msg
.message_case
= MGMTD__FE_MESSAGE__MESSAGE_COMMCFG_REPLY
;
535 fe_msg
.commcfg_reply
= &commcfg_reply
;
537 MGMTD_FE_ADAPTER_DBG(
538 "Sending COMMIT_CONFIG_REPLY message to MGMTD Frontend client '%s'",
539 session
->adapter
->name
);
542 * Cleanup the CONFIG transaction associated with this session.
544 if (session
->cfg_txn_id
545 && ((result
== MGMTD_SUCCESS
&& !validate_only
)
546 || (result
== MGMTD_NO_CFG_CHANGES
)))
547 mgmt_fe_session_register_event(
548 session
, MGMTD_FE_SESSION_CFG_TXN_CLNUP
);
550 if (mm
->perf_stats_en
)
551 gettimeofday(&session
->adapter
->cmt_stats
.last_end
, NULL
);
552 mgmt_fe_session_compute_commit_timers(&session
->adapter
->cmt_stats
);
553 return mgmt_fe_adapter_send_msg(session
->adapter
, &fe_msg
);
556 static int mgmt_fe_send_getcfg_reply(struct mgmt_fe_session_ctx
*session
,
557 Mgmtd__DatastoreId ds_id
,
558 uint64_t req_id
, bool success
,
559 Mgmtd__YangDataReply
*data
,
560 const char *error_if_any
)
562 Mgmtd__FeMessage fe_msg
;
563 Mgmtd__FeGetConfigReply getcfg_reply
;
565 assert(session
->adapter
);
567 mgmtd__fe_get_config_reply__init(&getcfg_reply
);
568 getcfg_reply
.session_id
= session
->session_id
;
569 getcfg_reply
.ds_id
= ds_id
;
570 getcfg_reply
.req_id
= req_id
;
571 getcfg_reply
.success
= success
;
572 getcfg_reply
.data
= data
;
574 getcfg_reply
.error_if_any
= (char *)error_if_any
;
576 mgmtd__fe_message__init(&fe_msg
);
577 fe_msg
.message_case
= MGMTD__FE_MESSAGE__MESSAGE_GETCFG_REPLY
;
578 fe_msg
.getcfg_reply
= &getcfg_reply
;
580 MGMTD_FE_ADAPTER_DBG(
581 "Sending GET_CONFIG_REPLY message to MGMTD Frontend client '%s'",
582 session
->adapter
->name
);
585 * Cleanup the SHOW transaction associated with this session.
587 if (session
->txn_id
&& (!success
|| (data
&& data
->next_indx
< 0)))
588 mgmt_fe_session_register_event(
589 session
, MGMTD_FE_SESSION_SHOW_TXN_CLNUP
);
591 return mgmt_fe_adapter_send_msg(session
->adapter
, &fe_msg
);
594 static int mgmt_fe_send_getdata_reply(struct mgmt_fe_session_ctx
*session
,
595 Mgmtd__DatastoreId ds_id
,
596 uint64_t req_id
, bool success
,
597 Mgmtd__YangDataReply
*data
,
598 const char *error_if_any
)
600 Mgmtd__FeMessage fe_msg
;
601 Mgmtd__FeGetDataReply getdata_reply
;
603 assert(session
->adapter
);
605 mgmtd__fe_get_data_reply__init(&getdata_reply
);
606 getdata_reply
.session_id
= session
->session_id
;
607 getdata_reply
.ds_id
= ds_id
;
608 getdata_reply
.req_id
= req_id
;
609 getdata_reply
.success
= success
;
610 getdata_reply
.data
= data
;
612 getdata_reply
.error_if_any
= (char *)error_if_any
;
614 mgmtd__fe_message__init(&fe_msg
);
615 fe_msg
.message_case
= MGMTD__FE_MESSAGE__MESSAGE_GETDATA_REPLY
;
616 fe_msg
.getdata_reply
= &getdata_reply
;
618 MGMTD_FE_ADAPTER_DBG(
619 "Sending GET_DATA_REPLY message to MGMTD Frontend client '%s'",
620 session
->adapter
->name
);
623 * Cleanup the SHOW transaction associated with this session.
625 if (session
->txn_id
&& (!success
|| (data
&& data
->next_indx
< 0)))
626 mgmt_fe_session_register_event(
627 session
, MGMTD_FE_SESSION_SHOW_TXN_CLNUP
);
629 return mgmt_fe_adapter_send_msg(session
->adapter
, &fe_msg
);
632 static void mgmt_fe_session_cfg_txn_clnup(struct event
*thread
)
634 struct mgmt_fe_session_ctx
*session
;
636 session
= (struct mgmt_fe_session_ctx
*)EVENT_ARG(thread
);
638 mgmt_fe_session_cfg_txn_cleanup(session
);
641 static void mgmt_fe_session_show_txn_clnup(struct event
*thread
)
643 struct mgmt_fe_session_ctx
*session
;
645 session
= (struct mgmt_fe_session_ctx
*)EVENT_ARG(thread
);
647 mgmt_fe_session_show_txn_cleanup(session
);
651 mgmt_fe_session_register_event(struct mgmt_fe_session_ctx
*session
,
652 enum mgmt_session_event event
)
654 struct timeval tv
= {.tv_sec
= 0,
655 .tv_usec
= MGMTD_FE_MSG_PROC_DELAY_USEC
};
658 case MGMTD_FE_SESSION_CFG_TXN_CLNUP
:
659 event_add_timer_tv(mgmt_fe_adapter_tm
,
660 mgmt_fe_session_cfg_txn_clnup
, session
,
661 &tv
, &session
->proc_cfg_txn_clnp
);
663 case MGMTD_FE_SESSION_SHOW_TXN_CLNUP
:
664 event_add_timer_tv(mgmt_fe_adapter_tm
,
665 mgmt_fe_session_show_txn_clnup
, session
,
666 &tv
, &session
->proc_show_txn_clnp
);
671 static struct mgmt_fe_client_adapter
*
672 mgmt_fe_find_adapter_by_fd(int conn_fd
)
674 struct mgmt_fe_client_adapter
*adapter
;
676 FOREACH_ADAPTER_IN_LIST (adapter
) {
677 if (adapter
->conn_fd
== conn_fd
)
684 static struct mgmt_fe_client_adapter
*
685 mgmt_fe_find_adapter_by_name(const char *name
)
687 struct mgmt_fe_client_adapter
*adapter
;
689 FOREACH_ADAPTER_IN_LIST (adapter
) {
690 if (!strncmp(adapter
->name
, name
, sizeof(adapter
->name
)))
697 static void mgmt_fe_adapter_disconnect(struct mgmt_fe_client_adapter
*adapter
)
699 if (adapter
->conn_fd
>= 0) {
700 close(adapter
->conn_fd
);
701 adapter
->conn_fd
= -1;
704 /* TODO: notify about client disconnect for appropriate cleanup */
705 mgmt_fe_cleanup_sessions(adapter
);
706 mgmt_fe_sessions_fini(&adapter
->fe_sessions
);
707 mgmt_fe_adapters_del(&mgmt_fe_adapters
, adapter
);
709 mgmt_fe_adapter_unlock(&adapter
);
713 mgmt_fe_adapter_cleanup_old_conn(struct mgmt_fe_client_adapter
*adapter
)
715 struct mgmt_fe_client_adapter
*old
;
717 FOREACH_ADAPTER_IN_LIST (old
) {
719 && !strncmp(adapter
->name
, old
->name
, sizeof(adapter
->name
))) {
721 * We have a Zombie lingering around
723 MGMTD_FE_ADAPTER_DBG(
724 "Client '%s' (FD:%d) seems to have reconnected. Removing old connection (FD:%d)!",
725 adapter
->name
, adapter
->conn_fd
, old
->conn_fd
);
726 mgmt_fe_adapter_disconnect(old
);
732 mgmt_fe_cleanup_adapters(void)
734 struct mgmt_fe_client_adapter
*adapter
;
736 FOREACH_ADAPTER_IN_LIST (adapter
) {
737 mgmt_fe_cleanup_sessions(adapter
);
738 mgmt_fe_adapter_unlock(&adapter
);
743 mgmt_fe_session_handle_lockds_req_msg(struct mgmt_fe_session_ctx
*session
,
744 Mgmtd__FeLockDsReq
*lockds_req
)
746 struct mgmt_ds_ctx
*ds_ctx
;
749 * Next check first if the SET_CONFIG_REQ is for Candidate DS
750 * or not. Report failure if its not. MGMTD currently only
751 * supports editing the Candidate DS.
753 if (lockds_req
->ds_id
!= MGMTD_DS_CANDIDATE
) {
754 mgmt_fe_send_lockds_reply(
755 session
, lockds_req
->ds_id
, lockds_req
->req_id
,
756 lockds_req
->lock
, false,
757 "Lock/Unlock on datastores other than Candidate DS not permitted!");
762 mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
, lockds_req
->ds_id
);
764 mgmt_fe_send_lockds_reply(
765 session
, lockds_req
->ds_id
, lockds_req
->req_id
,
766 lockds_req
->lock
, false,
767 "Failed to retrieve handle for DS!");
771 if (lockds_req
->lock
) {
772 if (mgmt_fe_session_write_lock_ds(lockds_req
->ds_id
,
775 mgmt_fe_send_lockds_reply(
776 session
, lockds_req
->ds_id
, lockds_req
->req_id
,
777 lockds_req
->lock
, false,
778 "Lock already taken on DS by another session!");
782 session
->ds_locked_implict
[lockds_req
->ds_id
] = false;
784 if (!session
->ds_write_locked
[lockds_req
->ds_id
]) {
785 mgmt_fe_send_lockds_reply(
786 session
, lockds_req
->ds_id
, lockds_req
->req_id
,
787 lockds_req
->lock
, false,
788 "Lock on DS was not taken by this session!");
792 (void)mgmt_fe_session_unlock_ds(lockds_req
->ds_id
, ds_ctx
,
793 session
, true, false);
796 if (mgmt_fe_send_lockds_reply(session
, lockds_req
->ds_id
,
797 lockds_req
->req_id
, lockds_req
->lock
,
800 MGMTD_FE_ADAPTER_DBG(
801 "Failed to send LOCK_DS_REPLY for DS %u Sessn: %p from %s",
802 lockds_req
->ds_id
, session
, session
->adapter
->name
);
809 mgmt_fe_session_handle_setcfg_req_msg(struct mgmt_fe_session_ctx
*session
,
810 Mgmtd__FeSetConfigReq
*setcfg_req
)
812 uint64_t cfg_session_id
;
813 struct mgmt_ds_ctx
*ds_ctx
, *dst_ds_ctx
;
815 if (mm
->perf_stats_en
)
816 gettimeofday(&session
->adapter
->setcfg_stats
.last_start
, NULL
);
819 * Next check first if the SET_CONFIG_REQ is for Candidate DS
820 * or not. Report failure if its not. MGMTD currently only
821 * supports editing the Candidate DS.
823 if (setcfg_req
->ds_id
!= MGMTD_DS_CANDIDATE
) {
824 mgmt_fe_send_setcfg_reply(
825 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
, false,
826 "Set-Config on datastores other than Candidate DS not permitted!",
827 setcfg_req
->implicit_commit
);
835 mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
, setcfg_req
->ds_id
);
837 mgmt_fe_send_setcfg_reply(
838 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
, false,
839 "No such DS exists!", setcfg_req
->implicit_commit
);
843 if (session
->cfg_txn_id
== MGMTD_TXN_ID_NONE
) {
845 * Check first if the current session can run a CONFIG
846 * transaction or not. Report failure if a CONFIG transaction
847 * from another session is already in progress.
849 cfg_session_id
= mgmt_config_txn_in_progress();
850 if (cfg_session_id
!= MGMTD_SESSION_ID_NONE
851 && cfg_session_id
!= session
->session_id
) {
852 mgmt_fe_send_setcfg_reply(
853 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
,
855 "Configuration already in-progress through a different user session!",
856 setcfg_req
->implicit_commit
);
857 goto mgmt_fe_sess_handle_setcfg_req_failed
;
862 * Try taking write-lock on the requested DS (if not already).
864 if (!session
->ds_write_locked
[setcfg_req
->ds_id
]) {
865 if (mgmt_fe_session_write_lock_ds(setcfg_req
->ds_id
,
868 mgmt_fe_send_setcfg_reply(
869 session
, setcfg_req
->ds_id
,
870 setcfg_req
->req_id
, false,
871 "Failed to lock the DS!",
872 setcfg_req
->implicit_commit
);
873 goto mgmt_fe_sess_handle_setcfg_req_failed
;
876 session
->ds_locked_implict
[setcfg_req
->ds_id
] = true;
880 * Start a CONFIG Transaction (if not started already)
882 session
->cfg_txn_id
= mgmt_create_txn(session
->session_id
,
883 MGMTD_TXN_TYPE_CONFIG
);
884 if (session
->cfg_txn_id
== MGMTD_SESSION_ID_NONE
) {
885 mgmt_fe_send_setcfg_reply(
886 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
,
888 "Failed to create a Configuration session!",
889 setcfg_req
->implicit_commit
);
890 goto mgmt_fe_sess_handle_setcfg_req_failed
;
893 MGMTD_FE_ADAPTER_DBG(
894 "Created new Config Txn 0x%llx for session %p",
895 (unsigned long long)session
->cfg_txn_id
, session
);
897 MGMTD_FE_ADAPTER_DBG(
898 "Config Txn 0x%llx for session %p already created",
899 (unsigned long long)session
->cfg_txn_id
, session
);
901 if (setcfg_req
->implicit_commit
) {
903 * In this scenario need to skip cleanup of the txn,
904 * so setting implicit commit to false.
906 mgmt_fe_send_setcfg_reply(
907 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
,
909 "A Configuration transaction is already in progress!",
916 if (setcfg_req
->implicit_commit
) {
917 dst_ds_ctx
= mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
,
918 setcfg_req
->commit_ds_id
);
920 mgmt_fe_send_setcfg_reply(
921 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
,
922 false, "No such commit DS exists!",
923 setcfg_req
->implicit_commit
);
929 * Create the SETConfig request under the transaction.
931 if (mgmt_txn_send_set_config_req(
932 session
->cfg_txn_id
, setcfg_req
->req_id
, setcfg_req
->ds_id
,
933 ds_ctx
, setcfg_req
->data
, setcfg_req
->n_data
,
934 setcfg_req
->implicit_commit
, setcfg_req
->commit_ds_id
,
937 mgmt_fe_send_setcfg_reply(
938 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
, false,
939 "Request processing for SET-CONFIG failed!",
940 setcfg_req
->implicit_commit
);
941 goto mgmt_fe_sess_handle_setcfg_req_failed
;
946 mgmt_fe_sess_handle_setcfg_req_failed
:
949 * Delete transaction created recently.
951 if (session
->cfg_txn_id
!= MGMTD_TXN_ID_NONE
)
952 mgmt_destroy_txn(&session
->cfg_txn_id
);
953 if (ds_ctx
&& session
->ds_write_locked
[setcfg_req
->ds_id
])
954 mgmt_fe_session_unlock_ds(setcfg_req
->ds_id
, ds_ctx
, session
,
961 mgmt_fe_session_handle_getcfg_req_msg(struct mgmt_fe_session_ctx
*session
,
962 Mgmtd__FeGetConfigReq
*getcfg_req
)
964 struct mgmt_ds_ctx
*ds_ctx
;
970 mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
, getcfg_req
->ds_id
);
972 mgmt_fe_send_getcfg_reply(session
, getcfg_req
->ds_id
,
973 getcfg_req
->req_id
, false, NULL
,
974 "No such DS exists!");
979 * Next check first if the SET_CONFIG_REQ is for Candidate DS
980 * or not. Report failure if its not. MGMTD currently only
981 * supports editing the Candidate DS.
983 if (getcfg_req
->ds_id
!= MGMTD_DS_CANDIDATE
984 && getcfg_req
->ds_id
!= MGMTD_DS_RUNNING
) {
985 mgmt_fe_send_getcfg_reply(
986 session
, getcfg_req
->ds_id
, getcfg_req
->req_id
, false,
988 "Get-Config on datastores other than Candidate or Running DS not permitted!");
992 if (session
->txn_id
== MGMTD_TXN_ID_NONE
) {
994 * Try taking read-lock on the requested DS (if not already
995 * locked). If the DS has already been write-locked by a ongoing
996 * CONFIG transaction we may allow reading the contents of the
999 if (!session
->ds_read_locked
[getcfg_req
->ds_id
]
1000 && !session
->ds_write_locked
[getcfg_req
->ds_id
]) {
1001 if (mgmt_fe_session_read_lock_ds(getcfg_req
->ds_id
,
1004 mgmt_fe_send_getcfg_reply(
1005 session
, getcfg_req
->ds_id
,
1006 getcfg_req
->req_id
, false, NULL
,
1007 "Failed to lock the DS! Another session might have locked it!");
1008 goto mgmt_fe_sess_handle_getcfg_req_failed
;
1011 session
->ds_locked_implict
[getcfg_req
->ds_id
] = true;
1015 * Start a SHOW Transaction (if not started already)
1017 session
->txn_id
= mgmt_create_txn(session
->session_id
,
1018 MGMTD_TXN_TYPE_SHOW
);
1019 if (session
->txn_id
== MGMTD_SESSION_ID_NONE
) {
1020 mgmt_fe_send_getcfg_reply(
1021 session
, getcfg_req
->ds_id
, getcfg_req
->req_id
,
1023 "Failed to create a Show transaction!");
1024 goto mgmt_fe_sess_handle_getcfg_req_failed
;
1027 MGMTD_FE_ADAPTER_DBG(
1028 "Created new Show Txn 0x%llx for session %p",
1029 (unsigned long long)session
->txn_id
, session
);
1031 MGMTD_FE_ADAPTER_DBG(
1032 "Show Txn 0x%llx for session %p already created",
1033 (unsigned long long)session
->txn_id
, session
);
1037 * Create a GETConfig request under the transaction.
1039 if (mgmt_txn_send_get_config_req(session
->txn_id
, getcfg_req
->req_id
,
1040 getcfg_req
->ds_id
, ds_ctx
,
1041 getcfg_req
->data
, getcfg_req
->n_data
)
1043 mgmt_fe_send_getcfg_reply(
1044 session
, getcfg_req
->ds_id
, getcfg_req
->req_id
, false,
1045 NULL
, "Request processing for GET-CONFIG failed!");
1046 goto mgmt_fe_sess_handle_getcfg_req_failed
;
1051 mgmt_fe_sess_handle_getcfg_req_failed
:
1054 * Destroy the transaction created recently.
1056 if (session
->txn_id
!= MGMTD_TXN_ID_NONE
)
1057 mgmt_destroy_txn(&session
->txn_id
);
1058 if (ds_ctx
&& session
->ds_read_locked
[getcfg_req
->ds_id
])
1059 mgmt_fe_session_unlock_ds(getcfg_req
->ds_id
, ds_ctx
, session
,
1066 mgmt_fe_session_handle_getdata_req_msg(struct mgmt_fe_session_ctx
*session
,
1067 Mgmtd__FeGetDataReq
*getdata_req
)
1069 struct mgmt_ds_ctx
*ds_ctx
;
1072 * Get the DS handle.
1074 ds_ctx
= mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
,
1075 getdata_req
->ds_id
);
1077 mgmt_fe_send_getdata_reply(session
, getdata_req
->ds_id
,
1078 getdata_req
->req_id
, false, NULL
,
1079 "No such DS exists!");
1083 if (session
->txn_id
== MGMTD_TXN_ID_NONE
) {
1085 * Try taking read-lock on the requested DS (if not already
1086 * locked). If the DS has already been write-locked by a ongoing
1087 * CONFIG transaction we may allow reading the contents of the
1090 if (!session
->ds_read_locked
[getdata_req
->ds_id
]
1091 && !session
->ds_write_locked
[getdata_req
->ds_id
]) {
1092 if (mgmt_fe_session_read_lock_ds(getdata_req
->ds_id
,
1095 mgmt_fe_send_getdata_reply(
1096 session
, getdata_req
->ds_id
,
1097 getdata_req
->req_id
, false, NULL
,
1098 "Failed to lock the DS! Another session might have locked it!");
1099 goto mgmt_fe_sess_handle_getdata_req_failed
;
1102 session
->ds_locked_implict
[getdata_req
->ds_id
] = true;
1106 * Start a SHOW Transaction (if not started already)
1108 session
->txn_id
= mgmt_create_txn(session
->session_id
,
1109 MGMTD_TXN_TYPE_SHOW
);
1110 if (session
->txn_id
== MGMTD_SESSION_ID_NONE
) {
1111 mgmt_fe_send_getdata_reply(
1112 session
, getdata_req
->ds_id
, getdata_req
->req_id
,
1114 "Failed to create a Show transaction!");
1115 goto mgmt_fe_sess_handle_getdata_req_failed
;
1118 MGMTD_FE_ADAPTER_DBG(
1119 "Created new Show Txn 0x%llx for session %p",
1120 (unsigned long long)session
->txn_id
, session
);
1122 MGMTD_FE_ADAPTER_DBG(
1123 "Show Txn 0x%llx for session %p already created",
1124 (unsigned long long)session
->txn_id
, session
);
1128 * Create a GETData request under the transaction.
1130 if (mgmt_txn_send_get_data_req(session
->txn_id
, getdata_req
->req_id
,
1131 getdata_req
->ds_id
, ds_ctx
,
1132 getdata_req
->data
, getdata_req
->n_data
)
1134 mgmt_fe_send_getdata_reply(
1135 session
, getdata_req
->ds_id
, getdata_req
->req_id
, false,
1136 NULL
, "Request processing for GET-CONFIG failed!");
1137 goto mgmt_fe_sess_handle_getdata_req_failed
;
1142 mgmt_fe_sess_handle_getdata_req_failed
:
1145 * Destroy the transaction created recently.
1147 if (session
->txn_id
!= MGMTD_TXN_ID_NONE
)
1148 mgmt_destroy_txn(&session
->txn_id
);
1150 if (ds_ctx
&& session
->ds_read_locked
[getdata_req
->ds_id
])
1151 mgmt_fe_session_unlock_ds(getdata_req
->ds_id
, ds_ctx
,
1152 session
, false, true);
1157 static int mgmt_fe_session_handle_commit_config_req_msg(
1158 struct mgmt_fe_session_ctx
*session
,
1159 Mgmtd__FeCommitConfigReq
*commcfg_req
)
1161 struct mgmt_ds_ctx
*src_ds_ctx
, *dst_ds_ctx
;
1163 if (mm
->perf_stats_en
)
1164 gettimeofday(&session
->adapter
->cmt_stats
.last_start
, NULL
);
1165 session
->adapter
->cmt_stats
.commit_cnt
++;
1167 * Get the source DS handle.
1169 src_ds_ctx
= mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
,
1170 commcfg_req
->src_ds_id
);
1172 mgmt_fe_send_commitcfg_reply(
1173 session
, commcfg_req
->src_ds_id
, commcfg_req
->dst_ds_id
,
1174 commcfg_req
->req_id
, MGMTD_INTERNAL_ERROR
,
1175 commcfg_req
->validate_only
,
1176 "No such source DS exists!");
1181 * Get the destination DS handle.
1183 dst_ds_ctx
= mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
,
1184 commcfg_req
->dst_ds_id
);
1186 mgmt_fe_send_commitcfg_reply(
1187 session
, commcfg_req
->src_ds_id
, commcfg_req
->dst_ds_id
,
1188 commcfg_req
->req_id
, MGMTD_INTERNAL_ERROR
,
1189 commcfg_req
->validate_only
,
1190 "No such destination DS exists!");
1195 * Next check first if the SET_CONFIG_REQ is for Candidate DS
1196 * or not. Report failure if its not. MGMTD currently only
1197 * supports editing the Candidate DS.
1199 if (commcfg_req
->dst_ds_id
!= MGMTD_DS_RUNNING
) {
1200 mgmt_fe_send_commitcfg_reply(
1201 session
, commcfg_req
->src_ds_id
, commcfg_req
->dst_ds_id
,
1202 commcfg_req
->req_id
, MGMTD_INTERNAL_ERROR
,
1203 commcfg_req
->validate_only
,
1204 "Set-Config on datastores other than Running DS not permitted!");
1208 if (session
->cfg_txn_id
== MGMTD_TXN_ID_NONE
) {
1210 * Start a CONFIG Transaction (if not started already)
1212 session
->cfg_txn_id
= mgmt_create_txn(session
->session_id
,
1213 MGMTD_TXN_TYPE_CONFIG
);
1214 if (session
->cfg_txn_id
== MGMTD_SESSION_ID_NONE
) {
1215 mgmt_fe_send_commitcfg_reply(
1216 session
, commcfg_req
->src_ds_id
,
1217 commcfg_req
->dst_ds_id
, commcfg_req
->req_id
,
1218 MGMTD_INTERNAL_ERROR
,
1219 commcfg_req
->validate_only
,
1220 "Failed to create a Configuration session!");
1223 MGMTD_FE_ADAPTER_DBG("Created txn %" PRIu64
1224 " for session %" PRIu64
1225 " for COMMIT-CFG-REQ",
1226 session
->cfg_txn_id
, session
->session_id
);
1231 * Try taking write-lock on the destination DS (if not already).
1233 if (!session
->ds_write_locked
[commcfg_req
->dst_ds_id
]) {
1234 if (mgmt_fe_session_write_lock_ds(commcfg_req
->dst_ds_id
,
1235 dst_ds_ctx
, session
)
1237 mgmt_fe_send_commitcfg_reply(
1238 session
, commcfg_req
->src_ds_id
,
1239 commcfg_req
->dst_ds_id
, commcfg_req
->req_id
,
1240 MGMTD_DS_LOCK_FAILED
,
1241 commcfg_req
->validate_only
,
1242 "Failed to lock the destination DS!");
1246 session
->ds_locked_implict
[commcfg_req
->dst_ds_id
] = true;
1250 * Create COMMITConfig request under the transaction
1252 if (mgmt_txn_send_commit_config_req(
1253 session
->cfg_txn_id
, commcfg_req
->req_id
,
1254 commcfg_req
->src_ds_id
, src_ds_ctx
, commcfg_req
->dst_ds_id
,
1255 dst_ds_ctx
, commcfg_req
->validate_only
, commcfg_req
->abort
,
1258 mgmt_fe_send_commitcfg_reply(
1259 session
, commcfg_req
->src_ds_id
, commcfg_req
->dst_ds_id
,
1260 commcfg_req
->req_id
, MGMTD_INTERNAL_ERROR
,
1261 commcfg_req
->validate_only
,
1262 "Request processing for COMMIT-CONFIG failed!");
1270 mgmt_fe_adapter_handle_msg(struct mgmt_fe_client_adapter
*adapter
,
1271 Mgmtd__FeMessage
*fe_msg
)
1273 struct mgmt_fe_session_ctx
*session
;
1276 * protobuf-c adds a max size enum with an internal, and changing by
1277 * version, name; cast to an int to avoid unhandled enum warnings
1279 switch ((int)fe_msg
->message_case
) {
1280 case MGMTD__FE_MESSAGE__MESSAGE_REGISTER_REQ
:
1281 MGMTD_FE_ADAPTER_DBG("Got Register Req Msg from '%s'",
1282 fe_msg
->register_req
->client_name
);
1284 if (strlen(fe_msg
->register_req
->client_name
)) {
1285 strlcpy(adapter
->name
,
1286 fe_msg
->register_req
->client_name
,
1287 sizeof(adapter
->name
));
1288 mgmt_fe_adapter_cleanup_old_conn(adapter
);
1291 case MGMTD__FE_MESSAGE__MESSAGE_SESSION_REQ
:
1292 if (fe_msg
->session_req
->create
1293 && fe_msg
->session_req
->id_case
1294 == MGMTD__FE_SESSION_REQ__ID_CLIENT_CONN_ID
) {
1295 MGMTD_FE_ADAPTER_DBG(
1296 "Got Session Create Req Msg for client-id %llu from '%s'",
1297 (unsigned long long)
1298 fe_msg
->session_req
->client_conn_id
,
1301 session
= mgmt_fe_create_session(
1302 adapter
, fe_msg
->session_req
->client_conn_id
);
1303 mgmt_fe_send_session_reply(adapter
, session
, true,
1304 session
? true : false);
1306 !fe_msg
->session_req
->create
1307 && fe_msg
->session_req
->id_case
1308 == MGMTD__FE_SESSION_REQ__ID_SESSION_ID
) {
1309 MGMTD_FE_ADAPTER_DBG(
1310 "Got Session Destroy Req Msg for session-id %llu from '%s'",
1311 (unsigned long long)
1312 fe_msg
->session_req
->session_id
,
1315 session
= mgmt_session_id2ctx(
1316 fe_msg
->session_req
->session_id
);
1317 mgmt_fe_send_session_reply(adapter
, session
, false,
1319 mgmt_fe_cleanup_session(&session
);
1322 case MGMTD__FE_MESSAGE__MESSAGE_LOCKDS_REQ
:
1323 session
= mgmt_session_id2ctx(
1324 fe_msg
->lockds_req
->session_id
);
1325 MGMTD_FE_ADAPTER_DBG(
1326 "Got %sockDS Req Msg for DS:%d for session-id %llx from '%s'",
1327 fe_msg
->lockds_req
->lock
? "L" : "Unl",
1328 fe_msg
->lockds_req
->ds_id
,
1329 (unsigned long long)fe_msg
->lockds_req
->session_id
,
1331 mgmt_fe_session_handle_lockds_req_msg(
1332 session
, fe_msg
->lockds_req
);
1334 case MGMTD__FE_MESSAGE__MESSAGE_SETCFG_REQ
:
1335 session
= mgmt_session_id2ctx(
1336 fe_msg
->setcfg_req
->session_id
);
1337 session
->adapter
->setcfg_stats
.set_cfg_count
++;
1338 MGMTD_FE_ADAPTER_DBG(
1339 "Got Set Config Req Msg (%d Xpaths, Implicit:%c) on DS:%d for session-id %llu from '%s'",
1340 (int)fe_msg
->setcfg_req
->n_data
,
1341 fe_msg
->setcfg_req
->implicit_commit
? 'T':'F',
1342 fe_msg
->setcfg_req
->ds_id
,
1343 (unsigned long long)fe_msg
->setcfg_req
->session_id
,
1346 mgmt_fe_session_handle_setcfg_req_msg(
1347 session
, fe_msg
->setcfg_req
);
1349 case MGMTD__FE_MESSAGE__MESSAGE_COMMCFG_REQ
:
1350 session
= mgmt_session_id2ctx(
1351 fe_msg
->commcfg_req
->session_id
);
1352 MGMTD_FE_ADAPTER_DBG(
1353 "Got Commit Config Req Msg for src-DS:%d dst-DS:%d (Abort:%c) on session-id %llu from '%s'",
1354 fe_msg
->commcfg_req
->src_ds_id
,
1355 fe_msg
->commcfg_req
->dst_ds_id
,
1356 fe_msg
->commcfg_req
->abort
? 'T':'F',
1357 (unsigned long long)fe_msg
->commcfg_req
->session_id
,
1359 mgmt_fe_session_handle_commit_config_req_msg(
1360 session
, fe_msg
->commcfg_req
);
1362 case MGMTD__FE_MESSAGE__MESSAGE_GETCFG_REQ
:
1363 session
= mgmt_session_id2ctx(
1364 fe_msg
->getcfg_req
->session_id
);
1365 MGMTD_FE_ADAPTER_DBG(
1366 "Got Get-Config Req Msg for DS:%d (xpaths: %d) on session-id %llu from '%s'",
1367 fe_msg
->getcfg_req
->ds_id
,
1368 (int)fe_msg
->getcfg_req
->n_data
,
1369 (unsigned long long)fe_msg
->getcfg_req
->session_id
,
1371 mgmt_fe_session_handle_getcfg_req_msg(
1372 session
, fe_msg
->getcfg_req
);
1374 case MGMTD__FE_MESSAGE__MESSAGE_GETDATA_REQ
:
1375 session
= mgmt_session_id2ctx(
1376 fe_msg
->getdata_req
->session_id
);
1377 MGMTD_FE_ADAPTER_DBG(
1378 "Got Get-Data Req Msg for DS:%d (xpaths: %d) on session-id %llu from '%s'",
1379 fe_msg
->getdata_req
->ds_id
,
1380 (int)fe_msg
->getdata_req
->n_data
,
1381 (unsigned long long)fe_msg
->getdata_req
->session_id
,
1383 mgmt_fe_session_handle_getdata_req_msg(
1384 session
, fe_msg
->getdata_req
);
1386 case MGMTD__FE_MESSAGE__MESSAGE_NOTIFY_DATA_REQ
:
1387 case MGMTD__FE_MESSAGE__MESSAGE_REGNOTIFY_REQ
:
1389 * TODO: Add handling code in future.
1393 * NOTE: The following messages are always sent from MGMTD to
1394 * Frontend clients only and/or need not be handled on MGMTd.
1396 case MGMTD__FE_MESSAGE__MESSAGE_SESSION_REPLY
:
1397 case MGMTD__FE_MESSAGE__MESSAGE_LOCKDS_REPLY
:
1398 case MGMTD__FE_MESSAGE__MESSAGE_SETCFG_REPLY
:
1399 case MGMTD__FE_MESSAGE__MESSAGE_COMMCFG_REPLY
:
1400 case MGMTD__FE_MESSAGE__MESSAGE_GETCFG_REPLY
:
1401 case MGMTD__FE_MESSAGE__MESSAGE_GETDATA_REPLY
:
1402 case MGMTD__FE_MESSAGE__MESSAGE__NOT_SET
:
1405 * A 'default' case is being added contrary to the
1406 * FRR code guidelines to take care of build
1407 * failures on certain build systems (courtesy of
1408 * the proto-c package).
1416 static void mgmt_fe_adapter_process_msg(void *user_ctx
, uint8_t *data
,
1419 struct mgmt_fe_client_adapter
*adapter
= user_ctx
;
1420 Mgmtd__FeMessage
*fe_msg
;
1422 fe_msg
= mgmtd__fe_message__unpack(NULL
, len
, data
);
1424 MGMTD_FE_ADAPTER_DBG(
1425 "Failed to decode %zu bytes for adapter: %s", len
,
1429 MGMTD_FE_ADAPTER_DBG(
1430 "Decoded %zu bytes of message: %u from adapter: %s", len
,
1431 fe_msg
->message_case
, adapter
->name
);
1432 (void)mgmt_fe_adapter_handle_msg(adapter
, fe_msg
);
1433 mgmtd__fe_message__free_unpacked(fe_msg
, NULL
);
1436 static void mgmt_fe_adapter_proc_msgbufs(struct event
*thread
)
1438 struct mgmt_fe_client_adapter
*adapter
= EVENT_ARG(thread
);
1440 if (mgmt_msg_procbufs(&adapter
->mstate
, mgmt_fe_adapter_process_msg
,
1441 adapter
, mgmt_debug_fe
))
1442 mgmt_fe_adapter_register_event(adapter
, MGMTD_FE_PROC_MSG
);
1445 static void mgmt_fe_adapter_read(struct event
*thread
)
1447 struct mgmt_fe_client_adapter
*adapter
= EVENT_ARG(thread
);
1448 enum mgmt_msg_rsched rv
;
1450 rv
= mgmt_msg_read(&adapter
->mstate
, adapter
->conn_fd
, mgmt_debug_fe
);
1451 if (rv
== MSR_DISCONNECT
) {
1452 mgmt_fe_adapter_disconnect(adapter
);
1455 if (rv
== MSR_SCHED_BOTH
)
1456 mgmt_fe_adapter_register_event(adapter
, MGMTD_FE_PROC_MSG
);
1457 mgmt_fe_adapter_register_event(adapter
, MGMTD_FE_CONN_READ
);
1460 static void mgmt_fe_adapter_write(struct event
*thread
)
1462 struct mgmt_fe_client_adapter
*adapter
= EVENT_ARG(thread
);
1463 enum mgmt_msg_wsched rv
;
1465 rv
= mgmt_msg_write(&adapter
->mstate
, adapter
->conn_fd
, mgmt_debug_fe
);
1466 if (rv
== MSW_SCHED_STREAM
)
1467 mgmt_fe_adapter_register_event(adapter
, MGMTD_FE_CONN_WRITE
);
1468 else if (rv
== MSW_DISCONNECT
)
1469 mgmt_fe_adapter_disconnect(adapter
);
1470 else if (rv
== MSW_SCHED_WRITES_OFF
) {
1471 mgmt_fe_adapter_writes_off(adapter
);
1472 mgmt_fe_adapter_register_event(adapter
,
1473 MGMTD_FE_CONN_WRITES_ON
);
1475 assert(rv
== MSW_SCHED_NONE
);
1478 static void mgmt_fe_adapter_resume_writes(struct event
*thread
)
1480 struct mgmt_fe_client_adapter
*adapter
;
1482 adapter
= (struct mgmt_fe_client_adapter
*)EVENT_ARG(thread
);
1483 assert(adapter
&& adapter
->conn_fd
!= -1);
1485 mgmt_fe_adapter_writes_on(adapter
);
1489 mgmt_fe_adapter_register_event(struct mgmt_fe_client_adapter
*adapter
,
1490 enum mgmt_fe_event event
)
1492 struct timeval tv
= {0};
1495 case MGMTD_FE_CONN_READ
:
1496 event_add_read(mgmt_fe_adapter_tm
, mgmt_fe_adapter_read
,
1497 adapter
, adapter
->conn_fd
, &adapter
->conn_read_ev
);
1499 case MGMTD_FE_CONN_WRITE
:
1500 event_add_write(mgmt_fe_adapter_tm
,
1501 mgmt_fe_adapter_write
, adapter
,
1502 adapter
->conn_fd
, &adapter
->conn_write_ev
);
1504 case MGMTD_FE_PROC_MSG
:
1505 tv
.tv_usec
= MGMTD_FE_MSG_PROC_DELAY_USEC
;
1506 event_add_timer_tv(mgmt_fe_adapter_tm
,
1507 mgmt_fe_adapter_proc_msgbufs
, adapter
,
1508 &tv
, &adapter
->proc_msg_ev
);
1510 case MGMTD_FE_CONN_WRITES_ON
:
1511 event_add_timer_msec(mgmt_fe_adapter_tm
,
1512 mgmt_fe_adapter_resume_writes
, adapter
,
1513 MGMTD_FE_MSG_WRITE_DELAY_MSEC
,
1514 &adapter
->conn_writes_on
);
1516 case MGMTD_FE_SERVER
:
1517 assert(!"mgmt_fe_adapter_post_event() called incorrectly");
1522 void mgmt_fe_adapter_lock(struct mgmt_fe_client_adapter
*adapter
)
1524 adapter
->refcount
++;
1528 mgmt_fe_adapter_unlock(struct mgmt_fe_client_adapter
**adapter
)
1530 assert(*adapter
&& (*adapter
)->refcount
);
1532 (*adapter
)->refcount
--;
1533 if (!(*adapter
)->refcount
) {
1534 mgmt_fe_adapters_del(&mgmt_fe_adapters
, *adapter
);
1535 EVENT_OFF((*adapter
)->conn_read_ev
);
1536 EVENT_OFF((*adapter
)->conn_write_ev
);
1537 EVENT_OFF((*adapter
)->proc_msg_ev
);
1538 EVENT_OFF((*adapter
)->conn_writes_on
);
1539 mgmt_msg_destroy(&(*adapter
)->mstate
);
1540 XFREE(MTYPE_MGMTD_FE_ADPATER
, *adapter
);
1546 int mgmt_fe_adapter_init(struct event_loop
*tm
, struct mgmt_master
*mm
)
1548 if (!mgmt_fe_adapter_tm
) {
1549 mgmt_fe_adapter_tm
= tm
;
1550 mgmt_fe_adapter_mm
= mm
;
1551 mgmt_fe_adapters_init(&mgmt_fe_adapters
);
1553 assert(!mgmt_fe_sessions
);
1554 mgmt_fe_sessions
= hash_create(mgmt_fe_session_hash_key
,
1555 mgmt_fe_session_hash_cmp
,
1556 "MGMT Frontend Sessions");
1562 void mgmt_fe_adapter_destroy(void)
1564 mgmt_fe_cleanup_adapters();
1565 mgmt_fe_session_hash_destroy();
1568 struct mgmt_fe_client_adapter
*
1569 mgmt_fe_create_adapter(int conn_fd
, union sockunion
*from
)
1571 struct mgmt_fe_client_adapter
*adapter
= NULL
;
1573 adapter
= mgmt_fe_find_adapter_by_fd(conn_fd
);
1575 adapter
= XCALLOC(MTYPE_MGMTD_FE_ADPATER
,
1576 sizeof(struct mgmt_fe_client_adapter
));
1579 adapter
->conn_fd
= conn_fd
;
1580 memcpy(&adapter
->conn_su
, from
, sizeof(adapter
->conn_su
));
1581 snprintf(adapter
->name
, sizeof(adapter
->name
), "Unknown-FD-%d",
1583 mgmt_fe_sessions_init(&adapter
->fe_sessions
);
1585 mgmt_msg_init(&adapter
->mstate
, MGMTD_FE_MAX_NUM_MSG_PROC
,
1586 MGMTD_FE_MAX_NUM_MSG_WRITE
, MGMTD_FE_MSG_MAX_LEN
,
1588 mgmt_fe_adapter_lock(adapter
);
1590 mgmt_fe_adapter_register_event(adapter
, MGMTD_FE_CONN_READ
);
1591 mgmt_fe_adapters_add_tail(&mgmt_fe_adapters
, adapter
);
1593 adapter
->setcfg_stats
.min_tm
= ULONG_MAX
;
1594 adapter
->cmt_stats
.min_tm
= ULONG_MAX
;
1595 MGMTD_FE_ADAPTER_DBG("Added new MGMTD Frontend adapter '%s'",
1599 /* Make client socket non-blocking. */
1600 set_nonblocking(adapter
->conn_fd
);
1601 setsockopt_so_sendbuf(adapter
->conn_fd
,
1602 MGMTD_SOCKET_FE_SEND_BUF_SIZE
);
1603 setsockopt_so_recvbuf(adapter
->conn_fd
,
1604 MGMTD_SOCKET_FE_RECV_BUF_SIZE
);
1608 struct mgmt_fe_client_adapter
*mgmt_fe_get_adapter(const char *name
)
1610 return mgmt_fe_find_adapter_by_name(name
);
1613 int mgmt_fe_send_set_cfg_reply(uint64_t session_id
, uint64_t txn_id
,
1614 Mgmtd__DatastoreId ds_id
, uint64_t req_id
,
1615 enum mgmt_result result
,
1616 const char *error_if_any
,
1617 bool implicit_commit
)
1619 struct mgmt_fe_session_ctx
*session
;
1621 session
= mgmt_session_id2ctx(session_id
);
1622 if (!session
|| session
->cfg_txn_id
!= txn_id
) {
1624 MGMTD_FE_ADAPTER_ERR(
1625 "Txn_id doesnot match, session txn is 0x%llx, current txn 0x%llx",
1626 (unsigned long long)session
->cfg_txn_id
,
1627 (unsigned long long)txn_id
);
1631 return mgmt_fe_send_setcfg_reply(
1632 session
, ds_id
, req_id
, result
== MGMTD_SUCCESS
? true : false,
1633 error_if_any
, implicit_commit
);
1636 int mgmt_fe_send_commit_cfg_reply(uint64_t session_id
, uint64_t txn_id
,
1637 Mgmtd__DatastoreId src_ds_id
,
1638 Mgmtd__DatastoreId dst_ds_id
,
1639 uint64_t req_id
, bool validate_only
,
1640 enum mgmt_result result
,
1641 const char *error_if_any
)
1643 struct mgmt_fe_session_ctx
*session
;
1645 session
= mgmt_session_id2ctx(session_id
);
1646 if (!session
|| session
->cfg_txn_id
!= txn_id
)
1649 return mgmt_fe_send_commitcfg_reply(session
, src_ds_id
, dst_ds_id
,
1650 req_id
, result
, validate_only
,
1654 int mgmt_fe_send_get_cfg_reply(uint64_t session_id
, uint64_t txn_id
,
1655 Mgmtd__DatastoreId ds_id
, uint64_t req_id
,
1656 enum mgmt_result result
,
1657 Mgmtd__YangDataReply
*data_resp
,
1658 const char *error_if_any
)
1660 struct mgmt_fe_session_ctx
*session
;
1662 session
= mgmt_session_id2ctx(session_id
);
1663 if (!session
|| session
->txn_id
!= txn_id
)
1666 return mgmt_fe_send_getcfg_reply(session
, ds_id
, req_id
,
1667 result
== MGMTD_SUCCESS
, data_resp
,
1671 int mgmt_fe_send_get_data_reply(uint64_t session_id
, uint64_t txn_id
,
1672 Mgmtd__DatastoreId ds_id
, uint64_t req_id
,
1673 enum mgmt_result result
,
1674 Mgmtd__YangDataReply
*data_resp
,
1675 const char *error_if_any
)
1677 struct mgmt_fe_session_ctx
*session
;
1679 session
= mgmt_session_id2ctx(session_id
);
1680 if (!session
|| session
->txn_id
!= txn_id
)
1683 return mgmt_fe_send_getdata_reply(session
, ds_id
, req_id
,
1684 result
== MGMTD_SUCCESS
,
1685 data_resp
, error_if_any
);
1688 int mgmt_fe_send_data_notify(Mgmtd__DatastoreId ds_id
,
1689 Mgmtd__YangData
* data_resp
[], int num_data
)
1691 /* struct mgmt_fe_session_ctx *session; */
1696 struct mgmt_setcfg_stats
*
1697 mgmt_fe_get_session_setcfg_stats(uint64_t session_id
)
1699 struct mgmt_fe_session_ctx
*session
;
1701 session
= mgmt_session_id2ctx(session_id
);
1702 if (!session
|| !session
->adapter
)
1705 return &session
->adapter
->setcfg_stats
;
1708 struct mgmt_commit_stats
*
1709 mgmt_fe_get_session_commit_stats(uint64_t session_id
)
1711 struct mgmt_fe_session_ctx
*session
;
1713 session
= mgmt_session_id2ctx(session_id
);
1714 if (!session
|| !session
->adapter
)
1717 return &session
->adapter
->cmt_stats
;
1721 mgmt_fe_adapter_cmt_stats_write(struct vty
*vty
,
1722 struct mgmt_fe_client_adapter
*adapter
)
1724 char buf
[100] = {0};
1726 if (!mm
->perf_stats_en
)
1729 vty_out(vty
, " Num-Commits: \t\t\t%lu\n",
1730 adapter
->cmt_stats
.commit_cnt
);
1731 if (adapter
->cmt_stats
.commit_cnt
> 0) {
1732 if (mm
->perf_stats_en
)
1733 vty_out(vty
, " Max-Commit-Duration: \t\t%lu uSecs\n",
1734 adapter
->cmt_stats
.max_tm
);
1735 vty_out(vty
, " Max-Commit-Batch-Size: \t\t%lu\n",
1736 adapter
->cmt_stats
.max_batch_cnt
);
1737 if (mm
->perf_stats_en
)
1738 vty_out(vty
, " Min-Commit-Duration: \t\t%lu uSecs\n",
1739 adapter
->cmt_stats
.min_tm
);
1740 vty_out(vty
, " Min-Commit-Batch-Size: \t\t%lu\n",
1741 adapter
->cmt_stats
.min_batch_cnt
);
1742 if (mm
->perf_stats_en
)
1744 " Last-Commit-Duration: \t\t%lu uSecs\n",
1745 adapter
->cmt_stats
.last_exec_tm
);
1746 vty_out(vty
, " Last-Commit-Batch-Size: \t\t%lu\n",
1747 adapter
->cmt_stats
.last_batch_cnt
);
1748 vty_out(vty
, " Last-Commit-CfgData-Reqs: \t\t%lu\n",
1749 adapter
->cmt_stats
.last_num_cfgdata_reqs
);
1750 vty_out(vty
, " Last-Commit-CfgApply-Reqs: \t\t%lu\n",
1751 adapter
->cmt_stats
.last_num_apply_reqs
);
1752 if (mm
->perf_stats_en
) {
1753 vty_out(vty
, " Last-Commit-Details:\n");
1754 vty_out(vty
, " Commit Start: \t\t\t%s\n",
1755 mgmt_realtime_to_string(
1756 &adapter
->cmt_stats
.last_start
, buf
,
1758 #ifdef MGMTD_LOCAL_VALIDATIONS_ENABLED
1759 vty_out(vty
, " Config-Validate Start: \t\t%s\n",
1760 mgmt_realtime_to_string(
1761 &adapter
->cmt_stats
.validate_start
, buf
,
1764 vty_out(vty
, " Prep-Config Start: \t\t%s\n",
1765 mgmt_realtime_to_string(
1766 &adapter
->cmt_stats
.prep_cfg_start
, buf
,
1768 vty_out(vty
, " Txn-Create Start: \t\t%s\n",
1769 mgmt_realtime_to_string(
1770 &adapter
->cmt_stats
.txn_create_start
,
1773 #ifdef MGMTD_LOCAL_VALIDATIONS_ENABLED
1774 " Send-Config Start: \t\t%s\n",
1776 " Send-Config-Validate Start: \t%s\n",
1778 mgmt_realtime_to_string(
1779 &adapter
->cmt_stats
.send_cfg_start
, buf
,
1781 vty_out(vty
, " Apply-Config Start: \t\t%s\n",
1782 mgmt_realtime_to_string(
1783 &adapter
->cmt_stats
.apply_cfg_start
, buf
,
1785 vty_out(vty
, " Apply-Config End: \t\t%s\n",
1786 mgmt_realtime_to_string(
1787 &adapter
->cmt_stats
.apply_cfg_end
, buf
,
1789 vty_out(vty
, " Txn-Delete Start: \t\t%s\n",
1790 mgmt_realtime_to_string(
1791 &adapter
->cmt_stats
.txn_del_start
, buf
,
1793 vty_out(vty
, " Commit End: \t\t\t%s\n",
1794 mgmt_realtime_to_string(
1795 &adapter
->cmt_stats
.last_end
, buf
,
1802 mgmt_fe_adapter_setcfg_stats_write(struct vty
*vty
,
1803 struct mgmt_fe_client_adapter
*adapter
)
1805 char buf
[100] = {0};
1807 if (!mm
->perf_stats_en
)
1810 vty_out(vty
, " Num-Set-Cfg: \t\t\t%lu\n",
1811 adapter
->setcfg_stats
.set_cfg_count
);
1812 if (mm
->perf_stats_en
&& adapter
->setcfg_stats
.set_cfg_count
> 0) {
1813 vty_out(vty
, " Max-Set-Cfg-Duration: \t\t%lu uSec\n",
1814 adapter
->setcfg_stats
.max_tm
);
1815 vty_out(vty
, " Min-Set-Cfg-Duration: \t\t%lu uSec\n",
1816 adapter
->setcfg_stats
.min_tm
);
1817 vty_out(vty
, " Avg-Set-Cfg-Duration: \t\t%lu uSec\n",
1818 adapter
->setcfg_stats
.avg_tm
);
1819 vty_out(vty
, " Last-Set-Cfg-Details:\n");
1820 vty_out(vty
, " Set-Cfg Start: \t\t\t%s\n",
1821 mgmt_realtime_to_string(&adapter
->setcfg_stats
.last_start
,
1823 vty_out(vty
, " Set-Cfg End: \t\t\t%s\n",
1824 mgmt_realtime_to_string(&adapter
->setcfg_stats
.last_end
,
1829 void mgmt_fe_adapter_status_write(struct vty
*vty
, bool detail
)
1831 struct mgmt_fe_client_adapter
*adapter
;
1832 struct mgmt_fe_session_ctx
*session
;
1833 Mgmtd__DatastoreId ds_id
;
1834 bool locked
= false;
1836 vty_out(vty
, "MGMTD Frontend Adpaters\n");
1838 FOREACH_ADAPTER_IN_LIST (adapter
) {
1839 vty_out(vty
, " Client: \t\t\t\t%s\n", adapter
->name
);
1840 vty_out(vty
, " Conn-FD: \t\t\t\t%d\n", adapter
->conn_fd
);
1842 mgmt_fe_adapter_setcfg_stats_write(vty
, adapter
);
1843 mgmt_fe_adapter_cmt_stats_write(vty
, adapter
);
1845 vty_out(vty
, " Sessions\n");
1846 FOREACH_SESSION_IN_LIST (adapter
, session
) {
1847 vty_out(vty
, " Session: \t\t\t\t%p\n", session
);
1848 vty_out(vty
, " Client-Id: \t\t\t%llu\n",
1849 (unsigned long long)session
->client_id
);
1850 vty_out(vty
, " Session-Id: \t\t\t%llx\n",
1851 (unsigned long long)session
->session_id
);
1852 vty_out(vty
, " DS-Locks:\n");
1853 FOREACH_MGMTD_DS_ID (ds_id
) {
1854 if (session
->ds_write_locked
[ds_id
]
1855 || session
->ds_read_locked
[ds_id
]) {
1858 " %s\t\t\t%s, %s\n",
1859 mgmt_ds_id2name(ds_id
),
1860 session
->ds_write_locked
[ds_id
]
1863 session
->ds_locked_implict
[ds_id
]
1869 vty_out(vty
, " None\n");
1871 vty_out(vty
, " Total-Sessions: \t\t\t%d\n",
1872 (int)mgmt_fe_sessions_count(&adapter
->fe_sessions
));
1873 vty_out(vty
, " Msg-Recvd: \t\t\t\t%" PRIu64
"\n",
1874 adapter
->mstate
.nrxm
);
1875 vty_out(vty
, " Bytes-Recvd: \t\t\t%" PRIu64
"\n",
1876 adapter
->mstate
.nrxb
);
1877 vty_out(vty
, " Msg-Sent: \t\t\t\t%" PRIu64
"\n",
1878 adapter
->mstate
.ntxm
);
1879 vty_out(vty
, " Bytes-Sent: \t\t\t%" PRIu64
"\n",
1880 adapter
->mstate
.ntxb
);
1882 vty_out(vty
, " Total: %d\n",
1883 (int)mgmt_fe_adapters_count(&mgmt_fe_adapters
));
1886 void mgmt_fe_adapter_perf_measurement(struct vty
*vty
, bool config
)
1888 mm
->perf_stats_en
= config
;
1891 void mgmt_fe_adapter_reset_perf_stats(struct vty
*vty
)
1893 struct mgmt_fe_client_adapter
*adapter
;
1894 struct mgmt_fe_session_ctx
*session
;
1896 FOREACH_ADAPTER_IN_LIST (adapter
) {
1897 memset(&adapter
->setcfg_stats
, 0, sizeof(adapter
->setcfg_stats
));
1898 FOREACH_SESSION_IN_LIST (adapter
, session
) {
1899 memset(&adapter
->cmt_stats
, 0, sizeof(adapter
->cmt_stats
));