Ejemplo n.º 1
0
/*
 * Adjust self on failing to Port
 */
void
node_adjust_deleted(node_t* f)
{
    node_t *ancestor;

    FN_W ("%s %s\n", __func__, NODE_NAME(f));

    for (ancestor = NODE_PARENT(f);
         ancestor != NULL;
         ancestor = NODE_PARENT(ancestor)) {
        /* Stop if we find a node which been already associated or is existed
         * and can be associated.
         */
        if (NODE_HAS_STATE(ancestor, NODE_STATE_ASSOCIATED) ||
          (node_lstat(ancestor) == 0 && port_add(ancestor) == 0)) {
            break;
        }
    }

    /* We assume we shouldn't reach here, because Root is always existed and
     * associated. But given bugster#6955199, if PORT FS has problems on root,
     * we may reach here. So just return ROOT and the whole GIO fen backend will
     * fail.
     */
    /* g_assert(ancestor != NULL); */
}
Ejemplo n.º 2
0
/* Add physical interface. */
lagopus_result_t
dpmgr_port_add(struct dpmgr *dpmgr, const struct port *port) {
  lagopus_result_t ret;

  ret = port_add(dpmgr->ports, port);

  return ret;
}
Ejemplo n.º 3
0
void
node_create_children_snapshot(node_t *f, gint created_event, gboolean emit)
{
	GDir *dir;
	GError *err = NULL;
    
    FN_W ("%s %s [0x%p]\n", __func__, NODE_NAME(f), f);

    dir = g_dir_open (NODE_NAME(f), 0, &err);
    if (dir) {
        const char *basename;
        node_t *child = NULL;
        
        while ((basename = g_dir_read_name (dir))) {
            node_t* data;
            GList *idx;

            child = node_get_child (f, basename);
            if (child == NULL) {
                gchar *filename;
            
                child = node_new (f, basename);
                children_add (f, child);
            }

            if (f->dir_subs) {
                /* We need monitor the new children, or the existed child which
                 * is in the DELETED mode.
                 */
                if (!NODE_HAS_STATE(child, NODE_STATE_ASSOCIATED) &&
                  node_lstat(child) == 0 && port_add(child) == 0) {
                    if (emit) {
                        /* Emit the whatever event for the new found file. */
                        node_emit_one_event(child, child->dir_subs, NULL, created_event);
                        node_emit_one_event(child, child->subs, NULL, created_event);
                        node_emit_one_event(child, f->dir_subs, NULL, created_event);
                        node_emit_one_event(child, f->subs, NULL, created_event);
                    }
                }
                /* else ignore, because it may be deleted. */
            }
        }
        g_dir_close (dir);

        /* We have finished children snapshot. Any other new added subs should
         * directory iterate the snapshot instead of scan directory again.
         */
        NODE_SET_FLAG(f, NODE_FLAG_SNAPSHOT_UPDATED);

    } else {
        FN_W (err->message);
        g_error_free (err);
    }
}
Ejemplo n.º 4
0
/**
 * fen_add
 * 
 * Won't hold a ref, we have a timout callback to clean unused node_t.
 * If there is no value for a key, add it and return it; else return the old
 * one.
 */
void
fen_add (const gchar *filename, gpointer sub, gboolean is_mondir)
{
	node_t* f;

    g_assert (filename);
    g_assert (sub);

    G_LOCK (fen_lock);
	f = node_find(NULL, filename, TRUE);
    FH_W ("%s 0x%p sub[0x%p] %s\n", __func__, f, sub, filename);
    g_assert (f);

    /* Update timestamp, the events in global queue will compare itself to this
     * timestamp to decide if be emitted. TODO, timestamp should be per sub.
     */
    if (!NODE_IS_ACTIVE(f)) {
        g_get_current_time(&f->atv);
    }

    if (is_mondir) {
        f->dir_subs = g_list_prepend(f->dir_subs, sub);
    } else {
        f->subs = g_list_prepend(f->subs, sub);
    }
    
    if (NODE_HAS_STATE(f, NODE_STATE_ASSOCIATED) ||
      (node_lstat(f) == 0 && port_add(f) == 0)) {
#ifndef GIO_COMPILATION
        gam_server_emit_one_event (NODE_NAME(f),
          gam_subscription_is_dir (sub), GAMIN_EVENT_EXISTS, sub, 1);
#endif
        if (is_mondir) {
            scan_children_init (f, sub);
        }
    } else {
#ifndef GIO_COMPILATION
        gam_server_emit_one_event (NODE_NAME(f),
          gam_subscription_is_dir (sub), GAMIN_EVENT_DELETED, sub, 1);
#endif
        node_adjust_deleted (f);
    }
#ifndef GIO_COMPILATION
    gam_server_emit_one_event (NODE_NAME(f),
      gam_subscription_is_dir (sub), GAMIN_EVENT_ENDEXISTS, sub, 1);
#endif
    G_UNLOCK (fen_lock);
}
Ejemplo n.º 5
0
void
test_port_add(void) {
    struct vector *ports;
    struct port port;
    lagopus_result_t rv;

    ports = ports_alloc();
    TEST_ASSERT_NOT_NULL_MESSAGE(ports, "ports_alloc error");

    strncpy(port.ofp_port.name, "port1", sizeof(port.ofp_port.name));
    port.ofp_port.port_no = 1;
    port.ifindex = 120;
    port.type = LAGOPUS_PORT_TYPE_NULL;
    rv = port_add(ports, &port);

    TEST_ASSERT_EQUAL_MESSAGE(rv, LAGOPUS_RESULT_OK, "port_add error");
}
Ejemplo n.º 6
0
/*
 * If all active children nodes are ported, then cancel monitor the parent
 * node. If we know how many children are created, then we can stop accordingly.
 *
 * Unsafe, need lock. 
 */
