use crate::error::{Result, from_daos_errno};
use crate::unsafe_inner::handle::{DaosHandle, validate_handle};
use crate::unsafe_inner::pointer::as_const_char_ptr;
use daos::{
daos_cont_info_t, daos_epoch_t, daos_event_t, daos_handle_t, daos_key_t, daos_obj_id_t,
daos_oclass_hints_t, daos_oclass_id_t, daos_otype_t, daos_pool_info_t, daos_recx_t,
};
const DER_SUCCESS: i32 = 0;
pub fn daos_init() -> Result<()> {
let ret = unsafe { daos::daos_init() };
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_fini() -> Result<()> {
let ret = unsafe { daos::daos_fini() };
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_pool_connect(pool: &str, sys: Option<&str>, flags: u32) -> Result<DaosHandle> {
let pool_cstr = as_const_char_ptr(pool)?;
let sys_cstr = match sys {
Some(s) => Some(as_const_char_ptr(s)?),
None => None,
};
let mut handle: daos_handle_t = daos_handle_t { cookie: 0 };
let ret = unsafe {
daos::daos_pool_connect2(
pool_cstr.as_ptr(),
sys_cstr
.as_ref()
.map_or(std::ptr::null_mut(), |s| s.as_ptr() as *mut _),
flags,
&mut handle,
std::ptr::null_mut(), std::ptr::null_mut(), )
};
if ret == DER_SUCCESS {
validate_handle(handle)?;
Ok(unsafe { DaosHandle::from_raw(handle) })
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_pool_disconnect(poh: DaosHandle) -> Result<()> {
let ret = unsafe { daos::daos_pool_disconnect(poh.as_raw(), std::ptr::null_mut()) };
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_cont_open(poh: DaosHandle, cont: &str, flags: u32) -> Result<DaosHandle> {
let cont_cstr = as_const_char_ptr(cont)?;
let mut coh: daos_handle_t = daos_handle_t { cookie: 0 };
let ret = unsafe {
daos::daos_cont_open2(
poh.as_raw(),
cont_cstr.as_ptr(),
flags,
&mut coh,
std::ptr::null_mut(), std::ptr::null_mut(), )
};
if ret == DER_SUCCESS {
validate_handle(coh)?;
Ok(unsafe { DaosHandle::from_raw(coh) })
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_cont_close(coh: DaosHandle) -> Result<()> {
let ret = unsafe { daos::daos_cont_close(coh.as_raw(), std::ptr::null_mut()) };
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_cont_query(coh: DaosHandle) -> Result<daos_cont_info_t> {
let mut info: daos_cont_info_t = unsafe { std::mem::zeroed() };
let ret = unsafe {
daos::daos_cont_query(
coh.as_raw(),
&mut info,
std::ptr::null_mut(), std::ptr::null_mut(), )
};
if ret == DER_SUCCESS {
Ok(info)
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_cont_create_with_label(
poh: DaosHandle,
label: &str,
uuid: Option<&mut std::mem::MaybeUninit<daos::uuid_t>>,
) -> Result<()> {
let label_cstr = as_const_char_ptr(label)?;
let uuid_ptr = match uuid {
Some(u) => u.as_mut_ptr(),
None => std::ptr::null_mut(),
};
let ret = unsafe {
daos::daos_cont_create_with_label(
poh.as_raw(),
label_cstr.as_ptr(),
std::ptr::null_mut(), uuid_ptr,
std::ptr::null_mut(), )
};
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_cont_alloc_oids(coh: DaosHandle, num_oids: u64) -> Result<u64> {
let mut oid: u64 = 0;
let ret = unsafe {
daos::daos_cont_alloc_oids(
coh.as_raw(),
num_oids,
&mut oid,
std::ptr::null_mut(), )
};
if ret == DER_SUCCESS {
Ok(oid)
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_pool_query(poh: DaosHandle) -> Result<daos_pool_info_t> {
let mut info: daos_pool_info_t = unsafe { std::mem::zeroed() };
let ret = unsafe {
daos::daos_pool_query(
poh.as_raw(),
std::ptr::null_mut(), &mut info,
std::ptr::null_mut(), std::ptr::null_mut(), )
};
if ret == DER_SUCCESS {
Ok(info)
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_obj_generate_oid(coh: DaosHandle, oid: &mut daos_obj_id_t) -> Result<()> {
let ret = unsafe {
daos::daos_obj_generate_oid2(
coh.as_raw(),
oid,
0 as daos_otype_t, 0 as daos_oclass_id_t, 0 as daos_oclass_hints_t, 0,
)
};
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_obj_open(coh: DaosHandle, oid: daos_obj_id_t, mode: u32) -> Result<DaosHandle> {
let mut oh: daos_handle_t = daos_handle_t { cookie: 0 };
let ret =
unsafe { daos::daos_obj_open(coh.as_raw(), oid, mode, &mut oh, std::ptr::null_mut()) };
if ret == DER_SUCCESS {
validate_handle(oh)?;
Ok(unsafe { DaosHandle::from_raw(oh) })
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_obj_close(oh: DaosHandle) -> Result<()> {
let ret = unsafe { daos::daos_obj_close(oh.as_raw(), std::ptr::null_mut()) };
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_cont_create_snap(coh: DaosHandle, name: Option<&str>) -> Result<u64> {
let name_cstr = match name {
Some(n) => Some(as_const_char_ptr(n)?),
None => None,
};
let mut epoch: u64 = 0;
let ret = unsafe {
daos::daos_cont_create_snap(
coh.as_raw(),
&mut epoch,
name_cstr
.as_ref()
.map_or(std::ptr::null_mut(), |n| n.as_ptr() as *mut _),
std::ptr::null_mut(), )
};
if ret == DER_SUCCESS {
Ok(epoch)
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_cont_destroy_snap(coh: DaosHandle, epoch: u64) -> Result<()> {
let epr = daos::daos_epoch_range_t {
epr_lo: epoch,
epr_hi: epoch,
};
let ret = unsafe {
daos::daos_cont_destroy_snap(
coh.as_raw(),
epr,
std::ptr::null_mut(), )
};
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_eq_create() -> Result<DaosHandle> {
let mut eqh: daos_handle_t = daos_handle_t { cookie: 0 };
let ret = unsafe { daos::daos_eq_create(&mut eqh) };
if ret == DER_SUCCESS {
validate_handle(eqh)?;
Ok(unsafe { DaosHandle::from_raw(eqh) })
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_eq_destroy(eqh: DaosHandle) -> Result<()> {
let ret = unsafe { daos::daos_eq_destroy(eqh.as_raw(), 0) };
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_event_init(eqh: DaosHandle) -> Result<daos_event_t> {
let mut ev: daos_event_t = unsafe { std::mem::zeroed() };
let ret = unsafe { daos::daos_event_init(&mut ev, eqh.as_raw(), std::ptr::null_mut()) };
if ret == DER_SUCCESS {
Ok(ev)
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_event_fini(ev: &mut daos_event_t) -> Result<()> {
let ret = unsafe { daos::daos_event_fini(ev) };
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub mod tx_flags {
use daos::DAOS_TF_RDONLY;
pub const TX_RDONLY: u64 = DAOS_TF_RDONLY as u64;
pub const TX_ZERO_COPY: u64 = (daos::DAOS_TF_ZERO_COPY) as u64;
}
pub fn daos_tx_open(coh: DaosHandle, flags: u64) -> Result<DaosHandle> {
let mut th: daos_handle_t = daos_handle_t { cookie: 0 };
let ret = unsafe { daos::daos_tx_open(coh.as_raw(), &mut th, flags, std::ptr::null_mut()) };
if ret == DER_SUCCESS {
validate_handle(th)?;
Ok(unsafe { DaosHandle::from_raw(th) })
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_tx_open_snap(coh: DaosHandle, epoch: u64) -> Result<DaosHandle> {
let mut th: daos_handle_t = daos_handle_t { cookie: 0 };
let ret =
unsafe { daos::daos_tx_open_snap(coh.as_raw(), epoch, &mut th, std::ptr::null_mut()) };
if ret == DER_SUCCESS {
validate_handle(th)?;
Ok(unsafe { DaosHandle::from_raw(th) })
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_tx_commit(th: DaosHandle) -> Result<()> {
let ret = unsafe { daos::daos_tx_commit(th.as_raw(), std::ptr::null_mut()) };
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_tx_abort(th: DaosHandle) -> Result<()> {
let ret = unsafe { daos::daos_tx_abort(th.as_raw(), std::ptr::null_mut()) };
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_tx_close(th: DaosHandle) -> Result<()> {
let ret = unsafe { daos::daos_tx_close(th.as_raw(), std::ptr::null_mut()) };
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_tx_restart(th: DaosHandle) -> Result<()> {
let ret = unsafe { daos::daos_tx_restart(th.as_raw(), std::ptr::null_mut()) };
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_obj_punch(oh: DaosHandle, th: daos_handle_t, flags: u64) -> Result<()> {
let ret = unsafe { daos::daos_obj_punch(oh.as_raw(), th, flags, std::ptr::null_mut()) };
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_obj_punch_dkeys(
oh: DaosHandle,
th: daos_handle_t,
flags: u64,
dkeys: &[daos_key_t],
) -> Result<()> {
let ret = unsafe {
daos::daos_obj_punch_dkeys(
oh.as_raw(),
th,
flags,
dkeys.len() as u32,
dkeys.as_ptr() as *mut daos_key_t,
std::ptr::null_mut(),
)
};
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_obj_punch_akeys(
oh: DaosHandle,
th: daos_handle_t,
flags: u64,
dkey: &daos_key_t,
akeys: &[daos_key_t],
) -> Result<()> {
let ret = unsafe {
daos::daos_obj_punch_akeys(
oh.as_raw(),
th,
flags,
dkey as *const daos_key_t as *mut daos_key_t,
akeys.len() as u32,
akeys.as_ptr() as *mut daos_key_t,
std::ptr::null_mut(),
)
};
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub mod query_flags {
pub const GET_MAX: u64 = 1 << 0;
pub const GET_MIN: u64 = 1 << 1;
pub const GET_DKEY: u64 = 1 << 2;
pub const GET_AKEY: u64 = 1 << 3;
pub const GET_RECX: u64 = 1 << 4;
}
pub fn daos_obj_query_key(
oh: DaosHandle,
th: daos_handle_t,
flags: u64,
dkey: &mut daos_key_t,
akey: &mut daos_key_t,
recx: &mut daos_recx_t,
) -> Result<()> {
let ret = unsafe {
daos::daos_obj_query_key(
oh.as_raw(),
th,
flags,
dkey as *mut daos_key_t,
akey as *mut daos_key_t,
recx as *mut daos_recx_t,
std::ptr::null_mut(),
)
};
if ret == DER_SUCCESS {
Ok(())
} else {
Err(from_daos_errno(ret))
}
}
pub fn daos_obj_query_max_epoch(oh: DaosHandle, th: daos_handle_t) -> Result<u64> {
let mut epoch: u64 = 0;
let ret = unsafe {
daos::daos_obj_query_max_epoch(oh.as_raw(), th, &mut epoch, std::ptr::null_mut())
};
if ret == DER_SUCCESS {
Ok(epoch)
} else {
Err(from_daos_errno(ret))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::unsafe_inner::handle::is_valid_handle;
#[test]
fn test_daos_init_and_fini() {
let result = daos_init();
assert!(result.is_ok());
let result = daos_fini();
assert!(result.is_ok());
}
#[test]
fn test_daos_handle_validation() {
let invalid = daos_handle_t { cookie: 0 };
assert!(!is_valid_handle(invalid));
let valid = daos_handle_t { cookie: 12345 };
assert!(is_valid_handle(valid));
}
}