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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +78 -0
  3. data/Gemfile +7 -3
  4. data/Rakefile +6 -1
  5. data/bin/console +1 -0
  6. data/exe/libvirt +1 -0
  7. data/lib/libvirt.rb +12 -12
  8. data/lib/libvirt/base_info.rb +34 -0
  9. data/lib/libvirt/connection.rb +111 -38
  10. data/lib/libvirt/domain.rb +113 -8
  11. data/lib/libvirt/domain_callback_storage.rb +20 -16
  12. data/lib/libvirt/errors.rb +65 -0
  13. data/lib/libvirt/event.rb +36 -28
  14. data/lib/libvirt/ffi.rb +17 -0
  15. data/lib/libvirt/ffi/common.rb +8 -1
  16. data/lib/libvirt/ffi/domain.rb +530 -196
  17. data/lib/libvirt/ffi/error.rb +243 -0
  18. data/lib/libvirt/ffi/event.rb +30 -36
  19. data/lib/libvirt/ffi/helpers.rb +17 -0
  20. data/lib/libvirt/ffi/host.rb +127 -0
  21. data/lib/libvirt/ffi/storage.rb +149 -0
  22. data/lib/libvirt/ffi/stream.rb +19 -17
  23. data/lib/libvirt/node_info.rb +2 -41
  24. data/lib/libvirt/storage_pool.rb +70 -0
  25. data/lib/libvirt/storage_pool_info.rb +7 -0
  26. data/lib/libvirt/storage_volume.rb +51 -0
  27. data/lib/libvirt/storage_volume_info.rb +7 -0
  28. data/lib/libvirt/stream.rb +33 -14
  29. data/lib/libvirt/util.rb +61 -8
  30. data/lib/libvirt/version.rb +1 -1
  31. data/lib/libvirt/xml.rb +23 -0
  32. data/lib/libvirt/xml/disk.rb +59 -0
  33. data/lib/libvirt/xml/domain.rb +76 -0
  34. data/lib/libvirt/xml/generic.rb +252 -0
  35. data/lib/libvirt/xml/graphics.rb +14 -0
  36. data/lib/libvirt/xml/max_vcpu.rb +12 -0
  37. data/lib/libvirt/xml/memory.rb +14 -0
  38. data/lib/libvirt/xml/storage_pool.rb +24 -0
  39. data/lib/libvirt/xml/storage_volume.rb +32 -0
  40. data/lib/libvirt/xml/vcpu.rb +12 -0
  41. data/lib/libvirt_ffi.rb +2 -0
  42. data/libvirt.gemspec +5 -1
  43. data/test_usage/support/libvirt_async.rb +27 -35
  44. data/test_usage/support/log_formatter.rb +5 -10
  45. data/test_usage/test_domain.rb +43 -0
  46. data/test_usage/test_event_loop.rb +115 -39
  47. data/test_usage/test_libvirtd_restart.rb +63 -0
  48. data/test_usage/test_metadata.rb +104 -0
  49. data/test_usage/test_screenshot.rb +14 -13
  50. data/test_usage/test_storage.rb +52 -0
  51. metadata +42 -6
  52. data/lib/libvirt/error.rb +0 -6
  53. data/lib/libvirt/ffi/connection.rb +0 -94
  54. data/lib/libvirt/ffi/libvirt.rb +0 -17
  55. data/lib/libvirt/ffi/node_info.rb +0 -37
