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; }
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; }
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; }
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; }