[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Minios-devel] [UNIKRAFT/CLICK PATCH 02/11] Initial public release: click.cc



Hi Florian,

This patch looks good.

Thanks,

-- Felipe

Reviewed-by: Felipe Huici <felipe.huici@xxxxxxxxx>

On 02.06.19, 07:53, "Florian Schmidt" <Florian.Schmidt@xxxxxxxxx> wrote:

    This is taken from from kohler/click/minios/, with an updated copyright
    header.
    
    Signed-off-by: Florian Schmidt <florian.schmidt@xxxxxxxxx>
    ---
     click.cc | 384 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
     1 file changed, 384 insertions(+)
     create mode 100644 click.cc
    
    diff --git a/click.cc b/click.cc
    new file mode 100644
    index 0000000..25bc524
    --- /dev/null
    +++ b/click.cc
    @@ -0,0 +1,384 @@
    +/* SPDX-License-Identifier: BSD-3-Clause */
    +/*
    + * Copyright (c) 2014 NEC Europe Ltd,
    + *               2019, NEC Laboratories Europe GmbH, NEC Corporation.
    + *               All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + *
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + * 3. Neither the name of the copyright holder nor the names of its
    + *    contributors may be used to endorse or promote products derived from
    + *    this software without specific prior written permission.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
IS"
    + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
THE
    + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
PURPOSE
    + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
BE
    + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
THE
    + * POSSIBILITY OF SUCH DAMAGE.
    + *
    + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
    + */
    +
    +#include <click/config.h>
    +#include <click/lexer.hh>
    +#include <click/router.hh>
    +#include <click/master.hh>
    +#include <click/error.hh>
    +#include <click/timer.hh>
    +#include <click/string.hh>
    +#include <click/straccum.hh>
    +#include <click/driver.hh>
    +
    +extern "C"{
    +#include <stdlib.h>
    +#include <stdio.h>
    +#include <string.h>
    +
    +#include <mini-os/xenbus.h>
    +#include <mini-os/shutdown.h>
    +#include <mini-os/sched.h>
    +}
    +
    +void *__dso_handle = NULL;
    +
    +#define NLOG(fmt, ...)
    +#define LOG(fmt, ...) \
    +   printf("[%s:%d] " fmt "\n", \
    +           __FUNCTION__, __LINE__, ##__VA_ARGS__)
    +
    +/**
    + * xenstore helpers
    + */
    +#define PATH_ROOT  "clickos"
    +#define PATH_MAX_LEN       1024
    +
    +struct xenstore_dev {
    +   domid_t dom;
    +   char *nodename;
    +   xenbus_event_queue events;
    +} *xsdev = NULL;
    +
    +uint32_t domid = -1;
    +u_int _shutdown = 0;
    +u_int _reason = 0;
    +
    +char*
    +event_token(char **key)
    +{
    +   char *p = *key, *p2;
    +   char *token;
    +   u_int sz;
    +
    +   p2 = strchr(++p, '/');
    +   sz = (p2 != NULL ? p2 - p : strlen(p));
    +   token = strndup(p, sz);
    +   *key = (p+sz);
    +
    +   return token;
    +}
    +
    +char*
    +read_rid(char *path)
    +{
    +   char *id = strdup(path + 1);
    +   char *id_end = strchr(id, '/');
    +   *id_end = '\0';
    +   return id;
    +}
    +
    +String *
    +read_config(u_int rid = 0)
    +{
    +   char path[PATH_MAX_LEN];
    +   String *cfg = new String();
    +   char *token;
    +
    +   for (int i = 0;; i++) {
    +           snprintf(path, PATH_MAX_LEN, "%s/%d/config/%d",
    +                           PATH_ROOT, rid, i);
    +           xenbus_read(XBT_NIL, path, &token);
    +           if (token == NULL)
    +                   break;
    +           *cfg += token;
    +   }
    +
    +   return cfg;
    +}
    +
    +/*
    + * click glue
    + */
    +
    +#define MAX_ROUTERS        64
    +static ErrorHandler *errh;
    +static Master master(1);
    +
    +struct router_instance {
    +   Router *r;
    +   u_int f_stop;
    +} router_list[MAX_ROUTERS];
    +
    +void
    +router_thread(void *thread_data)
    +{
    +   u_int *rid = (u_int*) thread_data;
    +   String *config = read_config(*rid);
    +   struct router_instance *ri = &router_list[*rid];
    +
    +   ri->r = click_read_router(*config, true, errh, false, &master);
    +   if (ri->r->initialize(errh) < 0) {
    +           LOG("Router init failed!");
    +           ri->f_stop = 1;
    +           return;
    +   }
    +
    +   ri->r->use();
    +   ri->r->activate(errh);
    +
    +   LOG("Starting driver...\n\n");
    +   ri->r->master()->thread(0)->driver();
    +
    +   LOG("Stopping driver...\n\n");
    +   ri->r->unuse();
    +   ri->f_stop = 1;
    +
    +   LOG("Master/driver stopped, closing router_thread");
    +   free(config);
    +   free(rid);
    +}
    +
    +void
    +router_stop(int n = MAX_ROUTERS)
    +{
    +   LOG("Stopping all routers...\n\n");
    +   for (int i = n - 1; i >= 0; --i) {
    +           Router *r = router_list[i].r;
    +
    +           if (router_list[i].f_stop)
    +                   continue;
    +
    +           LOG("Stopping instance = %d...\n\n", i);
    +
    +           do {
    +                   r->please_stop_driver();
    +                   schedule();
    +           } while (!(router_list[i].f_stop));
    +   }
    +   LOG("Stopped all routers...\n\n");
    +}
    +
    +void
    +router_suspend(int n = MAX_ROUTERS)
    +{
    +}
    +
    +void
    +router_resume(int n = MAX_ROUTERS)
    +{
    +}
    +
    +u_int
    +on_status(int rid, char *key, void *data)
    +{
    +   String status = (char *) data;
    +   struct router_instance *r = &router_list[rid];
    +
    +   LOG("router id %d", rid);
    +   LOG("status change to %s", data);
    +   if (status == "Running") {
    +           u_int *arg0;
    +
    +           if (!r->f_stop)
    +                   goto status_err;
    +
    +           arg0 = (u_int*) malloc(sizeof(u_int));
    +           *arg0 = rid;
    +           r->f_stop = 0;
    +           create_thread((char*)"click", router_thread, arg0);
    +   } else if (status == "Halted") {
    +           if (r->f_stop)
    +                   goto status_err;
    +
    +           router_stop(rid);
    +   }
    +
    +   return 0;
    +status_err:
    +   return -EINVAL;
    +}
    +
    +static void
    +read_cname(char *path, Element **e, const Handler **h, int rid)
    +{
    +   int sep = strchr(path, '/') - path;
    +   String ename(path, sep), hname(path + sep + 1);
    +   Router *r = router_list[rid].r;
    +
    +   NLOG("sep=%d element=%s handler=%s", sep,
    +                   ename.c_str(), hname.c_str());
    +
    +   *e = r->find(ename);
    +   *h = Router::handler(*e, hname);
    +   NLOG("ename %s=%p hname %s=%p", ename.c_str(), e, hname.c_str(), h);
    +}
    +
    +u_int
    +on_elem_readh(int rid, char *key, void *data)
    +{
    +   Element *e;
    +   const Handler* h;
    +   String val, h_path, lock_path;
    +   int f_stop = router_list[rid].f_stop;
    +
    +   if (strncmp(key, "/read/", 6))
    +           return 0;
    +
    +   if (f_stop)
    +           return 0;
    +
    +   read_cname(key+6, &e, &h, rid);
    +
    +   if (!h || !h->readable())
    +           return EINVAL;
    +
    +   val = h->call_read(e, "", ErrorHandler::default_handler());
    +   h_path = String(PATH_ROOT) + "/0/elements/" + e->name() + "/" + 
h->name();
    +   lock_path = h_path + "/lock";
    +
    +   xenbus_write(XBT_NIL, h_path.c_str(), val.c_str());
    +   xenbus_write(XBT_NIL, lock_path.c_str(), "0");
    +
    +   NLOG("element handler read %s", val.c_str());
    +   return 0;
    +}
    +
    +u_int
    +on_elem_writeh(int rid, char *key, void *data)
    +{
    +   Element *e;
    +   const Handler* h;
    +   int f_stop = router_list[rid].f_stop;
    +
    +   if (f_stop || strlen((char *) data) == 0)
    +           return 0;
    +
    +   read_cname(key+1, &e, &h, rid);
    +
    +   if (!h || !h->writable())
    +           return EINVAL;
    +
    +   h->call_write(String(data), e, ErrorHandler::default_handler());
    +   NLOG("element handler write %s value %s", data, "");
    +   return 0;
    +}
    +
    +u_int
    +on_router(char *key, void *data)
    +{
    +   char *p = key;
    +   String rev;
    +   u_int rid;
    +
    +   if (strlen(key) == 0)
    +           return 0;
    +
    +   rid = atoi(event_token(&p));
    +   rev = event_token(&p);
    +
    +   if (rev == "control")
    +           on_elem_readh(rid, p, data);
    +   else if (rev == "elements")
    +           on_elem_writeh(rid, p, data);
    +   else if (rev == "status")
    +           on_status(rid, key, data);
    +
    +   return 0;
    +}
    +
    +/* runs the event loop */
    +int main(int argc, char **argv)
    +{
    +   size_t len = sizeof(struct xenstore_dev);
    +
    +   click_static_initialize();
    +   errh = ErrorHandler::default_handler();
    +
    +   xsdev = (struct xenstore_dev*) malloc(len);
    +   memset(xsdev, 0, len);
    +   memset(router_list, 0, MAX_ROUTERS * sizeof(struct router_instance));
    +   for (int i = 0; i < MAX_ROUTERS; ++i) {
    +           router_list[i].f_stop = 1;
    +   }
    +
    +   xenbus_watch_path_token(XBT_NIL, PATH_ROOT, "router-watch",
    +                   &xsdev->events);
    +
    +   while (!_shutdown) {
    +           String value;
    +           char *err, *val, **path;
    +
    +           path = xenbus_wait_for_watch_return(&xsdev->events);
    +           if (!path || _shutdown)
    +                   continue;
    +
    +           err = xenbus_read(XBT_NIL, *path, &val);
    +           if (err)
    +                   continue;
    +
    +           on_router((*path + strlen(PATH_ROOT)), val);
    +   }
    +
    +   LOG("Shutting down...");
    +   xenbus_unwatch_path_token(XBT_NIL, PATH_ROOT, "router-watch");
    +
    +   fini_xenbus();
    +   free(xsdev);
    +
    +   return _reason;
    +}
    +
    +/* app shutdown hook from minios */
    +extern "C" {
    +int app_shutdown(unsigned reason)
    +{
    +   switch (reason) {
    +   case SHUTDOWN_poweroff:
    +           LOG("Requested shutdown reason=poweroff");
    +           _shutdown = 1;
    +           _reason = reason;
    +           router_stop();
    +           xenbus_release_wait_for_watch(&xsdev->events);
    +           break;
    +   case SHUTDOWN_reboot:
    +           LOG("Requested shutdown reason=reboot");
    +           _shutdown = 1;
    +           _reason = reason;
    +           router_stop();
    +           xenbus_release_wait_for_watch(&xsdev->events);
    +           break;
    +   case SHUTDOWN_suspend:
    +           LOG("Requested shutdown reason=suspend");
    +           router_suspend();
    +           kernel_suspend();
    +           router_resume();
    +   default:
    +           LOG("Requested shutdown with invalid reason (%d)", reason);
    +           break;
    +   }
    +
    +   return 0;
    +}
    +}
    -- 
    2.21.0
    
    

_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.