예제 #1
0
파일: psmx_ns.c 프로젝트: jshimek/libfabric
static int psmx_ns_connect_server(const char *server)
{
	struct addrinfo hints = {
		.ai_family   = AF_UNSPEC,
		.ai_socktype = SOCK_STREAM
	};
	struct addrinfo *res, *p;
	psm_uuid_t uuid;
	int port;
	char *service;
	int sockfd = -1;
	int n;

	psmx_get_uuid(uuid);
	port = psmx_uuid_to_port(uuid);

	if (asprintf(&service, "%d", port) < 0)
		return -1;

	n = getaddrinfo(server, service, &hints, &res);
	if (n < 0) {
		FI_INFO(&psmx_prov, FI_LOG_CORE,
			"(%s:%d):%s\n", server, port, gai_strerror(n));
		free(service);
		return -1;
	}

	for (p = res; p; p = p->ai_next) {
		sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
		if (sockfd >= 0) {
			if (!connect(sockfd, p->ai_addr, p->ai_addrlen))
				break;
			close(sockfd);
			sockfd = -1;
		}
	}

	if (sockfd < 0) {
		FI_INFO(&psmx_prov, FI_LOG_CORE,
			"couldn't connect to %s:%d\n", server, port);
	}

	freeaddrinfo(res);
	free(service);

	return sockfd;
}
예제 #2
0
void *psmx_resolve_name(const char *servername, int port)
{
	struct addrinfo hints = {
		.ai_family   = AF_UNSPEC,
		.ai_socktype = SOCK_STREAM
	};
	struct addrinfo *res, *p;
	psm_uuid_t uuid;
	char *service;
	void *dest_addr;
	int sockfd = -1;
	int n;

	if (!port) {
		psmx_get_uuid(uuid);
		port = psmx_uuid_to_port(uuid);
	}

	if (asprintf(&service, "%d", port) < 0)
		return NULL;

	n = getaddrinfo(servername, service, &hints, &res);
	if (n < 0) {
		FI_INFO(&psmx_prov, FI_LOG_CORE,
			"(%s:%d):%s\n", servername, port, gai_strerror(n));
		free(service);
		return NULL;
	}

	for (p = res; p; p = p->ai_next) {
		sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
		if (sockfd >= 0) {
			if (!connect(sockfd, p->ai_addr, p->ai_addrlen))
				break;
			close(sockfd);
			sockfd = -1;
		}
	}

	freeaddrinfo(res);
	free(service);

	if (sockfd < 0) {
		FI_INFO(&psmx_prov, FI_LOG_CORE,
			"couldn't connect to %s:%d\n", servername, port);
		return NULL;
	}

	dest_addr = calloc(1,sizeof(psm_epid_t));
	if (!dest_addr) {
		close(sockfd);
		return NULL;
	}

	if (read(sockfd, dest_addr, sizeof(psm_epid_t)) != sizeof(psm_epid_t)) {
		FI_INFO(&psmx_prov, FI_LOG_CORE,
			"error reading response from %s:%d\n", servername, port);
		free(dest_addr);
		close(sockfd);
		return NULL;
	}

	close(sockfd);

	return dest_addr;
}
예제 #3
0
void *psmx_name_server(void *args)
{
	struct psmx_fid_fabric *fabric;
	struct addrinfo hints = {
		.ai_flags = AI_PASSIVE,
		.ai_family = AF_UNSPEC,
		.ai_socktype = SOCK_STREAM
	};
	struct addrinfo *res, *p;
	char *service;
	int listenfd = -1, connfd;
	int port;
	int n;
	int ret;

	fabric = args;
	port = psmx_uuid_to_port(fabric->uuid);

	FI_INFO(&psmx_prov, FI_LOG_CORE, "port: %d\n", port);

	if (asprintf(&service, "%d", port) < 0)
		return NULL;

	n = getaddrinfo(NULL, service, &hints, &res);
	if (n < 0) {
		FI_INFO(&psmx_prov, FI_LOG_CORE,
			"port %d: %s\n", port, gai_strerror(n));
		free(service);
		return NULL;
	}

	for (p=res; p; p=p->ai_next) {
		listenfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
		if (listenfd >= 0) {
			n = 1;
			if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1)
				FI_WARN(&psmx_prov, FI_LOG_CORE, "setsockopt: %s\n", strerror(errno));
			if (!bind(listenfd, p->ai_addr, p->ai_addrlen))
				break;
			close(listenfd);
			listenfd = -1;
		}
	}

	freeaddrinfo(res);
	free(service);

	if (listenfd < 0) {
		FI_INFO(&psmx_prov, FI_LOG_CORE,
			"couldn't listen to port %d. try set FI_PSM_UUID to a different value?\n", port);
		return NULL;
	}

	listen(listenfd, 256);

	pthread_cleanup_push(psmx_name_server_cleanup, (void *)(uintptr_t)listenfd);
	FI_INFO(&psmx_prov, FI_LOG_CORE, "Start working ...\n");

	while (1) {
		connfd = accept(listenfd, NULL, 0);
		if (connfd >= 0) {
			if (fabric->active_domain) {
				ret = write(connfd, &fabric->active_domain->psm_epid,
					    sizeof(psm_epid_t));
				if (ret != sizeof(psm_epid_t))
					FI_WARN(&psmx_prov, FI_LOG_CORE,
						"error sending address info to the client\n");
			}
			close(connfd);
		}
	}

	pthread_cleanup_pop(1);

	return NULL;
}
예제 #4
0
파일: psmx_ns.c 프로젝트: jshimek/libfabric
static void *psmx_name_server_func(void *args)
{
	struct psmx_fid_fabric *fabric;
	struct addrinfo hints = {
		.ai_flags = AI_PASSIVE,
		.ai_family = AF_UNSPEC,
		.ai_socktype = SOCK_STREAM
	};
	struct addrinfo *res, *p;
	char *service;
	int listenfd = -1, connfd;
	int port;
	int n;
	int ret;
	struct psmx_ns_cmd cmd;

	fabric = args;
	port = psmx_uuid_to_port(fabric->uuid);

	FI_INFO(&psmx_prov, FI_LOG_CORE, "port: %d\n", port);

	if (asprintf(&service, "%d", port) < 0)
		return NULL;

	n = getaddrinfo(NULL, service, &hints, &res);
	if (n < 0) {
		FI_INFO(&psmx_prov, FI_LOG_CORE,
			"port %d: %s\n", port, gai_strerror(n));
		free(service);
		return NULL;
	}

	for (p=res; p; p=p->ai_next) {
		listenfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
		if (listenfd >= 0) {
			n = 1;
			if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1)
				FI_WARN(&psmx_prov, FI_LOG_CORE,
					"setsockopt: %s\n", strerror(errno));
			if (!bind(listenfd, p->ai_addr, p->ai_addrlen))
				break;
			close(listenfd);
			listenfd = -1;
		}
	}

	freeaddrinfo(res);
	free(service);

	if (listenfd < 0) {
		FI_INFO(&psmx_prov, FI_LOG_CORE,
			"couldn't bind to port %d. It is fine if another process from the "
			"same job has started the name server.\nHowever, if that's not the "
			"case, try set FI_PSM_UUID to a different value.\n",
			port);
		return NULL;
	}

	if (psmx_ns_map_init()) {
		close(listenfd);
		return NULL;
	}

	listen(listenfd, 256);

	pthread_cleanup_push(psmx_name_server_cleanup, (void *)(uintptr_t)listenfd);
	FI_INFO(&psmx_prov, FI_LOG_CORE, "Start working ...\n");

	while (1) {
		connfd = accept(listenfd, NULL, 0);
		if (connfd >= 0) {
			ret = read(connfd, &cmd, sizeof(cmd));
			if (ret != sizeof(cmd)) {
				FI_WARN(&psmx_prov, FI_LOG_CORE,
					"error reading command from client\n");
			} else {
				switch(cmd.op) {
				case PSMX_NS_ADD:
					psmx_ns_map_add(cmd.service, cmd.name);
					break;

				case PSMX_NS_DEL:
					psmx_ns_map_del(cmd.service, cmd.name);
					break;

				case PSMX_NS_QUERY:
					cmd.op = PSMX_NS_ACK;
					cmd.status = psmx_ns_map_lookup(&cmd.service, &cmd.name);
					ret = write(connfd, &cmd, sizeof(cmd));
					if (ret != sizeof(cmd))
						FI_WARN(&psmx_prov, FI_LOG_CORE,
							"error sending address info to the client\n");
					break;

				default:
					FI_WARN(&psmx_prov, FI_LOG_CORE,
						"invalid command from client: %d\n", cmd.op);
					break;
				}
			}
			close(connfd);
		}
	}

	pthread_cleanup_pop(1);

	return NULL;
}