1use std::ffi::CString;
20use std::{mem, ptr, str};
21
22use uuid::Uuid;
23
24use crate::connect::Connect;
25use crate::domain_snapshot::DomainSnapshot;
26use crate::error::Error;
27use crate::stream::Stream;
28use crate::typedparams::{from_params, to_params};
29use crate::util::c_ulong_to_u64;
30use crate::{param_field_in, param_field_out};
31
32#[derive(Clone, Debug)]
33pub struct DomainInfo {
34 pub state: sys::virDomainState,
36 pub max_mem: u64,
38 pub memory: u64,
40 pub nr_virt_cpu: u32,
42 pub cpu_time: u64,
44}
45
46impl DomainInfo {
47 pub unsafe fn from_ptr(ptr: sys::virDomainInfoPtr) -> DomainInfo {
51 DomainInfo {
52 state: (*ptr).state as sys::virDomainState,
53 max_mem: c_ulong_to_u64((*ptr).maxMem),
54 memory: c_ulong_to_u64((*ptr).memory),
55 nr_virt_cpu: (*ptr).nrVirtCpu as u32,
56 cpu_time: (*ptr).cpuTime,
57 }
58 }
59}
60
61#[derive(Clone, Debug)]
62pub struct BlockStats {
63 pub rd_req: i64,
65 pub rd_bytes: i64,
67 pub wr_req: i64,
69 pub wr_bytes: i64,
71 pub errs: i64,
73}
74
75impl BlockStats {
76 pub unsafe fn from_ptr(ptr: sys::virDomainBlockStatsPtr) -> BlockStats {
80 BlockStats {
81 rd_req: (*ptr).rd_req,
82 rd_bytes: (*ptr).rd_bytes,
83 wr_req: (*ptr).wr_req,
84 wr_bytes: (*ptr).wr_bytes,
85 errs: (*ptr).errs,
86 }
87 }
88}
89
90pub struct DomainStatsRecord {
91 pub ptr: sys::virDomainStatsRecordPtr,
93}
94
95#[derive(Clone, Debug)]
96pub struct BlockInfo {
97 pub capacity: u64,
100 pub allocation: u64,
103 pub physical: u64,
106}
107
108impl BlockInfo {
109 pub unsafe fn from_ptr(ptr: sys::virDomainBlockInfoPtr) -> BlockInfo {
113 BlockInfo {
114 capacity: (*ptr).capacity,
115 allocation: (*ptr).allocation,
116 physical: (*ptr).physical,
117 }
118 }
119}
120
121#[derive(Clone, Debug, Default)]
122pub struct MemoryParameters {
123 pub hard_limit: Option<u64>,
125 pub soft_limit: Option<u64>,
128 pub min_guarantee: Option<u64>,
131 pub swap_hard_limit: Option<u64>,
133}
134
135macro_rules! memory_parameters_fields {
136 ($dir:ident, $var:ident) => {
137 vec![
138 $dir!(sys::VIR_DOMAIN_MEMORY_HARD_LIMIT, UInt64, $var.hard_limit),
139 $dir!(sys::VIR_DOMAIN_MEMORY_SOFT_LIMIT, UInt64, $var.soft_limit),
140 $dir!(
141 sys::VIR_DOMAIN_MEMORY_MIN_GUARANTEE,
142 UInt64,
143 $var.min_guarantee
144 ),
145 $dir!(
146 sys::VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT,
147 UInt64,
148 $var.swap_hard_limit
149 ),
150 ]
151 };
152}
153
154impl MemoryParameters {
155 pub const VALUE_UNLIMITED: u64 = sys::VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
156
157 pub fn from_vec(vec: Vec<sys::virTypedParameter>) -> MemoryParameters {
158 let mut ret = MemoryParameters::default();
159 let fields = memory_parameters_fields!(param_field_in, ret);
160 from_params(vec, fields);
161 ret
162 }
163
164 pub fn to_vec(&self) -> Vec<sys::virTypedParameter> {
165 let fields = memory_parameters_fields!(param_field_out, self);
166 to_params(fields)
167 }
168}
169
170macro_rules! numa_parameters_fields {
171 ($dir:ident, $var:ident) => {
172 vec![
173 $dir!(sys::VIR_DOMAIN_NUMA_NODESET, String, $var.node_set),
174 $dir!(sys::VIR_DOMAIN_NUMA_MODE, Int32, $var.mode),
175 ]
176 };
177}
178
179#[derive(Clone, Debug, Default)]
180pub struct NUMAParameters {
181 pub node_set: Option<String>,
183 pub mode: Option<i32>,
186}
187
188impl NUMAParameters {
189 pub fn from_vec(vec: Vec<sys::virTypedParameter>) -> NUMAParameters {
190 let mut ret = NUMAParameters::default();
191 let fields = numa_parameters_fields!(param_field_in, ret);
192 from_params(vec, fields);
193 ret
194 }
195
196 pub fn to_vec(&self) -> Vec<sys::virTypedParameter> {
197 let fields = numa_parameters_fields!(param_field_out, self);
198 to_params(fields)
199 }
200}
201
202macro_rules! migrate_parameters_fields {
203 ($dir:ident, $var:ident) => {
204 vec![
205 $dir!(
206 sys::VIR_MIGRATE_PARAM_AUTO_CONVERGE_INCREMENT,
207 Int32,
208 $var.auto_converge_increment
209 ),
210 $dir!(
211 sys::VIR_MIGRATE_PARAM_AUTO_CONVERGE_INITIAL,
212 Int32,
213 $var.auto_converge_initial
214 ),
215 $dir!(sys::VIR_MIGRATE_PARAM_BANDWIDTH, UInt64, $var.bandwidth),
216 $dir!(
217 sys::VIR_MIGRATE_PARAM_BANDWIDTH_POSTCOPY,
218 UInt64,
219 $var.bandwidth_postcopy
220 ),
221 $dir!(sys::VIR_MIGRATE_PARAM_COMPRESSION, String, $var.compression),
222 $dir!(
223 sys::VIR_MIGRATE_PARAM_COMPRESSION_MT_DTHREADS,
224 Int32,
225 $var.compression_mt_dthreads
226 ),
227 $dir!(
228 sys::VIR_MIGRATE_PARAM_COMPRESSION_MT_LEVEL,
229 Int32,
230 $var.compression_mt_level
231 ),
232 $dir!(
233 sys::VIR_MIGRATE_PARAM_COMPRESSION_MT_THREADS,
234 Int32,
235 $var.compression_mt_threads
236 ),
237 $dir!(
238 sys::VIR_MIGRATE_PARAM_COMPRESSION_XBZRLE_CACHE,
239 UInt64,
240 $var.compression_xbzrle_cache
241 ),
242 $dir!(
243 sys::VIR_MIGRATE_PARAM_COMPRESSION_ZLIB_LEVEL,
244 Int32,
245 $var.compression_zlib_level
246 ),
247 $dir!(
248 sys::VIR_MIGRATE_PARAM_COMPRESSION_ZSTD_LEVEL,
249 Int32,
250 $var.compression_zstd_level
251 ),
252 $dir!(sys::VIR_MIGRATE_PARAM_DEST_NAME, String, $var.dest_name),
253 $dir!(sys::VIR_MIGRATE_PARAM_DEST_XML, String, $var.dest_xml),
254 $dir!(sys::VIR_MIGRATE_PARAM_DISKS_PORT, Int32, $var.disks_port),
255 $dir!(sys::VIR_MIGRATE_PARAM_DISKS_URI, String, $var.disks_uri),
256 $dir!(
257 sys::VIR_MIGRATE_PARAM_GRAPHICS_URI,
258 String,
259 $var.graphics_uri
260 ),
261 $dir!(
262 sys::VIR_MIGRATE_PARAM_LISTEN_ADDRESS,
263 String,
264 $var.listen_address
265 ),
266 $dir!(
267 sys::VIR_MIGRATE_PARAM_MIGRATE_DISKS,
268 VecString,
269 $var.migrate_disks
270 ),
271 $dir!(
272 sys::VIR_MIGRATE_PARAM_PARALLEL_CONNECTIONS,
273 Int32,
274 $var.parallel_connections
275 ),
276 $dir!(sys::VIR_MIGRATE_PARAM_PERSIST_XML, String, $var.persist_xml),
277 $dir!(
278 sys::VIR_MIGRATE_PARAM_TLS_DESTINATION,
279 String,
280 $var.tls_destination
281 ),
282 $dir!(sys::VIR_MIGRATE_PARAM_URI, String, $var.uri),
283 ]
284 };
285}
286
287#[derive(Clone, Debug, Default)]
288pub struct MigrateParameters {
289 pub auto_converge_increment: Option<i32>,
290 pub auto_converge_initial: Option<i32>,
291 pub bandwidth: Option<u64>,
292 pub bandwidth_postcopy: Option<u64>,
293 pub compression: Option<String>,
294 pub compression_mt_dthreads: Option<i32>,
295 pub compression_mt_level: Option<i32>,
296 pub compression_mt_threads: Option<i32>,
297 pub compression_xbzrle_cache: Option<u64>,
298 pub compression_zlib_level: Option<i32>,
299 pub compression_zstd_level: Option<i32>,
300 pub dest_name: Option<String>,
301 pub dest_xml: Option<String>,
302 pub disks_port: Option<i32>,
303 pub disks_uri: Option<String>,
304 pub graphics_uri: Option<String>,
305 pub listen_address: Option<String>,
306 pub migrate_disks: Vec<String>,
307 pub parallel_connections: Option<i32>,
308 pub persist_xml: Option<String>,
309 pub tls_destination: Option<String>,
310 pub uri: Option<String>,
311}
312
313impl MigrateParameters {
314 pub fn from_vec(vec: Vec<sys::virTypedParameter>) -> MigrateParameters {
315 let mut ret = MigrateParameters::default();
316 let fields = migrate_parameters_fields!(param_field_in, ret);
317 from_params(vec, fields);
318 ret
319 }
320
321 pub fn to_vec(&self) -> Vec<sys::virTypedParameter> {
322 let fields = migrate_parameters_fields!(param_field_out, self);
323 to_params(fields)
324 }
325}
326
327#[derive(Clone, Debug)]
328pub struct IPAddress {
329 pub typed: i64,
330 pub addr: String,
331 pub prefix: u64,
332}
333
334impl IPAddress {
335 pub unsafe fn from_ptr(ptr: sys::virDomainIPAddressPtr) -> IPAddress {
339 IPAddress {
340 typed: (*ptr).type_ as i64,
341 addr: c_chars_to_string!((*ptr).addr),
342 prefix: (*ptr).prefix as u64,
343 }
344 }
345}
346
347#[derive(Clone, Debug)]
348pub struct Interface {
349 pub name: String,
350 pub hwaddr: String,
351 pub naddrs: u64,
352 pub addrs: Vec<IPAddress>,
353}
354
355impl Interface {
356 pub unsafe fn from_ptr(ptr: sys::virDomainInterfacePtr) -> Interface {
360 let naddrs = (*ptr).naddrs;
361 let mut addrs = vec![];
362 for x in 0..naddrs as isize {
363 addrs.push(IPAddress::from_ptr((*ptr).addrs.offset(x)));
364 }
365 Interface {
366 name: c_chars_to_string!((*ptr).name),
367 hwaddr: c_chars_to_string!((*ptr).hwaddr),
368 naddrs: naddrs as u64,
369 addrs,
370 }
371 }
372}
373
374#[derive(Clone, Debug)]
375pub struct InterfaceStats {
376 pub rx_bytes: i64,
377 pub rx_packets: i64,
378 pub rx_errs: i64,
379 pub rx_drop: i64,
380 pub tx_bytes: i64,
381 pub tx_packets: i64,
382 pub tx_errs: i64,
383 pub tx_drop: i64,
384}
385
386impl InterfaceStats {
387 pub unsafe fn from_ptr(ptr: sys::virDomainInterfaceStatsPtr) -> InterfaceStats {
391 InterfaceStats {
392 rx_bytes: (*ptr).rx_bytes,
393 rx_packets: (*ptr).rx_packets,
394 rx_errs: (*ptr).rx_errs,
395 rx_drop: (*ptr).rx_drop,
396 tx_bytes: (*ptr).tx_bytes,
397 tx_packets: (*ptr).tx_packets,
398 tx_errs: (*ptr).tx_errs,
399 tx_drop: (*ptr).tx_drop,
400 }
401 }
402}
403
404#[derive(Clone, Debug)]
405pub struct MemoryStat {
406 pub tag: u32,
407 pub val: u64,
408}
409
410impl MemoryStat {
411 pub unsafe fn from_ptr(ptr: *const sys::virDomainMemoryStatStruct) -> MemoryStat {
415 MemoryStat {
416 tag: (*ptr).tag as u32,
417 val: (*ptr).val,
418 }
419 }
420}
421
422#[derive(Clone, Debug, Default)]
425pub struct JobStats {
426 pub r#type: i32,
427
428 pub auto_converge_throttle: Option<i32>,
429
430 pub compression_bytes: Option<u64>,
431 pub compression_cache: Option<u64>,
432 pub compression_cache_misses: Option<u64>,
433 pub compression_overflow: Option<u64>,
434 pub compression_pages: Option<u64>,
435
436 pub data_processed: Option<u64>,
437 pub data_remaining: Option<u64>,
438 pub data_total: Option<u64>,
439
440 pub disk_bps: Option<u64>,
441 pub disk_processed: Option<u64>,
442 pub disk_remaining: Option<u64>,
443 pub disk_temp_total: Option<u64>,
444 pub disk_temp_used: Option<u64>,
445 pub disk_total: Option<u64>,
446
447 pub downtime: Option<u64>,
448 pub downtime_net: Option<u64>,
449
450 pub error_message: Option<String>,
451
452 pub mem_bps: Option<u64>,
453 pub mem_constant: Option<u64>,
454 pub mem_dirty_rate: Option<u64>,
455 pub mem_iteration: Option<u64>,
456 pub mem_normal: Option<u64>,
457 pub mem_normal_bytes: Option<u64>,
458 pub mem_page_size: Option<u64>,
459 pub mem_postcopy_reqs: Option<u64>,
460 pub mem_processed: Option<u64>,
461 pub mem_remaining: Option<u64>,
462 pub mem_total: Option<u64>,
463
464 pub operation: Option<i32>,
465
466 pub setup_time: Option<u64>,
467
468 pub success: Option<bool>,
469
470 pub time_elapsed: Option<u64>,
471 pub time_elapsed_net: Option<u64>,
472 pub time_remaining: Option<u64>,
473}
474
475macro_rules! job_stats_fields {
476 ($dir:ident, $var:ident) => {
477 vec![
478 $dir!(
479 sys::VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE,
480 Int32,
481 $var.auto_converge_throttle
482 ),
483 $dir!(
484 sys::VIR_DOMAIN_JOB_COMPRESSION_BYTES,
485 UInt64,
486 $var.compression_bytes
487 ),
488 $dir!(
489 sys::VIR_DOMAIN_JOB_COMPRESSION_CACHE,
490 UInt64,
491 $var.compression_cache
492 ),
493 $dir!(
494 sys::VIR_DOMAIN_JOB_COMPRESSION_CACHE_MISSES,
495 UInt64,
496 $var.compression_cache_misses
497 ),
498 $dir!(
499 sys::VIR_DOMAIN_JOB_COMPRESSION_OVERFLOW,
500 UInt64,
501 $var.compression_overflow
502 ),
503 $dir!(
504 sys::VIR_DOMAIN_JOB_COMPRESSION_PAGES,
505 UInt64,
506 $var.compression_pages
507 ),
508 $dir!(
509 sys::VIR_DOMAIN_JOB_DATA_PROCESSED,
510 UInt64,
511 $var.data_processed
512 ),
513 $dir!(
514 sys::VIR_DOMAIN_JOB_DATA_REMAINING,
515 UInt64,
516 $var.data_remaining
517 ),
518 $dir!(sys::VIR_DOMAIN_JOB_DATA_TOTAL, UInt64, $var.data_total),
519 $dir!(sys::VIR_DOMAIN_JOB_DISK_BPS, UInt64, $var.disk_bps),
520 $dir!(
521 sys::VIR_DOMAIN_JOB_DISK_PROCESSED,
522 UInt64,
523 $var.disk_processed
524 ),
525 $dir!(
526 sys::VIR_DOMAIN_JOB_DISK_REMAINING,
527 UInt64,
528 $var.disk_remaining
529 ),
530 $dir!(
531 sys::VIR_DOMAIN_JOB_DISK_TEMP_TOTAL,
532 UInt64,
533 $var.disk_temp_total
534 ),
535 $dir!(
536 sys::VIR_DOMAIN_JOB_DISK_TEMP_USED,
537 UInt64,
538 $var.disk_temp_used
539 ),
540 $dir!(sys::VIR_DOMAIN_JOB_DISK_TOTAL, UInt64, $var.disk_total),
541 $dir!(sys::VIR_DOMAIN_JOB_DOWNTIME, UInt64, $var.downtime),
542 $dir!(sys::VIR_DOMAIN_JOB_DOWNTIME_NET, UInt64, $var.downtime_net),
543 $dir!(sys::VIR_DOMAIN_JOB_ERRMSG, String, $var.error_message),
544 $dir!(sys::VIR_DOMAIN_JOB_MEMORY_BPS, UInt64, $var.mem_bps),
545 $dir!(
546 sys::VIR_DOMAIN_JOB_MEMORY_CONSTANT,
547 UInt64,
548 $var.mem_constant
549 ),
550 $dir!(
551 sys::VIR_DOMAIN_JOB_MEMORY_DIRTY_RATE,
552 UInt64,
553 $var.mem_dirty_rate
554 ),
555 $dir!(
556 sys::VIR_DOMAIN_JOB_MEMORY_ITERATION,
557 UInt64,
558 $var.mem_iteration
559 ),
560 $dir!(sys::VIR_DOMAIN_JOB_MEMORY_NORMAL, UInt64, $var.mem_normal),
561 $dir!(
562 sys::VIR_DOMAIN_JOB_MEMORY_NORMAL_BYTES,
563 UInt64,
564 $var.mem_normal_bytes
565 ),
566 $dir!(
567 sys::VIR_DOMAIN_JOB_MEMORY_PAGE_SIZE,
568 UInt64,
569 $var.mem_page_size
570 ),
571 $dir!(
572 sys::VIR_DOMAIN_JOB_MEMORY_POSTCOPY_REQS,
573 UInt64,
574 $var.mem_postcopy_reqs
575 ),
576 $dir!(
577 sys::VIR_DOMAIN_JOB_MEMORY_PROCESSED,
578 UInt64,
579 $var.mem_processed
580 ),
581 $dir!(
582 sys::VIR_DOMAIN_JOB_MEMORY_REMAINING,
583 UInt64,
584 $var.mem_remaining
585 ),
586 $dir!(sys::VIR_DOMAIN_JOB_MEMORY_TOTAL, UInt64, $var.mem_total),
587 $dir!(sys::VIR_DOMAIN_JOB_OPERATION, Int32, $var.operation),
588 $dir!(sys::VIR_DOMAIN_JOB_SETUP_TIME, UInt64, $var.setup_time),
589 $dir!(sys::VIR_DOMAIN_JOB_SUCCESS, Bool, $var.success),
590 $dir!(sys::VIR_DOMAIN_JOB_TIME_ELAPSED, UInt64, $var.time_elapsed),
591 $dir!(
592 sys::VIR_DOMAIN_JOB_TIME_ELAPSED_NET,
593 UInt64,
594 $var.time_elapsed_net
595 ),
596 $dir!(
597 sys::VIR_DOMAIN_JOB_TIME_REMAINING,
598 UInt64,
599 $var.time_remaining
600 ),
601 ]
602 };
603}
604
605impl From<(i32, Vec<sys::virTypedParameter>)> for JobStats {
606 fn from((r#type, params): (i32, Vec<sys::virTypedParameter>)) -> Self {
607 let mut stats = Self {
608 r#type,
609 ..Default::default()
610 };
611
612 let fields = job_stats_fields!(param_field_in, stats);
613
614 from_params(params, fields);
615
616 stats
617 }
618}
619
620#[derive(Clone, Debug, Default)]
623pub struct SchedBandwidth {
624 pub period: Option<u64>,
625 pub quota: Option<i64>,
626}
627
628#[derive(Clone, Debug, Default)]
629pub struct SchedulerInfo {
630 pub scheduler_type: String,
631 pub cpu_shares: Option<u64>,
633 pub vcpu_bw: SchedBandwidth,
635 pub emulator_bw: SchedBandwidth,
637 pub global_bw: SchedBandwidth,
639 pub iothread_bw: SchedBandwidth,
641 pub weight: Option<u32>,
643 pub cap: Option<u32>,
645 pub reservation: Option<i64>,
647 pub limit: Option<i64>,
649 pub shares: Option<i32>,
651}
652
653macro_rules! scheduler_info_fields {
654 ($dir:ident, $var:ident) => {
655 vec![
656 $dir!(
657 sys::VIR_DOMAIN_SCHEDULER_CPU_SHARES,
658 UInt64,
659 $var.cpu_shares
660 ),
661 $dir!(
662 sys::VIR_DOMAIN_SCHEDULER_VCPU_PERIOD,
663 UInt64,
664 $var.vcpu_bw.period
665 ),
666 $dir!(
667 sys::VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
668 Int64,
669 $var.vcpu_bw.quota
670 ),
671 $dir!(
672 sys::VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD,
673 UInt64,
674 $var.emulator_bw.period
675 ),
676 $dir!(
677 sys::VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA,
678 Int64,
679 $var.emulator_bw.quota
680 ),
681 $dir!(
682 sys::VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD,
683 UInt64,
684 $var.global_bw.period
685 ),
686 $dir!(
687 sys::VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA,
688 Int64,
689 $var.global_bw.quota
690 ),
691 $dir!(
692 sys::VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD,
693 UInt64,
694 $var.iothread_bw.period
695 ),
696 $dir!(
697 sys::VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA,
698 Int64,
699 $var.iothread_bw.quota
700 ),
701 $dir!(sys::VIR_DOMAIN_SCHEDULER_WEIGHT, UInt32, $var.weight),
702 $dir!(sys::VIR_DOMAIN_SCHEDULER_CAP, UInt32, $var.cap),
703 $dir!(
704 sys::VIR_DOMAIN_SCHEDULER_RESERVATION,
705 Int64,
706 $var.reservation
707 ),
708 $dir!(sys::VIR_DOMAIN_SCHEDULER_LIMIT, Int64, $var.limit),
709 $dir!(sys::VIR_DOMAIN_SCHEDULER_SHARES, Int32, $var.shares),
710 ]
711 };
712}
713
714impl SchedulerInfo {
715 pub fn from_vec(vec: Vec<sys::virTypedParameter>, scheduler_type: String) -> SchedulerInfo {
716 let mut ret = SchedulerInfo {
717 scheduler_type,
718 ..Default::default()
719 };
720 let fields = scheduler_info_fields!(param_field_in, ret);
721 from_params(vec, fields);
722 ret
723 }
724
725 pub fn to_vec(&self) -> Vec<sys::virTypedParameter> {
726 let fields = scheduler_info_fields!(param_field_out, self);
727 to_params(fields)
728 }
729}
730
731#[derive(Debug)]
735pub struct Domain {
736 ptr: Option<sys::virDomainPtr>,
737}
738
739unsafe impl Send for Domain {}
740unsafe impl Sync for Domain {}
741
742impl Drop for Domain {
743 fn drop(&mut self) {
744 if self.ptr.is_some() {
745 if let Err(e) = self.free() {
746 panic!("Unable to drop memory for Domain: {e}")
747 }
748 }
749 }
750}
751
752impl Clone for Domain {
753 fn clone(&self) -> Self {
761 self.add_ref().unwrap()
762 }
763}
764
765impl Domain {
766 pub unsafe fn from_ptr(ptr: sys::virDomainPtr) -> Domain {
770 Domain { ptr: Some(ptr) }
771 }
772
773 fn add_ref(&self) -> Result<Domain, Error> {
774 unsafe {
775 if sys::virDomainRef(self.as_ptr()) == -1 {
776 return Err(Error::last_error());
777 }
778 }
779
780 Ok(unsafe { Domain::from_ptr(self.as_ptr()) })
781 }
782
783 pub fn as_ptr(&self) -> sys::virDomainPtr {
784 self.ptr.unwrap()
785 }
786
787 pub fn get_connect(&self) -> Result<Connect, Error> {
788 let ptr = unsafe { sys::virDomainGetConnect(self.as_ptr()) };
789 if ptr.is_null() {
790 return Err(Error::last_error());
791 }
792 Ok(unsafe { Connect::from_ptr(ptr) })
793 }
794
795 pub fn lookup_by_id(conn: &Connect, id: u32) -> Result<Domain, Error> {
796 let ptr = unsafe { sys::virDomainLookupByID(conn.as_ptr(), id as libc::c_int) };
797 if ptr.is_null() {
798 return Err(Error::last_error());
799 }
800 Ok(unsafe { Domain::from_ptr(ptr) })
801 }
802
803 pub fn lookup_by_name(conn: &Connect, id: &str) -> Result<Domain, Error> {
804 let id_buf = CString::new(id).unwrap();
805 let ptr = unsafe { sys::virDomainLookupByName(conn.as_ptr(), id_buf.as_ptr()) };
806 if ptr.is_null() {
807 return Err(Error::last_error());
808 }
809 Ok(unsafe { Domain::from_ptr(ptr) })
810 }
811
812 pub fn lookup_by_uuid(conn: &Connect, uuid: Uuid) -> Result<Domain, Error> {
813 let ptr = unsafe { sys::virDomainLookupByUUID(conn.as_ptr(), uuid.as_bytes().as_ptr()) };
814 if ptr.is_null() {
815 return Err(Error::last_error());
816 }
817 Ok(unsafe { Domain::from_ptr(ptr) })
818 }
819
820 pub fn lookup_by_uuid_string(conn: &Connect, uuid: &str) -> Result<Domain, Error> {
821 let uuid_buf = CString::new(uuid).unwrap();
822 let ptr = unsafe { sys::virDomainLookupByUUIDString(conn.as_ptr(), uuid_buf.as_ptr()) };
823 if ptr.is_null() {
824 return Err(Error::last_error());
825 }
826 Ok(unsafe { Domain::from_ptr(ptr) })
827 }
828
829 pub fn get_state(&self) -> Result<(sys::virDomainState, i32), Error> {
834 let mut state: libc::c_int = -1;
835 let mut reason: libc::c_int = -1;
836 let ret = unsafe { sys::virDomainGetState(self.as_ptr(), &mut state, &mut reason, 0) };
837 if ret == -1 {
838 return Err(Error::last_error());
839 }
840 Ok((state as sys::virDomainState, reason))
841 }
842
843 pub fn get_name(&self) -> Result<String, Error> {
845 let n = unsafe { sys::virDomainGetName(self.as_ptr()) };
846 if n.is_null() {
847 return Err(Error::last_error());
848 }
849 Ok(unsafe { c_chars_to_string!(n, nofree) })
850 }
851
852 pub fn get_os_type(&self) -> Result<String, Error> {
854 let n = unsafe { sys::virDomainGetOSType(self.as_ptr()) };
855 if n.is_null() {
856 return Err(Error::last_error());
857 }
858 Ok(unsafe { c_chars_to_string!(n) })
859 }
860
861 pub fn get_hostname(&self, flags: u32) -> Result<String, Error> {
863 let n = unsafe { sys::virDomainGetHostname(self.as_ptr(), flags as libc::c_uint) };
864 if n.is_null() {
865 return Err(Error::last_error());
866 }
867 Ok(unsafe { c_chars_to_string!(n) })
868 }
869
870 pub fn get_uuid(&self) -> Result<Uuid, Error> {
871 let mut uuid: [libc::c_uchar; sys::VIR_UUID_BUFLEN as usize] =
872 [0; sys::VIR_UUID_BUFLEN as usize];
873 let ret = unsafe { sys::virDomainGetUUID(self.as_ptr(), uuid.as_mut_ptr()) };
874 if ret == -1 {
875 return Err(Error::last_error());
876 }
877 Ok(Uuid::from_bytes(uuid))
878 }
879
880 pub fn get_uuid_string(&self) -> Result<String, Error> {
884 let mut uuid: [libc::c_char; sys::VIR_UUID_STRING_BUFLEN as usize] =
885 [0; sys::VIR_UUID_STRING_BUFLEN as usize];
886 let ret = unsafe { sys::virDomainGetUUIDString(self.as_ptr(), uuid.as_mut_ptr()) };
887 if ret == -1 {
888 return Err(Error::last_error());
889 }
890 Ok(unsafe { c_chars_to_string!(uuid.as_ptr(), nofree) })
891 }
892
893 pub fn get_id(&self) -> Option<u32> {
895 let ret = unsafe { sys::virDomainGetID(self.as_ptr()) };
896 if ret as i32 == -1 {
897 return None;
898 }
899 Some(ret)
900 }
901
902 pub fn get_xml_desc(&self, flags: sys::virDomainCreateFlags) -> Result<String, Error> {
907 let xml = unsafe { sys::virDomainGetXMLDesc(self.as_ptr(), flags) };
908 if xml.is_null() {
909 return Err(Error::last_error());
910 }
911 Ok(unsafe { c_chars_to_string!(xml) })
912 }
913
914 pub fn create(&self) -> Result<u32, Error> {
921 let ret = unsafe { sys::virDomainCreate(self.as_ptr()) };
922 if ret == -1 {
923 return Err(Error::last_error());
924 }
925 Ok(ret as u32)
926 }
927
928 pub fn create_with_flags(&self, flags: sys::virDomainCreateFlags) -> Result<u32, Error> {
931 let res = unsafe { sys::virDomainCreateWithFlags(self.as_ptr(), flags as libc::c_uint) };
932 if res == -1 {
933 return Err(Error::last_error());
934 }
935 Ok(res as u32)
936 }
937
938 pub fn get_info(&self) -> Result<DomainInfo, Error> {
942 let mut pinfo = mem::MaybeUninit::uninit();
943 let res = unsafe { sys::virDomainGetInfo(self.as_ptr(), pinfo.as_mut_ptr()) };
944 if res == -1 {
945 return Err(Error::last_error());
946 }
947 Ok(unsafe { DomainInfo::from_ptr(&mut pinfo.assume_init()) })
948 }
949
950 pub fn create_xml(
962 conn: &Connect,
963 xml: &str,
964 flags: sys::virDomainCreateFlags,
965 ) -> Result<Domain, Error> {
966 let xml_buf = CString::new(xml).unwrap();
967 let ptr = unsafe {
968 sys::virDomainCreateXML(conn.as_ptr(), xml_buf.as_ptr(), flags as libc::c_uint)
969 };
970 if ptr.is_null() {
971 return Err(Error::last_error());
972 }
973 Ok(unsafe { Domain::from_ptr(ptr) })
974 }
975
976 pub fn define_xml(conn: &Connect, xml: &str) -> Result<Domain, Error> {
990 let xml_buf = CString::new(xml).unwrap();
991 let ptr = unsafe { sys::virDomainDefineXML(conn.as_ptr(), xml_buf.as_ptr()) };
992 if ptr.is_null() {
993 return Err(Error::last_error());
994 }
995 Ok(unsafe { Domain::from_ptr(ptr) })
996 }
997
998 pub fn define_xml_flags(
1012 conn: &Connect,
1013 xml: &str,
1014 flags: sys::virDomainDefineFlags,
1015 ) -> Result<Domain, Error> {
1016 let xml_buf = CString::new(xml).unwrap();
1017 let ptr = unsafe {
1018 sys::virDomainDefineXMLFlags(conn.as_ptr(), xml_buf.as_ptr(), flags as libc::c_uint)
1019 };
1020 if ptr.is_null() {
1021 return Err(Error::last_error());
1022 }
1023 Ok(unsafe { Domain::from_ptr(ptr) })
1024 }
1025
1026 pub fn destroy(&self) -> Result<(), Error> {
1031 let ret = unsafe { sys::virDomainDestroy(self.as_ptr()) };
1032 if ret == -1 {
1033 return Err(Error::last_error());
1034 }
1035 Ok(())
1036 }
1037
1038 pub fn reset(&self) -> Result<u32, Error> {
1046 let ret = unsafe { sys::virDomainReset(self.as_ptr(), 0) };
1047 if ret == -1 {
1048 return Err(Error::last_error());
1049 }
1050 Ok(ret as u32)
1051 }
1052
1053 pub fn destroy_flags(&self, flags: sys::virDomainDestroyFlagsValues) -> Result<u32, Error> {
1058 let ret = unsafe { sys::virDomainDestroyFlags(self.as_ptr(), flags) };
1059 if ret == -1 {
1060 return Err(Error::last_error());
1061 }
1062 Ok(ret as u32)
1063 }
1064
1065 pub fn shutdown(&self) -> Result<u32, Error> {
1080 let ret = unsafe { sys::virDomainShutdown(self.as_ptr()) };
1081 if ret == -1 {
1082 return Err(Error::last_error());
1083 }
1084 Ok(ret as u32)
1085 }
1086
1087 pub fn shutdown_flags(&self, flags: sys::virDomainShutdownFlagValues) -> Result<u32, Error> {
1111 let ret = unsafe { sys::virDomainShutdownFlags(self.as_ptr(), flags as libc::c_uint) };
1112 if ret == -1 {
1113 return Err(Error::last_error());
1114 }
1115 Ok(ret as u32)
1116 }
1117
1118 pub fn reboot(&self, flags: sys::virDomainRebootFlagValues) -> Result<(), Error> {
1122 let ret = unsafe { sys::virDomainReboot(self.as_ptr(), flags) };
1123 if ret == -1 {
1124 return Err(Error::last_error());
1125 }
1126 Ok(())
1127 }
1128
1129 pub fn suspend(&self) -> Result<u32, Error> {
1141 let ret = unsafe { sys::virDomainSuspend(self.as_ptr()) };
1142 if ret == -1 {
1143 return Err(Error::last_error());
1144 }
1145 Ok(ret as u32)
1146 }
1147
1148 pub fn resume(&self) -> Result<u32, Error> {
1158 let ret = unsafe { sys::virDomainResume(self.as_ptr()) };
1159 if ret == -1 {
1160 return Err(Error::last_error());
1161 }
1162 Ok(ret as u32)
1163 }
1164
1165 pub fn pm_wakeup(&self, flags: u32) -> Result<u32, Error> {
1166 let ret = unsafe { sys::virDomainPMWakeup(self.as_ptr(), flags as libc::c_uint) };
1167 if ret == -1 {
1168 return Err(Error::last_error());
1169 }
1170 Ok(ret as u32)
1171 }
1172
1173 pub fn is_active(&self) -> Result<bool, Error> {
1175 let ret = unsafe { sys::virDomainIsActive(self.as_ptr()) };
1176 if ret == -1 {
1177 return Err(Error::last_error());
1178 }
1179 Ok(ret == 1)
1180 }
1181
1182 pub fn is_persistent(&self) -> Result<bool, Error> {
1185 let ret = unsafe { sys::virDomainIsPersistent(self.as_ptr()) };
1186 if ret == -1 {
1187 return Err(Error::last_error());
1188 }
1189 Ok(ret == 1)
1190 }
1191
1192 pub fn undefine(&self) -> Result<(), Error> {
1198 let ret = unsafe { sys::virDomainUndefine(self.as_ptr()) };
1199 if ret == -1 {
1200 return Err(Error::last_error());
1201 }
1202 Ok(())
1203 }
1204
1205 pub fn undefine_flags(&self, flags: sys::virDomainUndefineFlagsValues) -> Result<(), Error> {
1211 let ret = unsafe { sys::virDomainUndefineFlags(self.as_ptr(), flags) };
1212 if ret == -1 {
1213 return Err(Error::last_error());
1214 }
1215 Ok(())
1216 }
1217
1218 pub fn free(&mut self) -> Result<(), Error> {
1223 let ret = unsafe { sys::virDomainFree(self.as_ptr()) };
1224 if ret == -1 {
1225 return Err(Error::last_error());
1226 }
1227 self.ptr = None;
1228 Ok(())
1229 }
1230
1231 pub fn is_updated(&self) -> Result<bool, Error> {
1232 let ret = unsafe { sys::virDomainIsUpdated(self.as_ptr()) };
1233 if ret == -1 {
1234 return Err(Error::last_error());
1235 }
1236 Ok(ret == 1)
1237 }
1238
1239 pub fn get_autostart(&self) -> Result<bool, Error> {
1240 let mut autostart: libc::c_int = 0;
1241 let ret = unsafe { sys::virDomainGetAutostart(self.as_ptr(), &mut autostart) };
1242 if ret == -1 {
1243 return Err(Error::last_error());
1244 }
1245 Ok(autostart == 1)
1246 }
1247
1248 pub fn set_autostart(&self, autostart: bool) -> Result<bool, Error> {
1249 let ret = unsafe { sys::virDomainSetAutostart(self.as_ptr(), autostart as libc::c_int) };
1250 if ret == -1 {
1251 return Err(Error::last_error());
1252 }
1253 Ok(ret == 1)
1254 }
1255
1256 pub fn set_max_memory(&self, memory: u64) -> Result<bool, Error> {
1257 let ret = unsafe { sys::virDomainSetMaxMemory(self.as_ptr(), memory as libc::c_ulong) };
1258 if ret == -1 {
1259 return Err(Error::last_error());
1260 }
1261 Ok(ret == 1)
1262 }
1263
1264 pub fn get_max_memory(&self) -> Result<u64, Error> {
1265 let ret = unsafe { sys::virDomainGetMaxMemory(self.as_ptr()) };
1266 if ret == 0 {
1267 return Err(Error::last_error());
1268 }
1269 Ok(c_ulong_to_u64(ret))
1270 }
1271
1272 pub fn get_max_vcpus(&self) -> Result<u64, Error> {
1273 let ret = unsafe { sys::virDomainGetMaxVcpus(self.as_ptr()) };
1274 if ret == 0 {
1275 return Err(Error::last_error());
1276 }
1277 Ok(ret as u64)
1278 }
1279
1280 pub fn set_memory(&self, memory: u64) -> Result<bool, Error> {
1281 let ret = unsafe { sys::virDomainSetMemory(self.as_ptr(), memory as libc::c_ulong) };
1282 if ret == -1 {
1283 return Err(Error::last_error());
1284 }
1285 Ok(ret == 1)
1286 }
1287
1288 pub fn set_memory_flags(
1289 &self,
1290 memory: u64,
1291 flags: sys::virDomainMemoryModFlags,
1292 ) -> Result<bool, Error> {
1293 let ret = unsafe {
1294 sys::virDomainSetMemoryFlags(
1295 self.as_ptr(),
1296 memory as libc::c_ulong,
1297 flags as libc::c_uint,
1298 )
1299 };
1300 if ret == -1 {
1301 return Err(Error::last_error());
1302 }
1303 Ok(ret == 1)
1304 }
1305
1306 pub fn set_memory_stats_period(
1307 &self,
1308 period: i32,
1309 flags: sys::virDomainMemoryModFlags,
1310 ) -> Result<bool, Error> {
1311 let ret = unsafe {
1312 sys::virDomainSetMemoryStatsPeriod(
1313 self.as_ptr(),
1314 period as libc::c_int,
1315 flags as libc::c_uint,
1316 )
1317 };
1318 if ret == -1 {
1319 return Err(Error::last_error());
1320 }
1321 Ok(ret == 1)
1322 }
1323
1324 pub fn set_vcpus(&self, vcpus: u32) -> Result<bool, Error> {
1325 let ret = unsafe { sys::virDomainSetVcpus(self.as_ptr(), vcpus as libc::c_uint) };
1326 if ret == -1 {
1327 return Err(Error::last_error());
1328 }
1329 Ok(ret == 1)
1330 }
1331
1332 pub fn set_vcpus_flags(
1333 &self,
1334 vcpus: u32,
1335 flags: sys::virDomainVcpuFlags,
1336 ) -> Result<bool, Error> {
1337 let ret = unsafe {
1338 sys::virDomainSetVcpusFlags(self.as_ptr(), vcpus as libc::c_uint, flags as libc::c_uint)
1339 };
1340 if ret == -1 {
1341 return Err(Error::last_error());
1342 }
1343 Ok(ret == 1)
1344 }
1345
1346 pub fn domain_restore(conn: &Connect, path: &str) -> Result<(), Error> {
1347 let path_buf = CString::new(path).unwrap();
1348 let ret = unsafe { sys::virDomainRestore(conn.as_ptr(), path_buf.as_ptr()) };
1349 if ret == -1 {
1350 return Err(Error::last_error());
1351 }
1352 Ok(())
1353 }
1354
1355 pub fn domain_restore_flags(
1356 conn: &Connect,
1357 path: &str,
1358 dxml: Option<&str>,
1359 flags: sys::virDomainSaveRestoreFlags,
1360 ) -> Result<(), Error> {
1361 let path_buf = CString::new(path).unwrap();
1362 let dxml_buf = some_string_to_cstring!(dxml);
1363 let ret = unsafe {
1364 sys::virDomainRestoreFlags(
1365 conn.as_ptr(),
1366 path_buf.as_ptr(),
1367 some_cstring_to_c_chars!(dxml_buf),
1368 flags,
1369 )
1370 };
1371 if ret == -1 {
1372 return Err(Error::last_error());
1373 }
1374 Ok(())
1375 }
1376
1377 pub fn get_vcpus_flags(&self, flags: sys::virDomainVcpuFlags) -> Result<u32, Error> {
1378 let ret = unsafe { sys::virDomainGetVcpusFlags(self.as_ptr(), flags as libc::c_uint) };
1379 if ret == -1 {
1380 return Err(Error::last_error());
1381 }
1382 Ok(ret as u32)
1383 }
1384
1385 pub fn migrate_set_max_speed(&self, bandwidth: u64, flags: u32) -> Result<u32, Error> {
1386 let ret = unsafe {
1387 sys::virDomainMigrateSetMaxSpeed(
1388 self.as_ptr(),
1389 bandwidth as libc::c_ulong,
1390 flags as libc::c_uint,
1391 )
1392 };
1393 if ret == -1 {
1394 return Err(Error::last_error());
1395 }
1396 Ok(ret as u32)
1397 }
1398
1399 pub fn migrate_get_max_speed(&self, flags: u32) -> Result<u64, Error> {
1400 let mut bandwidth: libc::c_ulong = 0;
1401 let ret = unsafe {
1402 sys::virDomainMigrateGetMaxSpeed(self.as_ptr(), &mut bandwidth, flags as libc::c_uint)
1403 };
1404 if ret == -1 {
1405 return Err(Error::last_error());
1406 }
1407 Ok(c_ulong_to_u64(bandwidth))
1408 }
1409
1410 pub fn migrate_set_compression_cache(&self, size: u64, flags: u32) -> Result<u32, Error> {
1411 let ret = unsafe {
1412 sys::virDomainMigrateSetCompressionCache(
1413 self.as_ptr(),
1414 size as libc::c_ulonglong,
1415 flags as libc::c_uint,
1416 )
1417 };
1418 if ret == -1 {
1419 return Err(Error::last_error());
1420 }
1421 Ok(ret as u32)
1422 }
1423
1424 pub fn migrate_get_compression_cache(&self, flags: u32) -> Result<u64, Error> {
1425 let mut size: libc::c_ulonglong = 0;
1426 let ret = unsafe {
1427 sys::virDomainMigrateGetCompressionCache(
1428 self.as_ptr(),
1429 &mut size,
1430 flags as libc::c_uint,
1431 )
1432 };
1433 if ret == -1 {
1434 return Err(Error::last_error());
1435 }
1436 Ok(size)
1437 }
1438
1439 pub fn migrate_set_max_downtime(&self, downtime: u64, flags: u32) -> Result<u32, Error> {
1440 let ret = unsafe {
1441 sys::virDomainMigrateSetMaxDowntime(
1442 self.as_ptr(),
1443 downtime as libc::c_ulonglong,
1444 flags as libc::c_uint,
1445 )
1446 };
1447 if ret == -1 {
1448 return Err(Error::last_error());
1449 }
1450 Ok(ret as u32)
1451 }
1452
1453 pub fn set_time(&self, seconds: i64, nseconds: i32, flags: u32) -> Result<u32, Error> {
1454 let ret = unsafe {
1455 sys::virDomainSetTime(
1456 self.as_ptr(),
1457 seconds as libc::c_longlong,
1458 nseconds as libc::c_uint,
1459 flags as libc::c_uint,
1460 )
1461 };
1462 if ret == -1 {
1463 return Err(Error::last_error());
1464 }
1465 Ok(ret as u32)
1466 }
1467
1468 pub fn get_time(&self, flags: u32) -> Result<(i64, i32), Error> {
1469 let mut seconds: libc::c_longlong = 0;
1470 let mut nseconds: libc::c_uint = 0;
1471 let ret = unsafe {
1472 sys::virDomainGetTime(
1473 self.as_ptr(),
1474 &mut seconds,
1475 &mut nseconds,
1476 flags as libc::c_uint,
1477 )
1478 };
1479 if ret == -1 {
1480 return Err(Error::last_error());
1481 }
1482 Ok((seconds, nseconds as i32))
1483 }
1484
1485 pub fn get_block_info(&self, disk: &str, flags: u32) -> Result<BlockInfo, Error> {
1486 let mut pinfo = mem::MaybeUninit::uninit();
1487 let disk_buf = CString::new(disk).unwrap();
1488 let ret = unsafe {
1489 sys::virDomainGetBlockInfo(
1490 self.as_ptr(),
1491 disk_buf.as_ptr(),
1492 pinfo.as_mut_ptr(),
1493 flags as libc::c_uint,
1494 )
1495 };
1496 if ret == -1 {
1497 return Err(Error::last_error());
1498 }
1499 Ok(unsafe { BlockInfo::from_ptr(&mut pinfo.assume_init()) })
1500 }
1501
1502 pub fn get_block_stats(&self, disk: &str) -> Result<BlockStats, Error> {
1503 let mut pinfo = mem::MaybeUninit::uninit();
1504 let disk_buf = CString::new(disk).unwrap();
1505 let ret = unsafe {
1506 sys::virDomainBlockStats(
1507 self.as_ptr(),
1508 disk_buf.as_ptr(),
1509 pinfo.as_mut_ptr(),
1510 mem::size_of::<sys::virDomainBlockStatsStruct>(),
1511 )
1512 };
1513 if ret == -1 {
1514 return Err(Error::last_error());
1515 }
1516 Ok(unsafe { BlockStats::from_ptr(&mut pinfo.assume_init()) })
1517 }
1518
1519 pub fn pin_vcpu(&self, vcpu: u32, cpumap: &[u8]) -> Result<u32, Error> {
1520 let ret = unsafe {
1521 sys::virDomainPinVcpu(
1522 self.as_ptr(),
1523 vcpu as libc::c_uint,
1524 cpumap.as_ptr() as *mut _,
1525 cpumap.len() as libc::c_int,
1526 )
1527 };
1528 if ret == -1 {
1529 return Err(Error::last_error());
1530 }
1531 Ok(ret as u32)
1532 }
1533
1534 pub fn pin_vcpu_flags(&self, vcpu: u32, cpumap: &[u8], flags: u32) -> Result<u32, Error> {
1535 let ret = unsafe {
1536 sys::virDomainPinVcpuFlags(
1537 self.as_ptr(),
1538 vcpu as libc::c_uint,
1539 cpumap.as_ptr() as *mut _,
1540 cpumap.len() as libc::c_int,
1541 flags as libc::c_uint,
1542 )
1543 };
1544 if ret == -1 {
1545 return Err(Error::last_error());
1546 }
1547 Ok(ret as u32)
1548 }
1549
1550 pub fn pin_emulator(&self, cpumap: &[u8], flags: u32) -> Result<u32, Error> {
1551 let ret = unsafe {
1552 sys::virDomainPinEmulator(
1553 self.as_ptr(),
1554 cpumap.as_ptr() as *mut _,
1555 cpumap.len() as libc::c_int,
1556 flags as libc::c_uint,
1557 )
1558 };
1559 if ret == -1 {
1560 return Err(Error::last_error());
1561 }
1562 Ok(ret as u32)
1563 }
1564
1565 pub fn rename(&self, new_name: &str, flags: u32) -> Result<u32, Error> {
1566 let new_name_buf = CString::new(new_name).unwrap();
1567 let ret = unsafe {
1568 sys::virDomainRename(self.as_ptr(), new_name_buf.as_ptr(), flags as libc::c_uint)
1569 };
1570 if ret == -1 {
1571 return Err(Error::last_error());
1572 }
1573 Ok(ret as u32)
1574 }
1575
1576 pub fn set_user_password(&self, user: &str, password: &str, flags: u32) -> Result<u32, Error> {
1577 let user_buf = CString::new(user).unwrap();
1578 let password_buf = CString::new(password).unwrap();
1579 let ret = unsafe {
1580 sys::virDomainSetUserPassword(
1581 self.as_ptr(),
1582 user_buf.as_ptr(),
1583 password_buf.as_ptr(),
1584 flags as libc::c_uint,
1585 )
1586 };
1587 if ret == -1 {
1588 return Err(Error::last_error());
1589 }
1590 Ok(ret as u32)
1591 }
1592
1593 pub fn set_block_threshold(&self, dev: &str, threshold: u64, flags: u32) -> Result<u32, Error> {
1594 let dev_buf = CString::new(dev).unwrap();
1595 let ret = unsafe {
1596 sys::virDomainSetBlockThreshold(
1597 self.as_ptr(),
1598 dev_buf.as_ptr(),
1599 threshold as libc::c_ulonglong,
1600 flags as libc::c_uint,
1601 )
1602 };
1603 if ret == -1 {
1604 return Err(Error::last_error());
1605 }
1606 Ok(ret as u32)
1607 }
1608
1609 pub fn open_graphics(&self, idx: u32, fd: i32, flags: u32) -> Result<u32, Error> {
1610 let ret = unsafe {
1611 sys::virDomainOpenGraphics(
1612 self.as_ptr(),
1613 idx as libc::c_uint,
1614 fd as libc::c_int,
1615 flags as libc::c_uint,
1616 )
1617 };
1618 if ret == -1 {
1619 return Err(Error::last_error());
1620 }
1621 Ok(ret as u32)
1622 }
1623
1624 pub fn open_graphics_fd(&self, idx: u32, flags: u32) -> Result<u32, Error> {
1625 let ret = unsafe {
1626 sys::virDomainOpenGraphicsFD(self.as_ptr(), idx as libc::c_uint, flags as libc::c_uint)
1627 };
1628 if ret == -1 {
1629 return Err(Error::last_error());
1630 }
1631 Ok(ret as u32)
1632 }
1633
1634 pub fn open_channel(
1635 &self,
1636 name: Option<&str>,
1637 stream: &Stream,
1638 flags: u32,
1639 ) -> Result<u32, Error> {
1640 let name_buf = some_string_to_cstring!(name);
1641 let ret = unsafe {
1642 sys::virDomainOpenChannel(
1643 self.as_ptr(),
1644 some_cstring_to_c_chars!(name_buf),
1645 stream.as_ptr(),
1646 flags as libc::c_uint,
1647 )
1648 };
1649 if ret == -1 {
1650 return Err(Error::last_error());
1651 }
1652 Ok(ret as u32)
1653 }
1654
1655 pub fn open_console(
1656 &self,
1657 name: Option<&str>,
1658 stream: &Stream,
1659 flags: u32,
1660 ) -> Result<u32, Error> {
1661 let name_buf = some_string_to_cstring!(name);
1662 let ret = unsafe {
1663 sys::virDomainOpenConsole(
1664 self.as_ptr(),
1665 some_cstring_to_c_chars!(name_buf),
1666 stream.as_ptr(),
1667 flags as libc::c_uint,
1668 )
1669 };
1670 if ret == -1 {
1671 return Err(Error::last_error());
1672 }
1673 Ok(ret as u32)
1674 }
1675
1676 pub fn interface_addresses(
1677 &self,
1678 source: sys::virDomainInterfaceAddressesSource,
1679 flags: u32,
1680 ) -> Result<Vec<Interface>, Error> {
1681 let mut addresses: *mut sys::virDomainInterfacePtr = ptr::null_mut();
1682 let size = unsafe {
1683 sys::virDomainInterfaceAddresses(self.as_ptr(), &mut addresses, source, flags)
1684 };
1685 if size == -1 {
1686 return Err(Error::last_error());
1687 }
1688
1689 let mut array: Vec<Interface> = Vec::new();
1690 for x in 0..size as isize {
1691 array.push(unsafe { Interface::from_ptr(*addresses.offset(x)) });
1692 }
1693 unsafe { libc::free(addresses as *mut libc::c_void) };
1694
1695 Ok(array)
1696 }
1697
1698 pub fn interface_stats(&self, path: &str) -> Result<InterfaceStats, Error> {
1699 let mut pinfo = mem::MaybeUninit::uninit();
1700 let path_buf = CString::new(path).unwrap();
1701 let ret = unsafe {
1702 sys::virDomainInterfaceStats(
1703 self.as_ptr(),
1704 path_buf.as_ptr(),
1705 pinfo.as_mut_ptr(),
1706 mem::size_of::<sys::virDomainInterfaceStatsStruct>(),
1707 )
1708 };
1709 if ret == -1 {
1710 return Err(Error::last_error());
1711 }
1712 Ok(unsafe { InterfaceStats::from_ptr(&mut pinfo.assume_init()) })
1713 }
1714
1715 pub fn memory_stats(&self, flags: u32) -> Result<Vec<MemoryStat>, Error> {
1716 let mut pinfo: Vec<sys::virDomainMemoryStatStruct> =
1717 Vec::with_capacity(sys::VIR_DOMAIN_MEMORY_STAT_NR as usize);
1718 let ret = unsafe {
1719 sys::virDomainMemoryStats(
1720 self.as_ptr(),
1721 pinfo.as_mut_ptr(),
1722 sys::VIR_DOMAIN_MEMORY_STAT_NR,
1723 flags as libc::c_uint,
1724 )
1725 };
1726 if ret == -1 {
1727 return Err(Error::last_error());
1728 }
1729 unsafe { pinfo.set_len(ret as usize) };
1732
1733 let mut stats: Vec<MemoryStat> = Vec::with_capacity(ret as usize);
1734 for x in pinfo.iter().take(ret as usize) {
1735 stats.push(unsafe { MemoryStat::from_ptr(x) });
1736 }
1737 Ok(stats)
1738 }
1739
1740 pub fn get_job_stats(&self, flags: sys::virDomainGetJobStatsFlags) -> Result<JobStats, Error> {
1743 let mut r#type: libc::c_int = 0;
1744
1745 let mut nparams: libc::c_int = 0;
1748 let mut params: sys::virTypedParameterPtr = ptr::null_mut();
1749
1750 let ret = unsafe {
1751 sys::virDomainGetJobStats(
1752 self.as_ptr(),
1753 &mut r#type,
1754 &mut params,
1755 &mut nparams,
1756 flags as libc::c_uint,
1757 )
1758 };
1759
1760 if ret == -1 {
1761 return Err(Error::last_error());
1762 }
1763
1764 let res: Vec<sys::virTypedParameter> =
1765 unsafe { Vec::from_raw_parts(params, nparams as usize, nparams as usize) };
1766
1767 Ok((r#type, res).into())
1768 }
1769
1770 pub fn get_job_info(&self) -> Result<JobStats, Error> {
1774 unsafe {
1775 let mut job_info = mem::MaybeUninit::uninit();
1776 let ret = sys::virDomainGetJobInfo(self.as_ptr(), job_info.as_mut_ptr());
1777
1778 if ret == -1 {
1779 return Err(Error::last_error());
1780 }
1781
1782 let ptr: sys::virDomainJobInfoPtr = &mut job_info.assume_init();
1783
1784 Ok(JobStats {
1785 r#type: (*ptr).type_,
1786 time_elapsed: Some((*ptr).timeElapsed as u64),
1787 time_remaining: Some((*ptr).timeRemaining as u64),
1788 data_total: Some((*ptr).dataTotal as u64),
1789 data_processed: Some((*ptr).dataProcessed as u64),
1790 data_remaining: Some((*ptr).dataRemaining as u64),
1791 mem_total: Some((*ptr).memTotal as u64),
1792 mem_processed: Some((*ptr).memProcessed as u64),
1793 mem_remaining: Some((*ptr).memRemaining as u64),
1794 disk_total: Some((*ptr).fileTotal as u64),
1795 disk_processed: Some((*ptr).fileProcessed as u64),
1796 disk_remaining: Some((*ptr).fileRemaining as u64),
1797 ..Default::default()
1798 })
1799 }
1800 }
1801
1802 pub fn save_image_get_xml_desc(
1803 conn: &Connect,
1804 file: &str,
1805 flags: u32,
1806 ) -> Result<String, Error> {
1807 let file_buf = CString::new(file).unwrap();
1808 let ptr = unsafe {
1809 sys::virDomainSaveImageGetXMLDesc(
1810 conn.as_ptr(),
1811 file_buf.as_ptr(),
1812 flags as libc::c_uint,
1813 )
1814 };
1815 if ptr.is_null() {
1816 return Err(Error::last_error());
1817 }
1818 Ok(unsafe { c_chars_to_string!(ptr) })
1819 }
1820
1821 pub fn save_image_define_xml(
1822 conn: &Connect,
1823 file: &str,
1824 dxml: &str,
1825 flags: u32,
1826 ) -> Result<u32, Error> {
1827 let file_buf = CString::new(file).unwrap();
1828 let dxml_buf = CString::new(dxml).unwrap();
1829 let ret = unsafe {
1830 sys::virDomainSaveImageDefineXML(
1831 conn.as_ptr(),
1832 file_buf.as_ptr(),
1833 dxml_buf.as_ptr(),
1834 flags as libc::c_uint,
1835 )
1836 };
1837 if ret == -1 {
1838 return Err(Error::last_error());
1839 }
1840 Ok(ret as u32)
1841 }
1842
1843 pub fn attach_device(&self, xml: &str) -> Result<u32, Error> {
1844 let xml_buf = CString::new(xml).unwrap();
1845 let ret = unsafe { sys::virDomainAttachDevice(self.as_ptr(), xml_buf.as_ptr()) };
1846 if ret == -1 {
1847 return Err(Error::last_error());
1848 }
1849 Ok(ret as u32)
1850 }
1851
1852 pub fn attach_device_flags(&self, xml: &str, flags: u32) -> Result<u32, Error> {
1853 let xml_buf = CString::new(xml).unwrap();
1854 let ret = unsafe {
1855 sys::virDomainAttachDeviceFlags(self.as_ptr(), xml_buf.as_ptr(), flags as libc::c_uint)
1856 };
1857 if ret == -1 {
1858 return Err(Error::last_error());
1859 }
1860 Ok(ret as u32)
1861 }
1862
1863 pub fn detach_device(&self, xml: &str) -> Result<u32, Error> {
1864 let xml_buf = CString::new(xml).unwrap();
1865 let ret = unsafe { sys::virDomainDetachDevice(self.as_ptr(), xml_buf.as_ptr()) };
1866 if ret == -1 {
1867 return Err(Error::last_error());
1868 }
1869 Ok(ret as u32)
1870 }
1871
1872 pub fn detach_device_flags(&self, xml: &str, flags: u32) -> Result<u32, Error> {
1873 let xml_buf = CString::new(xml).unwrap();
1874 let ret = unsafe {
1875 sys::virDomainDetachDeviceFlags(self.as_ptr(), xml_buf.as_ptr(), flags as libc::c_uint)
1876 };
1877 if ret == -1 {
1878 return Err(Error::last_error());
1879 }
1880 Ok(ret as u32)
1881 }
1882
1883 pub fn update_device_flags(&self, xml: &str, flags: u32) -> Result<u32, Error> {
1884 let xml_buf = CString::new(xml).unwrap();
1885 let ret = unsafe {
1886 sys::virDomainUpdateDeviceFlags(self.as_ptr(), xml_buf.as_ptr(), flags as libc::c_uint)
1887 };
1888 if ret == -1 {
1889 return Err(Error::last_error());
1890 }
1891 Ok(ret as u32)
1892 }
1893
1894 pub fn managed_save(&self, flags: u32) -> Result<u32, Error> {
1895 let ret = unsafe { sys::virDomainManagedSave(self.as_ptr(), flags as libc::c_uint) };
1896 if ret == -1 {
1897 return Err(Error::last_error());
1898 }
1899 Ok(ret as u32)
1900 }
1901
1902 pub fn has_managed_save(&self, flags: u32) -> Result<bool, Error> {
1903 let ret =
1904 unsafe { sys::virDomainHasManagedSaveImage(self.as_ptr(), flags as libc::c_uint) };
1905 if ret == -1 {
1906 return Err(Error::last_error());
1907 }
1908 Ok(ret == 1)
1909 }
1910
1911 pub fn managed_save_remove(&self, flags: u32) -> Result<u32, Error> {
1912 let ret = unsafe { sys::virDomainManagedSaveRemove(self.as_ptr(), flags as libc::c_uint) };
1913 if ret == -1 {
1914 return Err(Error::last_error());
1915 }
1916 Ok(ret as u32)
1917 }
1918
1919 pub fn core_dump(&self, to: &str, flags: u32) -> Result<u32, Error> {
1920 let to_buf = CString::new(to).unwrap();
1921 let ret = unsafe {
1922 sys::virDomainCoreDump(self.as_ptr(), to_buf.as_ptr(), flags as libc::c_uint)
1923 };
1924 if ret == -1 {
1925 return Err(Error::last_error());
1926 }
1927 Ok(ret as u32)
1928 }
1929
1930 pub fn core_dump_with_format(&self, to: &str, format: u32, flags: u32) -> Result<u32, Error> {
1931 let to_buf = CString::new(to).unwrap();
1932 let ret = unsafe {
1933 sys::virDomainCoreDumpWithFormat(
1934 self.as_ptr(),
1935 to_buf.as_ptr(),
1936 format as libc::c_uint,
1937 flags as libc::c_uint,
1938 )
1939 };
1940 if ret == -1 {
1941 return Err(Error::last_error());
1942 }
1943 Ok(ret as u32)
1944 }
1945
1946 pub fn set_metadata(
1947 &self,
1948 kind: i32,
1949 metadata: Option<&str>,
1950 key: Option<&str>,
1951 uri: Option<&str>,
1952 flags: u32,
1953 ) -> Result<u32, Error> {
1954 let metadata_buf = some_string_to_cstring!(metadata);
1955 let key_buf = some_string_to_cstring!(key);
1956 let uri_buf = some_string_to_cstring!(uri);
1957 let ret = unsafe {
1958 sys::virDomainSetMetadata(
1959 self.as_ptr(),
1960 kind as libc::c_int,
1961 some_cstring_to_c_chars!(metadata_buf),
1962 some_cstring_to_c_chars!(key_buf),
1963 some_cstring_to_c_chars!(uri_buf),
1964 flags as libc::c_uint,
1965 )
1966 };
1967 if ret == -1 {
1968 return Err(Error::last_error());
1969 }
1970 Ok(ret as u32)
1971 }
1972
1973 pub fn get_metadata(&self, kind: i32, uri: Option<&str>, flags: u32) -> Result<String, Error> {
1974 let uri_buf = some_string_to_cstring!(uri);
1975 let n = unsafe {
1976 sys::virDomainGetMetadata(
1977 self.as_ptr(),
1978 kind as libc::c_int,
1979 some_cstring_to_c_chars!(uri_buf),
1980 flags as libc::c_uint,
1981 )
1982 };
1983 if n.is_null() {
1984 return Err(Error::last_error());
1985 }
1986 Ok(unsafe { c_chars_to_string!(n) })
1987 }
1988
1989 pub fn block_resize(&self, disk: &str, size: u64, flags: u32) -> Result<u32, Error> {
1990 let disk_buf = CString::new(disk).unwrap();
1991 let ret = unsafe {
1992 sys::virDomainBlockResize(
1993 self.as_ptr(),
1994 disk_buf.as_ptr(),
1995 size as libc::c_ulonglong,
1996 flags as libc::c_uint,
1997 )
1998 };
1999 if ret == -1 {
2000 return Err(Error::last_error());
2001 }
2002 Ok(ret as u32)
2003 }
2004
2005 pub fn get_memory_parameters(&self, flags: u32) -> Result<MemoryParameters, Error> {
2006 let mut nparams: libc::c_int = 0;
2007 let ret = unsafe {
2008 sys::virDomainGetMemoryParameters(
2009 self.as_ptr(),
2010 ptr::null_mut(),
2011 &mut nparams,
2012 flags as libc::c_uint,
2013 )
2014 };
2015 if ret == -1 {
2016 return Err(Error::last_error());
2017 }
2018 let mut params: Vec<sys::virTypedParameter> = Vec::with_capacity(nparams as usize);
2019 let ret = unsafe {
2020 sys::virDomainGetMemoryParameters(
2021 self.as_ptr(),
2022 params.as_mut_ptr(),
2023 &mut nparams,
2024 flags as libc::c_uint,
2025 )
2026 };
2027 if ret == -1 {
2028 return Err(Error::last_error());
2029 }
2030 unsafe { params.set_len(nparams as usize) };
2031 Ok(MemoryParameters::from_vec(params))
2032 }
2033
2034 pub fn set_memory_parameters(
2035 &self,
2036 params: MemoryParameters,
2037 flags: u32,
2038 ) -> Result<u32, Error> {
2039 let mut cparams = params.to_vec();
2040
2041 let ret = unsafe {
2042 sys::virDomainSetMemoryParameters(
2043 self.as_ptr(),
2044 cparams.as_mut_ptr(),
2045 cparams.len() as libc::c_int,
2046 flags as libc::c_uint,
2047 )
2048 };
2049 if ret == -1 {
2050 return Err(Error::last_error());
2051 }
2052 Ok(ret as u32)
2053 }
2054
2055 pub fn migrate(
2056 &self,
2057 dconn: &Connect,
2058 flags: u32,
2059 dname: Option<&str>,
2060 uri: Option<&str>,
2061 bandwidth: u64,
2062 ) -> Result<Domain, Error> {
2063 let dname_buf = some_string_to_cstring!(dname);
2064 let uri_buf = some_string_to_cstring!(uri);
2065 let ptr = unsafe {
2066 sys::virDomainMigrate(
2067 self.as_ptr(),
2068 dconn.as_ptr(),
2069 flags as libc::c_ulong,
2070 some_cstring_to_c_chars!(dname_buf),
2071 some_cstring_to_c_chars!(uri_buf),
2072 bandwidth as libc::c_ulong,
2073 )
2074 };
2075 if ptr.is_null() {
2076 return Err(Error::last_error());
2077 }
2078 Ok(unsafe { Domain::from_ptr(ptr) })
2079 }
2080
2081 pub fn migrate2(
2082 &self,
2083 dconn: &Connect,
2084 dxml: Option<&str>,
2085 flags: u32,
2086 dname: Option<&str>,
2087 uri: Option<&str>,
2088 bandwidth: u64,
2089 ) -> Result<Domain, Error> {
2090 let dxml_buf = some_string_to_cstring!(dxml);
2091 let dname_buf = some_string_to_cstring!(dname);
2092 let uri_buf = some_string_to_cstring!(uri);
2093 let ptr = unsafe {
2094 sys::virDomainMigrate2(
2095 self.as_ptr(),
2096 dconn.as_ptr(),
2097 some_cstring_to_c_chars!(dxml_buf),
2098 flags as libc::c_ulong,
2099 some_cstring_to_c_chars!(dname_buf),
2100 some_cstring_to_c_chars!(uri_buf),
2101 bandwidth as libc::c_ulong,
2102 )
2103 };
2104 if ptr.is_null() {
2105 return Err(Error::last_error());
2106 }
2107 Ok(unsafe { Domain::from_ptr(ptr) })
2108 }
2109
2110 pub fn migrate3(
2111 &self,
2112 dconn: &Connect,
2113 parameters: MigrateParameters,
2114 flags: u32,
2115 ) -> Result<Domain, Error> {
2116 let params = parameters.to_vec();
2117 let ptr = unsafe {
2118 sys::virDomainMigrate3(
2119 self.as_ptr(),
2120 dconn.as_ptr(),
2121 params.clone().as_mut_ptr(),
2122 params.len() as libc::c_uint,
2123 flags as libc::c_uint,
2124 )
2125 };
2126 if ptr.is_null() {
2127 return Err(Error::last_error());
2128 }
2129 Ok(unsafe { Domain::from_ptr(ptr) })
2130 }
2131
2132 pub fn migrate_to_uri(
2133 &self,
2134 duri: &str,
2135 flags: u32,
2136 dname: Option<&str>,
2137 bandwidth: u64,
2138 ) -> Result<(), Error> {
2139 let duri_buf = CString::new(duri).unwrap();
2140 let dname_buf = some_string_to_cstring!(dname);
2141 let ret = unsafe {
2142 sys::virDomainMigrateToURI(
2143 self.as_ptr(),
2144 duri_buf.as_ptr(),
2145 flags as libc::c_ulong,
2146 some_cstring_to_c_chars!(dname_buf),
2147 bandwidth as libc::c_ulong,
2148 )
2149 };
2150 if ret == -1 {
2151 return Err(Error::last_error());
2152 }
2153 Ok(())
2154 }
2155
2156 pub fn migrate_to_uri2(
2157 &self,
2158 dconn_uri: Option<&str>,
2159 mig_uri: Option<&str>,
2160 dxml: Option<&str>,
2161 flags: u32,
2162 dname: Option<&str>,
2163 bandwidth: u64,
2164 ) -> Result<(), Error> {
2165 let dconn_uri_buf = some_string_to_cstring!(dconn_uri);
2166 let mig_uri_buf = some_string_to_cstring!(mig_uri);
2167 let dxml_buf = some_string_to_cstring!(dxml);
2168 let dname_buf = some_string_to_cstring!(dname);
2169 let ret = unsafe {
2170 sys::virDomainMigrateToURI2(
2171 self.as_ptr(),
2172 some_cstring_to_c_chars!(dconn_uri_buf),
2173 some_cstring_to_c_chars!(mig_uri_buf),
2174 some_cstring_to_c_chars!(dxml_buf),
2175 flags as libc::c_ulong,
2176 some_cstring_to_c_chars!(dname_buf),
2177 bandwidth as libc::c_ulong,
2178 )
2179 };
2180 if ret == -1 {
2181 return Err(Error::last_error());
2182 }
2183 Ok(())
2184 }
2185
2186 pub fn migrate_to_uri3(
2187 &self,
2188 dconn_uri: Option<&str>,
2189 parameters: MigrateParameters,
2190 flags: u32,
2191 ) -> Result<(), Error> {
2192 let params = parameters.to_vec();
2193 let dconn_uri_buf = some_string_to_cstring!(dconn_uri);
2194 let ret = unsafe {
2195 sys::virDomainMigrateToURI3(
2196 self.as_ptr(),
2197 some_cstring_to_c_chars!(dconn_uri_buf),
2198 params.clone().as_mut_ptr(),
2199 params.len() as libc::c_uint,
2200 flags as libc::c_uint,
2201 )
2202 };
2203 if ret == -1 {
2204 return Err(Error::last_error());
2205 }
2206 Ok(())
2207 }
2208
2209 pub fn get_numa_parameters(&self, flags: u32) -> Result<NUMAParameters, Error> {
2210 let mut nparams: libc::c_int = 0;
2211 let ret = unsafe {
2212 sys::virDomainGetNumaParameters(
2213 self.as_ptr(),
2214 ptr::null_mut(),
2215 &mut nparams,
2216 flags as libc::c_uint,
2217 )
2218 };
2219 if ret == -1 {
2220 return Err(Error::last_error());
2221 }
2222 let mut params: Vec<sys::virTypedParameter> = Vec::with_capacity(nparams as usize);
2223 let ret = unsafe {
2224 sys::virDomainGetNumaParameters(
2225 self.as_ptr(),
2226 params.as_mut_ptr(),
2227 &mut nparams,
2228 flags as libc::c_uint,
2229 )
2230 };
2231 if ret == -1 {
2232 return Err(Error::last_error());
2233 }
2234 unsafe { params.set_len(nparams as usize) };
2235 let nparams = NUMAParameters::from_vec(params.clone());
2236 unsafe { typed_params_release_c_chars!(params) };
2237
2238 Ok(nparams)
2239 }
2240
2241 pub fn set_numa_parameters(&self, params: NUMAParameters, flags: u32) -> Result<u32, Error> {
2242 let mut cparams = params.to_vec();
2243 let ret = unsafe {
2244 sys::virDomainSetNumaParameters(
2245 self.as_ptr(),
2246 cparams.as_mut_ptr(),
2247 cparams.len() as libc::c_int,
2248 flags as libc::c_uint,
2249 )
2250 };
2251 unsafe { typed_params_release_c_chars!(cparams) };
2252 if ret == -1 {
2253 return Err(Error::last_error());
2254 }
2255 Ok(ret as u32)
2256 }
2257
2258 pub fn list_all_snapshots(&self, flags: u32) -> Result<Vec<DomainSnapshot>, Error> {
2259 let mut snaps: *mut sys::virDomainSnapshotPtr = ptr::null_mut();
2260 let size = unsafe {
2261 sys::virDomainListAllSnapshots(self.as_ptr(), &mut snaps, flags as libc::c_uint)
2262 };
2263 if size == -1 {
2264 return Err(Error::last_error());
2265 }
2266
2267 let mut array: Vec<DomainSnapshot> = Vec::new();
2268 for x in 0..size as isize {
2269 array.push(unsafe { DomainSnapshot::from_ptr(*snaps.offset(x)) });
2270 }
2271 unsafe { libc::free(snaps as *mut libc::c_void) };
2272
2273 Ok(array)
2274 }
2275
2276 pub fn get_scheduler_type(&self) -> Result<(String, i32), Error> {
2278 let mut nparams: libc::c_int = -1;
2279 let sched_type = unsafe { sys::virDomainGetSchedulerType(self.as_ptr(), &mut nparams) };
2280 if sched_type.is_null() {
2281 return Err(Error::last_error());
2282 }
2283
2284 Ok((unsafe { c_chars_to_string!(sched_type) }, nparams))
2285 }
2286
2287 pub fn get_scheduler_parameters(&self) -> Result<SchedulerInfo, Error> {
2289 let (sched_type, mut nparams) = self.get_scheduler_type()?;
2290 let mut params: Vec<sys::virTypedParameter> = Vec::with_capacity(nparams as usize);
2291 let ret = unsafe {
2292 sys::virDomainGetSchedulerParameters(self.as_ptr(), params.as_mut_ptr(), &mut nparams)
2293 };
2294 if ret == -1 {
2295 return Err(Error::last_error());
2296 }
2297 unsafe { params.set_len(nparams as usize) };
2298 Ok(SchedulerInfo::from_vec(params, sched_type))
2299 }
2300
2301 pub fn get_scheduler_parameters_flags(
2313 &self,
2314 flags: sys::virDomainModificationImpact,
2315 ) -> Result<SchedulerInfo, Error> {
2316 let (sched_type, mut nparams) = self.get_scheduler_type()?;
2317 let mut params: Vec<sys::virTypedParameter> = Vec::with_capacity(nparams as usize);
2318 let ret = unsafe {
2319 sys::virDomainGetSchedulerParametersFlags(
2320 self.as_ptr(),
2321 params.as_mut_ptr(),
2322 &mut nparams,
2323 flags as libc::c_uint,
2324 )
2325 };
2326 if ret == -1 {
2327 return Err(Error::last_error());
2328 }
2329 unsafe { params.set_len(nparams as usize) };
2330 Ok(SchedulerInfo::from_vec(params, sched_type))
2331 }
2332
2333 pub fn set_scheduler_parameters(&self, sched_info: &SchedulerInfo) -> Result<i32, Error> {
2335 let mut params = sched_info.to_vec();
2336 let ret = unsafe {
2337 sys::virDomainSetSchedulerParameters(
2338 self.as_ptr(),
2339 params.as_mut_ptr(),
2340 params.len() as libc::c_int,
2341 )
2342 };
2343 if ret == -1 {
2344 return Err(Error::last_error());
2345 }
2346 Ok(ret)
2347 }
2348
2349 pub fn set_scheduler_parameters_flags(
2361 &self,
2362 sched_info: &SchedulerInfo,
2363 flags: sys::virDomainModificationImpact,
2364 ) -> Result<i32, Error> {
2365 let mut params = sched_info.to_vec();
2366 let ret = unsafe {
2367 sys::virDomainSetSchedulerParametersFlags(
2368 self.as_ptr(),
2369 params.as_mut_ptr(),
2370 params.len() as libc::c_int,
2371 flags as libc::c_uint,
2372 )
2373 };
2374 if ret == -1 {
2375 return Err(Error::last_error());
2376 }
2377 Ok(ret)
2378 }
2379
2380 pub fn send_key(
2389 &self,
2390 codeset: sys::virKeycodeSet,
2391 holdtime: u32,
2392 keycodes: *mut u32,
2393 nkeycodes: i32,
2394 flags: u32,
2395 ) -> Result<(), Error> {
2396 let ret = unsafe {
2397 sys::virDomainSendKey(
2398 self.as_ptr(),
2399 codeset as libc::c_uint,
2400 holdtime as libc::c_uint,
2401 keycodes as *mut libc::c_uint,
2402 nkeycodes as libc::c_int,
2403 flags as libc::c_uint,
2404 )
2405 };
2406 if ret == -1 {
2407 return Err(Error::last_error());
2408 }
2409 Ok(())
2410 }
2411
2412 pub fn screenshot(&self, stream: &Stream, screen: u32, flags: u32) -> Result<String, Error> {
2421 let n = unsafe {
2422 sys::virDomainScreenshot(
2423 self.as_ptr(),
2424 stream.as_ptr(),
2425 screen as libc::c_uint,
2426 flags as libc::c_uint,
2427 )
2428 };
2429 if n.is_null() {
2430 return Err(Error::last_error());
2431 }
2432 Ok(unsafe { c_chars_to_string!(n) })
2433 }
2434
2435 #[cfg(feature = "qemu")]
2442 pub fn qemu_monitor_command(&self, cmd: &str, flags: u32) -> Result<String, Error> {
2443 let mut result: *mut libc::c_char = std::ptr::null_mut();
2444 let cmd_buf = CString::new(cmd).unwrap();
2445 let ret = unsafe {
2446 sys::virDomainQemuMonitorCommand(
2447 self.as_ptr(),
2448 cmd_buf.as_ptr(),
2449 &mut result,
2450 flags as libc::c_uint,
2451 )
2452 };
2453 if ret == -1 {
2454 return Err(Error::last_error());
2455 }
2456 Ok(unsafe { c_chars_to_string!(result) })
2457 }
2458
2459 #[cfg(feature = "qemu")]
2467 pub fn qemu_agent_command(&self, cmd: &str, timeout: i32, flags: u32) -> Result<String, Error> {
2468 let cmd_buf = CString::new(cmd).unwrap();
2469 let ret = unsafe {
2470 sys::virDomainQemuAgentCommand(
2471 self.as_ptr(),
2472 cmd_buf.as_ptr(),
2473 timeout as libc::c_int,
2474 flags as libc::c_uint,
2475 )
2476 };
2477
2478 if ret.is_null() {
2479 return Err(Error::last_error());
2480 }
2481 Ok(unsafe { c_chars_to_string!(ret) })
2482 }
2483}