static gboolean
glib_main (gpointer data)
{
	xmlDoc *doc = NULL;
	xmlNode *root_element = NULL;
	struct connection conn;
	static struct start_network_data start_network_data;


	if (!(start_network_data.client = nm_client_new()))
	{
		network_status (NULL, "Unable to connect to NetworkManager");
		g_main_loop_quit (loop);
	        return FALSE;
	}

	g_timeout_add_seconds (2, do_timeout, &start_network_data);
	start_network_data.should_quit = TRUE;

	/*parse the file and get the DOM */
	if( NULL == (doc = xmlReadFile(NETWORK_CONFIG, NULL, 0))) {
		network_status (start_network_data.client, "error: Could not parse " NETWORK_CONFIG "\n");
		g_main_loop_quit (loop);
		return FALSE;
	}

	/*Get the root element node */
	root_element = xmlDocGetRootElement(doc);
	if (root_element->type == XML_ELEMENT_NODE && !strcmp((char *)root_element->name, "configuration")) {
		gchar *err = read_connection(&conn, root_element);
		if (err) {
			gchar err2[1024];
			g_snprintf(err2, sizeof(err2), "Unable to parse configuration data: %s", err);
			network_status (start_network_data.client, err2);
			g_main_loop_quit (loop);
			return FALSE;
		}
	}
	else {
		network_status (start_network_data.client, "error: Invalid " NETWORK_CONFIG " file: No <configuration/> root node\n");
		g_main_loop_quit (loop);
		return FALSE;
	}

	xmlFreeDoc(doc);
	xmlCleanupParser();

	/* Generate the UUID from the connection information */
	generate_uuid(&conn, start_network_data.uuid, sizeof(start_network_data.uuid));


	/* Hand control over to do_connection.  Execution will continue in callbacks. */
	do_connection(&start_network_data);


	return FALSE;
}
Exemple #2
0
void main_loop(){
	
	do {
		network_status();
		sleep(300);
	} while(1);
	
}
static void
connections_read (NMSettingsInterface *settings, gpointer user_data)
{
	GSList *connections;
	NMConnection *connection;
	NMDevice *dev;
	struct start_network_data *data = (struct start_network_data *)user_data;
	static int tries = 0;

	if(!NM_IS_REMOTE_SETTINGS_SYSTEM(settings))
	{
		network_status (data->client, "Not a settings_system object!  Huh?\n");
		g_main_loop_quit (loop);
		return;
	}

	connections = nm_settings_interface_list_connections (settings);
	connection = find_connection(connections, data->uuid);

	if (!connection) {
		if (tries++ >= 2) {
			network_status (data->client, "Unable to find connection from " NETWORK_CONFIG " in system configs file");
			g_main_loop_quit(loop);
			return;
		}
		return;
	}

	dev = get_device_for_connection (data->client, connection);
	if (!dev) {
		network_status (data->client, "Unable to find correct device for connection");
		g_main_loop_quit(loop);
		return;
	}
	data->should_quit = FALSE;

	nm_client_activate_connection (data->client,
					NM_DBUS_SERVICE_SYSTEM_SETTINGS,
					nm_connection_get_path (connection),//con_path,
					dev,//device,
					NULL,//spec_object,
					activate_connection_cb,
					data);
	return;
}
static void
active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpointer user_data)
{
        NMActiveConnectionState state;
	struct start_network_data *data = (struct start_network_data *)user_data;

        state = nm_active_connection_get_state (active);

        if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
		/* Successful connection */
		network_status (data->client, NULL);
		g_main_loop_quit (loop);
		return;
        } else if (state == NM_ACTIVE_CONNECTION_STATE_UNKNOWN) { 
                network_status (data->client, "Connection activation failed.\n");
		g_main_loop_quit (loop);
		return;
        }
}
static gboolean
do_timeout (gpointer user_data)
{
	struct start_network_data *data = (struct start_network_data *)user_data;
	if (data->should_quit)
	{
		network_status (data->client, "error: Connect timed out\n");
		g_main_loop_quit (loop);
		return FALSE;
	}
	return TRUE;
}
static void
do_connection (struct start_network_data *user_data)
{
	DBusGConnection *bus;
	GError *error = NULL;
	NMRemoteSettingsSystem *system_settings;
	gboolean system_settings_running;
	struct start_network_data *data = (struct start_network_data *)user_data;

	bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
	if (!bus || error) {
		network_status (data->client, "Unable to connect to system bus");
		g_main_loop_quit (loop);
		goto out;
	}

	system_settings = nm_remote_settings_system_new(bus);
	if(!system_settings) {
		network_status (data->client, "Unable to get system settings");
		g_main_loop_quit (loop);
		goto out;
	}

	g_object_get (system_settings, NM_REMOTE_SETTINGS_SERVICE_RUNNING, &system_settings_running, NULL);
	if(!system_settings_running) {
		network_status (data->client, "System settings service is not running");
		g_main_loop_quit (loop);
		goto out;
	}


	g_signal_connect (system_settings, NM_SETTINGS_INTERFACE_CONNECTIONS_READ,
				G_CALLBACK (connections_read), data);

out:
	if (bus)
		dbus_g_connection_unref(bus);
	return;
}
static void
activate_connection_cb (gpointer user_data, const char *path, GError *error)
{
	struct start_network_data *data = (struct start_network_data *)user_data;
	NMActiveConnection *active;
	NMActiveConnectionState state;

	if (error) {
		gchar err[512];
		g_snprintf (err, sizeof(err), "Unable to connect: %s", error->message);
		network_status (data->client, err);
		g_main_loop_quit (loop);
		return;
	}

	active = nm_client_get_active_connection_by_path (data->client, path);
	if (!active) {
		gchar err[512];
		g_snprintf (err, sizeof(err), "Unable to obtain active connection state for %s", path);
		network_status (data->client, err);
		g_main_loop_quit (loop);
		return;
	}

	state = nm_active_connection_get_state (active);
	//g_print ("Connection %s state: %s\n", path, active_connection_state_to_string(state));

	/* If we actually connect, then quit */
	if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED)
	{
		g_main_loop_quit (loop);
		return;
	}

	g_signal_connect (active, "notify::state", G_CALLBACK (active_connection_state_cb), user_data);
	return;
}
Exemple #8
0
/**
 * Read and process an event from the network mailbox.
 *
 * \param[in,out] pi  Ping info
 *
 * \return 1 if processed an event, 0 if not, and negative error code otherwise
 */
