예제 #1
0
static void
find_another_host (ACE_TCHAR other_host[])
{
  static ACE_TCHAR cached_other_host[MAXHOSTNAMELEN] = {'\0'};

  if (cached_other_host[0] == '\0')
    {

      ACE_OS::strcpy (other_host,
                      ACE_DEFAULT_SERVER_HOST); // If all else fails

#if !defined (ACE_LACKS_GETHOSTENT)
      // These gethost-type things don't work everywhere.
      struct hostent *h = 0;
      ACE_utsname un;

      ACE_OS::uname (&un);

      h = ACE_OS::gethostbyname (un.nodename);

      if (h == 0)
        ACE_OS::strcpy (other_host, ACE_LOCALHOST);
      else
        // Use me if can't find another
        ACE_OS::strcpy (other_host, ACE_TEXT_CHAR_TO_TCHAR (h->h_name));

      // @@ We really need to add wrappers for these hostent methods.

      // Optimize for sequential access of DNS or hosts file.
      sethostent (1);

      int candidate_count = 0;

      // Accumulate candidates first.  There is some interaction on
      // Linux systems between <gethostent> and <gethostbyname_r>
      // (called by ACE_INET_Addr in host_is_up) This otherwise causes
      // an infinite loop on Linux --mas 03-08-2001
      while ((h = gethostent ()) != 0)
        {
          if (ACE_OS::strcmp (h->h_name,
                              ACE_TEXT_ALWAYS_CHAR (ACE_DEFAULT_SERVER_HOST)) == 0)
            continue;
          // AIX just _has_ to be different
          if (ACE_OS::strcmp (h->h_name, "loopback") == 0)
            continue;

          // If not me.
          if (ACE_OS::strcmp
                (h->h_name, ACE_TEXT_ALWAYS_CHAR (other_host)) != 0
              && ACE_OS::strcmp (h->h_name, un.nodename) != 0)
            {
               ACE_OS::strcpy (candidate[candidate_count].host_name,
                               ACE_TEXT_CHAR_TO_TCHAR (h->h_name));
               if (++candidate_count >= MAX_CANDIDATES)
                 break;
            }
        }

      // Now try to connect to candidates
      for (int i = 0; i < candidate_count; i++)
        if (host_is_up (candidate[i].host_name))
          {
            ACE_OS::strcpy (other_host, candidate[i].host_name);
            break;
          }

      sethostent (0);
      endhostent ();
#endif /* ! ACE_LACKS_GETHOSTENT */

      ACE_OS::strcpy (cached_other_host, other_host);
    }
  else
    ACE_OS::strcpy (other_host, cached_other_host);
}
예제 #2
0
static gfarm_error_t
gfm_server_switch_back_channel_common(
	struct peer *peer, gfp_xdr_xid_t xid, size_t *sizep,
	int from_client,
	int version, const char *diag, struct relayed_request *relay)
{
	gfarm_error_t e = GFARM_ERR_NO_ERROR, e2;
	struct host *host;
	gfp_xdr_async_peer_t async = NULL;
	struct local_peer *local_peer = NULL;
	int is_direct_connection;
	int i = 0;

#ifdef __GNUC__ /* workaround gcc warning: might be used uninitialized */
	host = NULL;
#endif
	is_direct_connection = (peer_get_parent(peer) == NULL);

	giant_lock();

	if (from_client) {
		gflog_debug(GFARM_MSG_1001995,
		    "Operation not permitted: from_client");
		e = GFARM_ERR_OPERATION_NOT_PERMITTED;
	} else if ((host = peer_get_host(peer)) == NULL) {
		gflog_debug(GFARM_MSG_1001996,
		    "Operation not permitted: peer_get_host() failed");
		e = GFARM_ERR_OPERATION_NOT_PERMITTED;
	} else if (is_direct_connection &&
	    (e = gfp_xdr_async_peer_new(&async)) != GFARM_ERR_NO_ERROR) {
		gflog_error(GFARM_MSG_1002288,
		    "%s: gfp_xdr_async_peer_new(): %s",
		    diag, gfarm_error_string(e));
	}
	giant_unlock();

	e2 = gfm_server_relay_put_reply(peer, xid, sizep, relay,
	    diag, &e,  "i", &i/*XXX FIXME*/);
	if (e2 != GFARM_ERR_NO_ERROR)
		return (e2);
	if (debug_mode)
		gflog_debug(GFARM_MSG_1000404, "gfp_xdr_flush");
	e2 = gfp_xdr_flush(peer_get_conn(peer));
	if (e2 != GFARM_ERR_NO_ERROR) {
		gflog_warning(GFARM_MSG_1000405,
		    "%s: protocol flush: %s",
		    diag, gfarm_error_string(e2));
		return (e2);
	} else if (e != GFARM_ERR_NO_ERROR)
		return (e2);

	if (is_direct_connection) {
		local_peer = peer_to_local_peer(peer);
		local_peer_set_async(local_peer, async); /* XXXRELAY */
		local_peer_set_readable_watcher(local_peer,
		    back_channel_recv_watcher);
	}

	if (host_is_up(host)) /* throw away old connetion */ {
		gflog_warning(GFARM_MSG_1002440,
		    "back_channel(%s): switching to new connection",
		    host_name(host));
		host_disconnect_request(host, NULL);
	}

	giant_lock();
	peer_set_peer_type(peer, peer_type_back_channel);
	abstract_host_set_peer(host_to_abstract_host(host), peer, version);
	giant_unlock();

	if (is_direct_connection) {
		local_peer_watch_readable(local_peer);
		gfarm_thr_statewait_signal(
		    local_peer_get_statewait(local_peer), e2, diag);
	}

	callout_setfunc(host_status_callout(host),
	    NULL /* or, use back_channel_send_manager thread pool? */,
	    gfs_client_status_callout, host);
	gfs_client_status_schedule(host, 1);
	gflog_info(GFARM_MSG_1004035,
	    "back_channel(%s): started", host_name(host));

	return (e2);
}