libvirt_ffi 0.4.0 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|