static int
net_mbox_event(ping_info_t *pi)
{
  ExamsgMID mid;
  static char msg[sizeof(ExamsgNetRqst) + sizeof(Examsg)];
  int s;

  if (network_status() != 0)
    return 0;

  s = examsgMboxRecv(EXAMSG_NETMBOX_ID, &mid, sizeof(mid),
	             msg, sizeof(msg));
  if (s == 0) /* Nothing to read */
      return 0;

  if (s <= sizeof(ExamsgNetRqst))
    {
      exalog_error("received %d bytes, error %s", s, exa_error_msg(s));
      return -EINVAL;
    }

  s = network_send(&mid, (ExamsgNetRqst *)msg);
  if (s < 0)
    {
      if (network_manageable(s))
	{
	  remember_unsent(&mid, msg, sizeof(msg));
	  return s;
	}

      exalog_error("net mailbox event: error %s", exa_error_msg(s));
      return -EIO;
    }

  reset_ping(pi);

  return 1;
}
Exemple #9
0
/**
 * Thread processing network events (coming from other nodes).
 *
 * This routine may set the network status to down as a side-effect
 * of calling network_recv(), and sets said status to up when the
 * network comes back.
 *
 * \param[in] dummy  Unused
 *
 * \return NULL
 */
static void
net_events_routine(void *dummy)
{
  int dest_mbox;
  ExamsgMID mid;
  size_t size;
  char *msg;
  int s;

  exalog_as(EXAMSG_CMSGD_ID);
  exalog_trace("network events routine started");

  while (!quit)
    {
      int status = network_status();
      bool retry;

      if (status == -ENETDOWN)
	{
	  network_waitup();
	  network_set_status(0);
	}

      do
	{
	  s = network_recv(net_mh, &mid, &msg, &size, &dest_mbox);
	  retry = (s < 0 && network_manageable(s) && s != -ENETDOWN);
	  if (retry)
	      os_sleep(1);
	}
      while (retry);

      /* Succeeded, the network status is ok */
      if (s > 0 && status != 0)
	network_set_status(0);

      if (s == 0 || s == -ENETDOWN)
	continue;

      EXA_ASSERT(s > 0);

      /* Ping from another node for keepalive */
      if (((ExamsgAny *)msg)->type == EXAMSG_PING)
	{
	  EXA_ASSERT(dest_mbox == EXAMSG_CMSGD_ID);
	  exalog_trace("received an EXAMSG_PING from %u:%s",
		       mid.netid.node, mid.host);
	  continue;
	}

      exalog_trace("delivering %" PRIzu " bytes to %d",
		   size, dest_mbox);

      s = examsgMboxSend(&mid, examsgOwner(net_mh), dest_mbox, msg, size);
      switch (s)
	{
	case -ENXIO:
         /* The mailbox does not exist (yet). This is not an error: csupd may
          * not be started yet and we receive an examsg for it.
          * XXX Doesn't sound too good to me, and we should at least check that
          * the destination is indeed csupd */
	  break;

	case -ENOSPC:
	  mailbox_full(dest_mbox, &mid, (Examsg *)msg);
	  break;

	default:
	  EXA_ASSERT_VERBOSE(s == size + sizeof(mid),
		             "Error %d delivering message to %d",
			     s, dest_mbox);
	  break;
	}
    }
}
Exemple #10
0
/**
 * Thread processing local events (coming from localhost).
 *
 * This routine may set the network status to down as a side-effect
 * of calling network_send().
 *
 * \param dummy  Unused
 *
 * \return NULL
 */