static void
foreach_known_children_scan(gpointer key, gpointer value, gpointer user_data)
{
    node_t* f = (node_t*)value;
    
    FN_W ("%s 0x%p %s\n", __func__, f, NODE_NAME(f));

    if (!NODE_HAS_STATE(f, NODE_STATE_ASSOCIATED)) {
        if (node_lstat(f) == 0 && port_add(f) == 0) {
            node_emit_one_event(f, f->dir_subs, NULL, FN_EVENT_CREATED);
            node_emit_one_event(f, f->subs, NULL, FN_EVENT_CREATED);
            if (NODE_PARENT(f)) {
                node_emit_one_event(f, NODE_PARENT(f)->dir_subs, NULL, FN_EVENT_CREATED);
                node_emit_one_event(f, NODE_PARENT(f)->subs, NULL, FN_EVENT_CREATED);
            }
        }
    }
}
Ejemplo n.º 7
0
/*
 * node_add_event:
 *
 */
static void
node_add_event (node_t *f, node_event_t *ev)
{
    FN_W ("%s %d\n", __func__, ev->e);

    /* Clean the events flag early, because all received events need be
     * processed in this function.
     */
    NODE_CLE_STATE(f, NODE_STATE_HAS_EVENTS);

    /*
     * Node the node has been created, so we can delete create event in
     * optimizing. To reduce the statings, we add it to Port on discoving
     * it then emit CREATED event. So we don't need to do anything here.
     */
    if (NODE_NEED_MONITOR(f)) {
        if (HAS_NO_EXCEPTION_EVENTS(ev->e)) {
            if (NODE_HAS_STATE(f, NODE_STATE_ASSOCIATED) || port_add(f) == 0) {
                if ((ev->e & FILE_MODIFIED) && NODE_HAS_FLAG(f, NODE_FLAG_DIR)) {
                    if (f->dir_subs) {
                        node_create_children_snapshot(f, FN_EVENT_CREATED, TRUE);
                    } else {
                        g_hash_table_foreach(f->children, foreach_known_children_scan, NULL);
                    }
                }
            } else {
                /* Emit delete event */
                ev->e |= FILE_DELETE;

                node_adjust_deleted(f);
            }

        } else {
            node_adjust_deleted(f);
        }

        /* Send events to clients. */
        node_emit_events (f, ev);
        
    } else {
        /* Send events to clients. */
        node_emit_events (f, ev);

        node_try_delete(f);
    }

    if (ev->pair_data) {
        node_t *from = ev->pair_data;
        g_assert(ev->e == FILE_RENAME_TO);

        if (NODE_NEED_MONITOR(from)) {
            /* Clean the events flag, since it may block free this node. */
            NODE_CLE_STATE(from, NODE_STATE_HAS_EVENTS);
            node_adjust_deleted(from);
        } else {
            node_try_delete(from);
        }
    }

    node_event_delete (ev);
}
Ejemplo n.º 8
0
int
SwitchWContexts::init_from_command_line_options(int argc, char *argv[],
                                                TargetParserIface *tp) {
  OptionsParser parser;
  parser.parse(argc, argv, tp);

  notifications_addr = parser.notifications_addr;
  auto transport = std::shared_ptr<TransportIface>(
      TransportIface::make_nanomsg(notifications_addr));
  transport->open();

#ifdef BMDEBUG_ON
  // has to be before init_objects because forces arith
  if (parser.debugger) {
    for (Context &c : contexts)
      c.set_force_arith(true);
    Debugger::init_debugger(parser.debugger_addr);
  }
#endif

  event_logger_addr = parser.event_logger_addr;

  if (parser.console_logging)
    Logger::set_logger_console();

  if (parser.file_logger != "")
    Logger::set_logger_file(parser.file_logger, parser.log_flush);

  Logger::set_log_level(parser.log_level);

  int status = init_objects(parser.config_file_path, parser.device_id,
                            transport);
  if (status != 0) return status;

  if (parser.use_files)
    set_dev_mgr_files(parser.wait_time);
  else if (parser.packet_in)
    set_dev_mgr_packet_in(device_id, parser.packet_in_addr, transport);
  else
    set_dev_mgr_bmi(device_id, transport);

  for (const auto &iface : parser.ifaces) {
    std::cout << "Adding interface " << iface.second
              << " as port " << iface.first
              << (parser.use_files ? " (files)" : "")
              << std::endl;

    const char* inFileName = NULL;
    const char* outFileName = NULL;

    std::string inFile;
    std::string outFile;

    if (parser.use_files) {
      inFile = iface.second + "_in.pcap";
      inFileName = inFile.c_str();
      outFile = iface.second + "_out.pcap";
      outFileName = outFile.c_str();
    } else if (parser.pcap) {
      inFile = iface.second + ".pcap";
      inFileName = inFile.c_str();
      outFileName = inFileName;
    }

    port_add(iface.second, iface.first, inFileName, outFileName);
  }
  thrift_port = parser.thrift_port;

  if (parser.state_file_path != "") {
    status = deserialize_from_file(parser.state_file_path);
    if (status != 0) return status;
  }

  // TODO(unknown): is this the right place to do this?
  set_packet_handler(packet_handler, static_cast<void *>(this));
  start();

  return status;
}