Skip to content

Commit 85232bd

Browse files
felixhuettnermartinmo
authored andcommitted
ovsdb-idl: Add loop_run until timeout or completion.
This change makes the ovsdb_idl_loop_run_completion() function from the northd code in OVN usable for other parts of the code and adapts the client synchronisation layer functions accordingly. It allows users to continue processing idl messages until some timeout arrives or no more messages exist. Signed-off-by: Martin Morgenstern <martin.morgenstern@cloudandheat.com> Signed-off-by: Felix Huettner <felix.huettner@stackit.cloud> (cherry picked from commit d00299c)
1 parent 001fb96 commit 85232bd

File tree

4 files changed

+57
-6
lines changed

4 files changed

+57
-6
lines changed

lib/ovsdb-cs.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -611,12 +611,12 @@ ovsdb_cs_db_add_event(struct ovsdb_cs_db *db, enum ovsdb_cs_event_type type)
611611
*
612612
* Initializes 'events' with a list of events that occurred on 'cs'. The
613613
* caller must process and destroy all of the events. */
614-
void
614+
int
615615
ovsdb_cs_run(struct ovsdb_cs *cs, struct ovs_list *events)
616616
{
617617
ovs_list_init(events);
618618
if (!cs->session) {
619-
return;
619+
return EINVAL;
620620
}
621621

622622
ovsdb_cs_send_cond_change(cs);
@@ -660,6 +660,12 @@ ovsdb_cs_run(struct ovsdb_cs *cs, struct ovs_list *events)
660660
}
661661
}
662662
ovs_list_push_back_all(events, &cs->data.events);
663+
664+
if (ret == EAGAIN) {
665+
return EAGAIN;
666+
} else {
667+
return 0;
668+
}
663669
}
664670

665671
/* Arranges for poll_block() to wake up when ovsdb_cs_run() has something to

lib/ovsdb-cs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ struct ovsdb_cs *ovsdb_cs_create(const char *database, int max_version,
118118
void *ops_aux);
119119
void ovsdb_cs_destroy(struct ovsdb_cs *);
120120

121-
void ovsdb_cs_run(struct ovsdb_cs *, struct ovs_list *events);
121+
int ovsdb_cs_run(struct ovsdb_cs *, struct ovs_list *events);
122122
void ovsdb_cs_wait(struct ovsdb_cs *);
123123

124124
/* Network connection. */

lib/ovsdb-idl.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "simap.h"
4646
#include "sset.h"
4747
#include "svec.h"
48+
#include "timeval.h"
4849
#include "util.h"
4950
#include "uuid.h"
5051
#include "openvswitch/vlog.h"
@@ -439,13 +440,14 @@ ovsdb_idl_clear(struct ovsdb_idl *db)
439440
/* Processes a batch of messages from the database server on 'idl'. This may
440441
* cause the IDL's contents to change. The client may check for that with
441442
* ovsdb_idl_get_seqno(). */
442-
void
443+
int
443444
ovsdb_idl_run(struct ovsdb_idl *idl)
444445
{
445446
ovs_assert(!idl->txn);
446447

447448
struct ovs_list events;
448-
ovsdb_cs_run(idl->cs, &events);
449+
int ret;
450+
ret = ovsdb_cs_run(idl->cs, &events);
449451

450452
struct ovsdb_cs_event *event;
451453
LIST_FOR_EACH_POP (event, list_node, &events) {
@@ -479,6 +481,8 @@ ovsdb_idl_run(struct ovsdb_idl *idl)
479481
ovsdb_idl_reparse_refs_to_inserted(idl);
480482
ovsdb_idl_reparse_deleted(idl);
481483
ovsdb_idl_row_destroy_postprocess(idl);
484+
485+
return ret;
482486
}
483487

484488
/* Arranges for poll_block() to wake up when ovsdb_idl_run() has something to
@@ -4391,6 +4395,44 @@ ovsdb_idl_loop_run(struct ovsdb_idl_loop *loop)
43914395
return loop->open_txn;
43924396
}
43934397

4398+
/* Run the ovsdb_idl_loop until there is no more data to be received.
4399+
* A timeout in milliseconds can be provided. The actual duration of the
4400+
* function is returned in the duration parameter. */
4401+
struct ovsdb_idl_txn *
4402+
ovsdb_idl_loop_run_completion(struct ovsdb_idl_loop *idl_loop,
4403+
unsigned long long timeout,
4404+
uint64_t *idl_duration)
4405+
{
4406+
unsigned long long duration, start = time_msec();
4407+
struct ovsdb_idl_txn *txn;
4408+
int n = 0;
4409+
4410+
/* Accumulate database changes as long as there are some,
4411+
* but no longer than the given timeout. */
4412+
while (time_msec() - start < timeout) {
4413+
if (ovsdb_idl_run(idl_loop->idl) == EAGAIN) {
4414+
break;
4415+
}
4416+
n++;
4417+
}
4418+
4419+
txn = ovsdb_idl_loop_run(idl_loop);
4420+
4421+
duration = time_msec() - start;
4422+
if (idl_duration) {
4423+
*idl_duration = duration;
4424+
}
4425+
/* ovsdb_idl_run() is called at least 2 times. Once directly and
4426+
* once in the ovsdb_idl_loop_run(). n > 2 means that we received
4427+
* data on at least 2 subsequent calls. */
4428+
if (n > 2 || duration > 100) {
4429+
VLOG(duration > timeout ? VLL_INFO : VLL_DBG,
4430+
"%d iterations in %lld ms", n + 1, duration);
4431+
}
4432+
4433+
return txn;
4434+
}
4435+
43944436
/* Attempts to commit the current transaction, if one is open.
43954437
*
43964438
* If a transaction was open, in this or a previous iteration of the main loop,

lib/ovsdb-idl.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void ovsdb_idl_destroy(struct ovsdb_idl *);
7373

7474
void ovsdb_idl_set_leader_only(struct ovsdb_idl *, bool leader_only);
7575

76-
void ovsdb_idl_run(struct ovsdb_idl *);
76+
int ovsdb_idl_run(struct ovsdb_idl *);
7777
void ovsdb_idl_wait(struct ovsdb_idl *);
7878

7979
void ovsdb_idl_get_memory_usage(struct ovsdb_idl *, struct simap *usage);
@@ -409,6 +409,9 @@ struct ovsdb_idl_loop {
409409

410410
void ovsdb_idl_loop_destroy(struct ovsdb_idl_loop *);
411411
struct ovsdb_idl_txn *ovsdb_idl_loop_run(struct ovsdb_idl_loop *);
412+
struct ovsdb_idl_txn *ovsdb_idl_loop_run_completion(
413+
struct ovsdb_idl_loop *idl_loop, unsigned long long timeout,
414+
uint64_t *idl_duration);
412415
int ovsdb_idl_loop_commit_and_wait(struct ovsdb_idl_loop *);
413416

414417
/* Conditional Replication

0 commit comments

Comments
 (0)