static void *
local_events_routine(void *dummy)
{
  ping_info_t pi;

  exalog_trace("local events routine started");

  reset_ping(&pi);

  while (!quit)
    {
      int status;
      int err;

      /* Must be interruptible because signal TERM triggers quit condition */
      err = examsgWaitInterruptible(local_mh, &pi.delay);
      if (err == -EINTR)
	continue;

      if (err == -ETIME)
	{
	  status = network_status();
	  if (status == -ENETDOWN)
	    {
	      reset_ping(&pi);
	      continue;
	    }

	  if (unsent.pending)
	    {
	      if (send_unsent() && status != 0)
		network_set_status(0);
	    }
	  else
	    {
	      send_ping();
	      adjust_ping(&pi);
	    }

	  continue;
	}

      /* Local mailbox messages are more important than network messages
       * because they may ask for resend, so they are processed first.
       *
       * Process as many local messages as possible before considering
       * network messages so as to avoid sending a new network message
       * when there still are important messages.
       */
      while (local_mbox_event(&pi) == 1)
	;

      status = network_status();
      if (status == -ENETDOWN)
	continue;

      if (unsent.pending)
	{
	  if (send_unsent() && status != 0)
	    network_set_status(0);
	}
      else
	net_mbox_event(&pi);
    }

  return NULL;
}
Exemple #11
0
/**
 * Process an event from a local mailbox.
 *
 * \param[in,out] pi  Ping info
 *
 * \return 1 if processed an event 0 if not, negative error code otherwise
 */
static int
local_mbox_event(ping_info_t *pi)
{
  ExamsgMID mid;
  static Examsg ev;
  int ev_size;
  int s;

  ev_size = examsgRecv(local_mh, &mid, &ev, sizeof(ev));
  if (ev_size <= 0)
    return 0;

  switch (ev.any.type)
  {
    case EXAMSG_EXIT:
      {
         exa_nodeset_t dest_nodes;
         quit = true;
	 exa_nodeset_single(&dest_nodes, mid.netid.node);
         examsgAckReply(local_mh, &ev, EXA_SUCCESS, mid.id, &dest_nodes);
      }
      /* Return 0 because, despite we received a message, we do not want the
       * main loop to continue to process messages as it is asked to stop now.
       * So returning 0 juste means here "no need to read anymore messages" */
      return 0;

    case EXAMSG_SUP_PING:
      if (network_status() == 0)
	network_special_send(&mid, &ev, ev_size);
      break;

    case EXAMSG_ADDNODE:
      {
	exa_nodeset_t dest_nodes;
	examsg_node_info_msg_t *info = (examsg_node_info_msg_t *)&ev;

	s = network_add_node(info->node_id, info->node_name);

	exa_nodeset_single(&dest_nodes, mid.netid.node);
	examsgAckReply(local_mh, &ev, s, mid.id, &dest_nodes);
      }
      break;

    case EXAMSG_DELNODE:
      {
	exa_nodeset_t dest_nodes;

	s = network_del_node(((examsg_node_info_msg_t *)&ev)->node_id);

	exa_nodeset_single(&dest_nodes, mid.netid.node);
	examsgAckReply(local_mh, &ev, s, mid.id, &dest_nodes);
      }
      break;

    case EXAMSG_RETRANSMIT_REQ:
      if (network_status() == 0)
	{
	  ExamsgRetransmitReq *retreq = (ExamsgRetransmitReq *)&ev;

	  exalog_debug("will send a retransmit request for %d to %u",
		       retreq->count, retreq->node_id);

	  s = network_send_retransmit_req(retreq->node_id, retreq->count);
	  EXA_ASSERT(s == 0);
	  reset_ping(pi);
	}
      break;

    case EXAMSG_RETRANSMIT:
      if (network_status() == 0)
	{
	  ExamsgRetransmit *retr = (ExamsgRetransmit *)&ev;
	  exalog_debug("will retransmit messages: %d", retr->count);

	  retransmit(retr->count);
	  reset_ping(pi);
	}
      break;

    case EXAMSG_FENCE:
      {
	const examsgd_fencing_req_t *req =
	  &((examsgd_fencing_req_msg_t *)&ev)->request;

	network_handle_fence_request(req);
      }
      break;

    case EXAMSG_NEW_COMER:
      reset_ping(pi);
      break;

    default:
      {
       exa_nodeset_t dest_nodes;

       exa_nodeset_single(&dest_nodes, mid.netid.node);
       examsgAckReply(local_mh, &ev, EINVAL, mid.id, &dest_nodes);
       exalog_error("got unknown message (type %d)", ev.any.type);
       EXA_ASSERT(false);
      }
      break;
    }

  return 1;
}