Пример #1
0
/********************************************************************
 * FUNCTION do_release_locks (local RPC)
 * 
 * release all the locks on the server
 *
 * INPUTS:
 *    server_cb == server control block to use
 *    rpc == RPC method for the history command
 *    line == CLI input in progress
 *    len == offset into line buffer to start parsing
 *
 * RETURNS:
 *   status
 *********************************************************************/
status_t
    do_release_locks (server_cb_t *server_cb,
                      obj_template_t *rpc,
                      const xmlChar *line,
                      uint32  len)
{
    ses_cb_t      *scb;
    val_value_t   *valset;
    uint32         locks_timeout, retry_interval;
    boolean        cleanup, done, needed;
    status_t       res;

    if (!server_cb->locks_active) {
        log_error("\nError: locks are not active");
        return ERR_NCX_OPERATION_FAILED;
    }
    scb = mgr_ses_get_scb(server_cb->mysid);
    if (scb == NULL) {
        log_error("\nError: active session dropped, cannot lock");
        return ERR_NCX_OPERATION_FAILED;
    }

    locks_timeout = server_cb->locks_timeout;
    retry_interval = server_cb->locks_retry_interval;
    cleanup = TRUE;

    res = NO_ERR;
    valset = get_valset(server_cb, rpc, &line[len], &res);
    if (res == NO_ERR || res == ERR_NCX_SKIPPED) {

        /* start the auto-unlock procedure */
        server_cb->locks_timeout = locks_timeout;
        server_cb->locks_retry_interval = retry_interval;
        server_cb->locks_cleanup = cleanup;
        needed = setup_unlock_cbs(server_cb);

        if (LOGINFO && needed) {
            log_info("\nSending <unlock> operations for release-locks...\n");
        }

        if (needed) {
            done = FALSE;
            res = handle_release_locks_request_to_server(server_cb,
                                                        TRUE,
                                                        &done);
            if (done) {
                /* need to close the session or report fatal error */
                clear_lock_cbs(server_cb);
            }
        }
    }

    if (valset != NULL) {
        val_free_value(valset);
    }

    return res;

}  /* do_release_locks */
Пример #2
0
/********************************************************************
 * FUNCTION do_show_session (sub-mode of local RPC)
 * 
 * show session startup screen
 *
 * INPUTS:
 *  server_cb == server control block to use
 *  mode == help mode
 *********************************************************************/
static void
    do_show_session (server_cb_t *server_cb,
                     help_mode_t mode)
{
    session_cb_t *session_cb = server_cb->cur_session_cb;
    ses_cb_t *scb = mgr_ses_get_scb(session_cb->mysid);
    if (scb == NULL) {
        /* session was dropped */
        log_write("\nError: No session available."
                  " Not connected to any server.\n");
        return;
    }

    report_capabilities(server_cb, session_cb, scb, FALSE, mode);
    log_write("\n");

}  /* do_show_session */
Пример #3
0
/********************************************************************
 * FUNCTION get_del_op
 * 
 * Check if remove operation allowed, or just delete
 *
 * INPUTS:
 *    session_cb == session control block to use
 * RETURNS:
 *    delete operation to use (OP_EDITOP_DELETE or OP_EDITOP_REMOVE)
 *********************************************************************/
