|
26 | 26 | #include "qrmi.h" |
27 | 27 | #include "spank_qrmi.h" |
28 | 28 |
|
| 29 | +extern char **environ; |
| 30 | + |
29 | 31 | /* |
30 | 32 | * Spank plugin for QRMI. |
31 | 33 | */ |
@@ -54,6 +56,32 @@ static void acquired_resource_destroy(void *object); |
54 | 56 | static qpu_resource_t *_acquire_qpu(spank_t spank_ctxt, char *name, QrmiResourceType type); |
55 | 57 | static void _release_qpu(qpu_resource_t *res); |
56 | 58 |
|
| 59 | +/* |
| 60 | + * @function _dump_environ |
| 61 | + * |
| 62 | + * Dumps all environment variables set for the current process. |
| 63 | + */ |
| 64 | +static void _dump_environ() { |
| 65 | + char **s = environ; |
| 66 | + int pid = (int)getpid(); |
| 67 | + int uid = (int)getuid(); |
| 68 | + |
| 69 | + slurm_debug("%s(%d, %d): environment variables ---", plugin_name, pid, uid); |
| 70 | + for (; *s; s++) { |
| 71 | + slurm_debug("%s(%d, %d): %s", plugin_name, pid, uid, *s); |
| 72 | + } |
| 73 | +} |
| 74 | + |
| 75 | +/* |
| 76 | + * @function _starts_with |
| 77 | + * |
| 78 | + * Tests if this string(`str`) starts with the specified `prefix`. |
| 79 | + */ |
| 80 | +static bool _starts_with(const char *str, const char *prefix) |
| 81 | +{ |
| 82 | + return strncmp(prefix, str, strlen(prefix)) == 0; |
| 83 | +} |
| 84 | + |
57 | 85 | /* |
58 | 86 | * @function _qpu_names_opt_cb |
59 | 87 | * |
@@ -183,11 +211,37 @@ int slurm_spank_init_post_opt(spank_t spank_ctxt, int argc, char **argv) { |
183 | 211 |
|
184 | 212 | QrmiConfig *cnf = qrmi_config_load(argv[0]); |
185 | 213 | if (cnf == NULL) { |
186 | | - slurm_error("%s, No QRMI config file (%s)", plugin_name, argv[0]); |
| 214 | + const char* last_error = qrmi_get_last_error(); |
| 215 | + slurm_error("%s, Failed to load QRMI config file(%s). %s", |
| 216 | + plugin_name, argv[0], last_error); |
| 217 | + spank_setenv(spank_ctxt, "QRMI_PLUGIN_ERROR", last_error, KEEP_IF_EXISTS); |
| 218 | + qrmi_string_free((char*)last_error); |
187 | 219 | return SLURM_ERROR; |
188 | 220 | } |
189 | 221 | slurm_debug("%s, config: %p", plugin_name, (void *)cnf); |
190 | 222 |
|
| 223 | + /* |
| 224 | + * Parses optional plugin arguments. |
| 225 | + * |
| 226 | + * Currently, only environment variable settings prefixed with |
| 227 | + * --env:{variable name}={value} are supported. |
| 228 | + */ |
| 229 | + for (int i = 1; i < argc; i++) { |
| 230 | + if (_starts_with(argv[i], "--env:")) { |
| 231 | + const char *input = &argv[i][strlen("--env:")]; |
| 232 | + const char *delimiter = strchr(input, '='); |
| 233 | + if (delimiter != NULL) { |
| 234 | + size_t key_len = (size_t)(delimiter - input); |
| 235 | + char env_name[key_len + 1]; |
| 236 | + strncpy(env_name, input, key_len); |
| 237 | + env_name[key_len] = '\0'; |
| 238 | + const char *env_value = delimiter + 1;; |
| 239 | + setenv(env_name, env_value, OVERWRITE); |
| 240 | + spank_setenv(spank_ctxt, env_name, env_value, OVERWRITE); |
| 241 | + } |
| 242 | + } |
| 243 | + } |
| 244 | + |
191 | 245 | size_t buflen = strlen(g_qpu_names_opt) + 1; |
192 | 246 | char *bufp = (char *)malloc(buflen); |
193 | 247 | char *rest = bufp; |
@@ -258,6 +312,8 @@ int slurm_spank_init_post_opt(spank_t spank_ctxt, int argc, char **argv) { |
258 | 312 | KEEP_IF_EXISTS); |
259 | 313 | } |
260 | 314 |
|
| 315 | + _dump_environ(); |
| 316 | + |
261 | 317 | /* |
262 | 318 | * Acquire QPU resource. |
263 | 319 | */ |
@@ -564,6 +620,7 @@ static qpu_resource_t *_acquire_qpu(spank_t spank_ctxt, char *name, QrmiResource |
564 | 620 | if ((rc != QRMI_RETURN_CODE_SUCCESS) || (is_accessible == false)) { |
565 | 621 | last_error = qrmi_get_last_error(); |
566 | 622 | slurm_error("%s, %s is not accessible. %s", plugin_name, name, last_error); |
| 623 | + spank_setenv(spank_ctxt, "QRMI_PLUGIN_ERROR", last_error, KEEP_IF_EXISTS); |
567 | 624 | qrmi_string_free((char*)last_error); |
568 | 625 | qrmi_resource_free(qrmi); |
569 | 626 | return NULL; |
|
0 commit comments