linkd

Control plane daemon for unos
git clone git://git.finwo.net/app/linkd
Log | Files | Refs | README

registry.c (2014B)


      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <strings.h>
      4 
      5 #include "dataplane.h"
      6 
      7 #include "registry.h"
      8 
      9 #define DP_MAX_BACKENDS 16
     10 
     11 static const struct dp_ops *backend[DP_MAX_BACKENDS];
     12 static int                  backend_count = 0;
     13 static const struct dp_ops *active        = NULL;
     14 
     15 int dp_register(const struct dp_ops *ops) {
     16   if (!ops) return DP_RET_ERROR;
     17 
     18   if (ops->abi != LINKD_DATAPLANE_ABI) {
     19     fprintf(stderr, "dataplane: refusing backend `%s`: abi %u, expected %u\n",
     20             ops->name ? ops->name : "(unnamed)", ops->abi, LINKD_DATAPLANE_ABI);
     21     return DP_RET_ERROR;
     22   }
     23 
     24   if (!ops->name || !ops->probe || !ops->init) {
     25     fprintf(stderr, "dataplane: refusing incomplete backend\n");
     26     return DP_RET_ERROR;
     27   }
     28 
     29   if (backend_count >= DP_MAX_BACKENDS) {
     30     fprintf(stderr, "dataplane: backend table full, dropping `%s`\n", ops->name);
     31     return DP_RET_ERROR;
     32   }
     33 
     34   backend[backend_count++] = ops;
     35   return DP_RET_OK;
     36 }
     37 
     38 int dp_select(const char *force) {
     39   int i;
     40 
     41   if (force) {
     42     for (i = 0; i < backend_count; i++) {
     43       if (!strcasecmp(backend[i]->name, force)) {
     44         active = backend[i];
     45         fprintf(stderr, "dataplane: using `%s` (forced)\n", active->name);
     46         return DP_RET_OK;
     47       }
     48     }
     49     fprintf(stderr, "dataplane: no backend named `%s`\n", force);
     50     return DP_RET_ERROR;
     51   }
     52 
     53   // Plugins are probed before the built-in kernel backend, which is
     54   // registered first and always succeeds -- so iterate in reverse.
     55   for (i = backend_count - 1; i >= 0; i--) {
     56     if (backend[i]->probe() != DP_RET_OK) continue;
     57     active = backend[i];
     58     fprintf(stderr, "dataplane: using `%s`\n", active->name);
     59     return DP_RET_OK;
     60   }
     61 
     62   fprintf(stderr, "dataplane: no usable backend\n");
     63   return DP_RET_ERROR;
     64 }
     65 
     66 const struct dp_ops * dp_active(void) {
     67   return active;
     68 }
     69 
     70 int dp_init(void) {
     71   if (!active) return DP_RET_ERROR;
     72   return active->init();
     73 }
     74 
     75 void dp_fini(void) {
     76   if (!active) return;
     77   if (active->fini) active->fini();
     78   active = NULL;
     79 }