static op_editop_t 
    get_del_op (session_cb_t *session_cb)
{
    ses_cb_t *scb = mgr_ses_get_scb(session_cb->mysid);
    if (scb == NULL) {
        return OP_EDITOP_DELETE;
    }

    switch (ses_get_protocol(scb)) {
    case NCX_PROTO_NETCONF10:
        return OP_EDITOP_DELETE;
    case NCX_PROTO_NETCONF11:
        return OP_EDITOP_REMOVE;
    default:
        return OP_EDITOP_DELETE;
    }

}  /* get_del_op */
Пример #4
0
/********************************************************************
* FUNCTION setup_lock_cbs
* 
* Setup the lock state info in all the lock control blocks
* in the specified server_cb; call when a new sesion is started
* 
* INPUTS:
*  server_cb == server control block to use
*********************************************************************/
static void
    setup_lock_cbs (server_cb_t *server_cb)
{
    ses_cb_t     *scb;
    mgr_scb_t    *mscb;
    ncx_cfg_t     cfg_id;

    scb = mgr_ses_get_scb(server_cb->mysid);
    if (scb == NULL) {
        log_error("\nError: active session dropped, cannot lock");
        return;
    }

    mscb = (mgr_scb_t *)scb->mgrcb;
    server_cb->locks_active = TRUE;
    server_cb->locks_waiting = FALSE;
    server_cb->locks_cur_cfg = NCX_CFGID_RUNNING;

    for (cfg_id = NCX_CFGID_RUNNING;
         cfg_id <= NCX_CFGID_STARTUP;
         cfg_id++) {

        server_cb->lock_cb[cfg_id].lock_state = LOCK_STATE_IDLE;
        server_cb->lock_cb[cfg_id].lock_used = FALSE;
        server_cb->lock_cb[cfg_id].start_time = (time_t)0;
        server_cb->lock_cb[cfg_id].last_msg_time = (time_t)0;
    }

    /* always request the lock on running */
    server_cb->lock_cb[NCX_CFGID_RUNNING].lock_used = TRUE;

    server_cb->lock_cb[NCX_CFGID_CANDIDATE].lock_used = 
        (cap_std_set(&mscb->caplist, CAP_STDID_CANDIDATE))
        ? TRUE : FALSE;

    server_cb->lock_cb[NCX_CFGID_STARTUP].lock_used =
        (cap_std_set(&mscb->caplist, CAP_STDID_STARTUP))
        ? TRUE : FALSE;

}  /* setup_lock_cbs */
Пример #5
0
/********************************************************************
* FUNCTION send_discard_changes_pdu_to_server
* 
* Send a <discard-changes> operation to the server
*
* INPUTS:
*   server_cb == server control block to use
*
* RETURNS:
*    status
*********************************************************************/
status_t
    send_discard_changes_pdu_to_server (server_cb_t *server_cb)
{
    obj_template_t        *rpc;
    mgr_rpc_req_t         *req;
    val_value_t           *reqdata;
    ses_cb_t              *scb;
    status_t               res;
    xmlns_id_t             obj_nsid;

    req = NULL;
    reqdata = NULL;
    res = NO_ERR;

    if (LOGDEBUG) {
        log_debug("\nSending <discard-changes> request");
    }
    
    rpc = ncx_find_object(get_netconf_mod(server_cb), 
                          NCX_EL_DISCARD_CHANGES);
    if (!rpc) {
        return SET_ERROR(ERR_NCX_DEF_NOT_FOUND);
    }

    obj_nsid = obj_get_nsid(rpc);

    /* construct a method node */
    reqdata = xml_val_new_flag(obj_get_name(rpc), 
                               obj_nsid);
    if (!reqdata) {
        log_error("\nError allocating a new RPC request");
        return ERR_INTERNAL_MEM;
    }

    scb = mgr_ses_get_scb(server_cb->mysid);
    if (!scb) {
        res = SET_ERROR(ERR_INTERNAL_PTR);
    } else {
        req = mgr_rpc_new_request(scb);
        if (!req) {
            res = ERR_INTERNAL_MEM;
            log_error("\nError allocating a new RPC request");
        } else {
            req->data = reqdata;
            req->rpc = rpc;
            req->timeout = server_cb->timeout;
        }
    }
        
    /* if all OK, send the RPC request */
    if (res == NO_ERR) {
        if (LOGDEBUG2) {
            log_debug2("\nabout to send RPC request with reqdata:");
            val_dump_value_max(reqdata, 
                               0,
                               server_cb->defindent,
                               DUMP_VAL_LOG,
                               server_cb->display_mode,
                               FALSE,
                               FALSE);
        }

        /* the request will be stored if this returns NO_ERR */
        res = mgr_rpc_send_request(scb, req, yangcli_reply_handler);
        if (res == NO_ERR) {
            server_cb->command_mode = CMD_MODE_AUTODISCARD;
        }
    }

    /* cleanup and set next state */
    if (res != NO_ERR) {
        if (req) {
            mgr_rpc_free_request(req);
        } else if (reqdata) {
            val_free_value(reqdata);
        }
    } else {
        server_cb->state = MGR_IO_ST_CONN_RPYWAIT;
    }

    return res;

} /* send_discard_changes_pdu_to_server */
Пример #6
0
/********************************************************************
 * FUNCTION do_get_locks (local RPC)
 * 
 * get all the locks on the server
 *
 * INPUTS:
 *    server_cb == server control block to use
 *    rpc == RPC method for the history command
 *    line == CLI input in progress
 *    len == offset into line buffer to start parsing
 *
 * RETURNS:
 *   status
 *********************************************************************/
