Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions plugins/spank_qrmi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,17 @@ Note that administrator needs to create `qrmi_config.json` file and specify the
optional /usr/lib64/slurm/spank_qrmi.so /etc/slurm/qrmi_config.json
```

> [!NOTE]
> There are optional argumentis available. It allows you to add environment variables to the Slurm process where the SPANK plugin is loaded. The format for specifying environment variables is defined as follows.
> ```bash
> --env:{variable name}={value}
> ```
>
> For example, when interacting with Quantum resources via an HTTP proxy, the environment variables `http_proxy`, `https_proxy`, and `no_proxy` are required. These can be added as shown below.
> ```bash
> optional /usr/lib64/slurm/spank_qrmi.so /etc/slurm/qrmi_config.json --env:http_proxy=http://192.168.1.128:3128 --env:https_proxy=http://192.168.1.128:3128
> ```

For allocator node, your don't need to specify the path to qrmi_config.json like below.

```bash
Expand Down
59 changes: 58 additions & 1 deletion plugins/spank_qrmi/spank_qrmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include "qrmi.h"
#include "spank_qrmi.h"

extern char **environ;

/*
* Spank plugin for QRMI.
*/
Expand Down Expand Up @@ -54,6 +56,32 @@ static void acquired_resource_destroy(void *object);
static qpu_resource_t *_acquire_qpu(spank_t spank_ctxt, char *name, QrmiResourceType type);
static void _release_qpu(qpu_resource_t *res);

/*
* @function _dump_environ
*
* Dumps all environment variables set for the current process.
*/
static void _dump_environ() {
char **s = environ;
int pid = (int)getpid();
int uid = (int)getuid();

slurm_debug("%s(%d, %d): environment variables ---", plugin_name, pid, uid);
for (; *s; s++) {
slurm_debug("%s(%d, %d): %s", plugin_name, pid, uid, *s);
}
}

/*
* @function _starts_with
*
* Tests if this string(`str`) starts with the specified `prefix`.
*/
static bool _starts_with(const char *str, const char *prefix)
{
return strncmp(prefix, str, strlen(prefix)) == 0;
}

/*
* @function _qpu_names_opt_cb
*
Expand Down Expand Up @@ -183,11 +211,37 @@ int slurm_spank_init_post_opt(spank_t spank_ctxt, int argc, char **argv) {

QrmiConfig *cnf = qrmi_config_load(argv[0]);
if (cnf == NULL) {
slurm_error("%s, No QRMI config file (%s)", plugin_name, argv[0]);
const char* last_error = qrmi_get_last_error();
slurm_error("%s, Failed to load QRMI config file(%s). %s",
plugin_name, argv[0], last_error);
spank_setenv(spank_ctxt, "QRMI_PLUGIN_ERROR", last_error, KEEP_IF_EXISTS);
qrmi_string_free((char*)last_error);
return SLURM_ERROR;
}
slurm_debug("%s, config: %p", plugin_name, (void *)cnf);

/*
* Parses optional plugin arguments.
*
* Currently, only environment variable settings prefixed with
* --env:{variable name}={value} are supported.
*/
for (int i = 1; i < argc; i++) {
if (_starts_with(argv[i], "--env:")) {
const char *input = &argv[i][strlen("--env:")];
const char *delimiter = strchr(input, '=');
if (delimiter != NULL) {
size_t key_len = (size_t)(delimiter - input);
char env_name[key_len + 1];
strncpy(env_name, input, key_len);
env_name[key_len] = '\0';
const char *env_value = delimiter + 1;;
setenv(env_name, env_value, OVERWRITE);
spank_setenv(spank_ctxt, env_name, env_value, OVERWRITE);
}
}
}

size_t buflen = strlen(g_qpu_names_opt) + 1;
char *bufp = (char *)malloc(buflen);
char *rest = bufp;
Expand Down Expand Up @@ -258,6 +312,8 @@ int slurm_spank_init_post_opt(spank_t spank_ctxt, int argc, char **argv) {
KEEP_IF_EXISTS);
}

_dump_environ();

/*
* Acquire QPU resource.
*/
Expand Down Expand Up @@ -564,6 +620,7 @@ static qpu_resource_t *_acquire_qpu(spank_t spank_ctxt, char *name, QrmiResource
if ((rc != QRMI_RETURN_CODE_SUCCESS) || (is_accessible == false)) {
last_error = qrmi_get_last_error();
slurm_error("%s, %s is not accessible. %s", plugin_name, name, last_error);
spank_setenv(spank_ctxt, "QRMI_PLUGIN_ERROR", last_error, KEEP_IF_EXISTS);
qrmi_string_free((char*)last_error);
qrmi_resource_free(qrmi);
return NULL;
Expand Down