blob: 867d136f59f92ce679a064241e8103743a74c9d6 [file] [log] [blame] [edit]
/*
* step.c - convert data between step related messages and perl HVs
*/
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>
#include <slurm/slurm.h>
#include "ppport.h"
#include "slurm-perl.h"
/*
* convert job_step_info_t to perl HV
*/
int
job_step_info_to_hv(job_step_info_t *step_info, HV *hv)
{
int j;
AV *av;
if(step_info->ckpt_dir)
STORE_FIELD(hv, step_info, ckpt_dir, charp);
STORE_FIELD(hv, step_info, ckpt_interval, uint16_t);
if(step_info->gres)
STORE_FIELD(hv, step_info, gres, charp);
STORE_FIELD(hv, step_info, job_id, uint32_t);
if(step_info->name)
STORE_FIELD(hv, step_info, name, charp);
if(step_info->network)
STORE_FIELD(hv, step_info, network, charp);
if(step_info->nodes)
STORE_FIELD(hv, step_info, nodes, charp);
av = newAV();
for(j = 0; ; j += 2) {
if(step_info->node_inx[j] == -1)
break;
av_store_int(av, j, step_info->node_inx[j]);
av_store_int(av, j+1, step_info->node_inx[j+1]);
}
hv_store_sv(hv, "node_inx", newRV_noinc((SV*)av));
STORE_FIELD(hv, step_info, num_cpus, uint32_t);
STORE_FIELD(hv, step_info, num_tasks, uint32_t);
if(step_info->partition)
STORE_FIELD(hv, step_info, partition, charp);
if(step_info->resv_ports)
STORE_FIELD(hv, step_info, resv_ports, charp);
STORE_FIELD(hv, step_info, run_time, time_t);
STORE_FIELD(hv, step_info, start_time, time_t);
STORE_FIELD(hv, step_info, step_id, uint32_t);
STORE_FIELD(hv, step_info, time_limit, uint32_t);
STORE_FIELD(hv, step_info, user_id, uint32_t);
return 0;
}
/*
* convert perl HV to job_step_info_t
*/
int
hv_to_job_step_info(HV *hv, job_step_info_t *step_info)
{
SV **svp;
AV *av;
int i, n;
FETCH_FIELD(hv, step_info, ckpt_dir, charp, FALSE);
FETCH_FIELD(hv, step_info, ckpt_interval, uint16_t, TRUE);
FETCH_FIELD(hv, step_info, gres, charp, FALSE);
FETCH_FIELD(hv, step_info, job_id, uint16_t, TRUE);
FETCH_FIELD(hv, step_info, name, charp, FALSE);
FETCH_FIELD(hv, step_info, network, charp, FALSE);
FETCH_FIELD(hv, step_info, nodes, charp, FALSE);
svp = hv_fetch(hv, "node_inx", 8, FALSE);
if (svp && SvROK(*svp) && SvTYPE(SvRV(*svp)) == SVt_PVAV) {
av = (AV*)SvRV(*svp);
n = av_len(av) + 2; /* for trailing -1 */
step_info->node_inx = xmalloc(n * sizeof(int));
for (i = 0 ; i < n-1; i += 2) {
step_info->node_inx[i] = (int)SvIV(*(av_fetch(av, i ,FALSE)));
step_info->node_inx[i+1] = (int)SvIV(*(av_fetch(av, i+1 ,FALSE)));
}
step_info->node_inx[n-1] = -1;
} else {
/* nothing to do */
}
FETCH_FIELD(hv, step_info, num_cpus, uint32_t, TRUE);
FETCH_FIELD(hv, step_info, num_tasks, uint32_t, TRUE);
FETCH_FIELD(hv, step_info, partition, charp, FALSE);
FETCH_FIELD(hv, step_info, resv_ports, charp, FALSE);
FETCH_FIELD(hv, step_info, run_time, time_t, TRUE);
FETCH_FIELD(hv, step_info, start_time, time_t, TRUE);
FETCH_FIELD(hv, step_info, step_id, uint32_t, TRUE);
FETCH_FIELD(hv, step_info, time_limit, uint32_t, TRUE);
FETCH_FIELD(hv, step_info, user_id, uint32_t, TRUE);
return 0;
}
/*
* convert job_step_info_response_msg_t to perl HV
*/
int
job_step_info_response_msg_to_hv(
job_step_info_response_msg_t *job_step_info_msg, HV *hv)
{
int i;
AV* av;
HV* hv_info;
STORE_FIELD(hv, job_step_info_msg, last_update, time_t);
/* job_step_count implied in job_steps */
av = newAV();
for(i = 0; i < job_step_info_msg->job_step_count; i ++) {
hv_info = newHV();
if (job_step_info_to_hv(
job_step_info_msg->job_steps + i, hv_info) < 0) {
SvREFCNT_dec(hv_info);
SvREFCNT_dec(av);
return -1;
}
av_store(av, i, newRV_noinc((SV*)hv_info));
}
hv_store_sv(hv, "job_steps", newRV_noinc((SV*)av));
return 0;
}
/*
* convert perl HV to job_step_info_response_msg_t
*/
int
hv_to_job_step_info_response_msg(HV *hv,
job_step_info_response_msg_t *step_info_msg)
{
int i, n;
SV **svp;
AV *av;
memset(step_info_msg, 0, sizeof(job_step_info_response_msg_t));
FETCH_FIELD(hv, step_info_msg, last_update, time_t, TRUE);
svp = hv_fetch(hv, "job_steps", 9, FALSE);
if (! (svp && SvROK(*svp) && SvTYPE(SvRV(*svp)) == SVt_PVAV)) {
Perl_warn (aTHX_ "job_steps is not an array reference in HV for job_step_info_response_msg_t");
return -1;
}
av = (AV*)SvRV(*svp);
n = av_len(av) + 1;
step_info_msg->job_step_count = n;
step_info_msg->job_steps = xmalloc(n * sizeof(job_step_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 job_steps is not valid", i);
return -1;
}
if (hv_to_job_step_info((HV*)SvRV(*svp), &step_info_msg->job_steps[i]) < 0) {
Perl_warn (aTHX_ "failed to convert element %d in job_steps", i);
return -1;
}
}
return 0;
}
/*
* convert slurm_step_layout_t to perl HV
*/
int
slurm_step_layout_to_hv(slurm_step_layout_t *step_layout, HV *hv)
{
AV* av, *av2;
int i, j;
STORE_FIELD(hv, step_layout, node_cnt, uint16_t);
if (step_layout->node_list)
STORE_FIELD(hv, step_layout, node_list, charp);
else {
Perl_warn(aTHX_ "node_list missing in slurm_step_layout_t");
return -1;
}
STORE_FIELD(hv, step_layout, plane_size, uint16_t);
av = newAV();
for(i = 0; i < step_layout->node_cnt; i ++)
av_store_uint16_t(av, i, step_layout->tasks[i]);
hv_store_sv(hv, "tasks", newRV_noinc((SV*)av));
STORE_FIELD(hv, step_layout, task_cnt, uint32_t);
STORE_FIELD(hv, step_layout, task_dist, uint16_t);
av = newAV();
for(i = 0; i < step_layout->node_cnt; i ++) {
av2 = newAV();
for(j = 0; j < step_layout->tasks[i]; j ++)
av_store_uint32_t(av2, i, step_layout->tids[i][j]);
av_store(av, i, newRV_noinc((SV*)av2));
}
hv_store_sv(hv, "tids", newRV_noinc((SV*)av));
return 0;
}
/* convert job_step_pids_t to perl HV */
int
job_step_pids_to_hv(job_step_pids_t *pids, HV *hv)
{
int i;
AV *av;
STORE_FIELD(hv, pids, node_name, charp);
/* pid_cnt implied in pid array */
av = newAV();
for (i = 0; i < pids->pid_cnt; i ++) {
av_store_uint32_t(av, i, pids->pid[i]);
}
hv_store_sv(hv, "pid", newRV_noinc((SV*)av));
return 0;
}
/* convert job_step_pids_response_msg_t to HV */
int
job_step_pids_response_msg_to_hv(job_step_pids_response_msg_t *pids_msg, HV *hv)
{
int i = 0;
ListIterator itr;
AV *av;
HV *hv_pids;
job_step_pids_t *pids;
STORE_FIELD(hv, pids_msg, job_id, uint32_t);
STORE_FIELD(hv, pids_msg, step_id, uint32_t);
av = newAV();
itr = slurm_list_iterator_create(pids_msg->pid_list);
while((pids = (job_step_pids_t *)slurm_list_next(itr))) {
hv_pids = newHV();
if (job_step_pids_to_hv(pids, hv_pids) < 0) {
Perl_warn(aTHX_ "failed to convert job_step_pids_t to hv for job_step_pids_response_msg_t");
SvREFCNT_dec(hv_pids);
SvREFCNT_dec(av);
return -1;
}
av_store(av, i++, newRV_noinc((SV*)hv_pids));
}
slurm_list_iterator_destroy(itr);
hv_store_sv(hv, "pid_list", newRV_noinc((SV*)av));
return 0;
}
/*
* convert job_step_stat_t to perl HV
*/
int
job_step_stat_to_hv(job_step_stat_t *stat, HV *hv)
{
HV *hv_pids;
STORE_PTR_FIELD(hv, stat, jobacct, "Slurm::jobacctinfo_t");
STORE_FIELD(hv, stat, num_tasks, uint32_t);
STORE_FIELD(hv, stat, return_code, uint32_t);
hv_pids = newHV();
if (job_step_pids_to_hv(stat->step_pids, hv_pids) < 0) {
Perl_warn(aTHX_ "failed to convert job_step_pids_t to hv for job_step_stat_t");
SvREFCNT_dec(hv_pids);
return -1;
}
hv_store_sv(hv, "step_pids", newRV_noinc((SV*)hv_pids));
return 0;
}
/*
* convert job_step_stat_response_msg_t to perl HV
*/
int
job_step_stat_response_msg_to_hv(job_step_stat_response_msg_t *stat_msg, HV *hv)
{
int i = 0;
ListIterator itr;
job_step_stat_t *stat;
AV *av;
HV *hv_stat;
STORE_FIELD(hv, stat_msg, job_id, uint32_t);
STORE_FIELD(hv, stat_msg, step_id, uint32_t);
av = newAV();
itr = slurm_list_iterator_create(stat_msg->stats_list);
while((stat = (job_step_stat_t *)slurm_list_next(itr))) {
hv_stat = newHV();
if(job_step_stat_to_hv(stat, hv_stat) < 0) {
Perl_warn(aTHX_ "failed to convert job_step_stat_t to hv for job_step_stat_response_msg_t");
SvREFCNT_dec(hv_stat);
SvREFCNT_dec(av);
return -1;
}
av_store(av, i++, newRV_noinc((SV*)hv_stat));
}
slurm_list_iterator_destroy(itr);
hv_store_sv(hv, "stats_list", newRV_noinc((SV*)av));
return 0;
}