1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2013      The University of Tennessee and The University
4  *                         of Tennessee Research Foundation.  All rights
5  *                         reserved.
6  * Copyright (c) 2013      Inria.  All rights reserved.
7  * Copyright (c) 2014-2017 Intel, Inc.  All rights reserved.
8  * Copyright (c) 2014-2017 Research Organization for Information Science
9  *                         and Technology (RIST). All rights reserved.
10  * Copyright (c) 2015      Los Alamos National Security, LLC. All rights
11  *                         reserved.
12  * $COPYRIGHT$
13  *
14  * Additional copyrights may follow
15  *
16  * $HEADER$
17  */
18 
19 #include "proc.h"
20 #include "opal/util/proc.h"
21 #include "opal/util/arch.h"
22 #include "opal/mca/pmix/pmix.h"
23 
24 opal_process_name_t opal_name_wildcard = {OPAL_JOBID_WILDCARD, OPAL_VPID_WILDCARD};
25 opal_process_name_t opal_name_invalid = {OPAL_JOBID_INVALID, OPAL_VPID_INVALID};
26 
27 opal_process_info_t opal_process_info = {
28     .nodename = NULL,
29     .job_session_dir = NULL,
30     .proc_session_dir = NULL,
31     .num_local_peers = 0,  /* there is nobody else but me */
32     .my_local_rank = 0,    /* I'm the only process around here */
33     .cpuset = NULL,
34 };
35 
36 static opal_proc_t opal_local_proc = {
37     { .opal_list_next = NULL,
38       .opal_list_prev = NULL},
39     {OPAL_JOBID_INVALID, OPAL_VPID_INVALID},
40     0,
41     0,
42     NULL,
43     NULL
44 };
45 static opal_proc_t* opal_proc_my_name = &opal_local_proc;
46 
opal_proc_construct(opal_proc_t * proc)47 static void opal_proc_construct(opal_proc_t* proc)
48 {
49     proc->proc_arch = opal_local_arch;
50     proc->proc_convertor = NULL;
51     proc->proc_flags = 0;
52     proc->proc_name = *OPAL_NAME_INVALID;
53     proc->proc_hostname  = NULL;
54 }
55 
opal_proc_destruct(opal_proc_t * proc)56 static void opal_proc_destruct(opal_proc_t* proc)
57 {
58     proc->proc_flags     = 0;
59     proc->proc_name      = *OPAL_NAME_INVALID;
60     proc->proc_hostname  = NULL;
61     proc->proc_convertor = NULL;
62 }
63 
64 OBJ_CLASS_INSTANCE(opal_proc_t, opal_list_item_t,
65                    opal_proc_construct, opal_proc_destruct);
66 
67 OBJ_CLASS_INSTANCE(opal_namelist_t, opal_list_item_t,
68                    NULL, NULL);
69 
70 static int
opal_compare_opal_procs(const opal_process_name_t p1,const opal_process_name_t p2)71 opal_compare_opal_procs(const opal_process_name_t p1,
72                         const opal_process_name_t p2)
73 {
74     if( p1.jobid < p2.jobid ) {
75         return  -1;
76     }
77     if( p1.jobid > p2.jobid ) {
78         return  1;
79     }
80     if( p1.vpid <  p2.vpid ) {
81         return -1;
82     }
83     if( p1.vpid >  p2.vpid ) {
84         return 1;
85     }
86     return 0;
87 }
88 
89 opal_compare_proc_fct_t opal_compare_proc = opal_compare_opal_procs;
90 
opal_proc_local_get(void)91 opal_proc_t* opal_proc_local_get(void)
92 {
93     return opal_proc_my_name;
94 }
95 
opal_proc_local_set(opal_proc_t * proc)96 int opal_proc_local_set(opal_proc_t* proc)
97 {
98     if( proc != opal_proc_my_name ) {
99         if( NULL != proc )
100             OBJ_RETAIN(proc);
101         if( &opal_local_proc != opal_proc_my_name )
102             OBJ_RELEASE(opal_proc_my_name);
103         if( NULL != proc ) {
104             opal_proc_my_name = proc;
105         } else {
106             opal_proc_my_name = &opal_local_proc;
107         }
108     }
109     return OPAL_SUCCESS;
110 }
111 
112 /* this function is used to temporarily set the local
113  * name while OPAL and upper layers are initializing,
114  * thus allowing debug messages to be more easily
115  * understood */
opal_proc_set_name(opal_process_name_t * name)116 void opal_proc_set_name(opal_process_name_t *name)
117 {
118     /* to protect alignment, copy the name across */
119     memcpy(&opal_local_proc.proc_name, name, sizeof(opal_process_name_t));
120 }
121 
122 /**
123  * The following functions are surrogates for the RTE functionality, and are not supposed
124  * to be called. Instead, the corresponding function pointer should be set by the upper layer
125  * before the call to opal_init, to make them point to the correct accessors based on the
126  * underlying RTE.
127  */
128 static char*
opal_process_name_print_should_never_be_called(const opal_process_name_t procname)129 opal_process_name_print_should_never_be_called(const opal_process_name_t procname)
130 {
131     return "My Name is Nobody";
132 }
133 
134 static char*
opal_vpid_print_should_never_be_called(const opal_vpid_t unused)135 opal_vpid_print_should_never_be_called(const opal_vpid_t unused)
136 {
137     return "My VPID";
138 }
139 
140 static char*
opal_jobid_print_should_never_be_called(const opal_jobid_t unused)141 opal_jobid_print_should_never_be_called(const opal_jobid_t unused)
142 {
143     return "My JOBID";
144 }
145 
opal_convert_string_to_process_name_should_never_be_called(opal_process_name_t * name,const char * name_string)146 static int opal_convert_string_to_process_name_should_never_be_called(opal_process_name_t *name,
147                                                                       const char* name_string)
148 {
149     return OPAL_ERR_NOT_SUPPORTED;
150 }
151 
opal_convert_process_name_to_string_should_never_be_called(char ** name_string,const opal_process_name_t * name)152 static int opal_convert_process_name_to_string_should_never_be_called(char** name_string,
153                                                                       const opal_process_name_t *name)
154 {
155     return OPAL_ERR_NOT_SUPPORTED;
156 }
157 
opal_snprintf_jobid_should_never_be_called(char * name_string,size_t size,opal_jobid_t jobid)158 static int opal_snprintf_jobid_should_never_be_called(char* name_string, size_t size, opal_jobid_t jobid)
159 {
160     (void)strncpy(name_string, "My JOBID", size);
161     return OPAL_SUCCESS;
162 }
163 
opal_convert_string_to_jobid_should_never_be_called(opal_jobid_t * jobid,const char * jobid_string)164 static int opal_convert_string_to_jobid_should_never_be_called(opal_jobid_t *jobid, const char *jobid_string)
165 {
166     return OPAL_ERR_NOT_SUPPORTED;
167 }
168 
opal_proc_for_name_should_never_be_called(opal_process_name_t name)169 static struct opal_proc_t *opal_proc_for_name_should_never_be_called (opal_process_name_t name)
170 {
171     return NULL;
172 }
173 
174 char* (*opal_process_name_print)(const opal_process_name_t) = opal_process_name_print_should_never_be_called;
175 char* (*opal_vpid_print)(const opal_vpid_t) = opal_vpid_print_should_never_be_called;
176 char* (*opal_jobid_print)(const opal_jobid_t) = opal_jobid_print_should_never_be_called;
177 int (*opal_convert_string_to_process_name)(opal_process_name_t *name, const char* name_string) = opal_convert_string_to_process_name_should_never_be_called;
178 int (*opal_convert_process_name_to_string)(char** name_string, const opal_process_name_t *name) = opal_convert_process_name_to_string_should_never_be_called;
179 int (*opal_snprintf_jobid)(char* name_string, size_t size, opal_jobid_t jobid) = opal_snprintf_jobid_should_never_be_called;
180 int (*opal_convert_string_to_jobid)(opal_jobid_t *jobid, const char *jobid_string) = opal_convert_string_to_jobid_should_never_be_called;
181 struct opal_proc_t *(*opal_proc_for_name) (const opal_process_name_t name) = opal_proc_for_name_should_never_be_called;
182 
opal_get_proc_hostname(const opal_proc_t * proc)183 char* opal_get_proc_hostname(const opal_proc_t *proc)
184 {
185     int ret;
186 
187     /* if the proc is NULL, then we can't know */
188     if (NULL == proc) {
189         return "unknown";
190     }
191 
192     /* if it is my own hostname we are after, then just hand back
193      * the value in opal_process_info */
194     if (proc == opal_proc_my_name) {
195         return opal_process_info.nodename;
196     }
197 
198     /* see if we already have the data - if so, pass it back */
199     if (NULL != proc->proc_hostname) {
200         return proc->proc_hostname;
201     }
202 
203     /* if we don't already have it, then try to get it */
204     OPAL_MODEX_RECV_VALUE_OPTIONAL(ret, OPAL_PMIX_HOSTNAME, &proc->proc_name,
205                                    (char**)&(proc->proc_hostname), OPAL_STRING);
206     if (OPAL_SUCCESS != ret) {
207         return "unknown";  // return something so the caller doesn't segfault
208     }
209 
210     /* user is not allowed to release the data */
211     return proc->proc_hostname;
212 }
213