status_t
    do_get_locks (server_cb_t *server_cb,
                  obj_template_t *rpc,
                  const xmlChar *line,
                  uint32  len)
{
    ses_cb_t      *scb;
    val_value_t   *valset, *parm;
    uint32         locks_timeout, retry_interval;
    boolean        cleanup, done;
    status_t       res;

    if (server_cb->locks_active) {
        log_error("\nError: locks are already active");
        return ERR_NCX_OPERATION_FAILED;
    }
    if (server_cb->state != MGR_IO_ST_CONN_IDLE) {
        log_error("\nError: no active session to lock");
        return ERR_NCX_OPERATION_FAILED;
    }

    scb = mgr_ses_get_scb(server_cb->mysid);
    if (scb == NULL) {
        log_error("\nError: active session dropped, cannot lock");
        return ERR_NCX_OPERATION_FAILED;
    }

    locks_timeout = server_cb->locks_timeout;
    retry_interval = server_cb->locks_retry_interval;
    cleanup = TRUE;

    res = NO_ERR;

    valset = get_valset(server_cb, rpc, &line[len], &res);
    if (valset && res == NO_ERR) {
        /* get the overall lock timeout */
        parm = val_find_child(valset, 
                              YANGCLI_MOD, 
                              YANGCLI_LOCK_TIMEOUT);
        if (parm && parm->res == NO_ERR) {
            locks_timeout = VAL_UINT(parm);
        }

        /* get the retry interval between failed locks */
        parm = val_find_child(valset, 
                              YANGCLI_MOD, 
                              YANGCLI_RETRY_INTERVAL);
        if (parm && parm->res == NO_ERR) {
            retry_interval = VAL_UINT(parm);
        }

        /* get the auto-cleanup flag */
        parm = val_find_child(valset, 
                              YANGCLI_MOD, 
                              YANGCLI_CLEANUP);
        if (parm && parm->res == NO_ERR) {
            cleanup = VAL_BOOL(parm);
        }
    }

    /* start the auto-lock procedure */
    setup_lock_cbs(server_cb);
    server_cb->locks_timeout = locks_timeout;
    server_cb->locks_retry_interval = retry_interval;
    server_cb->locks_cleanup = cleanup;

    done = FALSE;
    if (LOGINFO) {
        log_info("\nSending <lock> operations for get-locks...\n");
    }
    res = handle_get_locks_request_to_server(server_cb,
                                            TRUE,
                                            &done);
    if (res != NO_ERR && done) {
        /* need to undo the whole thing; whatever got done */

    }

    if (valset != NULL) {
        val_free_value(valset);
    }

    return res;

}  /* do_get_locks */
Пример #7
0
/********************************************************************
* FUNCTION send_lock_pdu_to_server
* 
* Send a <lock> or <unlock> operation to the server
*
* INPUTS:
*   server_cb == server control block to use
*   lockcb == lock control block to use within server_cb
*   islock == TRUE for lock; FALSE for unlock
*
* RETURNS:
*    status
*********************************************************************/
static status_t
    send_lock_pdu_to_server (server_cb_t *server_cb,
                            lock_cb_t *lockcb,
                            boolean islock)
{
    obj_template_t        *rpc, *input;
    mgr_rpc_req_t         *req;
    val_value_t           *reqdata, *targetval, *parmval;
    ses_cb_t              *scb;
    status_t               res;
    xmlns_id_t             obj_nsid;

    req = NULL;
    reqdata = NULL;
    res = NO_ERR;

    if (LOGDEBUG) {
        log_debug("\nSending <%s> request",
                  (islock) ? NCX_EL_LOCK : NCX_EL_UNLOCK);
    }

    if (islock) {
        rpc = ncx_find_object(get_netconf_mod(server_cb), 
                              NCX_EL_LOCK);
    } else {
        rpc = ncx_find_object(get_netconf_mod(server_cb), 
                              NCX_EL_UNLOCK);
    }
    if (!rpc) {
        return SET_ERROR(ERR_NCX_DEF_NOT_FOUND);
    }

    obj_nsid = obj_get_nsid(rpc);

    /* get the 'input' section container */
    input = obj_find_child(rpc, NULL, YANG_K_INPUT);
    if (!input) {
        return SET_ERROR(ERR_NCX_DEF_NOT_FOUND);
    }

    /* construct a method + parameter tree */
    reqdata = xml_val_new_struct(obj_get_name(rpc), obj_nsid);
    if (!reqdata) {
        log_error("\nError allocating a new RPC request");
        return ERR_INTERNAL_MEM;
    }

    /* set the [un]lock/input/target node XML namespace */
    targetval = xml_val_new_struct(NCX_EL_TARGET, obj_nsid);
    if (!targetval) {
        log_error("\nError allocating a new RPC request");
        val_free_value(reqdata);
        return ERR_INTERNAL_MEM;
    } else {
        val_add_child(targetval, reqdata);
    }

    parmval = xml_val_new_flag(lockcb->config_name,
                               obj_nsid);
    if (!parmval) {
        val_free_value(reqdata);
        return ERR_INTERNAL_MEM;
    } else {
        val_add_child(parmval, targetval);
    }

    scb = mgr_ses_get_scb(server_cb->mysid);
    if (!scb) {
        res = SET_ERROR(ERR_INTERNAL_PTR);
    } else {
        req = mgr_rpc_new_request(scb);
        if (!req) {
            res = ERR_INTERNAL_MEM;
            log_error("\nError allocating a new RPC request");
        } else {
            req->data = reqdata;
            req->rpc = rpc;
            req->timeout = server_cb->timeout;
        }
    }
        
    /* if all OK, send the RPC request */
    if (res == NO_ERR) {
        if (LOGDEBUG2) {
            log_debug2("\nabout to send RPC request with reqdata:");
            val_dump_value_max(reqdata, 
                               0,
                               server_cb->defindent,
                               DUMP_VAL_LOG,
                               server_cb->display_mode,
                               FALSE,
                               FALSE);
        }

        /* the request will be stored if this returns NO_ERR */
        res = mgr_rpc_send_request(scb, req, yangcli_reply_handler);
        if (res == NO_ERR) {
            if (islock) {
                lockcb->lock_state = LOCK_STATE_REQUEST_SENT;
            } else {
                lockcb->lock_state = LOCK_STATE_RELEASE_SENT;
            }
            (void)uptime(&lockcb->last_msg_time);
            server_cb->locks_cur_cfg = lockcb->config_id;
        }
    }

    /* cleanup and set next state */
    if (res != NO_ERR) {
        if (req) {
            mgr_rpc_free_request(req);
        } else if (reqdata) {
            val_free_value(reqdata);
        }
    } else {
        server_cb->state = MGR_IO_ST_CONN_RPYWAIT;
    }

    return res;

} /* send_lock_pdu_to_server */