From 998872a284db6b696cc53f8c8f86a44125446a59 Mon Sep 17 00:00:00 2001 From: Jeeves Date: Tue, 25 Jun 2024 06:23:28 -0600 Subject: [PATCH] zig libvirt: added pool and volume enums/structs --- server/src/libvirt.zig | 167 ++++++++++++++++++++++++++++++++++------- server/src/main.zig | 12 +++ 2 files changed, 150 insertions(+), 29 deletions(-) diff --git a/server/src/libvirt.zig b/server/src/libvirt.zig index dd7bf82..5eac5ec 100644 --- a/server/src/libvirt.zig +++ b/server/src/libvirt.zig @@ -73,6 +73,7 @@ fn intFromFlags(comptime T: type, flags: []const T) c_uint { fn Iterator(comptime T: type, comptime Ptr: type, comptime freeFn: *const fn (Ptr) callconv(.C) c_int) type { return struct { + allocator: mem.Allocator, list: [*]Ptr, num: c_int, curr: usize, @@ -83,11 +84,13 @@ fn Iterator(comptime T: type, comptime Ptr: type, comptime freeFn: *const fn (Pt comptime F: type, // Flags parent: *const P, flags: []const F, + allocator: mem.Allocator, initFn: *const fn (?*PP, [*c][*c]Ptr, c_uint) callconv(.C) c_int, ) !Self { var list: [*]Ptr = undefined; const num = initFn(parent.ptr, @ptrCast(&list), intFromFlags(F, flags)); return if (num < 0) handleError() else .{ + .allocator = allocator, .list = list, .num = num, .curr = 0, @@ -99,13 +102,15 @@ fn Iterator(comptime T: type, comptime Ptr: type, comptime freeFn: *const fn (Pt } pub fn first(self: *Self) T { self.curr = 0; - return .{ .ptr = self.list[self.curr] }; + // return .{ .ptr = self.list[self.curr], .arena = heap.ArenaAllocator.init(self.allocator) }; + return T.init(self.list[self.curr], self.allocator); } pub fn next(self: *Self) ?T { if (self.curr >= self.num) return null; const ptr = self.list[self.curr]; self.curr += 1; - return .{ .ptr = ptr }; + // return .{ .ptr = ptr, .arena = heap.ArenaAllocator.init(self.allocator) }; + return T.init(ptr, self.allocator); } const Self = @This(); }; @@ -154,6 +159,7 @@ pub const Connection = struct { Pool.ListFlags, self, flags, + self.allocator, c.virConnectListAllStoragePools, ); } @@ -175,6 +181,7 @@ pub const Connection = struct { Domain.ListFlags, self, flags, + self.allocator, c.virConnectListAllDomains, ); } @@ -182,18 +189,27 @@ pub const Connection = struct { pub const Pool = struct { ptr: c.virStoragePoolPtr, - arena: heap.ArenaAllocator, + arena: *heap.ArenaAllocator, pub fn init(ptr: c.virStoragePoolPtr, allocator: mem.Allocator) Pool { + var arena = heap.ArenaAllocator.init(allocator); return .{ .ptr = ptr, - .arena = heap.ArenaAllocator.init(allocator), + .arena = &arena, }; } pub fn deinit(self: *const Pool) void { self.arena.deinit(); } + pub fn getName(self: *const Pool) ![]const u8 { + const name = c.virStoragePoolGetName(self.ptr); + // defer std.c.free(name); + const str = string(name); + return if (str.len == 0) handleError() else str; + // return if (str.len == 0) handleError() else try self.arena.allocator().dupe(u8, str); + } + pub fn createVolume(pool: *const Pool, xml: []const u8, flags: []Volume.Flags) !Volume { const volume = c.virStorageVolCreateXML(pool, xml, intFromFlags(Volume.CreateFlags, flags)); return .{ .ptr = volume }; @@ -206,50 +222,131 @@ pub const Pool = struct { Volume.ListFlags, self, flags, + self.arena.allocator(), c.virStoragePoolListAllVolumes, ); } pub const ListFlags = enum(c_uint) { - Inactive = 1 << 0, - Active = 1 << 1, - Persistent = 1 << 2, - Transient = 1 << 3, - Autostart = 1 << 4, - NoAutostart = 1 << 5, - Dir = 1 << 6, - Fs = 1 << 7, - NetFs = 1 << 8, - Logical = 1 << 9, - Disk = 1 << 10, - Iscsi = 1 << 11, - Scsi = 1 << 12, - Mpath = 1 << 13, - Rbd = 1 << 14, - Sheepdog = 1 << 15, - Gluster = 1 << 16, - Zfs = 1 << 17, - Vstorage = 1 << 18, - IscsiDirect = 1 << 19, + Inactive = c.VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE, + Active = c.VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE, + Persistent = c.VIR_CONNECT_LIST_STORAGE_POOLS_PERSISTENT, + Transient = c.VIR_CONNECT_LIST_STORAGE_POOLS_TRANSIENT, + Autostart = c.VIR_CONNECT_LIST_STORAGE_POOLS_AUTOSTART, + NoAutostart = c.VIR_CONNECT_LIST_STORAGE_POOLS_NO_AUTOSTART, + Dir = c.VIR_CONNECT_LIST_STORAGE_POOLS_DIR, + Fs = c.VIR_CONNECT_LIST_STORAGE_POOLS_FS, + NetFs = c.VIR_CONNECT_LIST_STORAGE_POOLS_NETFS, + Logical = c.VIR_CONNECT_LIST_STORAGE_POOLS_LOGICAL, + Disk = c.VIR_CONNECT_LIST_STORAGE_POOLS_DISK, + Iscsi = c.VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI, + Scsi = c.VIR_CONNECT_LIST_STORAGE_POOLS_SCSI, + Mpath = c.VIR_CONNECT_LIST_STORAGE_POOLS_MPATH, + Rbd = c.VIR_CONNECT_LIST_STORAGE_POOLS_RBD, + Sheepdog = c.VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG, + Gluster = c.VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER, + Zfs = c.VIR_CONNECT_LIST_STORAGE_POOLS_ZFS, + Vstorage = c.VIR_CONNECT_LIST_STORAGE_POOLS_VSTORAGE, + IscsiDirect = c.VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI_DIRECT, + }; + pub const BuildFlags = enum(c_uint) {}; + pub const CreateFlags = enum(c_uint) {}; + pub const DefineFlags = enum(c_uint) {}; + pub const DeleteFlags = enum(c_uint) {}; + + pub const Info = struct { + state: State, + capacity: u64, + allocation: u64, + available: u64, + }; + + pub const State = enum(c_uint) { + Inactive = c.VIR_STORAGE_POOL_INACTIVE, + Building = c.VIR_STORAGE_POOL_BUILDING, + Running = c.VIR_STORAGE_POOL_RUNNING, + Degraded = c.VIR_STORAGE_POOL_DEGRADED, + Inaccessible = c.VIR_STORAGE_POOL_INACCESSIBLE, + Last = c.VIR_STORAGE_POOL_STATE_LAST, + }; + pub const EventID = enum(c_uint) { + Lifecycle = c.VIR_STORAGE_POOL_EVENT_ID_LIFECYCLE, + Refresh = c.VIR_STORAGE_POOL_EVENT_ID_REFRESH, + Last = c.VIR_STORAGE_POOL_EVENT_ID_LAST, + }; + pub const EventLifecycleType = enum(c_uint) { + Defined = c.VIR_STORAGE_POOL_EVENT_DEFINED, + Undefined = c.VIR_STORAGE_POOL_EVENT_UNDEFINED, + Started = c.VIR_STORAGE_POOL_EVENT_STARTED, + Stopped = c.VIR_STORAGE_POOL_EVENT_STOPPED, + Created = c.VIR_STORAGE_POOL_EVENT_CREATED, + Deleted = c.VIR_STORAGE_POOL_EVENT_DELETED, + Last = c.VIR_STORAGE_POOL_EVENT_LAST, }; pub const PoolIterator = Iterator(Pool, c.virStoragePoolPtr, c.virStoragePoolFree); pub const Volume = struct { ptr: c.virStorageVolPtr, + arena: *heap.ArenaAllocator, pub fn getName(self: *const Volume) ![]const u8 { const name = c.virStorageVolGetName(self.ptr); - defer std.c.free(name); + // defer std.c.free(name); const str = string(name); - return if (str.len == 0) handleError() else try self.arena.allocator().dupe(u8, str); + return if (str.len == 0) handleError() else str; } pub const ListFlags = enum(c_uint) {}; pub const CreateFlags = enum(c_uint) { - PreallocMetadata = 1 << 0, - Reflink = 1 << 1, - Validate = 1 << 2, + PreallocMetadata = c.VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, + Reflink = c.VIR_STORAGE_VOL_CREATE_REFLINK, + Validate = c.VIR_STORAGE_VOL_CREATE_VALIDATE, + }; + pub const DeleteFlags = enum(c_uint) { + Normal = c.VIR_STORAGE_VOL_DELETE_NORMAL, + Zeroed = c.VIR_STORAGE_VOL_DELETE_ZEROED, + WithSnapshots = c.VIR_STORAGE_VOL_DELETE_WITH_SNAPSHOTS, + }; + pub const DownloadFlags = enum(c_uint) { + SparseStream = c.VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM, + }; + pub const InfoFlags = enum(c_uint) { + UseAllocation = c.VIR_STORAGE_VOL_USE_ALLOCATION, + GetPhysical = c.VIR_STORAGE_VOL_GET_PHYSICAL, + }; + pub const ResizeFlags = enum(c_uint) { + Allocate = c.VIR_STORAGE_VOL_RESIZE_ALLOCATE, + Delta = c.VIR_STORAGE_VOL_RESIZE_DELTA, + Shrink = c.VIR_STORAGE_VOL_RESIZE_SHRINK, + }; + pub const UploadFlags = enum(c_uint) {}; + pub const Info = struct { + type: Type, + capacity: u64, + allocation: u64, + }; + pub const Type = enum(c_uint) { + File = c.VIR_STORAGE_VOL_FILE, + Block = c.VIR_STORAGE_VOL_BLOCK, + Dir = c.VIR_STORAGE_VOL_DIR, + Network = c.VIR_STORAGE_VOL_NETWORK, + Netdir = c.VIR_STORAGE_VOL_NETDIR, + Ploop = c.VIR_STORAGE_VOL_PLOOP, + Last = c.VIR_STORAGE_VOL_LAST, + }; + pub const WipeAlgorithm = enum(c_uint) { + Zero = c.VIR_STORAGE_VOL_WIPE_ALG_ZERO, + Nnsa = c.VIR_STORAGE_VOL_WIPE_ALG_NNSA, + Dod = c.VIR_STORAGE_VOL_WIPE_ALG_DOD, + Bsi = c.VIR_STORAGE_VOL_WIPE_ALG_BSI, + Gutmann = c.VIR_STORAGE_VOL_WIPE_ALG_GUTMANN, + Schneier = c.VIR_STORAGE_VOL_WIPE_ALG_SHNEIER, + Pfitzner7 = c.VIR_STORAGE_VOL_WIPE_ALG_PFITZNER7, + Pfitzner33 = c.VIR_STORAGE_VOL_WIPE_ALG_PFITZNER33, + Random = c.VIR_STORAGE_VOL_WIPE_ALG_RANDOM, + Trim = c.VIR_STORAGE_VOL_WIPE_ALG_TRIM, + Last = c.VIR_STORAGE_VOL_WIPE_ALG_LAST, }; pub const VolumeIterator = Iterator(Volume, c.virStorageVolPtr, c.virStorageVolFree); @@ -258,6 +355,18 @@ pub const Pool = struct { pub const Domain = struct { ptr: c.virDomainPtr, + arena: *heap.ArenaAllocator, + + pub fn init(ptr: c.virDomainPtr, allocator: mem.Allocator) Domain { + var arena = heap.ArenaAllocator.init(allocator); + return .{ + .ptr = ptr, + .arena = &arena, + }; + } + pub fn deinit(self: *const Domain) void { + self.arena.deinit(); + } pub fn getName(self: *const Domain) []const u8 { const name = c.virDomainGetName(self.ptr); diff --git a/server/src/main.zig b/server/src/main.zig index af501dc..db52873 100644 --- a/server/src/main.zig +++ b/server/src/main.zig @@ -55,6 +55,18 @@ pub fn main() !void { const name = domain.getName(); std.debug.print("name: {s}, active: {any}\n", .{ name, active }); } + + var pool_iter = try connection.iteratePools(&[_]libvirt.Pool.ListFlags{ + libvirt.Pool.ListFlags.Active, + libvirt.Pool.ListFlags.Inactive, + }); + defer pool_iter.deinit(); + + while (pool_iter.next()) |pool| { + // const active = pool.isActive(); + const name = try pool.getName(); + std.debug.print("name: {s}\n", .{name}); + } } pub const DomainSpec = struct {