static HYD_status exec_args_fn(char *arg, char ***argv) { long int i, count; struct HYD_exec *exec = NULL; HYD_status status = HYD_SUCCESS; if (**argv == NULL) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "NULL argument to exec args\n"); for (exec = HYD_pmcd_pmip.exec_list; exec->next; exec = exec->next); count = strtol(**argv, NULL, 10); if (errno == ERANGE || errno == EINVAL) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "Exec arg not convertible to integer\n"); for (i = 0; i < count; i++) { (*argv)++; exec->exec[i] = MPL_strdup(**argv); } exec->exec[i] = NULL; (*argv)++; fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDT_ftb_init(void) { int ret; FTB_client_t ci; HYD_status status = HYD_SUCCESS; MPL_strncpy(ci.event_space, "ftb.mpi.hydra", sizeof(ci.event_space)); MPL_strncpy(ci.client_name, "hydra " HYDRA_VERSION, sizeof(ci.client_name)); MPL_strncpy(ci.client_subscription_style, "FTB_SUBSCRIPTION_NONE", sizeof(ci.client_subscription_style)); ci.client_polling_queue_len = -1; ret = FTB_Connect(&ci, &ch); if (ret) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "ftb connect\n"); ret = FTB_Declare_publishable_events(ch, NULL, event_info, sizeof(event_info) / sizeof(event_info[0])); if (ret) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "ftb declare publishable\n"); fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
static HYD_status match_arg(char ***argv_p, struct HYD_arg_match_table *match_table) { struct HYD_arg_match_table *m; char *arg, *val; HYD_status status = HYD_SUCCESS; arg = **argv_p; while (*arg == '-') /* Remove leading dashes */ arg++; /* If arg is of the form foo=bar, we separate it out as two * arguments */ for (val = arg; *val && *val != '='; val++); if (*val == '=') { /* Found an '='; use the rest of the argument as a separate * argument */ **argv_p = val + 1; } else { /* Move to the next argument */ (*argv_p)++; } *val = 0; /* close out key */ m = match_table; while (m->handler_fn) { if (!strcasecmp(arg, m->arg)) { if (**argv_p && (!strcmp(**argv_p, "-h") || !strcmp(**argv_p, "-help") || !strcmp(**argv_p, "--help"))) { if (m->help_fn == NULL) { HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "No help message available\n"); } else { m->help_fn(); HYDU_ERR_SETANDJUMP(status, HYD_GRACEFUL_ABORT, "%s", ""); } } status = m->handler_fn(arg, argv_p); HYDU_ERR_POP(status, "match handler returned error\n"); break; } m++; } if (m->handler_fn == NULL) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "unrecognized argument %s\n", arg); fn_exit: return status; fn_fail: goto fn_exit; }
HYD_status HYDU_parse_hostfile(const char *hostfile, struct HYD_node **node_list, HYD_status(*process_token) (char *token, int newline, struct HYD_node ** node_list)) { char line[HYD_TMP_STRLEN], **tokens; FILE *fp; int i; HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); if ((fp = fopen(hostfile, "r")) == NULL) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "unable to open host file: %s\n", hostfile); if (node_list) *node_list = NULL; while (fgets(line, HYD_TMP_STRLEN, fp)) { char *linep = NULL; linep = line; strtok(linep, "#"); while (isspace(*linep)) linep++; /* Ignore blank lines & comments */ if ((*linep == '#') || (*linep == '\0')) continue; tokens = HYDU_str_to_strlist(linep); if (!tokens) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "Unable to convert host file entry to strlist\n"); for (i = 0; tokens[i]; i++) { status = process_token(tokens[i], !i, node_list); HYDU_ERR_POP(status, "unable to process token\n"); } HYDU_free_strlist(tokens); MPL_free(tokens); } fclose(fp); fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDU_process_mfile_token(char *token, int newline, struct HYD_node **node_list) { int num_procs; char *hostname, *procs, *binding, *tmp, *user, *saveptr; struct HYD_node *node; HYD_status status = HYD_SUCCESS; if (newline) { /* The first entry gives the hostname and processes */ hostname = strtok_r(token, ":", &saveptr); procs = strtok_r(NULL, ":", &saveptr); num_procs = procs ? atoi(procs) : 1; status = HYDU_add_to_node_list(hostname, num_procs, node_list); HYDU_ERR_POP(status, "unable to add to node list\n"); } else { /* Not a new line */ tmp = strtok_r(token, "=", &saveptr); if (!strcmp(tmp, "binding")) { binding = strtok_r(NULL, "=", &saveptr); for (node = *node_list; node->next; node = node->next); if (node->local_binding) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "duplicate local binding setting\n"); node->local_binding = MPL_strdup(binding); } else if (!strcmp(tmp, "user")) { user = strtok_r(NULL, "=", &saveptr); for (node = *node_list; node->next; node = node->next); if (node->user) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "duplicate username setting\n"); node->user = MPL_strdup(user); } else { HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "token %s not supported at this time\n", token); } } fn_exit: return status; fn_fail: goto fn_exit; }
HYD_status HYDU_sock_get_iface_ip(char *iface, char **ip) { HYD_status status = HYD_SUCCESS; #if defined(HAVE_GETIFADDRS) struct ifaddrs *ifaddr, *ifa; char buf[MAX_HOSTNAME_LEN]; struct sockaddr_in *sa; /* Got the interface name; let's query for the IP address */ if (getifaddrs(&ifaddr) == -1) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "getifaddrs failed\n"); for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) if (!strcmp(ifa->ifa_name, iface) && (ifa->ifa_addr) && (ifa->ifa_addr->sa_family == AF_INET)) break; if (!ifa) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "unable to find interface %s\n", iface); sa = (struct sockaddr_in *) ifa->ifa_addr; #if defined HAVE_INET_NTOP (*ip) = MPL_strdup((char *) inet_ntop(AF_INET, (const void *) &(sa->sin_addr), buf, MAX_HOSTNAME_LEN)); #else (*ip) = NULL; #endif /* HAVE_INET_NTOP */ if (!*ip) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "unable to find IP for interface %s\n", iface); freeifaddrs(ifaddr); #else /* For now just disable interface selection when getifaddrs isn't * available, such as on AIX. In the future we can implement in MPL * something along the lines of MPIDI_GetIPInterface from tcp_getip.c in * nemesis. */ HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "interface selection not supported on this platform\n"); #endif fn_exit: return status; fn_fail: goto fn_exit; }
HYD_status HYDTI_bscd_ll_query_node_count(int *count) { char *hostfile; HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); if (MPL_env2str("LOADL_HOSTFILE", (const char **) &hostfile) == 0) hostfile = NULL; if (hostfile == NULL) { HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "No LL nodefile found\n"); } else { total_node_count = 0; status = HYDU_parse_hostfile(hostfile, NULL, process_mfile_count); HYDU_ERR_POP(status, "error parsing hostfile\n"); *count = total_node_count; } fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDT_topo_bind(int idx) { HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); if (idx < 0 || ignore_binding) goto fn_exit; #if defined HAVE_HWLOC if (!strcmp(HYDT_topo_info.topolib, "hwloc")) { status = HYDT_topo_hwloc_bind(idx); HYDU_ERR_POP(status, "HWLOC failure binding process to core\n"); goto fn_exit; } #endif /* HAVE_HWLOC */ HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "no topology library available\n"); fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
static HYD_status exec_local_env_fn(char *arg, char ***argv) { struct HYD_exec *exec = NULL; int i, count; char *str; HYD_status status = HYD_SUCCESS; if (**argv == NULL) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "NULL argument to exec local env\n"); for (exec = HYD_pmcd_pmip.exec_list; exec->next; exec = exec->next); count = atoi(**argv); for (i = 0; i < count; i++) { (*argv)++; str = **argv; /* Environment variables are quoted; remove them */ if (*str == '\'') { str++; str[strlen(str) - 1] = 0; } HYDU_append_env_str_to_list(str, &exec->user_env); } (*argv)++; fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
static HYD_status exec_args_fn(char *arg, char ***argv) { int i, count; struct HYD_exec *exec = NULL; HYD_status status = HYD_SUCCESS; if (**argv == NULL) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "NULL argument to exec args\n"); for (exec = HYD_pmcd_pmip.exec_list; exec->next; exec = exec->next); count = atoi(**argv); for (i = 0; i < count; i++) { (*argv)++; exec->exec[i] = MPL_strdup(**argv); } exec->exec[i] = NULL; (*argv)++; fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
static HYD_status process_mfile_token(char *token, int newline, struct HYD_node **node_list) { int num_procs; static int entry_count = 0; static char *hostname; HYD_status status = HYD_SUCCESS; entry_count++; if (newline) { /* The first entry gives the hostname */ entry_count = 1; if (hostname) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "unexpected token %s\n", token); hostname = HYDU_strdup(token); } else { /* Not a new line */ if (entry_count != 2) goto fn_exit; num_procs = atoi(token); status = HYDU_add_to_node_list(hostname, num_procs, node_list); HYDU_ERR_POP(status, "unable to initialize proxy\n"); hostname = NULL; } fn_exit: return status; fn_fail: goto fn_exit; }
HYD_status HYDT_bscu_stdio_cb(int fd, HYD_event_t events, void *userp) { int stdfd, closed, i; HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); stdfd = (int) (size_t) userp; status = HYDU_sock_forward_stdio(fd, stdfd, &closed); HYDU_ERR_POP(status, "stdio forwarding error\n"); if (closed || (events & HYD_POLLHUP)) { /* connection has closed */ status = HYDT_dmx_deregister_fd(fd); HYDU_ERR_SETANDJUMP(status, status, "error deregistering fd %d\n", fd); for (i = 0; i < HYD_bscu_fd_count; i++) { if (HYD_bscu_fd_list[i] == fd) { HYD_bscu_fd_list[i] = HYD_FD_CLOSED; break; } } close(fd); } fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDU_strsplit(char *str, char **str1, char **str2, char sep) { int i; HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); if (str == NULL) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, ""); *str1 = HYDU_strdup(str); for (i = 0; (*str1)[i] && ((*str1)[i] != sep); i++); if ((*str1)[i] == 0) /* End of the string */ *str2 = NULL; else { *str2 = HYDU_strdup(&((*str1)[i + 1])); (*str1)[i] = 0; } fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDT_bscd_sge_query_node_list(struct HYD_node **node_list) { char *hostfile; HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); if (MPL_env2str("PE_HOSTFILE", (const char **) &hostfile) == 0) hostfile = NULL; if (hostfile == NULL) { *node_list = NULL; HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "No SGE nodefile found\n"); } else { status = HYDU_parse_hostfile(hostfile, node_list, process_mfile_token); HYDU_ERR_POP(status, "error parsing hostfile\n"); } fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDT_topo_hwloc_init(const char *binding, const char *mapping, const char *membind) { HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); HYDU_ASSERT(binding, status); hwloc_topology_init(&topology); hwloc_topology_load(topology); HYDT_topo_hwloc_info.total_num_pus = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_PU); hwloc_initialized = 1; /* bindings that don't require mapping */ if (!strncmp(binding, "user:"******"user:"******"user:"******"error binding to %s\n", binding); goto fn_exit; } else if (!strcmp(binding, "rr")) { status = handle_rr_binding(); HYDU_ERR_POP(status, "error binding to %s\n", binding); goto fn_exit; } status = handle_bitmap_binding(binding, mapping ? mapping : binding); HYDU_ERR_POP(status, "error binding with bind \"%s\" and map \"%s\"\n", binding, mapping); /* Memory binding options */ if (membind == NULL) HYDT_topo_hwloc_info.membind = HWLOC_MEMBIND_DEFAULT; else if (!strcmp(membind, "firsttouch")) HYDT_topo_hwloc_info.membind = HWLOC_MEMBIND_FIRSTTOUCH; else if (!strcmp(membind, "nexttouch")) HYDT_topo_hwloc_info.membind = HWLOC_MEMBIND_NEXTTOUCH; else if (!strncmp(membind, "bind:", strlen("bind:"))) { HYDT_topo_hwloc_info.membind = HWLOC_MEMBIND_BIND; } else if (!strncmp(membind, "interleave:", strlen("interleave:"))) { HYDT_topo_hwloc_info.membind = HWLOC_MEMBIND_INTERLEAVE; } else if (!strncmp(membind, "replicate:", strlen("replicate:"))) { HYDT_topo_hwloc_info.membind = HWLOC_MEMBIND_REPLICATE; } else { HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "unrecognized membind policy \"%s\"\n", membind); } fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
static HYD_status handle_pmi_cmd(int fd, int pgid, int pid, char *buf, int pmi_version) { char **args = NULL, *cmd = NULL; struct HYD_pmcd_pmi_handle *h; int i; HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); if (pmi_version == 1) HYD_pmcd_pmi_handle = HYD_pmcd_pmi_v1; else HYD_pmcd_pmi_handle = HYD_pmcd_pmi_v2; if (HYD_server_info.user_global.debug) HYDU_dump(stdout, "[pgid: %d] got PMI command: %s\n", pgid, buf); HYDU_MALLOC(args, char **, MAX_PMI_ARGS * sizeof(char *), status); for (i = 0; i < MAX_PMI_ARGS; i++) args[i] = NULL; status = HYD_pmcd_pmi_parse_pmi_cmd(buf, pmi_version, &cmd, args); HYDU_ERR_POP(status, "unable to parse PMI command\n"); #if defined ENABLE_PROFILING if (HYD_server_info.enable_profiling) HYD_server_info.num_pmi_calls++; #endif /* ENABLE_PROFILING */ h = HYD_pmcd_pmi_handle; while (h->handler) { if (!strcmp(cmd, h->cmd)) { status = h->handler(fd, pid, pgid, args); HYDU_ERR_POP(status, "PMI handler returned error\n"); break; } h++; } if (!h->handler) { /* We don't understand the command */ HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "Unrecognized PMI command: %s | cleaning up processes\n", cmd); } fn_exit: if (cmd) HYDU_FREE(cmd); if (args) { HYDU_free_strlist(args); HYDU_free(args); } HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDU_sock_accept(int listen_fd, int *fd) { int one = 1; HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); *fd = accept(listen_fd, 0, 0); if (*fd < 0) HYDU_ERR_SETANDJUMP(status, HYD_SOCK_ERROR, "accept error (%s)\n", MPL_strerror(errno)); /* Disable nagle */ if (setsockopt(*fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(int)) < 0) HYDU_ERR_SETANDJUMP(status, HYD_SOCK_ERROR, "cannot set TCP_NODELAY\n"); fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDU_sock_create_and_listen_portstr(char *iface, char *hostname, char *port_range, char **port_str, HYD_status(*callback) (int fd, HYD_event_t events, void *userp), void *userp) { int listenfd; char *sport, *real_port_range, *ip = NULL; uint16_t port; HYD_status status = HYD_SUCCESS; /* Listen on a port in the port range */ port = 0; real_port_range = port_range ? MPL_strdup(port_range) : NULL; status = HYDU_sock_listen(&listenfd, real_port_range, &port); HYDU_ERR_POP(status, "unable to listen on port\n"); /* Register the listening socket with the demux engine */ status = HYDT_dmx_register_fd(1, &listenfd, HYD_POLLIN, userp, callback); HYDU_ERR_POP(status, "unable to register fd\n"); /* Create a port string for MPI processes to use to connect to */ if (iface) { status = HYDU_sock_get_iface_ip(iface, &ip); HYDU_ERR_POP(status, "unable to get network interface IP\n"); } else if (hostname) { ip = MPL_strdup(hostname); } else { char localhost[MAX_HOSTNAME_LEN] = { 0 }; if (gethostname(localhost, MAX_HOSTNAME_LEN) < 0) HYDU_ERR_SETANDJUMP(status, HYD_SOCK_ERROR, "unable to get local hostname\n"); ip = MPL_strdup(localhost); } sport = HYDU_int_to_str(port); HYDU_MALLOC_OR_JUMP(*port_str, char *, strlen(ip) + 1 + strlen(sport) + 1, status); MPL_snprintf(*port_str, strlen(ip) + 1 + strlen(sport) + 1, "%s:%s", ip, sport); MPL_free(sport); fn_exit: if (ip) MPL_free(ip); return status; fn_fail: goto fn_exit; }
HYD_status HYDU_sock_read(int fd, void *buf, int maxlen, int *recvd, int *closed, enum HYDU_sock_comm_flag flag) { int tmp; HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); HYDU_ASSERT(maxlen, status); *recvd = 0; *closed = 0; while (1) { do { tmp = read(fd, (char *) buf + *recvd, maxlen - *recvd); if (tmp < 0) { if (errno == ECONNRESET || fd == STDIN_FILENO) { /* If the remote end closed the socket or if we * get an EINTR on stdin, set the socket to be * closed and jump out */ *closed = 1; status = HYD_SUCCESS; goto fn_exit; } } } while (tmp < 0 && errno == EINTR); if (tmp < 0) { HYDU_ERR_SETANDJUMP(status, HYD_SOCK_ERROR, "read error (%s)\n", MPL_strerror(errno)); } else if (tmp == 0) { *closed = 1; goto fn_exit; } else { *recvd += tmp; } if (flag == HYDU_SOCK_COMM_NONE || *recvd == maxlen) break; } fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDT_bscd_lsf_query_node_list(struct HYD_node **node_list) { char *hosts, *hostname, *num_procs_str, *thosts = NULL; int num_procs; HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); if (MPL_env2str("LSB_MCPU_HOSTS", (const char **) &hosts) == 0) hosts = NULL; if (hosts == NULL) { *node_list = NULL; HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "No LSF node list found\n"); } else { hosts = HYDU_strdup(hosts); thosts = hosts; hostname = strtok(hosts, " "); while (1) { if (hostname == NULL) break; /* the even fields in the list should be the number of * cores */ num_procs_str = strtok(NULL, " "); HYDU_ASSERT(num_procs_str, status); num_procs = atoi(num_procs_str); status = HYDU_add_to_node_list(hostname, num_procs, node_list); HYDU_ERR_POP(status, "unable to add to node list\n"); hostname = strtok(NULL, " "); } if (thosts) HYDU_FREE(thosts); } fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDT_ftb_finalize(void) { int ret; HYD_status status = HYD_SUCCESS; ret = FTB_Disconnect(ch); if (ret) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "ftb disconnect\n"); fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDU_set_str(char *arg, char **var, const char *val) { HYD_status status = HYD_SUCCESS; HYDU_ERR_CHKANDJUMP(status, *var, HYD_INTERNAL_ERROR, "duplicate setting: %s\n", arg); if (val == NULL) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "cannot assign NULL object\n"); *var = MPL_strdup(val); fn_exit: return status; fn_fail: goto fn_exit; }
static HYD_status version_fn(char *arg, char ***argv) { HYD_status status = HYD_SUCCESS; if (strcmp(**argv, HYDRA_VERSION)) { HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "UI version string does not match proxy version\n"); } (*argv)++; fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDT_bscd_ll_query_proxy_id(int *proxy_id) { HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); if (MPL_env2int("MP_CHILD", proxy_id) == 0) { *proxy_id = -1; HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "cannot find ll proxy ID\n"); } fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDU_sock_write(int fd, const void *buf, int maxlen, int *sent, int *closed, enum HYDU_sock_comm_flag flag) { int tmp; HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); HYDU_ASSERT(maxlen, status); *sent = 0; *closed = 0; while (1) { tmp = write(fd, (char *) buf + *sent, maxlen - *sent); if (tmp <= 0) { if (errno == EAGAIN) { if (flag == HYDU_SOCK_COMM_NONE) goto fn_exit; else continue; } else if (errno == ECONNRESET) { *closed = 1; goto fn_exit; } HYDU_ERR_SETANDJUMP(status, HYD_SOCK_ERROR, "write error (%s)\n", MPL_strerror(errno)); } else { *sent += tmp; } if (flag == HYDU_SOCK_COMM_NONE || *sent == maxlen) break; } fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDU_sock_is_local(char *host, int *is_local) { char lhost[MAX_HOSTNAME_LEN]; HYD_status status = HYD_SUCCESS; *is_local = 0; if (gethostname(lhost, MAX_HOSTNAME_LEN) < 0) { HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "gethostname returned an error\n"); } else if (!strcmp(lhost, host)) { *is_local = 1; } fn_exit: return status; fn_fail: goto fn_exit; }
HYD_status HYDT_ftb_publish(const char *event_name, const char *event_payload) { FTB_event_properties_t event_prop; FTB_event_handle_t event_handle; int ret; HYD_status status = HYD_SUCCESS; event_prop.event_type = 1; MPL_strncpy(event_prop.event_payload, event_payload, sizeof(event_prop.event_payload)); ret = FTB_Publish(ch, event_name, &event_prop, &event_handle); if (ret) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "ftb publish\n"); fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
HYD_status HYDU_sock_set_nonblock(int fd) { int flags; HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); if ((flags = fcntl(fd, F_GETFL, 0)) == -1) flags = 0; #if defined O_NONBLOCK if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) HYDU_ERR_SETANDJUMP(status, HYD_SOCK_ERROR, "fcntl failed on %d\n", fd); #endif /* O_NONBLOCK */ fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
char *HYDU_getcwd(void) { char *cwdval, *retval = NULL; const char *pwdval; HYD_status status = HYD_SUCCESS; #if defined HAVE_STAT struct stat spwd, scwd; #endif /* HAVE_STAT */ if (MPL_env2str("PWD", &pwdval) == 0) pwdval = NULL; HYDU_MALLOC_OR_JUMP(cwdval, char *, HYDRA_MAX_PATH, status); if (getcwd(cwdval, HYDRA_MAX_PATH) == NULL) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "allocated space is too small for absolute path\n"); #if defined HAVE_STAT if (pwdval && stat(pwdval, &spwd) != -1 && stat(cwdval, &scwd) != -1 && spwd.st_dev == scwd.st_dev && spwd.st_ino == scwd.st_ino) { /* PWD and getcwd() match; use the PWD value */ retval = MPL_strdup(pwdval); MPL_free(cwdval); } else #endif /* HAVE_STAT */ { /* PWD and getcwd() don't match; use the getcwd value and hope * for the best. */ retval = cwdval; } fn_exit: return retval; fn_fail: goto fn_exit; }
HYD_status HYDT_bscd_ll_launch_procs(char **args, struct HYD_proxy *proxy_list, int *control_fd) { int idx, i, total_procs, node_count; int *pid, *fd_list, exec_idx; char *targs[HYD_NUM_TMP_STRINGS], *node_list_str = NULL; char *path = NULL, *extra_arg_list = NULL, *extra_arg, quoted_exec_string[HYD_TMP_STRLEN]; struct HYD_proxy *proxy; struct HYDT_topo_cpuset_t cpuset; HYD_status status = HYD_SUCCESS; HYDU_FUNC_ENTER(); /* We use the following priority order for the executable path: * (1) user-specified; (2) search in path; (3) Hard-coded * location */ if (HYDT_bsci_info.launcher_exec) path = HYDU_strdup(HYDT_bsci_info.launcher_exec); if (!path) path = HYDU_find_full_path("poe"); if (!path) path = HYDU_strdup("/usr/bin/poe"); idx = 0; targs[idx++] = HYDU_strdup(path); if (!strcmp(HYDT_bsci_info.rmk, "ll")) { HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "ll does not support user-defined host lists\n"); } /* Check how many nodes are being passed for the launch */ status = HYDTI_bscd_ll_query_node_count(&total_procs); HYDU_ERR_POP(status, "unable to query for the node count\n"); node_count = 0; for (proxy = proxy_list; proxy; proxy = proxy->next) node_count++; if (total_procs != node_count) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "processes to be launched have to cover all nodes\n"); MPL_env2str("HYDRA_LAUNCHER_EXTRA_ARGS", (const char **) &extra_arg_list); if (extra_arg_list) { extra_arg = strtok(extra_arg_list, " "); while (extra_arg) { targs[idx++] = HYDU_strdup(extra_arg); extra_arg = strtok(NULL, " "); } } /* Fill in the remaining arguments */ exec_idx = idx; for (i = 0; args[i]; i++) targs[idx++] = HYDU_strdup(args[i]); /* Create a quoted version of the exec string, which is only used * when the executable is not launched directly, but through an * actual launcher */ HYDU_snprintf(quoted_exec_string, HYD_TMP_STRLEN, "\"%s\"", targs[exec_idx]); HYDU_FREE(targs[exec_idx]); targs[exec_idx] = quoted_exec_string; /* Increase pid list to accommodate the new pid */ HYDU_MALLOC(pid, int *, (HYD_bscu_pid_count + 1) * sizeof(int), status); for (i = 0; i < HYD_bscu_pid_count; i++) pid[i] = HYD_bscu_pid_list[i]; HYDU_FREE(HYD_bscu_pid_list); HYD_bscu_pid_list = pid; /* Increase fd list to accommodate these new fds */ HYDU_MALLOC(fd_list, int *, (HYD_bscu_fd_count + 3) * sizeof(int), status); for (i = 0; i < HYD_bscu_fd_count; i++) fd_list[i] = HYD_bscu_fd_list[i]; HYDU_FREE(HYD_bscu_fd_list); HYD_bscu_fd_list = fd_list; /* append proxy ID as -1 */ targs[idx++] = HYDU_int_to_str(-1); targs[idx++] = NULL; HYDT_topo_cpuset_zero(&cpuset); status = HYDU_create_process(targs, NULL, NULL, &fd_stdout, &fd_stderr, &HYD_bscu_pid_list[HYD_bscu_pid_count++], cpuset); HYDU_ERR_POP(status, "create process returned error\n"); HYD_bscu_fd_list[HYD_bscu_fd_count++] = fd_stdout; HYD_bscu_fd_list[HYD_bscu_fd_count++] = fd_stderr; status = HYDT_dmx_register_fd(1, &fd_stdout, HYD_POLLIN, (void *) (size_t) STDOUT_FILENO, HYDT_bscu_stdio_cb); HYDU_ERR_POP(status, "demux returned error registering fd\n"); status = HYDT_dmx_register_fd(1, &fd_stderr, HYD_POLLIN, (void *) (size_t) STDERR_FILENO, HYDT_bscu_stdio_cb); HYDU_ERR_POP(status, "demux returned error registering fd\n"); fn_exit: if (node_list_str) HYDU_FREE(node_list_str); HYDU_free_strlist(targs); if (path) HYDU_FREE(path); HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }