libvirt_ffi 0.4.0 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +78 -0
- data/Gemfile +7 -3
- data/Rakefile +6 -1
- data/bin/console +1 -0
- data/exe/libvirt +1 -0
- data/lib/libvirt.rb +12 -12
- data/lib/libvirt/base_info.rb +34 -0
- data/lib/libvirt/connection.rb +111 -38
- data/lib/libvirt/domain.rb +113 -8
- data/lib/libvirt/domain_callback_storage.rb +20 -16
- data/lib/libvirt/errors.rb +65 -0
- data/lib/libvirt/event.rb +36 -28
- data/lib/libvirt/ffi.rb +17 -0
- data/lib/libvirt/ffi/common.rb +8 -1
- data/lib/libvirt/ffi/domain.rb +530 -196
- data/lib/libvirt/ffi/error.rb +243 -0
- data/lib/libvirt/ffi/event.rb +30 -36
- data/lib/libvirt/ffi/helpers.rb +17 -0
- data/lib/libvirt/ffi/host.rb +127 -0
- data/lib/libvirt/ffi/storage.rb +149 -0
- data/lib/libvirt/ffi/stream.rb +19 -17
- data/lib/libvirt/node_info.rb +2 -41
- data/lib/libvirt/storage_pool.rb +70 -0
- data/lib/libvirt/storage_pool_info.rb +7 -0
- data/lib/libvirt/storage_volume.rb +51 -0
- data/lib/libvirt/storage_volume_info.rb +7 -0
- data/lib/libvirt/stream.rb +33 -14
- data/lib/libvirt/util.rb +61 -8
- data/lib/libvirt/version.rb +1 -1
- data/lib/libvirt/xml.rb +23 -0
- data/lib/libvirt/xml/disk.rb +59 -0
- data/lib/libvirt/xml/domain.rb +76 -0
- data/lib/libvirt/xml/generic.rb +252 -0
- data/lib/libvirt/xml/graphics.rb +14 -0
- data/lib/libvirt/xml/max_vcpu.rb +12 -0
- data/lib/libvirt/xml/memory.rb +14 -0
- data/lib/libvirt/xml/storage_pool.rb +24 -0
- data/lib/libvirt/xml/storage_volume.rb +32 -0
- data/lib/libvirt/xml/vcpu.rb +12 -0
- data/lib/libvirt_ffi.rb +2 -0
- data/libvirt.gemspec +5 -1
- data/test_usage/support/libvirt_async.rb +27 -35
- data/test_usage/support/log_formatter.rb +5 -10
- data/test_usage/test_domain.rb +43 -0
- data/test_usage/test_event_loop.rb +115 -39
- data/test_usage/test_libvirtd_restart.rb +63 -0
- data/test_usage/test_metadata.rb +104 -0
- data/test_usage/test_screenshot.rb +14 -13
- data/test_usage/test_storage.rb +52 -0
- metadata +42 -6
- data/lib/libvirt/error.rb +0 -6
- data/lib/libvirt/ffi/connection.rb +0 -94
- data/lib/libvirt/ffi/libvirt.rb +0 -17
- data/lib/libvirt/ffi/node_info.rb +0 -37
data/lib/libvirt/domain.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
module Libvirt
|
4
4
|
class Domain
|
5
|
-
|
6
5
|
def self.load_ref(dom_ptr)
|
7
6
|
ref_result = FFI::Domain.virDomainRef(dom_ptr)
|
8
|
-
raise
|
7
|
+
raise Errors::LibError, "Couldn't retrieve domain reference" if ref_result.negative?
|
8
|
+
|
9
9
|
new(dom_ptr)
|
10
10
|
end
|
11
11
|
|
@@ -13,9 +13,11 @@ module Libvirt
|
|
13
13
|
@dom_ptr = dom_ptr
|
14
14
|
|
15
15
|
free = ->(obj_id) do
|
16
|
+
Util.log(:debug) { "Finalize Libvirt::Domain 0x#{obj_id.to_s(16)} @dom_ptr=#{@dom_ptr}," }
|
16
17
|
return unless @dom_ptr
|
18
|
+
|
17
19
|
fr_result = FFI::Domain.virDomainFree(@dom_ptr)
|
18
|
-
|
20
|
+
warn "Couldn't free Libvirt::Domain (0x#{obj_id.to_s(16)}) pointer #{@dom_ptr.address}" if fr_result.negative?
|
19
21
|
end
|
20
22
|
ObjectSpace.define_finalizer(self, free)
|
21
23
|
end
|
@@ -24,8 +26,11 @@ module Libvirt
|
|
24
26
|
state = ::FFI::MemoryPointer.new(:int)
|
25
27
|
reason = ::FFI::MemoryPointer.new(:int)
|
26
28
|
result = FFI::Domain.virDomainGetState(@dom_ptr, state, reason, 0)
|
27
|
-
raise
|
28
|
-
|
29
|
+
raise Errors::LibError, "Couldn't get domain state" if result.negative?
|
30
|
+
|
31
|
+
state_sym = FFI::Domain.enum_type(:state)[state.read_int]
|
32
|
+
reason_sym = FFI::Domain.state_reason(state_sym, reason.read_int)
|
33
|
+
[state_sym, reason_sym]
|
29
34
|
end
|
30
35
|
|
31
36
|
def to_ptr
|
@@ -35,7 +40,8 @@ module Libvirt
|
|
35
40
|
def uuid
|
36
41
|
buff = ::FFI::MemoryPointer.new(:char, FFI::Domain::UUID_STRING_BUFLEN)
|
37
42
|
result = FFI::Domain.virDomainGetUUIDString(@dom_ptr, buff)
|
38
|
-
raise
|
43
|
+
raise Errors::LibError, "Couldn't get domain uuid" if result.negative?
|
44
|
+
|
39
45
|
buff.read_string
|
40
46
|
end
|
41
47
|
|
@@ -68,16 +74,115 @@ module Libvirt
|
|
68
74
|
end
|
69
75
|
|
70
76
|
def screenshot(stream, display = 0)
|
77
|
+
dbg { "#screenshot stream=#{stream}, display=#{display}," }
|
78
|
+
|
71
79
|
mime_type, pointer = FFI::Domain.virDomainScreenshot(@dom_ptr, stream.to_ptr, display, 0)
|
72
|
-
raise
|
80
|
+
raise Errors::LibError, "Couldn't attach domain screenshot" if pointer.null?
|
81
|
+
|
73
82
|
# free pointer required
|
74
83
|
mime_type
|
75
84
|
end
|
76
85
|
|
77
86
|
def free_domain
|
78
87
|
result = FFI::Domain.virDomainFree(@dom_ptr)
|
79
|
-
raise
|
88
|
+
raise Errors::LibError, "Couldn't free domain" if result.negative?
|
89
|
+
|
80
90
|
@dom_ptr = nil
|
81
91
|
end
|
92
|
+
|
93
|
+
def start(flags = 0)
|
94
|
+
result = FFI::Domain.virDomainCreateWithFlags(@dom_ptr, flags)
|
95
|
+
raise Errors::LibError, "Couldn't start domain" if result.negative?
|
96
|
+
end
|
97
|
+
|
98
|
+
def reboot(flags = 0)
|
99
|
+
result = FFI::Domain.virDomainReboot(@dom_ptr, flags)
|
100
|
+
raise Errors::LibError, "Couldn't reboot domain" if result.negative?
|
101
|
+
end
|
102
|
+
|
103
|
+
def shutdown(flags = :ACPI_POWER_BTN)
|
104
|
+
result = FFI::Domain.virDomainShutdownFlags(@dom_ptr, flags)
|
105
|
+
raise Errors::LibError, "Couldn't shutdown domain" if result.negative?
|
106
|
+
end
|
107
|
+
|
108
|
+
def power_off(flags = 0)
|
109
|
+
result = FFI::Domain.virDomainDestroyFlags(@dom_ptr, flags)
|
110
|
+
raise Errors::LibError, "Couldn't power off domain" if result.negative?
|
111
|
+
end
|
112
|
+
|
113
|
+
def reset(flags = 0)
|
114
|
+
result = FFI::Domain.virDomainReset(@dom_ptr, flags)
|
115
|
+
raise Errors::LibError, "Couldn't reset domain" if result.negative?
|
116
|
+
end
|
117
|
+
|
118
|
+
def suspend
|
119
|
+
result = FFI::Domain.virDomainSuspend(@dom_ptr)
|
120
|
+
raise Errors::LibError, "Couldn't suspend domain" if result.negative?
|
121
|
+
end
|
122
|
+
|
123
|
+
def resume
|
124
|
+
result = FFI::Domain.virDomainResume(@dom_ptr)
|
125
|
+
raise Errors::LibError, "Couldn't resume domain" if result.negative?
|
126
|
+
end
|
127
|
+
|
128
|
+
# Undefine a domain.
|
129
|
+
# If the domain is running, it's converted to transient domain, without stopping it.
|
130
|
+
# If the domain is inactive, the domain configuration is removed.
|
131
|
+
# @param options_or_flags [Array<Symbol>,Hash{Symbol=>Boolean},Integer,Symbol,nil]
|
132
|
+
# @see Libvirt::FFI::Domain enum :undefine_flags_values for acceptable keys
|
133
|
+
# @see Libvirt::Util.parse_flags for possible argument values
|
134
|
+
# @raise [Libvirt::Errors::LibError] if operation failed
|
135
|
+
def undefine(options_or_flags = nil)
|
136
|
+
flags = Util.parse_flags options_or_flags, FFI::Domain.enum_type(:undefine_flags_values)
|
137
|
+
result = FFI::Domain.virDomainUndefineFlags(@dom_ptr, flags)
|
138
|
+
raise Errors::LibError, "Couldn't resume domain" if result.negative?
|
139
|
+
end
|
140
|
+
|
141
|
+
# After save_memory(:PAUSED) you need to call #start and #resume
|
142
|
+
# to move domain to the running state.
|
143
|
+
def save_memory(flags = :PAUSED)
|
144
|
+
result = FFI::Domain.virDomainManagedSave(@dom_ptr, flags)
|
145
|
+
raise Errors::LibError, "Couldn't save domain memory" if result.negative?
|
146
|
+
end
|
147
|
+
|
148
|
+
# Sets metadata
|
149
|
+
# @param metadata [String] xml node for element type, text for other types
|
150
|
+
# DESCRIPTION 0x0 - Operate on <description>
|
151
|
+
# TITLE 0x1 - Operate on <title>
|
152
|
+
# ELEMENT 0x2 - Operate on <metadata>
|
153
|
+
# @param type [Integer,Symbol] one of :ELEMENT, :TITLE, :DESCRIPTION
|
154
|
+
# @param key [String] xml key (required for type element)
|
155
|
+
# @param uri [String] xml namespace (required for type element)
|
156
|
+
# @param flags [Integer,Symbol] one off AFFECT_CURRENT, AFFECT_CONFIG, AFFECT_LIVE
|
157
|
+
# AFFECT_CURRENT 0x0 - Affect current domain state.
|
158
|
+
# AFFECT_LIVE 0x1 - Affect running domain state.
|
159
|
+
# AFFECT_CONFIG 0x2 - Affect persistent domain state.
|
160
|
+
# @raise [Libvirt::Errors::LibError] if operation failed
|
161
|
+
def set_metadata(metadata, type: :ELEMENT, key: nil, uri: nil, flags: :AFFECT_CURRENT)
|
162
|
+
result = FFI::Domain.virDomainSetMetadata(@dom_ptr, type, metadata, key, uri, flags)
|
163
|
+
raise Errors::LibError, "Couldn't set domain metadata" if result.negative?
|
164
|
+
end
|
165
|
+
|
166
|
+
# Retrieves metadata
|
167
|
+
# @param type [Integer,Symbol] one of :ELEMENT, :TITLE, :DESCRIPTION
|
168
|
+
# @param uri [String] xml namespace (required for type element)
|
169
|
+
# @param flags [Integer,Symbol] one off AFFECT_CURRENT, AFFECT_CONFIG, AFFECT_LIVE
|
170
|
+
# AFFECT_CURRENT 0x0 - Affect current domain state.
|
171
|
+
# AFFECT_LIVE 0x1 - Affect running domain state.
|
172
|
+
# AFFECT_CONFIG 0x2 - Affect persistent domain state.
|
173
|
+
# @raise [Libvirt::Errors::LibError] if operation failed
|
174
|
+
# @return [String] xml node, title, or description.
|
175
|
+
def get_metadata(type: :ELEMENT, uri: nil, flags: :AFFECT_CURRENT)
|
176
|
+
result = FFI::Domain.virDomainGetMetadata(@dom_ptr, type, uri, flags)
|
177
|
+
raise Errors::LibError, "Couldn't get domain metadata" if result.nil?
|
178
|
+
|
179
|
+
result
|
180
|
+
end
|
181
|
+
|
182
|
+
private
|
183
|
+
|
184
|
+
def dbg(&block)
|
185
|
+
Util.log(:debug, 'Libvirt::Domain', &block)
|
186
|
+
end
|
82
187
|
end
|
83
188
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Libvirt
|
2
4
|
class DomainCallbackStorage
|
3
|
-
|
4
5
|
class CallbackDataStruct < ::FFI::Struct
|
5
6
|
layout :connection_pointer, :pointer,
|
6
7
|
:callback_id, :int
|
@@ -14,46 +15,43 @@ module Libvirt
|
|
14
15
|
# cb_data [Libvirt::DomainCallbackStorage::CallbackDataStruct],
|
15
16
|
# cb_data_free_func [FFI::Function]
|
16
17
|
def allocate_struct
|
17
|
-
|
18
|
+
dbg { '#allocate_struct' }
|
18
19
|
|
19
20
|
cb_data_ptr = ::FFI::MemoryPointer.new(:char, CallbackDataStruct.size, false)
|
20
21
|
cb_data = CallbackDataStruct.new(cb_data_ptr)
|
21
|
-
cb_data_free_func =
|
22
|
-
|
23
|
-
remove_struct(pointer
|
22
|
+
cb_data_free_func = FFI::Common.free_function do |pointer|
|
23
|
+
dbg { 'Libvirt::DomainCallbackStorage cb_data_free_func triggered' }
|
24
|
+
remove_struct(pointer)
|
24
25
|
end
|
25
26
|
[cb_data, cb_data_free_func]
|
26
27
|
end
|
27
28
|
|
28
29
|
def store_struct(cb_data, connection_pointer:, callback_id:, cb:, opaque:)
|
29
|
-
|
30
|
+
dbg { '#store_struct' }
|
30
31
|
|
31
32
|
cb_data[:connection_pointer] = connection_pointer
|
32
33
|
cb_data[:callback_id] = callback_id
|
33
34
|
@inner_storage[connection_pointer.address][callback_id] = { cb: cb, opaque: opaque, pointer: cb_data.pointer }
|
34
35
|
end
|
35
36
|
|
36
|
-
def remove_struct(pointer
|
37
|
-
|
37
|
+
def remove_struct(pointer)
|
38
|
+
dbg { "#remove_struct pointer=#{pointer}" }
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
40
|
+
cb_data_struct = CallbackDataStruct.new(pointer)
|
41
|
+
connection_pointer = cb_data_struct[:connection_pointer]
|
42
|
+
callback_id = cb_data_struct[:callback_id]
|
43
|
+
dbg { "#remove_struct pointer=#{pointer}, connection_pointer=#{connection_pointer}, callback_id=#{callback_id}," }
|
44
44
|
|
45
45
|
cb_data = @inner_storage[connection_pointer.address].delete(callback_id)
|
46
|
-
pointer ||= cb_data[:pointer]
|
47
46
|
@inner_storage.delete(connection_pointer.address) if @inner_storage[connection_pointer.address].empty?
|
48
47
|
|
49
|
-
#pointer.free
|
50
48
|
cb_data[:opaque]
|
51
49
|
end
|
52
50
|
|
53
51
|
# @param [::FFI::Pointer]
|
54
52
|
# @return [Array<2>] cb [Proc], opaque [Object]
|
55
53
|
def retrieve_from_pointer(pointer)
|
56
|
-
|
54
|
+
dbg { "#retrieve_from_pointer pointer=#{pointer}," }
|
57
55
|
|
58
56
|
cb_data_struct = CallbackDataStruct.new(pointer)
|
59
57
|
connection_pointer = cb_data_struct[:connection_pointer]
|
@@ -61,5 +59,11 @@ module Libvirt
|
|
61
59
|
cb_data = @inner_storage[connection_pointer.address][callback_id]
|
62
60
|
[cb_data[:cb], cb_data[:opaque]]
|
63
61
|
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def dbg(&block)
|
66
|
+
Util.log(:debug, 'Libvirt::DomainCallbackStorage', &block)
|
67
|
+
end
|
64
68
|
end
|
65
69
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Libvirt
|
4
|
+
module Errors
|
5
|
+
class Error < StandardError
|
6
|
+
# Generic error
|
7
|
+
end
|
8
|
+
|
9
|
+
class LibError < Error
|
10
|
+
# Object contains detailed error information retrieved from libvirt.
|
11
|
+
|
12
|
+
ERROR_FIELDS = [:code, :domain, :message, :level].freeze
|
13
|
+
|
14
|
+
attr_reader :client_message,
|
15
|
+
:error_data,
|
16
|
+
:error_code,
|
17
|
+
:error_domain,
|
18
|
+
:error_message,
|
19
|
+
:error_level
|
20
|
+
|
21
|
+
# @param client_message [String, nil] optional client message
|
22
|
+
# When client_message ommited and virGetLastError return error
|
23
|
+
# message will be following: "ERROR_LEVEL: ERROR_NUMBER (ERROR_DOMAIN) ERROR_MESSAGE".
|
24
|
+
# When client message provided and virGetLastError return error
|
25
|
+
# message will be following: "CLIENT_MESSAGE\nERROR_LEVEL: ERROR_NUMBER (ERROR_DOMAIN) ERROR_MESSAGE".
|
26
|
+
# When client message is provided and virGetLastError return no error
|
27
|
+
# message will be following: "CLIENT_MESSAGE".
|
28
|
+
def initialize(client_message = nil)
|
29
|
+
@client_message = client_message
|
30
|
+
ptr = FFI::Error.virGetLastError
|
31
|
+
unless ptr.null?
|
32
|
+
struct = FFI::Error::Struct.new(ptr)
|
33
|
+
@error_data = struct.members.map { |m| [m, struct[m]] }.to_h
|
34
|
+
@error_code = error_data[:code]
|
35
|
+
@error_domain = error_data[:domain]
|
36
|
+
@error_message = error_data[:message]
|
37
|
+
@error_level = error_data[:level]
|
38
|
+
end
|
39
|
+
|
40
|
+
super(build_message)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def build_message
|
46
|
+
if error_data.nil?
|
47
|
+
client_message
|
48
|
+
elsif client_message.nil?
|
49
|
+
format '%<level>s: %<code>s (%<domain>s) %<message>s',
|
50
|
+
level: error_level,
|
51
|
+
code: error_code,
|
52
|
+
domain: error_domain,
|
53
|
+
message: error_message
|
54
|
+
else
|
55
|
+
format "%<client_message>s\n%<level>s: %<code>s (%<domain>s) %<message>s",
|
56
|
+
client_message: client_message,
|
57
|
+
level: error_level,
|
58
|
+
code: error_code,
|
59
|
+
domain: error_domain,
|
60
|
+
message: error_message
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/libvirt/event.rb
CHANGED
@@ -21,19 +21,19 @@ module Libvirt
|
|
21
21
|
|
22
22
|
attr_accessor :debug
|
23
23
|
|
24
|
-
Opaque = Struct.new(:cb, :opaque, :
|
24
|
+
Opaque = Struct.new(:cb, :opaque, :free_func)
|
25
25
|
|
26
26
|
def invoke_handle_callback(watch, fd, events, opaque)
|
27
27
|
cb = opaque.cb
|
28
28
|
op = opaque.opaque
|
29
|
-
dbg { "
|
29
|
+
dbg { "INVOKE_HANDLE_CALLBACK watch=#{watch} fd=#{fd} events=#{events} op=#{op}" }
|
30
30
|
cb.call(watch, fd, events, op)
|
31
31
|
end
|
32
32
|
|
33
33
|
def invoke_timeout_callback(timer, opaque)
|
34
34
|
cb = opaque.cb
|
35
35
|
op = opaque.opaque
|
36
|
-
dbg { "
|
36
|
+
dbg { "INVOKE_TIMEOUT_CALLBACK timer=#{timer} op=#{op}" }
|
37
37
|
cb.call(timer, op)
|
38
38
|
end
|
39
39
|
|
@@ -59,20 +59,25 @@ module Libvirt
|
|
59
59
|
true
|
60
60
|
end
|
61
61
|
|
62
|
-
def
|
62
|
+
def schedule_operation(&block)
|
63
|
+
@schedule.call(&block)
|
64
|
+
end
|
65
|
+
|
66
|
+
def register(add_handle:, update_handle:, remove_handle:, add_timer:, update_timer:, remove_timer:, schedule:) # rubocop:disable Metrics/ParameterLists
|
63
67
|
@add_handle = add_handle
|
64
68
|
@update_handle = update_handle
|
65
69
|
@remove_handle = remove_handle
|
66
70
|
@add_timer = add_timer
|
67
71
|
@update_timer = update_timer
|
68
72
|
@remove_timer = remove_timer
|
73
|
+
@schedule = schedule
|
69
74
|
|
70
|
-
@add_handle_cb = FFI::Event.
|
71
|
-
@update_handle_cb =
|
72
|
-
@remove_handle_cb =
|
73
|
-
@add_timer_cb = FFI::Event.
|
74
|
-
@update_timer_cb =
|
75
|
-
@remove_timer_cb =
|
75
|
+
@add_handle_cb = FFI::Event.callback_function(:virEventAddHandleFunc, &method(:_add_handle))
|
76
|
+
@update_handle_cb = FFI::Event.callback_function(:virEventUpdateHandleFunc, &method(:_update_handle))
|
77
|
+
@remove_handle_cb = FFI::Event.callback_function(:virEventRemoveHandleFunc, &method(:_remove_handle))
|
78
|
+
@add_timer_cb = FFI::Event.callback_function(:virEventAddTimeoutFunc, &method(:_add_timer))
|
79
|
+
@update_timer_cb = FFI::Event.callback_function(:virEventUpdateTimeoutFunc, &method(:_update_timer))
|
80
|
+
@remove_timer_cb = FFI::Event.callback_function(:virEventRemoveTimeoutFunc, &method(:_remove_timer))
|
76
81
|
|
77
82
|
FFI::Event.virEventRegisterImpl(
|
78
83
|
@add_handle_cb,
|
@@ -87,51 +92,54 @@ module Libvirt
|
|
87
92
|
|
88
93
|
private
|
89
94
|
|
90
|
-
def _add_handle(fd, event, cb, opaque,
|
91
|
-
dbg { "
|
92
|
-
op = Opaque.new(cb, opaque,
|
95
|
+
def _add_handle(fd, event, cb, opaque, free_func)
|
96
|
+
dbg { "ADD_HANDLE fd=#{fd}, #{event}=event, cb=#{cb}, opaque=#{opaque}, free_func=#{free_func}" }
|
97
|
+
op = Opaque.new(cb, opaque, free_func)
|
93
98
|
@add_handle.call(fd, event, op)
|
94
99
|
end
|
95
100
|
|
96
101
|
def _update_handle(watch, event)
|
97
|
-
dbg { "
|
102
|
+
dbg { "UPDATE_HANDLE watch=#{watch}, event=#{event}" }
|
98
103
|
@update_handle.call(watch, event)
|
99
104
|
end
|
100
105
|
|
101
106
|
def _remove_handle(watch)
|
102
|
-
dbg { "
|
107
|
+
dbg { "REMOVE_HANDLE watch=#{watch}" }
|
103
108
|
op = @remove_handle.call(watch)
|
104
|
-
free_func = op.
|
109
|
+
free_func = op.free_func
|
105
110
|
opaque = op.opaque
|
106
|
-
|
111
|
+
schedule_operation do
|
112
|
+
dbg { "REMOVE_HANDLE delayed free_func watch=#{watch}" }
|
113
|
+
free_func.call(opaque) unless free_func.null?
|
114
|
+
end
|
107
115
|
0
|
108
116
|
end
|
109
117
|
|
110
|
-
def _add_timer(timeout, cb, opaque,
|
111
|
-
dbg { "
|
112
|
-
op = Opaque.new(cb, opaque,
|
118
|
+
def _add_timer(timeout, cb, opaque, free_func)
|
119
|
+
dbg { "ADD_TIMER timeout=#{timeout}, cb=#{cb}, opaque=#{opaque}, free_func=#{free_func}" }
|
120
|
+
op = Opaque.new(cb, opaque, free_func)
|
113
121
|
@add_timer.call(timeout, op)
|
114
122
|
end
|
115
123
|
|
116
124
|
def _update_timer(timer, timeout)
|
117
|
-
dbg { "
|
125
|
+
dbg { "UPDATE_TIMER timer=#{timer}, timeout=#{timeout}" }
|
118
126
|
@update_timer.call(timer, timeout)
|
119
127
|
end
|
120
128
|
|
121
129
|
def _remove_timer(timer)
|
122
|
-
dbg { "
|
130
|
+
dbg { "REMOVE_TIMER timer=#{timer}" }
|
123
131
|
op = @remove_timer.call(timer)
|
124
|
-
free_func = op.
|
132
|
+
free_func = op.free_func
|
125
133
|
opaque = op.opaque
|
126
|
-
|
134
|
+
schedule_operation do
|
135
|
+
dbg { "REMOVE_TIMER async free_func timer=#{timer}" }
|
136
|
+
free_func.call(opaque) unless free_func.null?
|
137
|
+
end
|
127
138
|
0
|
128
139
|
end
|
129
140
|
|
130
141
|
def dbg(&block)
|
131
|
-
|
132
|
-
|
133
|
-
Util.log(:debug, &block)
|
142
|
+
Util.log(:debug, 'Libvirt::Event', &block)
|
134
143
|
end
|
135
|
-
|
136
144
|
end
|
137
145
|
end
|
data/lib/libvirt/ffi.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Libvirt
|
4
|
+
module FFI
|
5
|
+
# https://libvirt.org/html/index.html
|
6
|
+
# namespace for libvirt C bindings
|
7
|
+
|
8
|
+
require 'libvirt/ffi/helpers'
|
9
|
+
require 'libvirt/ffi/common'
|
10
|
+
require 'libvirt/ffi/error'
|
11
|
+
require 'libvirt/ffi/host'
|
12
|
+
require 'libvirt/ffi/domain'
|
13
|
+
require 'libvirt/ffi/event'
|
14
|
+
require 'libvirt/ffi/stream'
|
15
|
+
require 'libvirt/ffi/storage'
|
16
|
+
end
|
17
|
+
end
|