@@ -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 Error, "Couldn't retrieve domain reference" if ref_result < 0
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
- STDERR.puts "Couldn't free Libvirt::Domain (0x#{obj_id.to_s(16)}) pointer #{@dom_ptr.address}" if fr_result < 0
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 Error, "Couldn't get domain state" if result < 0
28
- [state.read_int, reason.read_int]
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 Error, "Couldn't get domain uuid" if result < 0
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 Error, "Couldn't attach domain screenshot" if pointer.null?
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 Error, "Couldn't free domain" if result < 0
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
- Util.logger.debug { "Libvirt::DomainCallbackStorage#allocate_struct" }
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 = ::FFI::Function.new(:void, [:pointer]) do |pointer|
22
- Util.logger.debug { "Libvirt::DomainCallbackStorage cb_data_free_func triggered" }
23
- remove_struct(pointer: 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
- Util.logger.debug { "Libvirt::DomainCallbackStorage#store_struct" }
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: nil, connection_pointer: nil, callback_id: nil)
37
- Util.logger.debug { "Libvirt::DomainCallbackStorage#remove_struct pointer=#{pointer}, connection_pointer=#{connection_pointer}, callback_id=#{callback_id}," }
37
+ def remove_struct(pointer)
38
+ dbg { "#remove_struct pointer=#{pointer}" }
38
39
 
39
- if pointer
40
- cb_data_struct = CallbackDataStruct.new(pointer)
41
- connection_pointer = cb_data_struct[:connection_pointer]
42
- callback_id = cb_data_struct[:callback_id]
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
- Util.logger.debug { "Libvirt::DomainCallbackStorage#retrieve_from_pointer pointer=#{pointer}," }
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
@@ -21,19 +21,19 @@ module Libvirt
21
21
 
22
22
  attr_accessor :debug
23
23
 
24
- Opaque = Struct.new(:cb, :opaque, :ff)
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 { "Libvirt::Event INVOKE_HANDLE_CALLBACK watch=#{watch} fd=#{fd} events=#{events} op=#{op}" }
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 { "Libvirt::Event INVOKE_TIMEOUT_CALLBACK timer=#{timer} op=#{op}" }
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 register(add_handle:, update_handle:, remove_handle:, add_timer:, update_timer:, remove_timer:)
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.event_add_handle_func(&method(:_add_handle).to_proc)
71
- @update_handle_cb = ::FFI::Function.new(:void, [:int, :int], &method(:_update_handle).to_proc)
72
- @remove_handle_cb = ::FFI::Function.new(:int, [:int], &method(:_remove_handle).to_proc)
73
- @add_timer_cb = FFI::Event.event_add_timeout_func(&method(:_add_timer).to_proc)
74
- @update_timer_cb = ::FFI::Function.new(:void, [:int, :int], &method(:_update_timer).to_proc)
75
- @remove_timer_cb = ::FFI::Function.new(:int, [:int], &method(:_remove_timer).to_proc)
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, ff)
91
- dbg { "Libvirt::Event ADD_HANDLE fd=#{fd}, #{event}=event, cb=#{cb}, opaque=#{opaque}, ff=#{ff}" }
92
- op = Opaque.new(cb, opaque, ff)
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 { "Libvirt::Event UPDATE_HANDLE watch=#{watch}, event=#{event}" }
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 { "Libvirt::Event REMOVE_HANDLE watch=#{watch}" }
107
+ dbg { "REMOVE_HANDLE watch=#{watch}" }
103
108
  op = @remove_handle.call(watch)
104
- free_func = op.ff
109
+ free_func = op.free_func
105
110
  opaque = op.opaque
106
- free_func.call(opaque) unless free_func.null?
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, ff)
111
- dbg { "Libvirt::Event ADD_TIMER timeout=#{timeout}, cb=#{cb}, opaque=#{opaque}, ff=#{ff}" }
112
- op = Opaque.new(cb, opaque, ff)
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 { "Libvirt::Event UPDATE_TIMER timer=#{timer}, timeout=#{timeout}" }
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 { "Libvirt::Event REMOVE_TIMER timer=#{timer}" }
130
+ dbg { "REMOVE_TIMER timer=#{timer}" }
123
131
  op = @remove_timer.call(timer)
124
- free_func = op.ff
132
+ free_func = op.free_func
125
133
  opaque = op.opaque
126
- free_func.call(opaque) unless free_func.null?
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
- return unless debug
132
-
133
- Util.log(:debug, &block)
142
+ Util.log(:debug, 'Libvirt::Event', &block)
134
143
  end
135
-
136
144
  end
137
145
  end
@@ -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