Skip to content

Commit 1187c71

Browse files
committed
osctld: make Container::Stop wait for console being closed
1 parent 13b30c4 commit 1187c71

File tree

4 files changed

+62
-9
lines changed

4 files changed

+62
-9
lines changed

osctld/lib/osctld/commands/container/stop.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ def execute(ct)
5151
# in low memory situations.
5252
ct.cgparams.temporarily_expand_memory if ct.running?
5353

54+
run_conf = ct.get_run_conf
55+
promise = run_conf.get_exit_promise if run_conf.init_pid
56+
5457
begin
5558
DistConfig.run(
5659
ct.get_run_conf,
@@ -71,6 +74,10 @@ def execute(ct)
7174
error!(e.message)
7275
end
7376

77+
if promise && promise.wait.nil?
78+
log(:warn, "Timeout while waiting for exit promise of #{ct.ident}")
79+
end
80+
7481
remove_accounting_cgroups(ct)
7582

7683
if ct.ephemeral? && !indirect?

osctld/lib/osctld/console/console.rb

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,10 @@ def on_ct_stop
7575
)
7676
end
7777

78-
if ctrc.aborted? \
79-
|| ctrc.reboot? \
80-
|| (ct.ephemeral? && !ct.is_being_manipulated?) \
81-
|| ctrc.destroy_dataset_on_stop?
82-
# The current thread is used to handle the console and has to exit.
83-
# Manipulation must happen from another thread.
84-
t = Thread.new { handle_ct_stop(ctrc) }
85-
ThreadReaper.add(t, nil)
86-
end
78+
# The current thread is used to handle the console and has to exit.
79+
# Manipulation must happen from another thread.
80+
t = Thread.new { handle_ct_stop(ctrc) }
81+
ThreadReaper.add(t, nil)
8782

8883
ct.forget_past_run_conf
8984
end
@@ -105,6 +100,8 @@ def handle_ct_stop(ctrc)
105100
GarbageCollector.free_container_run_dataset(ctrc, ctrc.dataset)
106101
end
107102

103+
ctrc.fulfil_exit
104+
108105
if ctrc.reboot?
109106
sleep(1)
110107
reboot_ct

osctld/lib/osctld/container/run_configuration.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def initialize(ct, load_conf: true)
3535
@init_pid = nil
3636
@aborted = false
3737
@do_reboot = false
38+
@exit_promise = Promise.new
3839
@dist_network_configured = false
3940
self.load_conf(from_file: load_conf)
4041
end
@@ -149,6 +150,14 @@ def reboot?
149150
@do_reboot
150151
end
151152

153+
def get_exit_promise
154+
@exit_promise.add
155+
end
156+
157+
def fulfil_exit
158+
@exit_promise.fulfil
159+
end
160+
152161
def dist_configure_network?
153162
inclusively do
154163
!dist_network_configured && can_dist_configure_network?

osctld/lib/osctld/promise.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
require 'libosctl'
2+
3+
module OsCtld
4+
class Promise
5+
class Token
6+
def initialize
7+
@queue = OsCtl::Lib::Queue.new
8+
end
9+
10+
# Wait until the promise is fulfilled
11+
# @param timeout [Integer]
12+
# @return [true, nil]
13+
def wait(timeout: 60)
14+
@queue.pop(timeout:)
15+
end
16+
17+
# Fulfil the promise
18+
def fulfil
19+
@queue << true
20+
end
21+
end
22+
23+
def initialize
24+
@mutex = Mutex.new
25+
@tokens = []
26+
end
27+
28+
# @return [Token]
29+
def add
30+
t = Token.new
31+
@tokens << t
32+
t
33+
end
34+
35+
def fulfil
36+
@tokens.each(&:fulfil)
37+
nil
38+
end
39+
end
40+
end

0 commit comments

Comments
 (0)