The DB-API database variant allows an external process to initiate database edits, that are processed by the server as user or system edits.

The DB-API functions described in the this article can be used by the subsystem to edit the server configuration database.

This variant can be used with other variants for processing non-volatile storage. This variant is used to co-exist with a legacy or canonical database owned by the system.

 Configuration properties:

  • Tree-based data structures in memory for run-time transaction processing

  • This may or may not be the canonical database, depending on the non-volatile storage options.

  • There may be another database in the system

  • The server uses its copy in memory as the complete database

  • The DB-API “send_edit” and “send_edit_ex” API functions can be used to transfer configuration from the system to netconfd-pro.

  • Data is transferred in XML

  • Error responses are sent by the server if an edit is not accepted.

  • An error will be returned if a client is already in the process of editing the database

  • The db-api-app application is installed in /usr/share/yumapro/src/db-api-app by default, and includes some examples of initializing the DB-API service and sending edits to the server

DB-API Examples

The DB-API subsystem allows an external process on the same system as netconfd-pro to send database edits to the server.

  • db_api_register_service

  • db_api_service_ready

  • db_api_send_edit

  • db_api_send_edit_ex

  • db_api_send_edit_full

  • db_api_check_edit

extern status_t
    db_api_register_service (void);

extern boolean
    db_api_service_ready (void);

extern status_t
    db_api_send_edit (const xmlChar *edit_target,
                      const xmlChar *edit_operation,
                      const xmlChar *edit_xml_value);

extern status_t
    db_api_send_edit_ex (const xmlChar *edit_target,
                         const xmlChar *edit_operation,
                         const xmlChar *edit_xml_value,
                         const xmlChar *patch_id_str,
                         boolean system_edit);

* FUNCTION db_api_send_edit_full
* Create a YANG Patch edit request and send it to the DB-API service
* on the main server.
* The content should represent the intended target resource
* as specified in YANG-API (NOT RESTCONF)
* Only the data resource identifier is provided, not the
* API wrapper identifiers (so this can change when RESTCONF is supported)
* Example leaf:
*   edit_target == /interfaces/interface/eth0/mtu
*   edit_value == "<mtu>9000</mtu>
*   edit_operation == "merge"
*   patch_id_str == "my-patch-x01'
*   system_edit == true
* Example list:
*   edit_operation == <operation string>
*           "create"
*           "delete"
*           "insert"
*           "merge"
*           "move"
*           "replace"
*           "remove"
*   edit_target == /interfaces/interface/eth0/ipv4
*   edit_value == "<ipv4>
*                    <enabled>true</enabled><
*                    <forwarding>true</forwarding>
*                    <address></address>
*                    <prefix-length>24</prefix-length>
*                  </ipv4>"
*   edit_target == target resource (YANG-API path expression)
*   edit_operation == edit operation (create merge replace delete remove)
*   edit_xml_value == XML payload in string form, whitespace allowed
*                     MAY BE NULL if no value required (delete remove))
*   patch_id_str == string to use as the patch ID
*                == NULL to use the default patch-id field
*   system_edit == TRUE if this edit is from the system and should
*                  bypass access control enforcement
*               == FALSE if this edit is from a user and should not
*                  bypass access control enforcement
*   insert_point is a string like the target except a different instance
*             of the same list of leaf-list; only for before, after
*   insert_where == <insert enum string>
*           "before"
*           "after"
*           "first"
*           "last"
*   status
extern status_t
    db_api_send_edit_full (const xmlChar *edit_target,
                           const xmlChar *edit_operation,
                           const xmlChar *edit_xml_value,
                           const xmlChar *patch_id_str,
                           boolean system_edit,
                           const xmlChar *insert_point,
                           const xmlChar *insert_where);

* FUNCTION db_api_check_edit
* Check on the status of an edit in progress
*   status:
*     ERR_NCX_NOT_FOUND if final status and no message
*        response is pending
*     ERR_NCX_SKIPPED if final status is not known yet
*     NO_ERR if there is a last-completed operation that
*        completed with an OK response
*     <errcode> if there is a last-completed operation that
*        completed with an ERROR response
extern status_t
    db_api_check_edit (void);

 Example db-api-app send_edit from ap-api-app.c

* FUNCTION send_test_edit
* This is an example send edit function.
* The module ietf-interfaces needs to be loaded for this to work
static void
    send_test_edit (void)
    /* mef-cfm test */
    const xmlChar *path_str = (const xmlChar *)"/maintenance-domain/mdTest";
    const xmlChar *operation_str = (const xmlChar *)"merge";
    const xmlChar *value_str = (const xmlChar *)
        "<cfm:maintenance-domain xmlns:cfm='"

    const xmlChar *patch_id_str = NULL;
    boolean system_edit = FALSE;
    status_t res = db_api_send_edit_ex(path_str,
    if (res != NO_ERR) {
        log_error("\nSend test edit failed %s %s = %s (%s)\n",
                  operation_str, path_str, value_str,
    } else if (LOGDEBUG) {
        log_debug("\nSend test edit OK  %s %s = %s\n",
                  operation_str, path_str, value_str);

}  /* send_test_edit */

The db-api-app main function example:

* This is an example main function.
*   0 if NO_ERR
*   status code if error connecting or logging into ncxserver
int main (int argc, char **argv)

    /* 1) setup yumapro messaging service profile */
    status_t res = ycontrol_init(argc, argv,
                                 (const xmlChar *)"subsys1");

    /* 2) register services with the control layer */
    if (res == NO_ERR) {
        res = db_api_register_service();

    /* 3) do 2nd stage init of the control manager (connect to server) */
    if (res == NO_ERR) {
        res = ycontrol_init2();

    useconds_t usleep_val = 100000;  // 100K micro-sec == 1/10 sec
    boolean done = FALSE;

    /* 4) call ycontrol_check_io periodically from the main program
     * control loop
    int id = 0;
#endif  // DB_API_APP_DEBUG

    boolean test_done = FALSE;

    while (!done && res == NO_ERR) {
        if (LOGDEBUG3) {
            log_debug3("\ndb-api-app: checking ycontrol IO %d", id++);
#endif  // DB_API_APP_DEBUG

        res = ycontrol_check_io();

        if (ycontrol_shutdown_now()) {
            // YControl has received a <shutdown-event>
            // from the server subsystem is no longer active
            // could ignore or shut down YControl IO loop
            done = TRUE;

        // Using sleep to represent other program work; remove for real
        if (!done && res == NO_ERR) {

        if (db_api_service_ready() && !test_done) {
            test_done = TRUE;


    /* 5) cleanup the control layer before exit */


    return (int)res;

}  /* main */