1 /*
2 * step.c - convert data between step related messages and perl HVs
3 */
4
5 #include <EXTERN.h>
6 #include <perl.h>
7 #include <XSUB.h>
8 #include <slurm/slurm.h>
9 #include "ppport.h"
10
11 #include "slurm-perl.h"
12
13
14 /*
15 * convert job_step_info_t to perl HV
16 */
17 int
job_step_info_to_hv(job_step_info_t * step_info,HV * hv)18 job_step_info_to_hv(job_step_info_t *step_info, HV *hv)
19 {
20 int j;
21 AV *av;
22
23 STORE_FIELD(hv, step_info, array_job_id, uint32_t);
24 STORE_FIELD(hv, step_info, array_task_id, uint32_t);
25 if (step_info->tres_per_node)
26 STORE_FIELD(hv, step_info, tres_per_node, charp);
27 STORE_FIELD(hv, step_info, job_id, uint32_t);
28 if (step_info->name)
29 STORE_FIELD(hv, step_info, name, charp);
30 if (step_info->network)
31 STORE_FIELD(hv, step_info, network, charp);
32 if (step_info->nodes)
33 STORE_FIELD(hv, step_info, nodes, charp);
34 av = newAV();
35 for (j = 0; ; j += 2) {
36 if(step_info->node_inx[j] == -1)
37 break;
38 av_store_int(av, j, step_info->node_inx[j]);
39 av_store_int(av, j+1, step_info->node_inx[j+1]);
40 }
41 hv_store_sv(hv, "node_inx", newRV_noinc((SV*)av));
42 STORE_FIELD(hv, step_info, num_cpus, uint32_t);
43 STORE_FIELD(hv, step_info, num_tasks, uint32_t);
44 if(step_info->partition)
45 STORE_FIELD(hv, step_info, partition, charp);
46 if(step_info->resv_ports)
47 STORE_FIELD(hv, step_info, resv_ports, charp);
48 STORE_FIELD(hv, step_info, run_time, time_t);
49 STORE_FIELD(hv, step_info, start_time, time_t);
50 STORE_FIELD(hv, step_info, step_id, uint32_t);
51 STORE_FIELD(hv, step_info, time_limit, uint32_t);
52 STORE_FIELD(hv, step_info, user_id, uint32_t);
53 STORE_FIELD(hv, step_info, state, uint32_t);
54
55 return 0;
56 }
57
58 /*
59 * convert perl HV to job_step_info_t
60 */
61 int
hv_to_job_step_info(HV * hv,job_step_info_t * step_info)62 hv_to_job_step_info(HV *hv, job_step_info_t *step_info)
63 {
64 SV **svp;
65 AV *av;
66 int i, n;
67
68 memset(step_info, 0, sizeof(job_step_info_t));
69
70 FETCH_FIELD(hv, step_info, array_job_id, uint32_t, TRUE);
71 FETCH_FIELD(hv, step_info, array_task_id, uint32_t, TRUE);
72 FETCH_FIELD(hv, step_info, tres_per_node, charp, FALSE);
73 FETCH_FIELD(hv, step_info, job_id, uint16_t, TRUE);
74 FETCH_FIELD(hv, step_info, name, charp, FALSE);
75 FETCH_FIELD(hv, step_info, network, charp, FALSE);
76 FETCH_FIELD(hv, step_info, nodes, charp, FALSE);
77
78 svp = hv_fetch(hv, "node_inx", 8, FALSE);
79 if (svp && SvROK(*svp) && SvTYPE(SvRV(*svp)) == SVt_PVAV) {
80 av = (AV*)SvRV(*svp);
81 n = av_len(av) + 2; /* for trailing -1 */
82 step_info->node_inx = xmalloc(n * sizeof(int));
83 for (i = 0 ; i < n-1; i += 2) {
84 step_info->node_inx[i] = (int)SvIV(*(av_fetch(av, i ,FALSE)));
85 step_info->node_inx[i+1] = (int)SvIV(*(av_fetch(av, i+1 ,FALSE)));
86 }
87 step_info->node_inx[n-1] = -1;
88 } else {
89 /* nothing to do */
90 }
91
92 FETCH_FIELD(hv, step_info, num_cpus, uint32_t, TRUE);
93 FETCH_FIELD(hv, step_info, num_tasks, uint32_t, TRUE);
94 FETCH_FIELD(hv, step_info, partition, charp, FALSE);
95 FETCH_FIELD(hv, step_info, resv_ports, charp, FALSE);
96 FETCH_FIELD(hv, step_info, run_time, time_t, TRUE);
97 FETCH_FIELD(hv, step_info, start_time, time_t, TRUE);
98 FETCH_FIELD(hv, step_info, step_id, uint32_t, TRUE);
99 FETCH_FIELD(hv, step_info, time_limit, uint32_t, TRUE);
100 FETCH_FIELD(hv, step_info, user_id, uint32_t, TRUE);
101 FETCH_FIELD(hv, step_info, state, uint32_t, TRUE);
102
103 return 0;
104 }
105
106 /*
107 * convert job_step_info_response_msg_t to perl HV
108 */
109 int
job_step_info_response_msg_to_hv(job_step_info_response_msg_t * job_step_info_msg,HV * hv)110 job_step_info_response_msg_to_hv(
111 job_step_info_response_msg_t *job_step_info_msg, HV *hv)
112 {
113 int i;
114 AV* av;
115 HV* hv_info;
116
117 STORE_FIELD(hv, job_step_info_msg, last_update, time_t);
118 /* job_step_count implied in job_steps */
119 av = newAV();
120 for(i = 0; i < job_step_info_msg->job_step_count; i ++) {
121 hv_info = newHV();
122 if (job_step_info_to_hv(
123 job_step_info_msg->job_steps + i, hv_info) < 0) {
124 SvREFCNT_dec(hv_info);
125 SvREFCNT_dec(av);
126 return -1;
127 }
128 av_store(av, i, newRV_noinc((SV*)hv_info));
129 }
130 hv_store_sv(hv, "job_steps", newRV_noinc((SV*)av));
131 return 0;
132 }
133
134 /*
135 * convert perl HV to job_step_info_response_msg_t
136 */
137 int
hv_to_job_step_info_response_msg(HV * hv,job_step_info_response_msg_t * step_info_msg)138 hv_to_job_step_info_response_msg(HV *hv,
139 job_step_info_response_msg_t *step_info_msg)
140 {
141 int i, n;
142 SV **svp;
143 AV *av;
144
145 memset(step_info_msg, 0, sizeof(job_step_info_response_msg_t));
146
147 FETCH_FIELD(hv, step_info_msg, last_update, time_t, TRUE);
148
149 svp = hv_fetch(hv, "job_steps", 9, FALSE);
150 if (! (svp && SvROK(*svp) && SvTYPE(SvRV(*svp)) == SVt_PVAV)) {
151 Perl_warn (aTHX_ "job_steps is not an array reference in HV for job_step_info_response_msg_t");
152 return -1;
153 }
154
155 av = (AV*)SvRV(*svp);
156 n = av_len(av) + 1;
157 step_info_msg->job_step_count = n;
158
159 step_info_msg->job_steps = xmalloc(n * sizeof(job_step_info_t));
160 for (i = 0; i < n; i ++) {
161 svp = av_fetch(av, i, FALSE);
162 if (! (svp && SvROK(*svp) && SvTYPE(SvRV(*svp)) == SVt_PVHV)) {
163 Perl_warn (aTHX_ "element %d in job_steps is not valid", i);
164 return -1;
165 }
166 if (hv_to_job_step_info((HV*)SvRV(*svp), &step_info_msg->job_steps[i]) < 0) {
167 Perl_warn (aTHX_ "failed to convert element %d in job_steps", i);
168 return -1;
169 }
170 }
171 return 0;
172 }
173
174
175 /*
176 * convert slurm_step_layout_t to perl HV
177 */
178 int
slurm_step_layout_to_hv(slurm_step_layout_t * step_layout,HV * hv)179 slurm_step_layout_to_hv(slurm_step_layout_t *step_layout, HV *hv)
180 {
181 AV* av, *av2;
182 int i, j;
183
184 if (step_layout->front_end)
185 STORE_FIELD(hv, step_layout, front_end, charp);
186 STORE_FIELD(hv, step_layout, node_cnt, uint16_t);
187 if (step_layout->node_list)
188 STORE_FIELD(hv, step_layout, node_list, charp);
189 else {
190 Perl_warn(aTHX_ "node_list missing in slurm_step_layout_t");
191 return -1;
192 }
193 STORE_FIELD(hv, step_layout, plane_size, uint16_t);
194 av = newAV();
195 for (i = 0; i < step_layout->node_cnt; i ++)
196 av_store_uint16_t(av, i, step_layout->tasks[i]);
197 hv_store_sv(hv, "tasks", newRV_noinc((SV*)av));
198 STORE_FIELD(hv, step_layout, task_cnt, uint32_t);
199 STORE_FIELD(hv, step_layout, task_dist, uint16_t);
200 av = newAV();
201 for (i = 0; i < step_layout->node_cnt; i ++) {
202 av2 = newAV();
203 for (j = 0; j < step_layout->tasks[i]; j ++)
204 av_store_uint32_t(av2, i, step_layout->tids[i][j]);
205 av_store(av, i, newRV_noinc((SV*)av2));
206 }
207 hv_store_sv(hv, "tids", newRV_noinc((SV*)av));
208
209 return 0;
210 }
211
212 /* convert job_step_pids_t to perl HV */
213 int
job_step_pids_to_hv(job_step_pids_t * pids,HV * hv)214 job_step_pids_to_hv(job_step_pids_t *pids, HV *hv)
215 {
216 int i;
217 AV *av;
218
219 STORE_FIELD(hv, pids, node_name, charp);
220 /* pid_cnt implied in pid array */
221 av = newAV();
222 for (i = 0; i < pids->pid_cnt; i ++) {
223 av_store_uint32_t(av, i, pids->pid[i]);
224 }
225 hv_store_sv(hv, "pid", newRV_noinc((SV*)av));
226
227 return 0;
228 }
229
230 /* convert job_step_pids_response_msg_t to HV */
231 int
job_step_pids_response_msg_to_hv(job_step_pids_response_msg_t * pids_msg,HV * hv)232 job_step_pids_response_msg_to_hv(job_step_pids_response_msg_t *pids_msg, HV *hv)
233 {
234 int i = 0;
235 ListIterator itr;
236 AV *av;
237 HV *hv_pids;
238 job_step_pids_t *pids;
239
240 STORE_FIELD(hv, pids_msg, job_id, uint32_t);
241 STORE_FIELD(hv, pids_msg, step_id, uint32_t);
242
243 av = newAV();
244 itr = slurm_list_iterator_create(pids_msg->pid_list);
245 while ((pids = (job_step_pids_t *)slurm_list_next(itr))) {
246 hv_pids = newHV();
247 if (job_step_pids_to_hv(pids, hv_pids) < 0) {
248 Perl_warn(aTHX_ "failed to convert job_step_pids_t to hv for job_step_pids_response_msg_t");
249 SvREFCNT_dec(hv_pids);
250 SvREFCNT_dec(av);
251 slurm_list_iterator_destroy(itr);
252 return -1;
253 }
254 av_store(av, i++, newRV_noinc((SV*)hv_pids));
255 }
256 slurm_list_iterator_destroy(itr);
257 hv_store_sv(hv, "pid_list", newRV_noinc((SV*)av));
258
259 return 0;
260 }
261
262 /*
263 * convert job_step_stat_t to perl HV
264 */
265 int
job_step_stat_to_hv(job_step_stat_t * stat,HV * hv)266 job_step_stat_to_hv(job_step_stat_t *stat, HV *hv)
267 {
268 HV *hv_pids;
269
270 STORE_PTR_FIELD(hv, stat, jobacct, "Slurm::jobacctinfo_t");
271 STORE_FIELD(hv, stat, num_tasks, uint32_t);
272 STORE_FIELD(hv, stat, return_code, uint32_t);
273 hv_pids = newHV();
274 if (job_step_pids_to_hv(stat->step_pids, hv_pids) < 0) {
275 Perl_warn(aTHX_ "failed to convert job_step_pids_t to hv for job_step_stat_t");
276 SvREFCNT_dec(hv_pids);
277 return -1;
278 }
279 hv_store_sv(hv, "step_pids", newRV_noinc((SV*)hv_pids));
280
281 return 0;
282 }
283
284 /*
285 * convert job_step_stat_response_msg_t to perl HV
286 */
287 int
job_step_stat_response_msg_to_hv(job_step_stat_response_msg_t * stat_msg,HV * hv)288 job_step_stat_response_msg_to_hv(job_step_stat_response_msg_t *stat_msg, HV *hv)
289 {
290 int i = 0;
291 ListIterator itr;
292 job_step_stat_t *stat;
293 AV *av;
294 HV *hv_stat;
295
296 STORE_FIELD(hv, stat_msg, job_id, uint32_t);
297 STORE_FIELD(hv, stat_msg, step_id, uint32_t);
298
299 av = newAV();
300 itr = slurm_list_iterator_create(stat_msg->stats_list);
301 while ((stat = (job_step_stat_t *)slurm_list_next(itr))) {
302 hv_stat = newHV();
303 if(job_step_stat_to_hv(stat, hv_stat) < 0) {
304 Perl_warn(aTHX_ "failed to convert job_step_stat_t to hv for job_step_stat_response_msg_t");
305 SvREFCNT_dec(hv_stat);
306 SvREFCNT_dec(av);
307 slurm_list_iterator_destroy(itr);
308 return -1;
309 }
310 av_store(av, i++, newRV_noinc((SV*)hv_stat));
311 }
312 slurm_list_iterator_destroy(itr);
313 hv_store_sv(hv, "stats_list", newRV_noinc((SV*)av));
314
315 return 0;
316 }
317