Skip to content

Commit 072da6f

Browse files
authored
Merge pull request #9389 from tvpartytonight/backport-9386-to-7.x
[Backport 7.x] Stop using FFI threads and use ruby threads for the windows puppet daemon
2 parents 372e9a0 + d226f1b commit 072da6f

File tree

2 files changed

+66
-32
lines changed

2 files changed

+66
-32
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
test_name 'Test agent state via service control manager' do
2+
3+
tag 'audit:integration'
4+
5+
confine :to, platform: 'windows'
6+
7+
teardown do
8+
agents.each do |agent|
9+
state = query_agent_state(agent)
10+
if state != "STOPPED"
11+
stop_puppet_windows_daemon(agent)
12+
ensure_agent_state(agent, "STOPPED")
13+
end
14+
end
15+
end
16+
17+
def query_agent_state(host)
18+
on(host, 'sc query puppet').stdout.match(/STATE.+\s{1}(\w+)/)[1]
19+
end
20+
21+
def start_puppet_windows_daemon(host)
22+
on(host, 'sc start puppet')
23+
end
24+
25+
def stop_puppet_windows_daemon(host)
26+
on(host, 'sc stop puppet')
27+
end
28+
29+
def ensure_agent_state(host, state)
30+
retry_attempts = 0
31+
while retry_attempts < 5
32+
return if state == query_agent_state(host)
33+
retry_attempts += 1
34+
sleep 1
35+
end
36+
fail_test "State not #{state} after 5 tries"
37+
end
38+
39+
step 'store initial state' do
40+
41+
agents.each do |agent|
42+
initial_state = query_agent_state(agent)
43+
assert_match("STOPPED", initial_state, "agent daemon should initially be stopped")
44+
45+
start_puppet_windows_daemon(agent)
46+
ensure_agent_state(agent, "RUNNING")
47+
stop_puppet_windows_daemon(agent)
48+
ensure_agent_state(agent, "STOPPED")
49+
end
50+
end
51+
end

lib/puppet/util/windows/daemon.rb

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -188,25 +188,6 @@ class Daemon
188188
end
189189
end
190190

191-
ThreadProc = FFI::Function.new(:ulong,[:pointer]) do |lpParameter|
192-
ste = FFI::MemoryPointer.new(SERVICE_TABLE_ENTRYW, 2)
193-
194-
s = SERVICE_TABLE_ENTRYW.new(ste[0])
195-
s[:lpServiceName] = FFI::MemoryPointer.from_string('')
196-
s[:lpServiceProc] = lpParameter
197-
198-
s = SERVICE_TABLE_ENTRYW.new(ste[1])
199-
s[:lpServiceName] = nil
200-
s[:lpServiceProc] = nil
201-
202-
# No service to step, no service handle, no ruby exceptions, just terminate the thread..
203-
if !StartServiceCtrlDispatcherW(ste)
204-
return 1
205-
end
206-
207-
return 0
208-
end
209-
210191
# This is a shortcut for Daemon.new + Daemon#mainloop.
211192
#
212193
def self.mainloop
@@ -256,26 +237,28 @@ def mainloop
256237
raise SystemCallError.new('CreateEvent', FFI.errno)
257238
end
258239

259-
hThread = CreateThread(nil, 0, ThreadProc, Service_Main, 0, nil)
240+
hThread = Thread.new do
241+
ste = FFI::MemoryPointer.new(SERVICE_TABLE_ENTRYW, 2)
260242

261-
if hThread == 0
262-
raise SystemCallError.new('CreateThread', FFI.errno)
263-
end
243+
s = SERVICE_TABLE_ENTRYW.new(ste[0])
244+
s[:lpServiceName] = FFI::MemoryPointer.from_string("")
245+
s[:lpServiceProc] = Service_Main
264246

265-
events = FFI::MemoryPointer.new(:pointer, 2)
266-
events.put_pointer(0, FFI::Pointer.new(hThread))
267-
events.put_pointer(FFI::Pointer.size, FFI::Pointer.new(@@hStartEvent))
247+
s = SERVICE_TABLE_ENTRYW.new(ste[1])
248+
s[:lpServiceName] = nil
249+
s[:lpServiceProc] = nil
268250

269-
while ((index = WaitForMultipleObjects(2, events, 0, 1000)) == WAIT_TIMEOUT) do
251+
# No service to step, no service handle, no ruby exceptions, just terminate the thread..
252+
StartServiceCtrlDispatcherW(ste)
270253
end
271254

272-
if index == WAIT_FAILED
273-
raise SystemCallError.new('WaitForMultipleObjects', FFI.errno)
255+
while (index = WaitForSingleObject(@@hStartEvent, 1000)) == WAIT_TIMEOUT
256+
# The thread exited, so the show is off.
257+
raise "Service_Main thread exited abnormally" unless hThread.alive?
274258
end
275259

276-
# The thread exited, so the show is off.
277-
if index == WAIT_OBJECT_0
278-
raise "Service_Main thread exited abnormally"
260+
if index == WAIT_FAILED
261+
raise SystemCallError.new("WaitForSingleObject", FFI.errno)
279262
end
280263

281264
thr = Thread.new do

0 commit comments

Comments
 (0)