Skip to content

Commit

Permalink
Merge pull request #4132 from opensourcerouting/northbound-debug
Browse files Browse the repository at this point in the history
lib: add fine-grained debugging in the northbound
  • Loading branch information
Mark Stapp committed Apr 16, 2019
2 parents c74fea1 + 9eb2c0a commit ce3c7c2
Show file tree
Hide file tree
Showing 6 changed files with 311 additions and 65 deletions.
2 changes: 1 addition & 1 deletion lib/debug.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static const struct debug_callbacks *callbacks;
DEFUN_NOSH(debug_all, debug_all_cmd, "[no] debug all", DEFUN_NOSH(debug_all, debug_all_cmd, "[no] debug all",
NO_STR DEBUG_STR "Toggle all debugging output\n") NO_STR DEBUG_STR "Toggle all debugging output\n")
{ {
bool set = strmatch(argv[0]->text, "no"); bool set = !strmatch(argv[0]->text, "no");
uint32_t mode = DEBUG_NODE2MODE(vty->node); uint32_t mode = DEBUG_NODE2MODE(vty->node);


if (callbacks->debug_set_all) if (callbacks->debug_set_all)
Expand Down
86 changes: 71 additions & 15 deletions lib/northbound.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "log.h" #include "log.h"
#include "lib_errors.h" #include "lib_errors.h"
#include "command.h" #include "command.h"
#include "debug.h"
#include "db.h" #include "db.h"
#include "northbound.h" #include "northbound.h"
#include "northbound_cli.h" #include "northbound_cli.h"
Expand All @@ -40,7 +41,7 @@ struct nb_config *running_config;
*/ */
static bool transaction_in_progress; static bool transaction_in_progress;


static int nb_configuration_callback(const enum nb_event event, static int nb_callback_configuration(const enum nb_event event,
struct nb_config_change *change); struct nb_config_change *change);
static struct nb_transaction *nb_transaction_new(struct nb_config *config, static struct nb_transaction *nb_transaction_new(struct nb_config *config,
struct nb_config_cbs *changes, struct nb_config_cbs *changes,
Expand Down Expand Up @@ -592,7 +593,7 @@ static int nb_candidate_validate_changes(struct nb_config *candidate,
struct nb_config_change *change = (struct nb_config_change *)cb; struct nb_config_change *change = (struct nb_config_change *)cb;
int ret; int ret;


ret = nb_configuration_callback(NB_EV_VALIDATE, change); ret = nb_callback_configuration(NB_EV_VALIDATE, change);
if (ret != NB_OK) if (ret != NB_OK)
return NB_ERR_VALIDATION; return NB_ERR_VALIDATION;
} }
Expand Down Expand Up @@ -714,7 +715,7 @@ static void nb_log_callback(const enum nb_event event,
* Call the northbound configuration callback associated to a given * Call the northbound configuration callback associated to a given
* configuration change. * configuration change.
*/ */
static int nb_configuration_callback(const enum nb_event event, static int nb_callback_configuration(const enum nb_event event,
struct nb_config_change *change) struct nb_config_change *change)
{ {
enum nb_operation operation = change->cb.operation; enum nb_operation operation = change->cb.operation;
Expand All @@ -724,7 +725,7 @@ static int nb_configuration_callback(const enum nb_event event,
union nb_resource *resource; union nb_resource *resource;
int ret = NB_ERR; int ret = NB_ERR;


if (debug_northbound) { if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) {
const char *value = "(none)"; const char *value = "(none)";


if (dnode && !yang_snode_is_typeless_data(dnode->schema)) if (dnode && !yang_snode_is_typeless_data(dnode->schema))
Expand Down Expand Up @@ -791,6 +792,57 @@ static int nb_configuration_callback(const enum nb_event event,
return ret; return ret;
} }


struct yang_data *nb_callback_get_elem(const struct nb_node *nb_node,
const char *xpath,
const void *list_entry)
{
DEBUGD(&nb_dbg_cbs_state,
"northbound callback (get_elem): xpath [%s] list_entry [%p]",
xpath, list_entry);

return nb_node->cbs.get_elem(xpath, list_entry);
}

const void *nb_callback_get_next(const struct nb_node *nb_node,
const void *parent_list_entry,
const void *list_entry)
{
DEBUGD(&nb_dbg_cbs_state,
"northbound callback (get_next): node [%s] parent_list_entry [%p] list_entry [%p]",
nb_node->xpath, parent_list_entry, list_entry);

return nb_node->cbs.get_next(parent_list_entry, list_entry);
}

int nb_callback_get_keys(const struct nb_node *nb_node, const void *list_entry,
struct yang_list_keys *keys)
{
DEBUGD(&nb_dbg_cbs_state,
"northbound callback (get_keys): node [%s] list_entry [%p]",
nb_node->xpath, list_entry);

return nb_node->cbs.get_keys(list_entry, keys);
}

const void *nb_callback_lookup_entry(const struct nb_node *nb_node,
const void *parent_list_entry,
const struct yang_list_keys *keys)
{
DEBUGD(&nb_dbg_cbs_state,
"northbound callback (lookup_entry): node [%s] parent_list_entry [%p]",
nb_node->xpath, parent_list_entry);

return nb_node->cbs.lookup_entry(parent_list_entry, keys);
}

int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
const struct list *input, struct list *output)
{
DEBUGD(&nb_dbg_cbs_rpc, "northbound RPC: %s", xpath);

return nb_node->cbs.rpc(xpath, input, output);
}

static struct nb_transaction *nb_transaction_new(struct nb_config *config, static struct nb_transaction *nb_transaction_new(struct nb_config *config,
struct nb_config_cbs *changes, struct nb_config_cbs *changes,
enum nb_client client, enum nb_client client,
Expand Down Expand Up @@ -843,7 +895,7 @@ static int nb_transaction_process(enum nb_event event,
break; break;


/* Call the appropriate callback. */ /* Call the appropriate callback. */
ret = nb_configuration_callback(event, change); ret = nb_callback_configuration(event, change);
switch (event) { switch (event) {
case NB_EV_PREPARE: case NB_EV_PREPARE:
if (ret != NB_OK) if (ret != NB_OK)
Expand Down Expand Up @@ -958,7 +1010,7 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction)


/* Call the 'apply_finish' callbacks, sorted by their priorities. */ /* Call the 'apply_finish' callbacks, sorted by their priorities. */
RB_FOREACH (cb, nb_config_cbs, &cbs) { RB_FOREACH (cb, nb_config_cbs, &cbs) {
if (debug_northbound) if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL))
nb_log_callback(NB_EV_APPLY, NB_OP_APPLY_FINISH, nb_log_callback(NB_EV_APPLY, NB_OP_APPLY_FINISH,
cb->xpath, NULL); cb->xpath, NULL);


Expand Down Expand Up @@ -1010,7 +1062,7 @@ static int nb_oper_data_iter_leaf(const struct nb_node *nb_node,
if (lys_is_key((struct lys_node_leaf *)nb_node->snode, NULL)) if (lys_is_key((struct lys_node_leaf *)nb_node->snode, NULL))
return NB_OK; return NB_OK;


data = nb_node->cbs.get_elem(xpath, list_entry); data = nb_callback_get_elem(nb_node, xpath, list_entry);
if (data == NULL) if (data == NULL)
/* Leaf of type "empty" is not present. */ /* Leaf of type "empty" is not present. */
return NB_OK; return NB_OK;
Expand All @@ -1034,7 +1086,7 @@ static int nb_oper_data_iter_container(const struct nb_node *nb_node,
struct yang_data *data; struct yang_data *data;
int ret; int ret;


data = nb_node->cbs.get_elem(xpath, list_entry); data = nb_callback_get_elem(nb_node, xpath, list_entry);
if (data == NULL) if (data == NULL)
/* Presence container is not present. */ /* Presence container is not present. */
return NB_OK; return NB_OK;
Expand Down Expand Up @@ -1066,13 +1118,13 @@ nb_oper_data_iter_leaflist(const struct nb_node *nb_node, const char *xpath,
struct yang_data *data; struct yang_data *data;
int ret; int ret;


list_entry = list_entry = nb_callback_get_next(nb_node, parent_list_entry,
nb_node->cbs.get_next(parent_list_entry, list_entry); list_entry);
if (!list_entry) if (!list_entry)
/* End of the list. */ /* End of the list. */
break; break;


data = nb_node->cbs.get_elem(xpath, list_entry); data = nb_callback_get_elem(nb_node, xpath, list_entry);
if (data == NULL) if (data == NULL)
continue; continue;


Expand Down Expand Up @@ -1105,15 +1157,16 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node,
int ret; int ret;


/* Obtain list entry. */ /* Obtain list entry. */
list_entry = list_entry = nb_callback_get_next(nb_node, parent_list_entry,
nb_node->cbs.get_next(parent_list_entry, list_entry); list_entry);
if (!list_entry) if (!list_entry)
/* End of the list. */ /* End of the list. */
break; break;


if (!CHECK_FLAG(nb_node->flags, F_NB_NODE_KEYLESS_LIST)) { if (!CHECK_FLAG(nb_node->flags, F_NB_NODE_KEYLESS_LIST)) {
/* Obtain the list entry keys. */ /* Obtain the list entry keys. */
if (nb_node->cbs.get_keys(list_entry, &list_keys) if (nb_callback_get_keys(nb_node, list_entry,
&list_keys)
!= NB_OK) { != NB_OK) {
flog_warn(EC_LIB_NB_CB_STATE, flog_warn(EC_LIB_NB_CB_STATE,
"%s: failed to get list keys", "%s: failed to get list keys",
Expand Down Expand Up @@ -1291,7 +1344,8 @@ int nb_oper_data_iterate(const char *xpath, struct yang_translator *translator,


/* Find the list entry pointer. */ /* Find the list entry pointer. */
nn = dn->schema->priv; nn = dn->schema->priv;
list_entry = nn->cbs.lookup_entry(list_entry, &list_keys); list_entry =
nb_callback_lookup_entry(nn, list_entry, &list_keys);
if (list_entry == NULL) { if (list_entry == NULL) {
list_delete(&list_dnodes); list_delete(&list_dnodes);
yang_dnode_free(dnode); yang_dnode_free(dnode);
Expand Down Expand Up @@ -1485,6 +1539,8 @@ int nb_notification_send(const char *xpath, struct list *arguments)
{ {
int ret; int ret;


DEBUGD(&nb_dbg_notif, "northbound notification: %s", xpath);

ret = hook_call(nb_notification_send, xpath, arguments); ret = hook_call(nb_notification_send, xpath, arguments);
if (arguments) if (arguments)
list_delete(&arguments); list_delete(&arguments);
Expand Down
29 changes: 28 additions & 1 deletion lib/northbound.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ extern "C" {


/* Forward declaration(s). */ /* Forward declaration(s). */
struct vty; struct vty;
struct debug;


/* Northbound events. */ /* Northbound events. */
enum nb_event { enum nb_event {
Expand Down Expand Up @@ -458,12 +459,38 @@ typedef int (*nb_oper_data_cb)(const struct lys_node *snode,
/* Iterate over direct child nodes only. */ /* Iterate over direct child nodes only. */
#define NB_OPER_DATA_ITER_NORECURSE 0x0001 #define NB_OPER_DATA_ITER_NORECURSE 0x0001


/* Hooks. */
DECLARE_HOOK(nb_notification_send, (const char *xpath, struct list *arguments), DECLARE_HOOK(nb_notification_send, (const char *xpath, struct list *arguments),
(xpath, arguments)) (xpath, arguments))
DECLARE_HOOK(nb_client_debug_config_write, (struct vty *vty), (vty))
DECLARE_HOOK(nb_client_debug_set_all, (uint32_t flags, bool set), (flags, set))


extern int debug_northbound; /* Northbound debugging records */
extern struct debug nb_dbg_cbs_config;
extern struct debug nb_dbg_cbs_state;
extern struct debug nb_dbg_cbs_rpc;
extern struct debug nb_dbg_notif;
extern struct debug nb_dbg_events;

/* Global running configuration. */
extern struct nb_config *running_config; extern struct nb_config *running_config;


/* Wrappers for the northbound callbacks. */
extern struct yang_data *nb_callback_get_elem(const struct nb_node *nb_node,
const char *xpath,
const void *list_entry);
extern const void *nb_callback_get_next(const struct nb_node *nb_node,
const void *parent_list_entry,
const void *list_entry);
extern int nb_callback_get_keys(const struct nb_node *nb_node,
const void *list_entry,
struct yang_list_keys *keys);
extern const void *nb_callback_lookup_entry(const struct nb_node *nb_node,
const void *parent_list_entry,
const struct yang_list_keys *keys);
extern int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
const struct list *input, struct list *output);

/* /*
* Create a northbound node for all YANG schema nodes. * Create a northbound node for all YANG schema nodes.
*/ */
Expand Down
Loading

0 comments on commit ce3c7c2

Please sign in to comment.