1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use linked_list_c::ConstList;
use log::{trace,info,warn,error};
use std::ffi::{CString,CStr};
use std::ptr::null_mut;
use pbs_sys::{attrl, attropl, batch_status};
use crate::bindings::{is_err,get_err,stat};
use crate::helpers::{self,optstr_to_cstr};
use crate::types::{Attribs,StatResp,Server};
type PbsStatSignature = unsafe extern fn(i32, *mut i8, *mut attrl, *mut i8) -> *mut batch_status;
unsafe extern fn sched_stat(conn: i32, n: *mut i8, a: *mut attrl, _ex: *mut i8) -> *mut batch_status {
stat::pbs_statsched(conn, a, n)
}
unsafe extern fn srv_stat(conn: i32, n: *mut i8, a: *mut attrl, _ex: *mut i8) -> *mut batch_status {
stat::pbs_statserver(conn, a, n)
}
impl Server {
pub fn stat_host(&self, name: &Option<String>, info: Option<Attribs>) -> Result<StatResp, String> {
trace!("performing a host stat");
self.stat(name, info, stat::pbs_stathost)
}
pub fn stat_reservation(&self, name: &Option<String>, info: Option<Attribs>) -> Result<StatResp, String> {
trace!("performing a reservation stat");
self.stat(name, info, stat::pbs_statresv)
}
pub fn stat_resource(&self, name: &Option<String>, info: Option<Attribs>) -> Result<StatResp, String> {
trace!("performing a resource stat");
self.stat(name, info, stat::pbs_statrsc)
}
pub fn stat_vnode(&self, name: &Option<String>, info: Option<Attribs>) -> Result<StatResp, String> {
trace!("performing a vnode stat");
self.stat(name, info, stat::pbs_statvnode)
}
pub fn stat_que(&self, name: &Option<String>, info: Option<Attribs>) -> Result<StatResp, String> {
trace!("performing a que stat");
self.stat(name, info, stat::pbs_statque)
}
pub fn stat_scheduler(&self, name: &Option<String>, info: Option<Attribs>) -> Result<StatResp, String> {
trace!("performing a scheduler stat");
self.stat(name, info, sched_stat)
}
pub fn stat_server(&self, name: &Option<String>, info: Option<Attribs>) -> Result<StatResp, String> {
trace!("performing a server stat");
self.stat(name, info, srv_stat)
}
pub fn stat_job(&self, criteria: Attribs, _output: Option<Attribs>) -> Result<StatResp, String> {
trace!("performing a job stat");
let crit: ConstList<attrl> = criteria.into();
trace!("calling pbs server");
let data = unsafe{stat::pbs_selstat(self.conn(), crit.head() as *mut attropl, null_mut(), null_mut())};
if data.is_null() && is_err() {
error!("job stat request failed {}", get_err());
Err(get_err())
}else{
trace!("stat complete, returning list {:?}", &data);
Ok(data.into())
}
}
fn stat(&self, name: &Option<String>, _info: Option<Attribs>, api: PbsStatSignature) -> Result<StatResp,String> {
let n_ptr = optstr_to_cstr(name.as_deref());
let data = {
trace!("Performing stat");
let resp = unsafe{api(self.conn(), n_ptr, null_mut(), null_mut())};
if !n_ptr.is_null() {
trace!("dropping n_ptr");
_ = unsafe{CString::from_raw(n_ptr)};
}
if resp.is_null() && is_err() {
error!("stat request failed {}", get_err());
Err(get_err())
}else{
trace!("got good response");
Ok(resp)
}
}?;
trace!("stat complete, returning list {:?}", &data);
Ok(data.into())
}
pub fn submit(&self, attributes: Attribs, script: &str, queue: &str) -> Result<String, String> {
trace!("Job submission, generating attributes list");
let attribs: ConstList<pbs_sys::attrl> = attributes.into();
trace!("Submitting job request");
let jobid = unsafe{pbs_sys::pbs_submit(self.conn(), attribs.head() as *mut pbs_sys::attropl, helpers::str_to_cstr(script), helpers::str_to_cstr(queue), null_mut())};
if !jobid.is_null() {
let resp = Ok(unsafe{CStr::from_ptr(jobid)}.to_str().unwrap().to_string());
trace!("Job submitted, got resp {:?}", &resp);
unsafe{libc::free(jobid as *mut libc::c_void)};
resp
} else {
warn!("Error submitting job {}", get_err());
Err(get_err())
}
}
pub fn del_job(&self, jobid: &str, msg: Option<&str>) -> Result<(), String> {
trace!("Deleting job {jobid}");
let resp = unsafe{pbs_sys::pbs_deljob(self.conn(), helpers::str_to_cstr(jobid), helpers::optstr_to_cstr(msg))};
if resp != 0 {
info!("Error deleting job {jobid}: {}", get_err());
return Err(get_err());
}
Ok(())
}
}