static void idl_loop_commit_and_wait(struct idl_loop *loop) { if (loop->open_txn) { loop->committing_txn = loop->open_txn; loop->open_txn = NULL; loop->precommit_seqno = ovsdb_idl_get_seqno(loop->idl); } struct ovsdb_idl_txn *txn = loop->committing_txn; if (txn) { enum ovsdb_idl_txn_status status = ovsdb_idl_txn_commit(txn); if (status != TXN_INCOMPLETE) { switch (status) { case TXN_TRY_AGAIN: /* We want to re-evaluate the database when it's changed from * the contents that it had when we started the commit. (That * might have already happened.) */ loop->skip_seqno = loop->precommit_seqno; if (ovsdb_idl_get_seqno(loop->idl) != loop->skip_seqno) { poll_immediate_wake(); } break; case TXN_SUCCESS: /* If the database has already changed since we started the * commit, re-evaluate it immediately to avoid missing a change * for a while. */ if (ovsdb_idl_get_seqno(loop->idl) != loop->precommit_seqno) { poll_immediate_wake(); } break; case TXN_UNCHANGED: case TXN_ABORTED: case TXN_NOT_LOCKED: case TXN_ERROR: break; case TXN_UNCOMMITTED: case TXN_INCOMPLETE: OVS_NOT_REACHED(); } ovsdb_idl_txn_destroy(txn); loop->committing_txn = NULL; } } ovsdb_idl_wait(loop->idl); }
/* Create a connection to the OVSDB at db_path and create a dB cache * for this daemon. */ void classifierd_ovsdb_init(const char *db_path) { VLOG_DBG("%s: db_path = %s\n",__FUNCTION__,db_path); /* Initialize IDL through a new connection to the dB. */ idl = ovsdb_idl_create(db_path, &ovsrec_idl_class, false, true); idl_seqno = ovsdb_idl_get_seqno(idl); ovsdb_idl_set_lock(idl, "ops_classifierd"); /* Reject writes to columns which are not marked write-only using * ovsdb_idl_omit_alert(). */ ovsdb_idl_verify_write_only(idl); /* Choose some OVSDB tables and columns to cache. */ ovsdb_idl_add_table(idl, &ovsrec_table_system); ovsdb_idl_add_table(idl, &ovsrec_table_subsystem); /* Monitor the following columns, marking them read-only. */ ovsdb_idl_add_column(idl, &ovsrec_system_col_cur_cfg); /* Initialize ovsdb interfaces for ACL */ acl_ovsdb_init(idl); } /* classifierd_ovsdb_init */
/* Perform all of the per-loop processing. */ static void daemon_run(void) { unsigned int new_idl_seqno = ovsdb_idl_get_seqno(idl); ovsdb_idl_run(idl); if (ovsdb_idl_is_lock_contended(idl)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); VLOG_ERR_RL(&rl, "another ops-usermgmt process is running, " "disabling this process until it goes away"); return; } else if (!ovsdb_idl_has_lock(idl)) { return; } /* Acquired lock, we're officially ops-usermgmt now. */ if (!populated) { /* First time we got this far, populate database from passwd. */ if (sync_to_db()) populated = true; daemonize_complete(); vlog_enable_async(); VLOG_INFO_ONCE("%s (OpenSwitch usermgmt)", program_name); } if (new_idl_seqno == idl_seqno) return; /* Change in OVSDB detected. */ idl_seqno = new_idl_seqno; sync_from_db(); }
static struct ovsdb_idl_txn * idl_loop_run(struct idl_loop *loop) { ovsdb_idl_run(loop->idl); loop->open_txn = (loop->committing_txn || ovsdb_idl_get_seqno(loop->idl) == loop->skip_seqno ? NULL : ovsdb_idl_txn_create(loop->idl)); return loop->open_txn; }
static int classifierd_reconfigure(void) { int rc = 0; unsigned int new_idl_seqno = 0; const struct ovsrec_port *port_row = NULL; const struct ovsrec_acl *acl_row = NULL; new_idl_seqno = ovsdb_idl_get_seqno(idl); if (new_idl_seqno == idl_seqno) { VLOG_DBG("%s: no change in the db\n",__FUNCTION__); /* There was no change in the dB. */ return 0; } /* get first port row from IDL cache */ port_row = ovsrec_port_first(idl); if(port_row) { /* if port table is not changed then do not go ahead */ if ( (!OVSREC_IDL_ANY_TABLE_ROWS_MODIFIED(port_row, idl_seqno)) && (!OVSREC_IDL_ANY_TABLE_ROWS_INSERTED(port_row, idl_seqno)) && (!OVSREC_IDL_ANY_TABLE_ROWS_DELETED(port_row, idl_seqno)) ) { VLOG_DBG("%s: not a port row change\n",__FUNCTION__); } else { /* Perform ports reconfigure event for ACL */ rc = acl_ports_reconfigure(idl,idl_seqno); } } /* get first acl row from IDL cache */ acl_row = ovsrec_acl_first(idl); if(acl_row) { /* if port table is not changed then do not go ahead */ if ( (!OVSREC_IDL_ANY_TABLE_ROWS_MODIFIED(acl_row, idl_seqno)) && (!OVSREC_IDL_ANY_TABLE_ROWS_INSERTED(acl_row, idl_seqno)) && (!OVSREC_IDL_ANY_TABLE_ROWS_DELETED(acl_row, idl_seqno)) ) { VLOG_DBG("%s: not a acl row change\n",__FUNCTION__); } else { /* Perform acl_list_reconfigure event for ACL */ rc = acl_reconfigure(idl,idl_seqno); } } /* Update idl_seqno after handling all OVSDB updates. */ idl_seqno = new_idl_seqno; /* Setup a poll timer to wake up the daemon */ classifierd_run_timer = true; return rc; } /* classifierd_reconfigure */
static void usermgmt_init(const char *remote) { /* Create connection to OVSDB. */ idl = ovsdb_idl_create(remote, &ovsrec_idl_class, false, true); idl_seqno = ovsdb_idl_get_seqno(idl); ovsdb_idl_set_lock(idl, "ops_usermgmt"); /* Get notified when either of these change. */ ovsdb_idl_add_column(idl, &ovsrec_user_col_username); ovsdb_idl_add_column(idl, &ovsrec_user_col_password); }
/*----------------------------------------------------------------------------- | Function: vtysh_ovsdb_read_config | Responsibility : reads ovsdb config by traversing the vtysh_ovsdb_tables | Parameters: | FILE *fp : file pointer to write data to | Return: void -----------------------------------------------------------------------------*/ void vtysh_ovsdb_read_config(FILE *fp) { vtysh_contextid contextid=0; vtysh_ovsdb_cbmsg msg; VLOG_DBG("readconfig:before- idl 0x%p seq no %d", idl, ovsdb_idl_get_seqno(idl)); msg.fp = fp; msg.idl = idl; msg.contextid = 0; msg.clientid = 0; VLOG_DBG("readconfig:after idl 0x%p seq no %d", idl, ovsdb_idl_get_seqno(idl)); fprintf(fp, "!\n"); for(contextid = 0; contextid < e_vtysh_context_id_max; contextid++) { msg.contextid = contextid; msg.clientid = 0; vtysh_context_iterateoverclients(contextid, &msg); } }
int main(int argc, char *argv[]) { struct ovsdb_idl *idl; struct ctl_command *commands; struct shash local_options; unsigned int seqno; size_t n_commands; char *args; set_program_name(argv[0]); fatal_ignore_sigpipe(); vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN); vlog_set_levels_from_string_assert("reconnect:warn"); sbrec_init(); sbctl_cmd_init(); /* Log our arguments. This is often valuable for debugging systems. */ args = process_escape_args(argv); VLOG(ctl_might_write_to_db(argv) ? VLL_INFO : VLL_DBG, "Called as %s", args); /* Parse command line. */ shash_init(&local_options); parse_options(argc, argv, &local_options); commands = ctl_parse_commands(argc - optind, argv + optind, &local_options, &n_commands); if (timeout) { time_alarm(timeout); } /* Initialize IDL. */ idl = the_idl = ovsdb_idl_create(db, &sbrec_idl_class, false, false); run_prerequisites(commands, n_commands, idl); /* Execute the commands. * * 'seqno' is the database sequence number for which we last tried to * execute our transaction. There's no point in trying to commit more than * once for any given sequence number, because if the transaction fails * it's because the database changed and we need to obtain an up-to-date * view of the database before we try the transaction again. */ seqno = ovsdb_idl_get_seqno(idl); for (;;) { ovsdb_idl_run(idl); if (!ovsdb_idl_is_alive(idl)) { int retval = ovsdb_idl_get_last_error(idl); ctl_fatal("%s: database connection failed (%s)", db, ovs_retval_to_string(retval)); } if (seqno != ovsdb_idl_get_seqno(idl)) { seqno = ovsdb_idl_get_seqno(idl); if (do_sbctl(args, commands, n_commands, idl)) { free(args); exit(EXIT_SUCCESS); } } if (seqno == ovsdb_idl_get_seqno(idl)) { ovsdb_idl_wait(idl); poll_block(); } } }