blob: 18d29598382acb6086abd07fe131a129a90b7bcf [file] [log] [blame] [edit]
/*
* node.c - convert data between node related messages and perl HVs
*/
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>
#include "ppport.h"
#include <slurm/slurm.h>
#include "slurm-perl.h"
#ifdef HAVE_BG
/* These are just helper functions from slurm proper that don't get
* exported regularly. Copied from src/common/slurm_protocol_defs.h.
*/
#define IS_NODE_ALLOCATED(_X) \
((_X->node_state & NODE_STATE_BASE) == NODE_STATE_ALLOCATED)
#define IS_NODE_COMPLETING(_X) \
(_X->node_state & NODE_STATE_COMPLETING)
#endif
/*
* convert node_info_t to perl HV
*/
int
node_info_to_hv(node_info_t *node_info, uint16_t node_scaling, HV *hv)
{
uint16_t err_cpus = 0, alloc_cpus = 0;
#ifdef HAVE_BG
int cpus_per_node = 1;
if(node_scaling)
cpus_per_node = node_info->cpus / node_scaling;
#endif
if(node_info->arch)
STORE_FIELD(hv, node_info, arch, charp);
STORE_FIELD(hv, node_info, boot_time, time_t);
STORE_FIELD(hv, node_info, cores, uint16_t);
STORE_FIELD(hv, node_info, cpus, uint16_t);
if(node_info->features)
STORE_FIELD(hv, node_info, features, charp);
if(node_info->gres)
STORE_FIELD(hv, node_info, gres, charp);
if (node_info->name)
STORE_FIELD(hv, node_info, name, charp);
else {
Perl_warn (aTHX_ "node name missing in node_info_t");
return -1;
}
STORE_FIELD(hv, node_info, node_state, uint16_t);
if(node_info->os)
STORE_FIELD(hv, node_info, os, charp);
STORE_FIELD(hv, node_info, real_memory, uint32_t);
if(node_info->reason)
STORE_FIELD(hv, node_info, reason, charp);
STORE_FIELD(hv, node_info, reason_time, time_t);
STORE_FIELD(hv, node_info, reason_uid, uint32_t);
STORE_FIELD(hv, node_info, slurmd_start_time, time_t);
STORE_FIELD(hv, node_info, sockets, uint16_t);
STORE_FIELD(hv, node_info, threads, uint16_t);
STORE_FIELD(hv, node_info, tmp_disk, uint32_t);
slurm_get_select_nodeinfo(node_info->select_nodeinfo,
SELECT_NODEDATA_SUBCNT,
NODE_STATE_ALLOCATED,
&alloc_cpus);
#ifdef HAVE_BG
if(!alloc_cpus
&& (IS_NODE_ALLOCATED(node_info) || IS_NODE_COMPLETING(node_info)))
alloc_cpus = node_info->cpus;
else
alloc_cpus *= cpus_per_node;
#endif
slurm_get_select_nodeinfo(node_info->select_nodeinfo,
SELECT_NODEDATA_SUBCNT,
NODE_STATE_ERROR,
&err_cpus);
#ifdef HAVE_BG
err_cpus *= cpus_per_node;
#endif
hv_store_uint16_t(hv, "alloc_cpus", alloc_cpus);
hv_store_uint16_t(hv, "err_cpus", err_cpus);
STORE_PTR_FIELD(hv, node_info, select_nodeinfo, "Slurm::dynamic_plugin_data_t");
STORE_FIELD(hv, node_info, weight, uint32_t);
return 0;
}
/*
* convert perl HV to node_info_t
*/
int
hv_to_node_info(HV *hv, node_info_t *node_info)
{
memset(node_info, 0, sizeof(node_info_t));
FETCH_FIELD(hv, node_info, arch, charp, FALSE);
FETCH_FIELD(hv, node_info, boot_time, time_t, TRUE);
FETCH_FIELD(hv, node_info, cores, uint16_t, TRUE);
FETCH_FIELD(hv, node_info, cpus, uint16_t, TRUE);
FETCH_FIELD(hv, node_info, features, charp, FALSE);
FETCH_FIELD(hv, node_info, gres, charp, FALSE);
FETCH_FIELD(hv, node_info, name, charp, TRUE);
FETCH_FIELD(hv, node_info, node_state, uint16_t, TRUE);
FETCH_FIELD(hv, node_info, os, charp, FALSE);
FETCH_FIELD(hv, node_info, real_memory, uint32_t, TRUE);
FETCH_FIELD(hv, node_info, reason, charp, FALSE);
FETCH_FIELD(hv, node_info, reason_time, time_t, TRUE);
FETCH_FIELD(hv, node_info, reason_uid, uint32_t, TRUE);
FETCH_FIELD(hv, node_info, slurmd_start_time, time_t, TRUE);
FETCH_FIELD(hv, node_info, sockets, uint16_t, TRUE);
FETCH_FIELD(hv, node_info, threads, uint16_t, TRUE);
FETCH_FIELD(hv, node_info, tmp_disk, uint32_t, TRUE);
FETCH_FIELD(hv, node_info, weight, uint32_t, TRUE);
FETCH_PTR_FIELD(hv, node_info, select_nodeinfo, "Slurm::dynamic_plugin_data_t", TRUE);
return 0;
}
/*
* convert node_info_msg_t to perl HV
*/
int
node_info_msg_to_hv(node_info_msg_t *node_info_msg, HV *hv)
{
int i;
HV *hv_info;
AV *av;
STORE_FIELD(hv, node_info_msg, last_update, time_t);
STORE_FIELD(hv, node_info_msg, node_scaling, uint16_t);
/* record_count implied in node_array */
av = newAV();
for(i = 0; i < node_info_msg->record_count; i ++) {
hv_info =newHV();
if (node_info_to_hv(node_info_msg->node_array + i,
node_info_msg->node_scaling, hv_info) < 0) {
SvREFCNT_dec((SV*)hv_info);
SvREFCNT_dec((SV*)av);
return -1;
}
av_store(av, i, newRV_noinc((SV*)hv_info));
}
hv_store_sv(hv, "node_array", newRV_noinc((SV*)av));
return 0;
}
/*
* convert perl HV to node_info_msg_t
*/
int
hv_to_node_info_msg(HV *hv, node_info_msg_t *node_info_msg)
{
SV **svp;
AV *av;
int i, n;
memset(node_info_msg, 0, sizeof(node_info_msg_t));
FETCH_FIELD(hv, node_info_msg, last_update, time_t, TRUE);
FETCH_FIELD(hv, node_info_msg, node_scaling, uint16_t, TRUE);
svp = hv_fetch(hv, "node_array", 10, FALSE);
if (! (svp && SvROK(*svp) && SvTYPE(SvRV(*svp)) == SVt_PVAV)) {
Perl_warn (aTHX_ "node_array is not an array reference in HV for node_info_msg_t");
return -1;
}
av = (AV*)SvRV(*svp);
n = av_len(av) + 1;
node_info_msg->record_count = n;
node_info_msg->node_array = xmalloc(n * sizeof(node_info_t));
for (i = 0; i < n; i ++) {
svp = av_fetch(av, i, FALSE);
if (! (svp && SvROK(*svp) && SvTYPE(SvRV(*svp)) == SVt_PVHV)) {
Perl_warn (aTHX_ "element %d in node_array is not valid", i);
return -1;
}
if (hv_to_node_info((HV*)SvRV(*svp), &node_info_msg->node_array[i]) < 0) {
Perl_warn (aTHX_ "failed to convert element %d in node_array", i);
return -1;
}
}
return 0;
}
/*
* convert perl HV to update_node_msg_t
*/
int
hv_to_update_node_msg(HV *hv, update_node_msg_t *update_msg)
{
slurm_init_update_node_msg(update_msg);
FETCH_FIELD(hv, update_msg, node_names, charp, TRUE);
FETCH_FIELD(hv, update_msg, node_state, uint16_t, FALSE);
FETCH_FIELD(hv, update_msg, reason, charp, FALSE);
FETCH_FIELD(hv, update_msg, features, charp, FALSE);
FETCH_FIELD(hv, update_msg, weight, uint32_t, FALSE);
return 0;
}