Class: OsCtld::Console::Console

Inherits:
TTY
  • Object
show all
Defined in:
lib/osctld/console/console.rb

Overview

Special case for tty0 (/dev/console)

tty0 is opened on container start, at least when it's started by osctld. The tty is accessed using unix server socket created by the osctld container wrapper.

Instance Attribute Summary

Attributes inherited from TTY

#ct, #n, #tty_in_io, #tty_out_io, #tty_pid

Instance Method Summary collapse

Methods inherited from TTY

#add_client, #client_read, #close, #initialize, #opened?, #remove_client, #start, #sync, #tty_read, #tty_write, #wake, #watch_ios

Methods included from Utils::SwitchUser

#ct_attach, #ct_syscmd

Constructor Details

This class inherits a constructor from OsCtld::Console::TTY

Instance Method Details

#connect(pid, socket) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/osctld/console/console.rb', line 15

def connect(pid, socket)
  tries = 0

  begin
    c = UNIXSocket.new(socket)

  rescue Errno::ENOENT
    raise if tries >= (0.2 * 50 * 10) # try for 10 seconds
    tries += 1
    sleep(0.2)
    retry
  end

  sync do
    @opened = true
    self.tty_pid = pid
    self.tty_in_io = c
    self.tty_out_io = c
    wake
  end
end

#handle_ct_stop(ctrc) ⇒ Object (protected)



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/osctld/console/console.rb', line 66

def handle_ct_stop(ctrc)
  if ctrc.destroy_dataset_on_stop?
    begin
      zfs(:destroy, nil, ctrc.dataset)
    rescue SystemCommandFailed => e
      log(:warn, ctrc, "Unable to destroy dataset '#{ctrc.dataset}': #{e.message}")
    end
  end

  if ctrc.reboot?
    sleep(1)
    reboot_ct

  elsif ct.ephemeral? && !ct.is_being_manipulated?
    Commands::Container::Delete.run({
      pool: ct.pool.name,
      id: ct.id,
      force: true,
      manipulation_lock: 'wait',
    })
  end
end

#on_closeObject (protected)



38
39
40
41
42
# File 'lib/osctld/console/console.rb', line 38

def on_close
  if ct.state == :stopped
    on_ct_stop
  end
end

#on_ct_stopObject (protected)



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/osctld/console/console.rb', line 44

def on_ct_stop
  ctrc = ct.get_past_run_conf

  if ctrc.nil?
    # This means that {UserControl::Commands::CtPostStop} hasn't run for some
    # reason.
    log(:fatal, ctrc, 'Unable to properly handle container stop')
    return
  end

  if ctrc.reboot? \
     || (ct.ephemeral? && !ct.is_being_manipulated?) \
     || (ctrc && ctrc.destroy_dataset_on_stop?)
    # The current thread is used to handle the console and has to exit.
    # Manipulation must happen from another thread.
    t = Thread.new { handle_ct_stop(ctrc) }
    ThreadReaper.add(t, nil)
  end

  ct.forget_past_run_conf
end

#openObject



11
12
13
# File 'lib/osctld/console/console.rb', line 11

def open
  # Does nothing for tty0, it is opened automatically on ct start
end

#reboot_ctObject (protected)



89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/osctld/console/console.rb', line 89

def reboot_ct
  ret = Commands::Container::Start.run({
    pool: ct.pool.name,
    id: ct.id,
    force: true,
    manipulation_lock: 'wait',
  })

  if !ret.is_a?(Hash)
    log(:warn, ct, 'Reboot failed: reason unknown')
  elsif !ret[:status]
    log(:warn, ct, "Reboot failed: #{ret[:message]}")
  end
end