1 /*
2  * reservation.c - convert data between reservation related messages
3  *                 and perl HVs
4  */
5 
6 #include <EXTERN.h>
7 #include <perl.h>
8 #include <XSUB.h>
9 #include "ppport.h"
10 
11 #include <slurm/slurm.h>
12 #include "slurm-perl.h"
13 
14 /*
15  * convert reserve_info_t to perl HV
16  */
17 int
reserve_info_to_hv(reserve_info_t * reserve_info,HV * hv)18 reserve_info_to_hv(reserve_info_t *reserve_info, HV *hv)
19 {
20 	if (reserve_info->accounts)
21 		STORE_FIELD(hv, reserve_info, accounts, charp);
22 	STORE_FIELD(hv, reserve_info, end_time, time_t);
23 	if (reserve_info->features)
24 		STORE_FIELD(hv, reserve_info, features, charp);
25 	STORE_FIELD(hv, reserve_info, flags, uint64_t);
26 	if (reserve_info->licenses)
27 		STORE_FIELD(hv, reserve_info, licenses, charp);
28 	if (reserve_info->name)
29 		STORE_FIELD(hv, reserve_info, name, charp);
30 	STORE_FIELD(hv, reserve_info, node_cnt, uint32_t);
31 	if (reserve_info->node_list)
32 		STORE_FIELD(hv, reserve_info, node_list, charp);
33 
34 	/* no store for int pointers yet */
35 	if (reserve_info->node_inx) {
36 		int j;
37 		AV *av = newAV();
38 		for(j = 0; ; j += 2) {
39 			if(reserve_info->node_inx[j] == -1)
40 				break;
41 			av_store(av, j, newSVuv(reserve_info->node_inx[j]));
42 			av_store(av, j+1,
43 				 newSVuv(reserve_info->node_inx[j+1]));
44 		}
45 		hv_store_sv(hv, "node_inx", newRV_noinc((SV*)av));
46 	}
47 	if (reserve_info->partition)
48 		STORE_FIELD(hv, reserve_info, partition, charp);
49 	STORE_FIELD(hv, reserve_info, start_time, time_t);
50 	if (reserve_info->users)
51 		STORE_FIELD(hv, reserve_info, users, charp);
52 
53 	return 0;
54 }
55 
56 /*
57  * convert perl HV to reserve_info_t
58  */
59 int
hv_to_reserve_info(HV * hv,reserve_info_t * resv_info)60 hv_to_reserve_info(HV *hv, reserve_info_t *resv_info)
61 {
62 	SV **svp;
63 	AV *av;
64 	int i, n;
65 
66 	memset(resv_info, 0, sizeof(reserve_info_t));
67 
68 	FETCH_FIELD(hv, resv_info, accounts, charp, FALSE);
69 	FETCH_FIELD(hv, resv_info, end_time, time_t, TRUE);
70 	FETCH_FIELD(hv, resv_info, features, charp, FALSE);
71 	FETCH_FIELD(hv, resv_info, flags, uint64_t, TRUE);
72 	FETCH_FIELD(hv, resv_info, licenses, charp, FALSE);
73 	FETCH_FIELD(hv, resv_info, name, charp, TRUE);
74 	FETCH_FIELD(hv, resv_info, node_cnt, uint32_t, TRUE);
75 	svp = hv_fetch(hv, "node_inx", 8, FALSE);
76 	if (svp && SvROK(*svp) && SvTYPE(SvRV(*svp)) == SVt_PVAV) {
77 		av = (AV*)SvRV(*svp);
78 		n = av_len(av) + 2; /* for trailing -1 */
79 		resv_info->node_inx = xmalloc(n * sizeof(int));
80 		for (i = 0 ; i < n-1; i += 2) {
81 			resv_info->node_inx[i] = (int)SvIV(*(av_fetch(av, i ,FALSE)));
82 			resv_info->node_inx[i+1] = (int)SvIV(*(av_fetch(av, i+1 ,FALSE)));
83 		}
84 		resv_info->node_inx[n-1] = -1;
85 	} else {
86 		/* nothing to do */
87 	}
88 	FETCH_FIELD(hv, resv_info, node_list, charp, FALSE);
89 	FETCH_FIELD(hv, resv_info, partition, charp, FALSE);
90 	FETCH_FIELD(hv, resv_info, start_time, time_t, TRUE);
91 	FETCH_FIELD(hv, resv_info, users, charp, FALSE);
92 	return 0;
93 }
94 
95 /*
96  * convert reserve_info_msg_t to perl HV
97  */
98 int
reserve_info_msg_to_hv(reserve_info_msg_t * reserve_info_msg,HV * hv)99 reserve_info_msg_to_hv(reserve_info_msg_t *reserve_info_msg, HV *hv)
100 {
101 	int i;
102 	HV *hv_info;
103 	AV *av;
104 
105 	STORE_FIELD(hv, reserve_info_msg, last_update, time_t);
106 	/* record_count implied in reservation_array */
107 	av = newAV();
108 	for(i = 0; i < reserve_info_msg->record_count; i ++) {
109 		hv_info = newHV();
110 		if (reserve_info_to_hv(reserve_info_msg->reservation_array + i,
111 				       hv_info)
112 		    < 0) {
113 			SvREFCNT_dec(hv_info);
114 			SvREFCNT_dec(av);
115 			return -1;
116 		}
117 		av_store(av, i, newRV_noinc((SV*)hv_info));
118 	}
119 	hv_store_sv(hv, "reservation_array", newRV_noinc((SV*)av));
120 	return 0;
121 }
122 
123 /*
124  * convert perl HV to reserve_info_msg_t
125  */
126 int
hv_to_reserve_info_msg(HV * hv,reserve_info_msg_t * resv_info_msg)127 hv_to_reserve_info_msg(HV *hv, reserve_info_msg_t *resv_info_msg)
128 {
129 	SV **svp;
130 	AV *av;
131 	int i, n;
132 
133 	memset(resv_info_msg, 0, sizeof(reserve_info_msg_t));
134 
135 	FETCH_FIELD(hv, resv_info_msg, last_update, time_t, TRUE);
136 
137 	svp = hv_fetch(hv, "reservation_array", 17, FALSE);
138 	if (! (svp && SvROK(*svp) && SvTYPE(SvRV(*svp)) == SVt_PVAV)) {
139 		Perl_warn (aTHX_ "reservation_array is not an array reference in HV for reservation_info_msg_t");
140 		return -1;
141 	}
142 
143 	av = (AV*)SvRV(*svp);
144 	n = av_len(av) + 1;
145 	resv_info_msg->record_count = n;
146 
147 	resv_info_msg->reservation_array = xmalloc(n * sizeof(reserve_info_t));
148 	for (i = 0; i < n; i ++) {
149 		svp = av_fetch(av, i, FALSE);
150 		if (! (svp && SvROK(*svp) && SvTYPE(SvRV(*svp)) == SVt_PVHV)) {
151 			Perl_warn (aTHX_ "element %d in reservation_array is not valid", i);
152 			return -1;
153 		}
154 		if (hv_to_reserve_info((HV*)SvRV(*svp), &resv_info_msg->reservation_array[i]) < 0) {
155 			Perl_warn (aTHX_ "failed to convert element %d in reservation_array", i);
156 			return -1;
157 		}
158 	}
159 	return 0;
160 }
161 
162 /*
163  * convert perl HV to resv_desc_msg_t.
164  */
165 int
hv_to_update_reservation_msg(HV * hv,resv_desc_msg_t * resv_msg)166 hv_to_update_reservation_msg(HV *hv, resv_desc_msg_t *resv_msg)
167 {
168 	slurm_init_resv_desc_msg(resv_msg);
169 
170  	FETCH_FIELD(hv, resv_msg, accounts, charp, FALSE);
171 	FETCH_FIELD(hv, resv_msg, duration, uint32_t, FALSE);
172 	FETCH_FIELD(hv, resv_msg, end_time, time_t, FALSE);
173 	FETCH_FIELD(hv, resv_msg, features, charp, FALSE);
174 	FETCH_FIELD(hv, resv_msg, flags, uint64_t, FALSE);
175 	FETCH_FIELD(hv, resv_msg, licenses, charp, FALSE);
176 	FETCH_FIELD(hv, resv_msg, name, charp, FALSE);
177 	FETCH_PTR_FIELD(hv, resv_msg, node_cnt, "SLURM::uint32_t", FALSE);
178 	FETCH_FIELD(hv, resv_msg, node_list, charp, FALSE);
179 	FETCH_FIELD(hv, resv_msg, partition, charp, FALSE);
180 	FETCH_FIELD(hv, resv_msg, start_time, time_t, FALSE);
181 	FETCH_FIELD(hv, resv_msg, users, charp, FALSE);
182 
183 	return 0;
184 }
185 
186 /*
187  * convert perl HV to reservation_name_msg_t.
188  */
189 int
hv_to_delete_reservation_msg(HV * hv,reservation_name_msg_t * resv_name)190 hv_to_delete_reservation_msg(HV *hv, reservation_name_msg_t *resv_name)
191 {
192 	resv_name->name = NULL;
193 
194 	FETCH_FIELD(hv, resv_name, name, charp, FALSE);
195 
196 	return 0;
197 }
198