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 #define MGMTD_FE_ADAPTER_DBG(fmt, ...) \
23 DEBUGD(&mgmt_debug_fe, "%s:" fmt, __func__, ##__VA_ARGS__)
24 #define MGMTD_FE_ADAPTER_ERR(fmt, ...) \
25 zlog_err("%s: ERROR: " fmt, __func__, ##__VA_ARGS__)
27 #define FOREACH_ADAPTER_IN_LIST(adapter) \
28 frr_each_safe (mgmt_fe_adapters, &mgmt_fe_adapters, (adapter))
30 enum mgmt_session_event
{
31 MGMTD_FE_SESSION_CFG_TXN_CLNUP
= 1,
32 MGMTD_FE_SESSION_SHOW_TXN_CLNUP
,
35 struct mgmt_fe_session_ctx
{
36 struct mgmt_fe_client_adapter
*adapter
;
41 uint8_t ds_write_locked
[MGMTD_DS_MAX_ID
];
42 uint8_t ds_read_locked
[MGMTD_DS_MAX_ID
];
43 uint8_t ds_locked_implict
[MGMTD_DS_MAX_ID
];
44 struct event
*proc_cfg_txn_clnp
;
45 struct event
*proc_show_txn_clnp
;
47 struct mgmt_fe_sessions_item list_linkage
;
50 DECLARE_LIST(mgmt_fe_sessions
, struct mgmt_fe_session_ctx
, list_linkage
);
52 #define FOREACH_SESSION_IN_LIST(adapter, session) \
53 frr_each_safe (mgmt_fe_sessions, &(adapter)->fe_sessions, (session))
55 static struct event_loop
*mgmt_fe_adapter_tm
;
56 static struct mgmt_master
*mgmt_fe_adapter_mm
;
58 static struct mgmt_fe_adapters_head mgmt_fe_adapters
;
60 static struct hash
*mgmt_fe_sessions
;
61 static uint64_t mgmt_fe_next_session_id
;
63 /* Forward declarations */
65 mgmt_fe_adapter_register_event(struct mgmt_fe_client_adapter
*adapter
,
66 enum mgmt_fe_event event
);
68 mgmt_fe_adapter_disconnect(struct mgmt_fe_client_adapter
*adapter
);
70 mgmt_fe_session_register_event(struct mgmt_fe_session_ctx
*session
,
71 enum mgmt_session_event event
);
74 mgmt_fe_session_write_lock_ds(Mgmtd__DatastoreId ds_id
,
75 struct mgmt_ds_ctx
*ds_ctx
,
76 struct mgmt_fe_session_ctx
*session
)
78 if (!session
->ds_write_locked
[ds_id
]) {
79 if (mgmt_ds_write_lock(ds_ctx
) != 0) {
81 "Failed to lock the DS %u for Sessn: %p from %s!",
82 ds_id
, session
, session
->adapter
->name
);
86 session
->ds_write_locked
[ds_id
] = true;
88 "Write-Locked the DS %u for Sessn: %p from %s!", ds_id
,
89 session
, session
->adapter
->name
);
96 mgmt_fe_session_read_lock_ds(Mgmtd__DatastoreId ds_id
,
97 struct mgmt_ds_ctx
*ds_ctx
,
98 struct mgmt_fe_session_ctx
*session
)
100 if (!session
->ds_read_locked
[ds_id
]) {
101 if (mgmt_ds_read_lock(ds_ctx
) != 0) {
102 MGMTD_FE_ADAPTER_DBG(
103 "Failed to lock the DS %u for Sessn: %p from %s!",
104 ds_id
, session
, session
->adapter
->name
);
108 session
->ds_read_locked
[ds_id
] = true;
109 MGMTD_FE_ADAPTER_DBG(
110 "Read-Locked the DS %u for Sessn: %p from %s!", ds_id
,
111 session
, session
->adapter
->name
);
117 static int mgmt_fe_session_unlock_ds(Mgmtd__DatastoreId ds_id
,
118 struct mgmt_ds_ctx
*ds_ctx
,
119 struct mgmt_fe_session_ctx
*session
,
120 bool unlock_write
, bool unlock_read
)
122 if (unlock_write
&& session
->ds_write_locked
[ds_id
]) {
123 session
->ds_write_locked
[ds_id
] = false;
124 session
->ds_locked_implict
[ds_id
] = false;
125 if (mgmt_ds_unlock(ds_ctx
) != 0) {
126 MGMTD_FE_ADAPTER_DBG(
127 "Failed to unlock the DS %u taken earlier by Sessn: %p from %s!",
128 ds_id
, session
, session
->adapter
->name
);
132 MGMTD_FE_ADAPTER_DBG(
133 "Unlocked DS %u write-locked earlier by Sessn: %p from %s",
134 ds_id
, session
, session
->adapter
->name
);
135 } else if (unlock_read
&& session
->ds_read_locked
[ds_id
]) {
136 session
->ds_read_locked
[ds_id
] = false;
137 session
->ds_locked_implict
[ds_id
] = false;
138 if (mgmt_ds_unlock(ds_ctx
) != 0) {
139 MGMTD_FE_ADAPTER_DBG(
140 "Failed to unlock the DS %u taken earlier by Sessn: %p from %s!",
141 ds_id
, session
, session
->adapter
->name
);
145 MGMTD_FE_ADAPTER_DBG(
146 "Unlocked DS %u read-locked earlier by Sessn: %p from %s",
147 ds_id
, session
, session
->adapter
->name
);
154 mgmt_fe_session_cfg_txn_cleanup(struct mgmt_fe_session_ctx
*session
)
156 Mgmtd__DatastoreId ds_id
;
157 struct mgmt_ds_ctx
*ds_ctx
;
160 * Ensure any uncommitted changes in Candidate DS
163 mgmt_ds_copy_dss(mm
->running_ds
, mm
->candidate_ds
, false);
165 for (ds_id
= 0; ds_id
< MGMTD_DS_MAX_ID
; ds_id
++) {
166 ds_ctx
= mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
, ds_id
);
168 if (session
->ds_locked_implict
[ds_id
])
169 mgmt_fe_session_unlock_ds(
170 ds_id
, ds_ctx
, session
, true, false);
175 * Destroy the actual transaction created earlier.
177 if (session
->cfg_txn_id
!= MGMTD_TXN_ID_NONE
)
178 mgmt_destroy_txn(&session
->cfg_txn_id
);
182 mgmt_fe_session_show_txn_cleanup(struct mgmt_fe_session_ctx
*session
)
184 Mgmtd__DatastoreId ds_id
;
185 struct mgmt_ds_ctx
*ds_ctx
;
187 for (ds_id
= 0; ds_id
< MGMTD_DS_MAX_ID
; ds_id
++) {
188 ds_ctx
= mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
, ds_id
);
190 mgmt_fe_session_unlock_ds(ds_id
, ds_ctx
, session
,
196 * Destroy the transaction created recently.
198 if (session
->txn_id
!= MGMTD_TXN_ID_NONE
)
199 mgmt_destroy_txn(&session
->txn_id
);
203 mgmt_fe_adapter_compute_set_cfg_timers(struct mgmt_setcfg_stats
*setcfg_stats
)
205 setcfg_stats
->last_exec_tm
= timeval_elapsed(setcfg_stats
->last_end
,
206 setcfg_stats
->last_start
);
207 if (setcfg_stats
->last_exec_tm
> setcfg_stats
->max_tm
)
208 setcfg_stats
->max_tm
= setcfg_stats
->last_exec_tm
;
210 if (setcfg_stats
->last_exec_tm
< setcfg_stats
->min_tm
)
211 setcfg_stats
->min_tm
= setcfg_stats
->last_exec_tm
;
213 setcfg_stats
->avg_tm
=
214 (((setcfg_stats
->avg_tm
* (setcfg_stats
->set_cfg_count
- 1))
215 + setcfg_stats
->last_exec_tm
)
216 / setcfg_stats
->set_cfg_count
);
220 mgmt_fe_session_compute_commit_timers(struct mgmt_commit_stats
*cmt_stats
)
222 cmt_stats
->last_exec_tm
=
223 timeval_elapsed(cmt_stats
->last_end
, cmt_stats
->last_start
);
224 if (cmt_stats
->last_exec_tm
> cmt_stats
->max_tm
) {
225 cmt_stats
->max_tm
= cmt_stats
->last_exec_tm
;
226 cmt_stats
->max_batch_cnt
= cmt_stats
->last_batch_cnt
;
229 if (cmt_stats
->last_exec_tm
< cmt_stats
->min_tm
) {
230 cmt_stats
->min_tm
= cmt_stats
->last_exec_tm
;
231 cmt_stats
->min_batch_cnt
= cmt_stats
->last_batch_cnt
;
235 static void mgmt_fe_cleanup_session(struct mgmt_fe_session_ctx
**session
)
237 if ((*session
)->adapter
) {
238 mgmt_fe_session_cfg_txn_cleanup((*session
));
239 mgmt_fe_session_show_txn_cleanup((*session
));
240 mgmt_fe_session_unlock_ds(MGMTD_DS_CANDIDATE
,
241 mgmt_fe_adapter_mm
->candidate_ds
,
242 *session
, true, true);
243 mgmt_fe_session_unlock_ds(MGMTD_DS_RUNNING
,
244 mgmt_fe_adapter_mm
->running_ds
,
245 *session
, true, true);
247 mgmt_fe_sessions_del(&(*session
)->adapter
->fe_sessions
,
249 mgmt_fe_adapter_unlock(&(*session
)->adapter
);
252 hash_release(mgmt_fe_sessions
, *session
);
253 XFREE(MTYPE_MGMTD_FE_SESSION
, *session
);
257 static struct mgmt_fe_session_ctx
*
258 mgmt_fe_find_session_by_client_id(struct mgmt_fe_client_adapter
*adapter
,
261 struct mgmt_fe_session_ctx
*session
;
263 FOREACH_SESSION_IN_LIST (adapter
, session
) {
264 if (session
->client_id
== client_id
)
271 static unsigned int mgmt_fe_session_hash_key(const void *data
)
273 const struct mgmt_fe_session_ctx
*session
= data
;
275 return jhash2((uint32_t *) &session
->session_id
,
276 sizeof(session
->session_id
) / sizeof(uint32_t), 0);
279 static bool mgmt_fe_session_hash_cmp(const void *d1
, const void *d2
)
281 const struct mgmt_fe_session_ctx
*session1
= d1
;
282 const struct mgmt_fe_session_ctx
*session2
= d2
;
284 return (session1
->session_id
== session2
->session_id
);
287 static void mgmt_fe_session_hash_free(void *data
)
289 struct mgmt_fe_session_ctx
*session
= data
;
291 mgmt_fe_cleanup_session(&session
);
294 static void mgmt_fe_session_hash_destroy(void)
296 if (mgmt_fe_sessions
== NULL
)
299 hash_clean(mgmt_fe_sessions
,
300 mgmt_fe_session_hash_free
);
301 hash_free(mgmt_fe_sessions
);
302 mgmt_fe_sessions
= NULL
;
305 static inline struct mgmt_fe_session_ctx
*
306 mgmt_session_id2ctx(uint64_t session_id
)
308 struct mgmt_fe_session_ctx key
= {0};
309 struct mgmt_fe_session_ctx
*session
;
311 if (!mgmt_fe_sessions
)
314 key
.session_id
= session_id
;
315 session
= hash_lookup(mgmt_fe_sessions
, &key
);
320 static struct mgmt_fe_session_ctx
*
321 mgmt_fe_create_session(struct mgmt_fe_client_adapter
*adapter
,
324 struct mgmt_fe_session_ctx
*session
;
326 session
= mgmt_fe_find_session_by_client_id(adapter
, client_id
);
328 mgmt_fe_cleanup_session(&session
);
330 session
= XCALLOC(MTYPE_MGMTD_FE_SESSION
,
331 sizeof(struct mgmt_fe_session_ctx
));
333 session
->client_id
= client_id
;
334 session
->adapter
= adapter
;
335 session
->txn_id
= MGMTD_TXN_ID_NONE
;
336 session
->cfg_txn_id
= MGMTD_TXN_ID_NONE
;
337 mgmt_fe_adapter_lock(adapter
);
338 mgmt_fe_sessions_add_tail(&adapter
->fe_sessions
, session
);
339 if (!mgmt_fe_next_session_id
)
340 mgmt_fe_next_session_id
++;
341 session
->session_id
= mgmt_fe_next_session_id
++;
342 hash_get(mgmt_fe_sessions
, session
, hash_alloc_intern
);
348 mgmt_fe_cleanup_sessions(struct mgmt_fe_client_adapter
*adapter
)
350 struct mgmt_fe_session_ctx
*session
;
352 FOREACH_SESSION_IN_LIST (adapter
, session
)
353 mgmt_fe_cleanup_session(&session
);
357 mgmt_fe_adapter_sched_msg_write(struct mgmt_fe_client_adapter
*adapter
)
359 if (!CHECK_FLAG(adapter
->flags
, MGMTD_FE_ADAPTER_FLAGS_WRITES_OFF
))
360 mgmt_fe_adapter_register_event(adapter
,
361 MGMTD_FE_CONN_WRITE
);
365 mgmt_fe_adapter_writes_on(struct mgmt_fe_client_adapter
*adapter
)
367 MGMTD_FE_ADAPTER_DBG("Resume writing msgs for '%s'", adapter
->name
);
368 UNSET_FLAG(adapter
->flags
, MGMTD_FE_ADAPTER_FLAGS_WRITES_OFF
);
369 mgmt_fe_adapter_sched_msg_write(adapter
);
373 mgmt_fe_adapter_writes_off(struct mgmt_fe_client_adapter
*adapter
)
375 SET_FLAG(adapter
->flags
, MGMTD_FE_ADAPTER_FLAGS_WRITES_OFF
);
376 MGMTD_FE_ADAPTER_DBG("Paused writing msgs for '%s'", adapter
->name
);
380 mgmt_fe_adapter_send_msg(struct mgmt_fe_client_adapter
*adapter
,
381 Mgmtd__FeMessage
*fe_msg
)
383 if (adapter
->conn_fd
== -1) {
384 MGMTD_FE_ADAPTER_DBG("can't send message on closed connection");
388 int rv
= mgmt_msg_send_msg(
389 &adapter
->mstate
, fe_msg
,
390 mgmtd__fe_message__get_packed_size(fe_msg
),
391 (size_t(*)(void *, void *))mgmtd__fe_message__pack
,
392 MGMT_DEBUG_FE_CHECK());
393 mgmt_fe_adapter_sched_msg_write(adapter
);
398 mgmt_fe_send_session_reply(struct mgmt_fe_client_adapter
*adapter
,
399 struct mgmt_fe_session_ctx
*session
,
400 bool create
, bool success
)
402 Mgmtd__FeMessage fe_msg
;
403 Mgmtd__FeSessionReply session_reply
;
405 mgmtd__fe_session_reply__init(&session_reply
);
406 session_reply
.create
= create
;
408 session_reply
.has_client_conn_id
= 1;
409 session_reply
.client_conn_id
= session
->client_id
;
411 session_reply
.session_id
= session
->session_id
;
412 session_reply
.success
= success
;
414 mgmtd__fe_message__init(&fe_msg
);
415 fe_msg
.message_case
= MGMTD__FE_MESSAGE__MESSAGE_SESSION_REPLY
;
416 fe_msg
.session_reply
= &session_reply
;
418 MGMTD_FE_ADAPTER_DBG(
419 "Sending SESSION_REPLY message to MGMTD Frontend client '%s'",
422 return mgmt_fe_adapter_send_msg(adapter
, &fe_msg
);
425 static int mgmt_fe_send_lockds_reply(struct mgmt_fe_session_ctx
*session
,
426 Mgmtd__DatastoreId ds_id
,
427 uint64_t req_id
, bool lock_ds
,
428 bool success
, const char *error_if_any
)
430 Mgmtd__FeMessage fe_msg
;
431 Mgmtd__FeLockDsReply lockds_reply
;
433 assert(session
->adapter
);
435 mgmtd__fe_lock_ds_reply__init(&lockds_reply
);
436 lockds_reply
.session_id
= session
->session_id
;
437 lockds_reply
.ds_id
= ds_id
;
438 lockds_reply
.req_id
= req_id
;
439 lockds_reply
.lock
= lock_ds
;
440 lockds_reply
.success
= success
;
442 lockds_reply
.error_if_any
= (char *)error_if_any
;
444 mgmtd__fe_message__init(&fe_msg
);
445 fe_msg
.message_case
= MGMTD__FE_MESSAGE__MESSAGE_LOCKDS_REPLY
;
446 fe_msg
.lockds_reply
= &lockds_reply
;
448 MGMTD_FE_ADAPTER_DBG(
449 "Sending LOCK_DS_REPLY message to MGMTD Frontend client '%s'",
450 session
->adapter
->name
);
452 return mgmt_fe_adapter_send_msg(session
->adapter
, &fe_msg
);
455 static int mgmt_fe_send_setcfg_reply(struct mgmt_fe_session_ctx
*session
,
456 Mgmtd__DatastoreId ds_id
,
457 uint64_t req_id
, bool success
,
458 const char *error_if_any
,
459 bool implicit_commit
)
461 Mgmtd__FeMessage fe_msg
;
462 Mgmtd__FeSetConfigReply setcfg_reply
;
464 assert(session
->adapter
);
466 if (implicit_commit
&& session
->cfg_txn_id
)
467 mgmt_fe_session_register_event(
468 session
, MGMTD_FE_SESSION_CFG_TXN_CLNUP
);
470 mgmtd__fe_set_config_reply__init(&setcfg_reply
);
471 setcfg_reply
.session_id
= session
->session_id
;
472 setcfg_reply
.ds_id
= ds_id
;
473 setcfg_reply
.req_id
= req_id
;
474 setcfg_reply
.success
= success
;
476 setcfg_reply
.error_if_any
= (char *)error_if_any
;
478 mgmtd__fe_message__init(&fe_msg
);
479 fe_msg
.message_case
= MGMTD__FE_MESSAGE__MESSAGE_SETCFG_REPLY
;
480 fe_msg
.setcfg_reply
= &setcfg_reply
;
482 MGMTD_FE_ADAPTER_DBG(
483 "Sending SET_CONFIG_REPLY message to MGMTD Frontend client '%s'",
484 session
->adapter
->name
);
486 if (implicit_commit
) {
487 if (mm
->perf_stats_en
)
488 gettimeofday(&session
->adapter
->cmt_stats
.last_end
,
490 mgmt_fe_session_compute_commit_timers(
491 &session
->adapter
->cmt_stats
);
494 if (mm
->perf_stats_en
)
495 gettimeofday(&session
->adapter
->setcfg_stats
.last_end
, NULL
);
496 mgmt_fe_adapter_compute_set_cfg_timers(&session
->adapter
->setcfg_stats
);
498 return mgmt_fe_adapter_send_msg(session
->adapter
, &fe_msg
);
501 static int mgmt_fe_send_commitcfg_reply(
502 struct mgmt_fe_session_ctx
*session
, Mgmtd__DatastoreId src_ds_id
,
503 Mgmtd__DatastoreId dst_ds_id
, uint64_t req_id
, enum mgmt_result result
,
504 bool validate_only
, const char *error_if_any
)
506 Mgmtd__FeMessage fe_msg
;
507 Mgmtd__FeCommitConfigReply commcfg_reply
;
509 assert(session
->adapter
);
511 mgmtd__fe_commit_config_reply__init(&commcfg_reply
);
512 commcfg_reply
.session_id
= session
->session_id
;
513 commcfg_reply
.src_ds_id
= src_ds_id
;
514 commcfg_reply
.dst_ds_id
= dst_ds_id
;
515 commcfg_reply
.req_id
= req_id
;
516 commcfg_reply
.success
=
517 (result
== MGMTD_SUCCESS
|| result
== MGMTD_NO_CFG_CHANGES
)
520 commcfg_reply
.validate_only
= validate_only
;
522 commcfg_reply
.error_if_any
= (char *)error_if_any
;
524 mgmtd__fe_message__init(&fe_msg
);
525 fe_msg
.message_case
= MGMTD__FE_MESSAGE__MESSAGE_COMMCFG_REPLY
;
526 fe_msg
.commcfg_reply
= &commcfg_reply
;
528 MGMTD_FE_ADAPTER_DBG(
529 "Sending COMMIT_CONFIG_REPLY message to MGMTD Frontend client '%s'",
530 session
->adapter
->name
);
533 * Cleanup the CONFIG transaction associated with this session.
535 if (session
->cfg_txn_id
536 && ((result
== MGMTD_SUCCESS
&& !validate_only
)
537 || (result
== MGMTD_NO_CFG_CHANGES
)))
538 mgmt_fe_session_register_event(
539 session
, MGMTD_FE_SESSION_CFG_TXN_CLNUP
);
541 if (mm
->perf_stats_en
)
542 gettimeofday(&session
->adapter
->cmt_stats
.last_end
, NULL
);
543 mgmt_fe_session_compute_commit_timers(&session
->adapter
->cmt_stats
);
544 return mgmt_fe_adapter_send_msg(session
->adapter
, &fe_msg
);
547 static int mgmt_fe_send_getcfg_reply(struct mgmt_fe_session_ctx
*session
,
548 Mgmtd__DatastoreId ds_id
,
549 uint64_t req_id
, bool success
,
550 Mgmtd__YangDataReply
*data
,
551 const char *error_if_any
)
553 Mgmtd__FeMessage fe_msg
;
554 Mgmtd__FeGetConfigReply getcfg_reply
;
556 assert(session
->adapter
);
558 mgmtd__fe_get_config_reply__init(&getcfg_reply
);
559 getcfg_reply
.session_id
= session
->session_id
;
560 getcfg_reply
.ds_id
= ds_id
;
561 getcfg_reply
.req_id
= req_id
;
562 getcfg_reply
.success
= success
;
563 getcfg_reply
.data
= data
;
565 getcfg_reply
.error_if_any
= (char *)error_if_any
;
567 mgmtd__fe_message__init(&fe_msg
);
568 fe_msg
.message_case
= MGMTD__FE_MESSAGE__MESSAGE_GETCFG_REPLY
;
569 fe_msg
.getcfg_reply
= &getcfg_reply
;
571 MGMTD_FE_ADAPTER_DBG(
572 "Sending GET_CONFIG_REPLY message to MGMTD Frontend client '%s'",
573 session
->adapter
->name
);
576 * Cleanup the SHOW transaction associated with this session.
578 if (session
->txn_id
&& (!success
|| (data
&& data
->next_indx
< 0)))
579 mgmt_fe_session_register_event(
580 session
, MGMTD_FE_SESSION_SHOW_TXN_CLNUP
);
582 return mgmt_fe_adapter_send_msg(session
->adapter
, &fe_msg
);
585 static int mgmt_fe_send_getdata_reply(struct mgmt_fe_session_ctx
*session
,
586 Mgmtd__DatastoreId ds_id
,
587 uint64_t req_id
, bool success
,
588 Mgmtd__YangDataReply
*data
,
589 const char *error_if_any
)
591 Mgmtd__FeMessage fe_msg
;
592 Mgmtd__FeGetDataReply getdata_reply
;
594 assert(session
->adapter
);
596 mgmtd__fe_get_data_reply__init(&getdata_reply
);
597 getdata_reply
.session_id
= session
->session_id
;
598 getdata_reply
.ds_id
= ds_id
;
599 getdata_reply
.req_id
= req_id
;
600 getdata_reply
.success
= success
;
601 getdata_reply
.data
= data
;
603 getdata_reply
.error_if_any
= (char *)error_if_any
;
605 mgmtd__fe_message__init(&fe_msg
);
606 fe_msg
.message_case
= MGMTD__FE_MESSAGE__MESSAGE_GETDATA_REPLY
;
607 fe_msg
.getdata_reply
= &getdata_reply
;
609 MGMTD_FE_ADAPTER_DBG(
610 "Sending GET_DATA_REPLY message to MGMTD Frontend client '%s'",
611 session
->adapter
->name
);
614 * Cleanup the SHOW transaction associated with this session.
616 if (session
->txn_id
&& (!success
|| (data
&& data
->next_indx
< 0)))
617 mgmt_fe_session_register_event(
618 session
, MGMTD_FE_SESSION_SHOW_TXN_CLNUP
);
620 return mgmt_fe_adapter_send_msg(session
->adapter
, &fe_msg
);
623 static void mgmt_fe_session_cfg_txn_clnup(struct event
*thread
)
625 struct mgmt_fe_session_ctx
*session
;
627 session
= (struct mgmt_fe_session_ctx
*)EVENT_ARG(thread
);
629 mgmt_fe_session_cfg_txn_cleanup(session
);
632 static void mgmt_fe_session_show_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_show_txn_cleanup(session
);
642 mgmt_fe_session_register_event(struct mgmt_fe_session_ctx
*session
,
643 enum mgmt_session_event event
)
645 struct timeval tv
= {.tv_sec
= 0,
646 .tv_usec
= MGMTD_FE_MSG_PROC_DELAY_USEC
};
649 case MGMTD_FE_SESSION_CFG_TXN_CLNUP
:
650 event_add_timer_tv(mgmt_fe_adapter_tm
,
651 mgmt_fe_session_cfg_txn_clnup
, session
,
652 &tv
, &session
->proc_cfg_txn_clnp
);
654 case MGMTD_FE_SESSION_SHOW_TXN_CLNUP
:
655 event_add_timer_tv(mgmt_fe_adapter_tm
,
656 mgmt_fe_session_show_txn_clnup
, session
,
657 &tv
, &session
->proc_show_txn_clnp
);
662 static struct mgmt_fe_client_adapter
*
663 mgmt_fe_find_adapter_by_fd(int conn_fd
)
665 struct mgmt_fe_client_adapter
*adapter
;
667 FOREACH_ADAPTER_IN_LIST (adapter
) {
668 if (adapter
->conn_fd
== conn_fd
)
675 static struct mgmt_fe_client_adapter
*
676 mgmt_fe_find_adapter_by_name(const char *name
)
678 struct mgmt_fe_client_adapter
*adapter
;
680 FOREACH_ADAPTER_IN_LIST (adapter
) {
681 if (!strncmp(adapter
->name
, name
, sizeof(adapter
->name
)))
688 static void mgmt_fe_adapter_disconnect(struct mgmt_fe_client_adapter
*adapter
)
690 if (adapter
->conn_fd
>= 0) {
691 close(adapter
->conn_fd
);
692 adapter
->conn_fd
= -1;
695 /* TODO: notify about client disconnect for appropriate cleanup */
696 mgmt_fe_cleanup_sessions(adapter
);
697 mgmt_fe_sessions_fini(&adapter
->fe_sessions
);
698 mgmt_fe_adapters_del(&mgmt_fe_adapters
, adapter
);
700 mgmt_fe_adapter_unlock(&adapter
);
704 mgmt_fe_adapter_cleanup_old_conn(struct mgmt_fe_client_adapter
*adapter
)
706 struct mgmt_fe_client_adapter
*old
;
708 FOREACH_ADAPTER_IN_LIST (old
) {
709 if (old
!= adapter
&&
710 !strncmp(adapter
->name
, old
->name
, sizeof(adapter
->name
))) {
712 * We have a Zombie lingering around
714 MGMTD_FE_ADAPTER_DBG(
715 "Client '%s' (FD:%d) seems to have reconnected. Removing old connection (FD:%d)!",
716 adapter
->name
, adapter
->conn_fd
, old
->conn_fd
);
717 mgmt_fe_adapter_disconnect(old
);
723 mgmt_fe_cleanup_adapters(void)
725 struct mgmt_fe_client_adapter
*adapter
;
727 FOREACH_ADAPTER_IN_LIST (adapter
) {
728 mgmt_fe_cleanup_sessions(adapter
);
729 mgmt_fe_adapter_unlock(&adapter
);
734 mgmt_fe_session_handle_lockds_req_msg(struct mgmt_fe_session_ctx
*session
,
735 Mgmtd__FeLockDsReq
*lockds_req
)
737 struct mgmt_ds_ctx
*ds_ctx
;
740 * Next check first if the SET_CONFIG_REQ is for Candidate DS
741 * or not. Report failure if its not. MGMTD currently only
742 * supports editing the Candidate DS.
744 if (lockds_req
->ds_id
!= MGMTD_DS_CANDIDATE
) {
745 mgmt_fe_send_lockds_reply(
746 session
, lockds_req
->ds_id
, lockds_req
->req_id
,
747 lockds_req
->lock
, false,
748 "Lock/Unlock on datastores other than Candidate DS not permitted!");
753 mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
, lockds_req
->ds_id
);
755 mgmt_fe_send_lockds_reply(
756 session
, lockds_req
->ds_id
, lockds_req
->req_id
,
757 lockds_req
->lock
, false,
758 "Failed to retrieve handle for DS!");
762 if (lockds_req
->lock
) {
763 if (mgmt_fe_session_write_lock_ds(lockds_req
->ds_id
,
766 mgmt_fe_send_lockds_reply(
767 session
, lockds_req
->ds_id
, lockds_req
->req_id
,
768 lockds_req
->lock
, false,
769 "Lock already taken on DS by another session!");
773 session
->ds_locked_implict
[lockds_req
->ds_id
] = false;
775 if (!session
->ds_write_locked
[lockds_req
->ds_id
]) {
776 mgmt_fe_send_lockds_reply(
777 session
, lockds_req
->ds_id
, lockds_req
->req_id
,
778 lockds_req
->lock
, false,
779 "Lock on DS was not taken by this session!");
783 (void)mgmt_fe_session_unlock_ds(lockds_req
->ds_id
, ds_ctx
,
784 session
, true, false);
787 if (mgmt_fe_send_lockds_reply(session
, lockds_req
->ds_id
,
788 lockds_req
->req_id
, lockds_req
->lock
,
791 MGMTD_FE_ADAPTER_DBG(
792 "Failed to send LOCK_DS_REPLY for DS %u Sessn: %p from %s",
793 lockds_req
->ds_id
, session
, session
->adapter
->name
);
800 mgmt_fe_session_handle_setcfg_req_msg(struct mgmt_fe_session_ctx
*session
,
801 Mgmtd__FeSetConfigReq
*setcfg_req
)
803 uint64_t cfg_session_id
;
804 struct mgmt_ds_ctx
*ds_ctx
, *dst_ds_ctx
;
806 if (mm
->perf_stats_en
)
807 gettimeofday(&session
->adapter
->setcfg_stats
.last_start
, NULL
);
810 * Next check first if the SET_CONFIG_REQ is for Candidate DS
811 * or not. Report failure if its not. MGMTD currently only
812 * supports editing the Candidate DS.
814 if (setcfg_req
->ds_id
!= MGMTD_DS_CANDIDATE
) {
815 mgmt_fe_send_setcfg_reply(
816 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
, false,
817 "Set-Config on datastores other than Candidate DS not permitted!",
818 setcfg_req
->implicit_commit
);
826 mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
, setcfg_req
->ds_id
);
828 mgmt_fe_send_setcfg_reply(
829 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
, false,
830 "No such DS exists!", setcfg_req
->implicit_commit
);
834 if (session
->cfg_txn_id
== MGMTD_TXN_ID_NONE
) {
836 * Check first if the current session can run a CONFIG
837 * transaction or not. Report failure if a CONFIG transaction
838 * from another session is already in progress.
840 cfg_session_id
= mgmt_config_txn_in_progress();
841 if (cfg_session_id
!= MGMTD_SESSION_ID_NONE
842 && cfg_session_id
!= session
->session_id
) {
843 mgmt_fe_send_setcfg_reply(
844 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
,
846 "Configuration already in-progress through a different user session!",
847 setcfg_req
->implicit_commit
);
848 goto mgmt_fe_sess_handle_setcfg_req_failed
;
853 * Try taking write-lock on the requested DS (if not already).
855 if (!session
->ds_write_locked
[setcfg_req
->ds_id
]) {
856 if (mgmt_fe_session_write_lock_ds(setcfg_req
->ds_id
,
859 mgmt_fe_send_setcfg_reply(
860 session
, setcfg_req
->ds_id
,
861 setcfg_req
->req_id
, false,
862 "Failed to lock the DS!",
863 setcfg_req
->implicit_commit
);
864 goto mgmt_fe_sess_handle_setcfg_req_failed
;
867 session
->ds_locked_implict
[setcfg_req
->ds_id
] = true;
871 * Start a CONFIG Transaction (if not started already)
873 session
->cfg_txn_id
= mgmt_create_txn(session
->session_id
,
874 MGMTD_TXN_TYPE_CONFIG
);
875 if (session
->cfg_txn_id
== MGMTD_SESSION_ID_NONE
) {
876 mgmt_fe_send_setcfg_reply(
877 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
,
879 "Failed to create a Configuration session!",
880 setcfg_req
->implicit_commit
);
881 goto mgmt_fe_sess_handle_setcfg_req_failed
;
884 MGMTD_FE_ADAPTER_DBG(
885 "Created new Config Txn 0x%llx for session %p",
886 (unsigned long long)session
->cfg_txn_id
, session
);
888 MGMTD_FE_ADAPTER_DBG(
889 "Config Txn 0x%llx for session %p already created",
890 (unsigned long long)session
->cfg_txn_id
, session
);
892 if (setcfg_req
->implicit_commit
) {
894 * In this scenario need to skip cleanup of the txn,
895 * so setting implicit commit to false.
897 mgmt_fe_send_setcfg_reply(
898 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
,
900 "A Configuration transaction is already in progress!",
907 if (setcfg_req
->implicit_commit
) {
908 dst_ds_ctx
= mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
,
909 setcfg_req
->commit_ds_id
);
911 mgmt_fe_send_setcfg_reply(
912 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
,
913 false, "No such commit DS exists!",
914 setcfg_req
->implicit_commit
);
920 * Create the SETConfig request under the transaction.
922 if (mgmt_txn_send_set_config_req(
923 session
->cfg_txn_id
, setcfg_req
->req_id
, setcfg_req
->ds_id
,
924 ds_ctx
, setcfg_req
->data
, setcfg_req
->n_data
,
925 setcfg_req
->implicit_commit
, setcfg_req
->commit_ds_id
,
928 mgmt_fe_send_setcfg_reply(
929 session
, setcfg_req
->ds_id
, setcfg_req
->req_id
, false,
930 "Request processing for SET-CONFIG failed!",
931 setcfg_req
->implicit_commit
);
932 goto mgmt_fe_sess_handle_setcfg_req_failed
;
937 mgmt_fe_sess_handle_setcfg_req_failed
:
940 * Delete transaction created recently.
942 if (session
->cfg_txn_id
!= MGMTD_TXN_ID_NONE
)
943 mgmt_destroy_txn(&session
->cfg_txn_id
);
944 if (ds_ctx
&& session
->ds_write_locked
[setcfg_req
->ds_id
])
945 mgmt_fe_session_unlock_ds(setcfg_req
->ds_id
, ds_ctx
, session
,
952 mgmt_fe_session_handle_getcfg_req_msg(struct mgmt_fe_session_ctx
*session
,
953 Mgmtd__FeGetConfigReq
*getcfg_req
)
955 struct mgmt_ds_ctx
*ds_ctx
;
961 mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
, getcfg_req
->ds_id
);
963 mgmt_fe_send_getcfg_reply(session
, getcfg_req
->ds_id
,
964 getcfg_req
->req_id
, false, NULL
,
965 "No such DS exists!");
970 * Next check first if the SET_CONFIG_REQ is for Candidate DS
971 * or not. Report failure if its not. MGMTD currently only
972 * supports editing the Candidate DS.
974 if (getcfg_req
->ds_id
!= MGMTD_DS_CANDIDATE
975 && getcfg_req
->ds_id
!= MGMTD_DS_RUNNING
) {
976 mgmt_fe_send_getcfg_reply(
977 session
, getcfg_req
->ds_id
, getcfg_req
->req_id
, false,
979 "Get-Config on datastores other than Candidate or Running DS not permitted!");
983 if (session
->txn_id
== MGMTD_TXN_ID_NONE
) {
985 * Try taking read-lock on the requested DS (if not already
986 * locked). If the DS has already been write-locked by a ongoing
987 * CONFIG transaction we may allow reading the contents of the
990 if (!session
->ds_read_locked
[getcfg_req
->ds_id
]
991 && !session
->ds_write_locked
[getcfg_req
->ds_id
]) {
992 if (mgmt_fe_session_read_lock_ds(getcfg_req
->ds_id
,
995 mgmt_fe_send_getcfg_reply(
996 session
, getcfg_req
->ds_id
,
997 getcfg_req
->req_id
, false, NULL
,
998 "Failed to lock the DS! Another session might have locked it!");
999 goto mgmt_fe_sess_handle_getcfg_req_failed
;
1002 session
->ds_locked_implict
[getcfg_req
->ds_id
] = true;
1006 * Start a SHOW Transaction (if not started already)
1008 session
->txn_id
= mgmt_create_txn(session
->session_id
,
1009 MGMTD_TXN_TYPE_SHOW
);
1010 if (session
->txn_id
== MGMTD_SESSION_ID_NONE
) {
1011 mgmt_fe_send_getcfg_reply(
1012 session
, getcfg_req
->ds_id
, getcfg_req
->req_id
,
1014 "Failed to create a Show transaction!");
1015 goto mgmt_fe_sess_handle_getcfg_req_failed
;
1018 MGMTD_FE_ADAPTER_DBG(
1019 "Created new Show Txn 0x%llx for session %p",
1020 (unsigned long long)session
->txn_id
, session
);
1022 MGMTD_FE_ADAPTER_DBG(
1023 "Show Txn 0x%llx for session %p already created",
1024 (unsigned long long)session
->txn_id
, session
);
1028 * Create a GETConfig request under the transaction.
1030 if (mgmt_txn_send_get_config_req(session
->txn_id
, getcfg_req
->req_id
,
1031 getcfg_req
->ds_id
, ds_ctx
,
1032 getcfg_req
->data
, getcfg_req
->n_data
)
1034 mgmt_fe_send_getcfg_reply(
1035 session
, getcfg_req
->ds_id
, getcfg_req
->req_id
, false,
1036 NULL
, "Request processing for GET-CONFIG failed!");
1037 goto mgmt_fe_sess_handle_getcfg_req_failed
;
1042 mgmt_fe_sess_handle_getcfg_req_failed
:
1045 * Destroy the transaction created recently.
1047 if (session
->txn_id
!= MGMTD_TXN_ID_NONE
)
1048 mgmt_destroy_txn(&session
->txn_id
);
1049 if (ds_ctx
&& session
->ds_read_locked
[getcfg_req
->ds_id
])
1050 mgmt_fe_session_unlock_ds(getcfg_req
->ds_id
, ds_ctx
, session
,
1057 mgmt_fe_session_handle_getdata_req_msg(struct mgmt_fe_session_ctx
*session
,
1058 Mgmtd__FeGetDataReq
*getdata_req
)
1060 struct mgmt_ds_ctx
*ds_ctx
;
1063 * Get the DS handle.
1065 ds_ctx
= mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
,
1066 getdata_req
->ds_id
);
1068 mgmt_fe_send_getdata_reply(session
, getdata_req
->ds_id
,
1069 getdata_req
->req_id
, false, NULL
,
1070 "No such DS exists!");
1074 if (session
->txn_id
== MGMTD_TXN_ID_NONE
) {
1076 * Try taking read-lock on the requested DS (if not already
1077 * locked). If the DS has already been write-locked by a ongoing
1078 * CONFIG transaction we may allow reading the contents of the
1081 if (!session
->ds_read_locked
[getdata_req
->ds_id
]
1082 && !session
->ds_write_locked
[getdata_req
->ds_id
]) {
1083 if (mgmt_fe_session_read_lock_ds(getdata_req
->ds_id
,
1086 mgmt_fe_send_getdata_reply(
1087 session
, getdata_req
->ds_id
,
1088 getdata_req
->req_id
, false, NULL
,
1089 "Failed to lock the DS! Another session might have locked it!");
1090 goto mgmt_fe_sess_handle_getdata_req_failed
;
1093 session
->ds_locked_implict
[getdata_req
->ds_id
] = true;
1097 * Start a SHOW Transaction (if not started already)
1099 session
->txn_id
= mgmt_create_txn(session
->session_id
,
1100 MGMTD_TXN_TYPE_SHOW
);
1101 if (session
->txn_id
== MGMTD_SESSION_ID_NONE
) {
1102 mgmt_fe_send_getdata_reply(
1103 session
, getdata_req
->ds_id
,
1104 getdata_req
->req_id
, false, NULL
,
1105 "Failed to create a Show transaction!");
1106 goto mgmt_fe_sess_handle_getdata_req_failed
;
1109 MGMTD_FE_ADAPTER_DBG(
1110 "Created new Show Txn 0x%llx for session %p",
1111 (unsigned long long)session
->txn_id
, session
);
1113 MGMTD_FE_ADAPTER_DBG(
1114 "Show Txn 0x%llx for session %p already created",
1115 (unsigned long long)session
->txn_id
, session
);
1119 * Create a GETData request under the transaction.
1121 if (mgmt_txn_send_get_data_req(session
->txn_id
, getdata_req
->req_id
,
1122 getdata_req
->ds_id
, ds_ctx
,
1123 getdata_req
->data
, getdata_req
->n_data
)
1125 mgmt_fe_send_getdata_reply(
1126 session
, getdata_req
->ds_id
, getdata_req
->req_id
, false,
1127 NULL
, "Request processing for GET-CONFIG failed!");
1128 goto mgmt_fe_sess_handle_getdata_req_failed
;
1133 mgmt_fe_sess_handle_getdata_req_failed
:
1136 * Destroy the transaction created recently.
1138 if (session
->txn_id
!= MGMTD_TXN_ID_NONE
)
1139 mgmt_destroy_txn(&session
->txn_id
);
1141 if (ds_ctx
&& session
->ds_read_locked
[getdata_req
->ds_id
])
1142 mgmt_fe_session_unlock_ds(getdata_req
->ds_id
, ds_ctx
,
1143 session
, false, true);
1148 static int mgmt_fe_session_handle_commit_config_req_msg(
1149 struct mgmt_fe_session_ctx
*session
,
1150 Mgmtd__FeCommitConfigReq
*commcfg_req
)
1152 struct mgmt_ds_ctx
*src_ds_ctx
, *dst_ds_ctx
;
1154 if (mm
->perf_stats_en
)
1155 gettimeofday(&session
->adapter
->cmt_stats
.last_start
, NULL
);
1156 session
->adapter
->cmt_stats
.commit_cnt
++;
1158 * Get the source DS handle.
1160 src_ds_ctx
= mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
,
1161 commcfg_req
->src_ds_id
);
1163 mgmt_fe_send_commitcfg_reply(
1164 session
, commcfg_req
->src_ds_id
, commcfg_req
->dst_ds_id
,
1165 commcfg_req
->req_id
, MGMTD_INTERNAL_ERROR
,
1166 commcfg_req
->validate_only
,
1167 "No such source DS exists!");
1172 * Get the destination DS handle.
1174 dst_ds_ctx
= mgmt_ds_get_ctx_by_id(mgmt_fe_adapter_mm
,
1175 commcfg_req
->dst_ds_id
);
1177 mgmt_fe_send_commitcfg_reply(
1178 session
, commcfg_req
->src_ds_id
, commcfg_req
->dst_ds_id
,
1179 commcfg_req
->req_id
, MGMTD_INTERNAL_ERROR
,
1180 commcfg_req
->validate_only
,
1181 "No such destination DS exists!");
1186 * Next check first if the SET_CONFIG_REQ is for Candidate DS
1187 * or not. Report failure if its not. MGMTD currently only
1188 * supports editing the Candidate DS.
1190 if (commcfg_req
->dst_ds_id
!= MGMTD_DS_RUNNING
) {
1191 mgmt_fe_send_commitcfg_reply(
1192 session
, commcfg_req
->src_ds_id
, commcfg_req
->dst_ds_id
,
1193 commcfg_req
->req_id
, MGMTD_INTERNAL_ERROR
,
1194 commcfg_req
->validate_only
,
1195 "Set-Config on datastores other than Running DS not permitted!");
1199 if (session
->cfg_txn_id
== MGMTD_TXN_ID_NONE
) {
1201 * Start a CONFIG Transaction (if not started already)
1203 session
->cfg_txn_id
= mgmt_create_txn(session
->session_id
,
1204 MGMTD_TXN_TYPE_CONFIG
);
1205 if (session
->cfg_txn_id
== MGMTD_SESSION_ID_NONE
) {
1206 mgmt_fe_send_commitcfg_reply(
1207 session
, commcfg_req
->src_ds_id
,
1208 commcfg_req
->dst_ds_id
, commcfg_req
->req_id
,
1209 MGMTD_INTERNAL_ERROR
,
1210 commcfg_req
->validate_only
,
1211 "Failed to create a Configuration session!");
1214 MGMTD_FE_ADAPTER_DBG("Created txn %" PRIu64
1215 " for session %" PRIu64
1216 " for COMMIT-CFG-REQ",
1217 session
->cfg_txn_id
, session
->session_id
);
1222 * Try taking write-lock on the destination DS (if not already).
1224 if (!session
->ds_write_locked
[commcfg_req
->dst_ds_id
]) {
1225 if (mgmt_fe_session_write_lock_ds(commcfg_req
->dst_ds_id
,
1226 dst_ds_ctx
, session
)
1228 mgmt_fe_send_commitcfg_reply(
1229 session
, commcfg_req
->src_ds_id
,
1230 commcfg_req
->dst_ds_id
, commcfg_req
->req_id
,
1231 MGMTD_DS_LOCK_FAILED
,
1232 commcfg_req
->validate_only
,
1233 "Failed to lock the destination DS!");
1237 session
->ds_locked_implict
[commcfg_req
->dst_ds_id
] = true;
1241 * Create COMMITConfig request under the transaction
1243 if (mgmt_txn_send_commit_config_req(
1244 session
->cfg_txn_id
, commcfg_req
->req_id
,
1245 commcfg_req
->src_ds_id
, src_ds_ctx
, commcfg_req
->dst_ds_id
,
1246 dst_ds_ctx
, commcfg_req
->validate_only
, commcfg_req
->abort
,
1249 mgmt_fe_send_commitcfg_reply(
1250 session
, commcfg_req
->src_ds_id
, commcfg_req
->dst_ds_id
,
1251 commcfg_req
->req_id
, MGMTD_INTERNAL_ERROR
,
1252 commcfg_req
->validate_only
,
1253 "Request processing for COMMIT-CONFIG failed!");
1261 mgmt_fe_adapter_handle_msg(struct mgmt_fe_client_adapter
*adapter
,
1262 Mgmtd__FeMessage
*fe_msg
)
1264 struct mgmt_fe_session_ctx
*session
;
1267 * protobuf-c adds a max size enum with an internal, and changing by
1268 * version, name; cast to an int to avoid unhandled enum warnings
1270 switch ((int)fe_msg
->message_case
) {
1271 case MGMTD__FE_MESSAGE__MESSAGE_REGISTER_REQ
:
1272 MGMTD_FE_ADAPTER_DBG("Got Register Req Msg from '%s'",
1273 fe_msg
->register_req
->client_name
);
1275 if (strlen(fe_msg
->register_req
->client_name
)) {
1276 strlcpy(adapter
->name
,
1277 fe_msg
->register_req
->client_name
,
1278 sizeof(adapter
->name
));
1279 mgmt_fe_adapter_cleanup_old_conn(adapter
);
1282 case MGMTD__FE_MESSAGE__MESSAGE_SESSION_REQ
:
1283 if (fe_msg
->session_req
->create
1284 && fe_msg
->session_req
->id_case
1285 == MGMTD__FE_SESSION_REQ__ID_CLIENT_CONN_ID
) {
1286 MGMTD_FE_ADAPTER_DBG(
1287 "Got Session Create Req Msg for client-id %llu from '%s'",
1288 (unsigned long long)
1289 fe_msg
->session_req
->client_conn_id
,
1292 session
= mgmt_fe_create_session(
1293 adapter
, fe_msg
->session_req
->client_conn_id
);
1294 mgmt_fe_send_session_reply(adapter
, session
, true,
1295 session
? true : false);
1297 !fe_msg
->session_req
->create
1298 && fe_msg
->session_req
->id_case
1299 == MGMTD__FE_SESSION_REQ__ID_SESSION_ID
) {
1300 MGMTD_FE_ADAPTER_DBG(
1301 "Got Session Destroy Req Msg for session-id %llu from '%s'",
1302 (unsigned long long)
1303 fe_msg
->session_req
->session_id
,
1306 session
= mgmt_session_id2ctx(
1307 fe_msg
->session_req
->session_id
);
1308 mgmt_fe_send_session_reply(adapter
, session
, false,
1310 mgmt_fe_cleanup_session(&session
);
1313 case MGMTD__FE_MESSAGE__MESSAGE_LOCKDS_REQ
:
1314 session
= mgmt_session_id2ctx(
1315 fe_msg
->lockds_req
->session_id
);
1316 MGMTD_FE_ADAPTER_DBG(
1317 "Got %sockDS Req Msg for DS:%d for session-id %llx from '%s'",
1318 fe_msg
->lockds_req
->lock
? "L" : "Unl",
1319 fe_msg
->lockds_req
->ds_id
,
1320 (unsigned long long)fe_msg
->lockds_req
->session_id
,
1322 mgmt_fe_session_handle_lockds_req_msg(
1323 session
, fe_msg
->lockds_req
);
1325 case MGMTD__FE_MESSAGE__MESSAGE_SETCFG_REQ
:
1326 session
= mgmt_session_id2ctx(
1327 fe_msg
->setcfg_req
->session_id
);
1328 session
->adapter
->setcfg_stats
.set_cfg_count
++;
1329 MGMTD_FE_ADAPTER_DBG(
1330 "Got Set Config Req Msg (%d Xpaths, Implicit:%c) on DS:%d for session-id %llu from '%s'",
1331 (int)fe_msg
->setcfg_req
->n_data
,
1332 fe_msg
->setcfg_req
->implicit_commit
? 'T':'F',
1333 fe_msg
->setcfg_req
->ds_id
,
1334 (unsigned long long)fe_msg
->setcfg_req
->session_id
,
1337 mgmt_fe_session_handle_setcfg_req_msg(
1338 session
, fe_msg
->setcfg_req
);
1340 case MGMTD__FE_MESSAGE__MESSAGE_COMMCFG_REQ
:
1341 session
= mgmt_session_id2ctx(
1342 fe_msg
->commcfg_req
->session_id
);
1343 MGMTD_FE_ADAPTER_DBG(
1344 "Got Commit Config Req Msg for src-DS:%d dst-DS:%d (Abort:%c) on session-id %llu from '%s'",
1345 fe_msg
->commcfg_req
->src_ds_id
,
1346 fe_msg
->commcfg_req
->dst_ds_id
,
1347 fe_msg
->commcfg_req
->abort
? 'T':'F',
1348 (unsigned long long)fe_msg
->commcfg_req
->session_id
,
1350 mgmt_fe_session_handle_commit_config_req_msg(
1351 session
, fe_msg
->commcfg_req
);
1353 case MGMTD__FE_MESSAGE__MESSAGE_GETCFG_REQ
:
1354 session
= mgmt_session_id2ctx(
1355 fe_msg
->getcfg_req
->session_id
);
1356 MGMTD_FE_ADAPTER_DBG(
1357 "Got Get-Config Req Msg for DS:%d (xpaths: %d) on session-id %llu from '%s'",
1358 fe_msg
->getcfg_req
->ds_id
,
1359 (int)fe_msg
->getcfg_req
->n_data
,
1360 (unsigned long long)fe_msg
->getcfg_req
->session_id
,
1362 mgmt_fe_session_handle_getcfg_req_msg(
1363 session
, fe_msg
->getcfg_req
);
1365 case MGMTD__FE_MESSAGE__MESSAGE_GETDATA_REQ
:
1366 session
= mgmt_session_id2ctx(
1367 fe_msg
->getdata_req
->session_id
);
1368 MGMTD_FE_ADAPTER_DBG(
1369 "Got Get-Data Req Msg for DS:%d (xpaths: %d) on session-id %llu from '%s'",
1370 fe_msg
->getdata_req
->ds_id
,
1371 (int)fe_msg
->getdata_req
->n_data
,
1372 (unsigned long long)fe_msg
->getdata_req
->session_id
,
1374 mgmt_fe_session_handle_getdata_req_msg(
1375 session
, fe_msg
->getdata_req
);
1377 case MGMTD__FE_MESSAGE__MESSAGE_NOTIFY_DATA_REQ
:
1378 case MGMTD__FE_MESSAGE__MESSAGE_REGNOTIFY_REQ
:
1380 * TODO: Add handling code in future.
1384 * NOTE: The following messages are always sent from MGMTD to
1385 * Frontend clients only and/or need not be handled on MGMTd.
1387 case MGMTD__FE_MESSAGE__MESSAGE_SESSION_REPLY
:
1388 case MGMTD__FE_MESSAGE__MESSAGE_LOCKDS_REPLY
:
1389 case MGMTD__FE_MESSAGE__MESSAGE_SETCFG_REPLY
:
1390 case MGMTD__FE_MESSAGE__MESSAGE_COMMCFG_REPLY
:
1391 case MGMTD__FE_MESSAGE__MESSAGE_GETCFG_REPLY
:
1392 case MGMTD__FE_MESSAGE__MESSAGE_GETDATA_REPLY
:
1393 case MGMTD__FE_MESSAGE__MESSAGE__NOT_SET
:
1396 * A 'default' case is being added contrary to the
1397 * FRR code guidelines to take care of build
1398 * failures on certain build systems (courtesy of
1399 * the proto-c package).
1407 static void mgmt_fe_adapter_process_msg(void *user_ctx
, uint8_t *data
,
1410 struct mgmt_fe_client_adapter
*adapter
= user_ctx
;
1411 Mgmtd__FeMessage
*fe_msg
;
1413 fe_msg
= mgmtd__fe_message__unpack(NULL
, len
, data
);
1415 MGMTD_FE_ADAPTER_DBG(
1416 "Failed to decode %zu bytes for adapter: %s", len
,
1420 MGMTD_FE_ADAPTER_DBG(
1421 "Decoded %zu bytes of message: %u from adapter: %s", len
,
1422 fe_msg
->message_case
, adapter
->name
);
1423 (void)mgmt_fe_adapter_handle_msg(adapter
, fe_msg
);
1424 mgmtd__fe_message__free_unpacked(fe_msg
, NULL
);
1427 static void mgmt_fe_adapter_proc_msgbufs(struct event
*thread
)
1429 struct mgmt_fe_client_adapter
*adapter
= EVENT_ARG(thread
);
1431 if (mgmt_msg_procbufs(&adapter
->mstate
, mgmt_fe_adapter_process_msg
,
1432 adapter
, MGMT_DEBUG_FE_CHECK()))
1433 mgmt_fe_adapter_register_event(adapter
, MGMTD_FE_PROC_MSG
);
1436 static void mgmt_fe_adapter_read(struct event
*thread
)
1438 struct mgmt_fe_client_adapter
*adapter
= EVENT_ARG(thread
);
1439 enum mgmt_msg_rsched rv
;
1441 rv
= mgmt_msg_read(&adapter
->mstate
, adapter
->conn_fd
,
1442 MGMT_DEBUG_FE_CHECK());
1443 if (rv
== MSR_DISCONNECT
) {
1444 mgmt_fe_adapter_disconnect(adapter
);
1447 if (rv
== MSR_SCHED_BOTH
)
1448 mgmt_fe_adapter_register_event(adapter
, MGMTD_FE_PROC_MSG
);
1449 mgmt_fe_adapter_register_event(adapter
, MGMTD_FE_CONN_READ
);
1452 static void mgmt_fe_adapter_write(struct event
*thread
)
1454 struct mgmt_fe_client_adapter
*adapter
= EVENT_ARG(thread
);
1455 enum mgmt_msg_wsched rv
;
1457 rv
= mgmt_msg_write(&adapter
->mstate
, adapter
->conn_fd
,
1458 MGMT_DEBUG_FE_CHECK());
1459 if (rv
== MSW_SCHED_STREAM
)
1460 mgmt_fe_adapter_register_event(adapter
, MGMTD_FE_CONN_WRITE
);
1461 else if (rv
== MSW_DISCONNECT
)
1462 mgmt_fe_adapter_disconnect(adapter
);
1463 else if (rv
== MSW_SCHED_WRITES_OFF
) {
1464 mgmt_fe_adapter_writes_off(adapter
);
1465 mgmt_fe_adapter_register_event(adapter
,
1466 MGMTD_FE_CONN_WRITES_ON
);
1468 assert(rv
== MSW_SCHED_NONE
);
1471 static void mgmt_fe_adapter_resume_writes(struct event
*thread
)
1473 struct mgmt_fe_client_adapter
*adapter
;
1475 adapter
= (struct mgmt_fe_client_adapter
*)EVENT_ARG(thread
);
1476 assert(adapter
&& adapter
->conn_fd
!= -1);
1478 mgmt_fe_adapter_writes_on(adapter
);
1482 mgmt_fe_adapter_register_event(struct mgmt_fe_client_adapter
*adapter
,
1483 enum mgmt_fe_event event
)
1485 struct timeval tv
= {0};
1488 case MGMTD_FE_CONN_READ
:
1489 event_add_read(mgmt_fe_adapter_tm
, mgmt_fe_adapter_read
,
1490 adapter
, adapter
->conn_fd
, &adapter
->conn_read_ev
);
1492 case MGMTD_FE_CONN_WRITE
:
1493 event_add_write(mgmt_fe_adapter_tm
,
1494 mgmt_fe_adapter_write
, adapter
,
1495 adapter
->conn_fd
, &adapter
->conn_write_ev
);
1497 case MGMTD_FE_PROC_MSG
:
1498 tv
.tv_usec
= MGMTD_FE_MSG_PROC_DELAY_USEC
;
1499 event_add_timer_tv(mgmt_fe_adapter_tm
,
1500 mgmt_fe_adapter_proc_msgbufs
, adapter
,
1501 &tv
, &adapter
->proc_msg_ev
);
1503 case MGMTD_FE_CONN_WRITES_ON
:
1504 event_add_timer_msec(mgmt_fe_adapter_tm
,
1505 mgmt_fe_adapter_resume_writes
, adapter
,
1506 MGMTD_FE_MSG_WRITE_DELAY_MSEC
,
1507 &adapter
->conn_writes_on
);
1509 case MGMTD_FE_SERVER
:
1510 assert(!"mgmt_fe_adapter_post_event() called incorrectly");
1515 void mgmt_fe_adapter_lock(struct mgmt_fe_client_adapter
*adapter
)
1517 adapter
->refcount
++;
1521 mgmt_fe_adapter_unlock(struct mgmt_fe_client_adapter
**adapter
)
1523 assert(*adapter
&& (*adapter
)->refcount
);
1525 (*adapter
)->refcount
--;
1526 if (!(*adapter
)->refcount
) {
1527 mgmt_fe_adapters_del(&mgmt_fe_adapters
, *adapter
);
1528 EVENT_OFF((*adapter
)->conn_read_ev
);
1529 EVENT_OFF((*adapter
)->conn_write_ev
);
1530 EVENT_OFF((*adapter
)->proc_msg_ev
);
1531 EVENT_OFF((*adapter
)->conn_writes_on
);
1532 mgmt_msg_destroy(&(*adapter
)->mstate
);
1533 XFREE(MTYPE_MGMTD_FE_ADPATER
, *adapter
);
1539 int mgmt_fe_adapter_init(struct event_loop
*tm
, struct mgmt_master
*mm
)
1541 if (!mgmt_fe_adapter_tm
) {
1542 mgmt_fe_adapter_tm
= tm
;
1543 mgmt_fe_adapter_mm
= mm
;
1544 mgmt_fe_adapters_init(&mgmt_fe_adapters
);
1546 assert(!mgmt_fe_sessions
);
1547 mgmt_fe_sessions
= hash_create(mgmt_fe_session_hash_key
,
1548 mgmt_fe_session_hash_cmp
,
1549 "MGMT Frontend Sessions");
1555 void mgmt_fe_adapter_destroy(void)
1557 mgmt_fe_cleanup_adapters();
1558 mgmt_fe_session_hash_destroy();
1561 struct mgmt_fe_client_adapter
*
1562 mgmt_fe_create_adapter(int conn_fd
, union sockunion
*from
)
1564 struct mgmt_fe_client_adapter
*adapter
= NULL
;
1566 adapter
= mgmt_fe_find_adapter_by_fd(conn_fd
);
1568 adapter
= XCALLOC(MTYPE_MGMTD_FE_ADPATER
,
1569 sizeof(struct mgmt_fe_client_adapter
));
1572 adapter
->conn_fd
= conn_fd
;
1573 memcpy(&adapter
->conn_su
, from
, sizeof(adapter
->conn_su
));
1574 snprintf(adapter
->name
, sizeof(adapter
->name
), "Unknown-FD-%d",
1576 mgmt_fe_sessions_init(&adapter
->fe_sessions
);
1578 mgmt_msg_init(&adapter
->mstate
, MGMTD_FE_MAX_NUM_MSG_PROC
,
1579 MGMTD_FE_MAX_NUM_MSG_WRITE
, MGMTD_FE_MSG_MAX_LEN
,
1581 mgmt_fe_adapter_lock(adapter
);
1583 mgmt_fe_adapter_register_event(adapter
, MGMTD_FE_CONN_READ
);
1584 mgmt_fe_adapters_add_tail(&mgmt_fe_adapters
, adapter
);
1586 adapter
->setcfg_stats
.min_tm
= ULONG_MAX
;
1587 adapter
->cmt_stats
.min_tm
= ULONG_MAX
;
1588 MGMTD_FE_ADAPTER_DBG("Added new MGMTD Frontend adapter '%s'",
1592 /* Make client socket non-blocking. */
1593 set_nonblocking(adapter
->conn_fd
);
1594 setsockopt_so_sendbuf(adapter
->conn_fd
,
1595 MGMTD_SOCKET_FE_SEND_BUF_SIZE
);
1596 setsockopt_so_recvbuf(adapter
->conn_fd
,
1597 MGMTD_SOCKET_FE_RECV_BUF_SIZE
);
1601 struct mgmt_fe_client_adapter
*mgmt_fe_get_adapter(const char *name
)
1603 return mgmt_fe_find_adapter_by_name(name
);
1606 int mgmt_fe_send_set_cfg_reply(uint64_t session_id
, uint64_t txn_id
,
1607 Mgmtd__DatastoreId ds_id
, uint64_t req_id
,
1608 enum mgmt_result result
,
1609 const char *error_if_any
,
1610 bool implicit_commit
)
1612 struct mgmt_fe_session_ctx
*session
;
1614 session
= mgmt_session_id2ctx(session_id
);
1615 if (!session
|| session
->cfg_txn_id
!= txn_id
) {
1617 MGMTD_FE_ADAPTER_ERR(
1618 "Txn_id doesnot match, session txn is 0x%llx, current txn 0x%llx",
1619 (unsigned long long)session
->cfg_txn_id
,
1620 (unsigned long long)txn_id
);
1624 return mgmt_fe_send_setcfg_reply(
1625 session
, ds_id
, req_id
, result
== MGMTD_SUCCESS
? true : false,
1626 error_if_any
, implicit_commit
);
1629 int mgmt_fe_send_commit_cfg_reply(uint64_t session_id
, uint64_t txn_id
,
1630 Mgmtd__DatastoreId src_ds_id
,
1631 Mgmtd__DatastoreId dst_ds_id
,
1632 uint64_t req_id
, bool validate_only
,
1633 enum mgmt_result result
,
1634 const char *error_if_any
)
1636 struct mgmt_fe_session_ctx
*session
;
1638 session
= mgmt_session_id2ctx(session_id
);
1639 if (!session
|| session
->cfg_txn_id
!= txn_id
)
1642 return mgmt_fe_send_commitcfg_reply(session
, src_ds_id
, dst_ds_id
,
1643 req_id
, result
, validate_only
,
1647 int mgmt_fe_send_get_cfg_reply(uint64_t session_id
, uint64_t txn_id
,
1648 Mgmtd__DatastoreId ds_id
, uint64_t req_id
,
1649 enum mgmt_result result
,
1650 Mgmtd__YangDataReply
*data_resp
,
1651 const char *error_if_any
)
1653 struct mgmt_fe_session_ctx
*session
;
1655 session
= mgmt_session_id2ctx(session_id
);
1656 if (!session
|| session
->txn_id
!= txn_id
)
1659 return mgmt_fe_send_getcfg_reply(session
, ds_id
, req_id
,
1660 result
== MGMTD_SUCCESS
, data_resp
,
1664 int mgmt_fe_send_get_data_reply(uint64_t session_id
, uint64_t txn_id
,
1665 Mgmtd__DatastoreId ds_id
, uint64_t req_id
,
1666 enum mgmt_result result
,
1667 Mgmtd__YangDataReply
*data_resp
,
1668 const char *error_if_any
)
1670 struct mgmt_fe_session_ctx
*session
;
1672 session
= mgmt_session_id2ctx(session_id
);
1673 if (!session
|| session
->txn_id
!= txn_id
)
1676 return mgmt_fe_send_getdata_reply(session
, ds_id
, req_id
,
1677 result
== MGMTD_SUCCESS
,
1678 data_resp
, error_if_any
);
1681 int mgmt_fe_send_data_notify(Mgmtd__DatastoreId ds_id
,
1682 Mgmtd__YangData
* data_resp
[], int num_data
)
1684 /* struct mgmt_fe_session_ctx *session; */
1689 struct mgmt_setcfg_stats
*
1690 mgmt_fe_get_session_setcfg_stats(uint64_t session_id
)
1692 struct mgmt_fe_session_ctx
*session
;
1694 session
= mgmt_session_id2ctx(session_id
);
1695 if (!session
|| !session
->adapter
)
1698 return &session
->adapter
->setcfg_stats
;
1701 struct mgmt_commit_stats
*
1702 mgmt_fe_get_session_commit_stats(uint64_t session_id
)
1704 struct mgmt_fe_session_ctx
*session
;
1706 session
= mgmt_session_id2ctx(session_id
);
1707 if (!session
|| !session
->adapter
)
1710 return &session
->adapter
->cmt_stats
;
1714 mgmt_fe_adapter_cmt_stats_write(struct vty
*vty
,
1715 struct mgmt_fe_client_adapter
*adapter
)
1717 char buf
[MGMT_LONG_TIME_MAX_LEN
];
1719 if (!mm
->perf_stats_en
)
1722 vty_out(vty
, " Num-Commits: \t\t\t%lu\n",
1723 adapter
->cmt_stats
.commit_cnt
);
1724 if (adapter
->cmt_stats
.commit_cnt
> 0) {
1725 if (mm
->perf_stats_en
)
1726 vty_out(vty
, " Max-Commit-Duration: \t\t%lu uSecs\n",
1727 adapter
->cmt_stats
.max_tm
);
1728 vty_out(vty
, " Max-Commit-Batch-Size: \t\t%lu\n",
1729 adapter
->cmt_stats
.max_batch_cnt
);
1730 if (mm
->perf_stats_en
)
1731 vty_out(vty
, " Min-Commit-Duration: \t\t%lu uSecs\n",
1732 adapter
->cmt_stats
.min_tm
);
1733 vty_out(vty
, " Min-Commit-Batch-Size: \t\t%lu\n",
1734 adapter
->cmt_stats
.min_batch_cnt
);
1735 if (mm
->perf_stats_en
)
1737 " Last-Commit-Duration: \t\t%lu uSecs\n",
1738 adapter
->cmt_stats
.last_exec_tm
);
1739 vty_out(vty
, " Last-Commit-Batch-Size: \t\t%lu\n",
1740 adapter
->cmt_stats
.last_batch_cnt
);
1741 vty_out(vty
, " Last-Commit-CfgData-Reqs: \t\t%lu\n",
1742 adapter
->cmt_stats
.last_num_cfgdata_reqs
);
1743 vty_out(vty
, " Last-Commit-CfgApply-Reqs: \t\t%lu\n",
1744 adapter
->cmt_stats
.last_num_apply_reqs
);
1745 if (mm
->perf_stats_en
) {
1746 vty_out(vty
, " Last-Commit-Details:\n");
1747 vty_out(vty
, " Commit Start: \t\t\t%s\n",
1748 mgmt_realtime_to_string(
1749 &adapter
->cmt_stats
.last_start
, buf
,
1751 #ifdef MGMTD_LOCAL_VALIDATIONS_ENABLED
1752 vty_out(vty
, " Config-Validate Start: \t\t%s\n",
1753 mgmt_realtime_to_string(
1754 &adapter
->cmt_stats
.validate_start
, buf
,
1757 vty_out(vty
, " Prep-Config Start: \t\t%s\n",
1758 mgmt_realtime_to_string(
1759 &adapter
->cmt_stats
.prep_cfg_start
, buf
,
1761 vty_out(vty
, " Txn-Create Start: \t\t%s\n",
1762 mgmt_realtime_to_string(
1763 &adapter
->cmt_stats
.txn_create_start
,
1766 #ifdef MGMTD_LOCAL_VALIDATIONS_ENABLED
1767 " Send-Config Start: \t\t%s\n",
1769 " Send-Config-Validate Start: \t%s\n",
1771 mgmt_realtime_to_string(
1772 &adapter
->cmt_stats
.send_cfg_start
, buf
,
1774 vty_out(vty
, " Apply-Config Start: \t\t%s\n",
1775 mgmt_realtime_to_string(
1776 &adapter
->cmt_stats
.apply_cfg_start
,
1778 vty_out(vty
, " Apply-Config End: \t\t%s\n",
1779 mgmt_realtime_to_string(
1780 &adapter
->cmt_stats
.apply_cfg_end
, buf
,
1782 vty_out(vty
, " Txn-Delete Start: \t\t%s\n",
1783 mgmt_realtime_to_string(
1784 &adapter
->cmt_stats
.txn_del_start
, buf
,
1786 vty_out(vty
, " Commit End: \t\t\t%s\n",
1787 mgmt_realtime_to_string(
1788 &adapter
->cmt_stats
.last_end
, buf
,
1795 mgmt_fe_adapter_setcfg_stats_write(struct vty
*vty
,
1796 struct mgmt_fe_client_adapter
*adapter
)
1798 char buf
[MGMT_LONG_TIME_MAX_LEN
];
1800 if (!mm
->perf_stats_en
)
1803 vty_out(vty
, " Num-Set-Cfg: \t\t\t%lu\n",
1804 adapter
->setcfg_stats
.set_cfg_count
);
1805 if (mm
->perf_stats_en
&& adapter
->setcfg_stats
.set_cfg_count
> 0) {
1806 vty_out(vty
, " Max-Set-Cfg-Duration: \t\t%lu uSec\n",
1807 adapter
->setcfg_stats
.max_tm
);
1808 vty_out(vty
, " Min-Set-Cfg-Duration: \t\t%lu uSec\n",
1809 adapter
->setcfg_stats
.min_tm
);
1810 vty_out(vty
, " Avg-Set-Cfg-Duration: \t\t%lu uSec\n",
1811 adapter
->setcfg_stats
.avg_tm
);
1812 vty_out(vty
, " Last-Set-Cfg-Details:\n");
1813 vty_out(vty
, " Set-Cfg Start: \t\t\t%s\n",
1814 mgmt_realtime_to_string(
1815 &adapter
->setcfg_stats
.last_start
, buf
,
1817 vty_out(vty
, " Set-Cfg End: \t\t\t%s\n",
1818 mgmt_realtime_to_string(&adapter
->setcfg_stats
.last_end
,
1823 void mgmt_fe_adapter_status_write(struct vty
*vty
, bool detail
)
1825 struct mgmt_fe_client_adapter
*adapter
;
1826 struct mgmt_fe_session_ctx
*session
;
1827 Mgmtd__DatastoreId ds_id
;
1828 bool locked
= false;
1830 vty_out(vty
, "MGMTD Frontend Adpaters\n");
1832 FOREACH_ADAPTER_IN_LIST (adapter
) {
1833 vty_out(vty
, " Client: \t\t\t\t%s\n", adapter
->name
);
1834 vty_out(vty
, " Conn-FD: \t\t\t\t%d\n", adapter
->conn_fd
);
1836 mgmt_fe_adapter_setcfg_stats_write(vty
, adapter
);
1837 mgmt_fe_adapter_cmt_stats_write(vty
, adapter
);
1839 vty_out(vty
, " Sessions\n");
1840 FOREACH_SESSION_IN_LIST (adapter
, session
) {
1841 vty_out(vty
, " Session: \t\t\t\t%p\n", session
);
1842 vty_out(vty
, " Client-Id: \t\t\t%llu\n",
1843 (unsigned long long)session
->client_id
);
1844 vty_out(vty
, " Session-Id: \t\t\t%llx\n",
1845 (unsigned long long)session
->session_id
);
1846 vty_out(vty
, " DS-Locks:\n");
1847 FOREACH_MGMTD_DS_ID (ds_id
) {
1848 if (session
->ds_write_locked
[ds_id
]
1849 || session
->ds_read_locked
[ds_id
]) {
1852 " %s\t\t\t%s, %s\n",
1853 mgmt_ds_id2name(ds_id
),
1854 session
->ds_write_locked
[ds_id
]
1857 session
->ds_locked_implict
[ds_id
]
1863 vty_out(vty
, " None\n");
1865 vty_out(vty
, " Total-Sessions: \t\t\t%d\n",
1866 (int)mgmt_fe_sessions_count(&adapter
->fe_sessions
));
1867 vty_out(vty
, " Msg-Recvd: \t\t\t\t%" PRIu64
"\n",
1868 adapter
->mstate
.nrxm
);
1869 vty_out(vty
, " Bytes-Recvd: \t\t\t%" PRIu64
"\n",
1870 adapter
->mstate
.nrxb
);
1871 vty_out(vty
, " Msg-Sent: \t\t\t\t%" PRIu64
"\n",
1872 adapter
->mstate
.ntxm
);
1873 vty_out(vty
, " Bytes-Sent: \t\t\t%" PRIu64
"\n",
1874 adapter
->mstate
.ntxb
);
1876 vty_out(vty
, " Total: %d\n",
1877 (int)mgmt_fe_adapters_count(&mgmt_fe_adapters
));
1880 void mgmt_fe_adapter_perf_measurement(struct vty
*vty
, bool config
)
1882 mm
->perf_stats_en
= config
;
1885 void mgmt_fe_adapter_reset_perf_stats(struct vty
*vty
)
1887 struct mgmt_fe_client_adapter
*adapter
;
1888 struct mgmt_fe_session_ctx
*session
;
1890 FOREACH_ADAPTER_IN_LIST (adapter
) {
1891 memset(&adapter
->setcfg_stats
, 0,
1892 sizeof(adapter
->setcfg_stats
));
1893 FOREACH_SESSION_IN_LIST (adapter
, session
) {
1894 memset(&adapter
->cmt_stats
, 0,
1895 sizeof(adapter
->cmt_stats
));