[rust PATCH] Implement virStoragePoolListAllVolumes and virStoragePoolListVolumes for StoragePool

mathias at pius.io mathias at pius.io
Sat Feb 15 20:08:12 UTC 2020


From: Mathias Pius <mathias at pius.io>

Now as a single patch, and with Signed-off-by tag in accordance with DCO.

This patch implements virStoragePoolListAllVolumes and virStoragePoolListVolumes for the StoragePool object. I'm not too familiar with the libvirt codebase, so I've used similar functions from connect.rs and domain.rs for so the implementations should (hopefully) be as correct as those. I've taken the liberty of using Vec::with_capacity when allocating vectors to store the result of these operations in, to prevent reallocations while converting the object types from the internal type to StorageVol and Strings.

Signed-off-by: Mathias Pius <mathias at pius.io>
---
 src/storage_pool.rs   | 55 ++++++++++++++++++++++++++++++++++++++++++-
 tests/storage_pool.rs | 34 ++++++++++++++++++++++++++
 2 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/src/storage_pool.rs b/src/storage_pool.rs
index 96258f0..571fabd 100644
--- a/src/storage_pool.rs
+++ b/src/storage_pool.rs
@@ -18,7 +18,7 @@
 
 extern crate libc;
 
-use std::str;
+use std::{mem, ptr, str};
 
 use connect::sys::virConnectPtr;
 use storage_vol::sys::virStorageVolPtr;
@@ -78,6 +78,16 @@ extern "C" {
     fn virStoragePoolFree(ptr: sys::virStoragePoolPtr) -> libc::c_int;
     fn virStoragePoolIsActive(ptr: sys::virStoragePoolPtr) -> libc::c_int;
     fn virStoragePoolIsPersistent(ptr: sys::virStoragePoolPtr) -> libc::c_int;
+    fn virStoragePoolListAllVolumes(
+        ptr: sys::virStoragePoolPtr,
+        vols: *mut *mut virStorageVolPtr,
+        flags: libc::c_uint,
+    ) -> libc::c_int;
+    fn virStoragePoolListVolumes(
+        ptr: sys::virStoragePoolPtr,
+        names: *mut *mut libc::c_char,
+        maxnames: libc::c_int,
+    ) -> libc::c_int;
     fn virStoragePoolGetName(ptr: sys::virStoragePoolPtr) -> *const libc::c_char;
     fn virStoragePoolGetXMLDesc(
         ptr: sys::virStoragePoolPtr,
@@ -119,6 +129,8 @@ pub const VIR_STORAGE_POOL_RUNNING: StoragePoolState = 2;
 pub const VIR_STORAGE_POOL_DEGRADED: StoragePoolState = 3;
 pub const VIR_STORAGE_POOL_INACCESSIBLE: StoragePoolState = 4;
 
+pub type StoragePoolListAllVolumesFlags = self::libc::c_uint;
+
 #[derive(Clone, Debug)]
 pub struct StoragePoolInfo {
     /// A `StoragePoolState` flags
@@ -373,6 +385,47 @@ impl StoragePool {
         }
     }
 
+    pub fn list_all_volumes(
+        &self,
+        flags: StoragePoolListAllVolumesFlags,
+    ) -> Result<Vec<StorageVol>, Error> {
+        unsafe {
+            let mut volumes: *mut virStorageVolPtr = ptr::null_mut();
+
+            let size =
+                virStoragePoolListAllVolumes(self.as_ptr(), &mut volumes, flags as libc::c_uint);
+            if size == -1 {
+                return Err(Error::new());
+            }
+
+            mem::forget(volumes);
+
+            let mut array: Vec<StorageVol> = Vec::with_capacity(size as usize);
+            for x in 0..size as isize {
+                array.push(StorageVol::new(*volumes.offset(x)));
+            }
+            libc::free(volumes as *mut libc::c_void);
+
+            Ok(array)
+        }
+    }
+
+    pub fn list_volumes(&self) -> Result<Vec<String>, Error> {
+        unsafe {
+            let mut names: [*mut libc::c_char; 1024] = [ptr::null_mut(); 1024];
+            let size = virStoragePoolListVolumes(self.as_ptr(), names.as_mut_ptr(), 1024);
+            if size == -1 {
+                return Err(Error::new());
+            }
+
+            let mut array: Vec<String> = Vec::with_capacity(size as usize);
+            for x in 0..size as usize {
+                array.push(c_chars_to_string!(names[x]));
+            }
+            return Ok(array);
+        }
+    }
+
     pub fn refresh(&self, flags: u32) -> Result<u32, Error> {
         unsafe {
             let ret = virStoragePoolRefresh(self.as_ptr(), flags as libc::c_uint);
diff --git a/tests/storage_pool.rs b/tests/storage_pool.rs
index 4bfa71d..21c1139 100644
--- a/tests/storage_pool.rs
+++ b/tests/storage_pool.rs
@@ -58,3 +58,37 @@ fn test_lookup_storage_pool_by_name() {
     }
     common::close(c);
 }
+
+#[test]
+fn test_list_volumes() {
+    match Connect::open("test:///default") {
+        Ok(mut conn) => {
+            let sp = conn.list_storage_pools().unwrap_or(vec![]);
+            match StoragePool::lookup_by_name(&conn, &sp[0]) {
+                Ok(storage_pool) => {
+                    storage_pool.list_volumes().unwrap();
+                }
+                Err(e) => panic!("failed with code {}, message: {}", e.code, e.message),
+            }
+            assert_eq!(0, conn.close().unwrap_or(-1));
+        }
+        Err(e) => panic!("failed with code {}, message: {}", e.code, e.message),
+    }
+}
+
+#[test]
+fn test_list_all_volumes() {
+    match Connect::open("test:///default") {
+        Ok(mut conn) => {
+            let sp = conn.list_storage_pools().unwrap_or(vec![]);
+            match StoragePool::lookup_by_name(&conn, &sp[0]) {
+                Ok(storage_pool) => {
+                    storage_pool.list_all_volumes(0).unwrap();
+                }
+                Err(e) => panic!("failed with code {}, message: {}", e.code, e.message),
+            }
+            assert_eq!(0, conn.close().unwrap_or(-1));
+        }
+        Err(e) => panic!("failed with code {}, message: {}", e.code, e.message),
+    }
+}
-- 
2.25.0

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 839 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20200215/fdbff620/attachment-0001.sig>


More information about the libvir-list mailing list