Class: OsCtl::Lib::OsProcess
- Inherits:
-
Object
- Object
- OsCtl::Lib::OsProcess
- Defined in:
- lib/libosctl/os_process.rb
Overview
Interface to system processes, reading information from ‘/proc`
Constant Summary collapse
Instance Attribute Summary collapse
- #egid ⇒ Integer readonly
- #euid ⇒ Integer readonly
- #name ⇒ String readonly
- #nice ⇒ Integer readonly
- #nspid ⇒ Array readonly
- #num_threads ⇒ Integer readonly
-
#opts ⇒ Object
readonly
protected
Returns the value of attribute opts.
-
#path ⇒ Object
readonly
protected
Returns the value of attribute path.
-
#pgrp ⇒ Integer
readonly
Process group ID.
-
#pid ⇒ Integer
readonly
Process ID.
-
#ppid ⇒ Integer
readonly
Parent process ID.
- #rgid ⇒ Integer readonly
-
#rss ⇒ Integer
readonly
Resident set size in bytes.
- #ruid ⇒ Integer readonly
-
#start_time ⇒ Time
readonly
Time when the process was started.
- #state ⇒ String readonly
-
#sys_time ⇒ Integer
readonly
Number of seconds this process was scheduled in kernel mode.
-
#user_time ⇒ Integer
readonly
Number of seconds this process was scheduled in user mode.
-
#vmsize ⇒ Integer
readonly
Virtual memory size in bytes.
Class Method Summary collapse
Instance Method Summary collapse
- #cache(key) ⇒ Object protected
-
#cmdline ⇒ String
Read /proc/<pid>/cmdline.
- #ct_egid ⇒ Integer?
- #ct_euid ⇒ Integer?
-
#ct_id ⇒ Array?
Return container pool and id as a tuple or nil.
-
#ct_pid ⇒ Integer
Return PID as seen in the container’s PID namespace.
- #ct_rgid ⇒ Integer?
- #ct_ruid ⇒ Integer?
-
#flush ⇒ Object
Flush cache and read fresh information from ‘/proc`.
- #grandparent ⇒ OsProcess
- #id_map(type) ⇒ Object protected
-
#initialize(pid, **opts) ⇒ OsProcess
constructor
A new instance of OsProcess.
- #parent ⇒ OsProcess
-
#parse ⇒ Object
Menually invoke parsing of ‘/proc/<pid>/stat` and `/proc/<pid>/status`.
- #parse_id_map(type) ⇒ Object protected
- #parse_stat ⇒ Object protected
- #parse_status ⇒ Object protected
- #uns_host_to_ns(type, host_id) ⇒ Object protected
- #volatile ⇒ Object protected
Constructor Details
#initialize(pid, **opts) ⇒ OsProcess
Returns a new instance of OsProcess.
78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/libosctl/os_process.rb', line 78 def initialize(pid, **opts) @path = File.join('/proc', pid.to_s) @pid = pid @cache = {} @id_maps = {} @opts = opts volatile do parse_stat if opts.fetch(:parse_stat, true) parse_status if opts.fetch(:parse_status, true) end end |
Instance Attribute Details
#egid ⇒ Integer (readonly)
40 41 42 |
# File 'lib/libosctl/os_process.rb', line 40 def egid @egid end |
#euid ⇒ Integer (readonly)
34 35 36 |
# File 'lib/libosctl/os_process.rb', line 34 def euid @euid end |
#name ⇒ String (readonly)
46 47 48 |
# File 'lib/libosctl/os_process.rb', line 46 def name @name end |
#nice ⇒ Integer (readonly)
57 58 59 |
# File 'lib/libosctl/os_process.rb', line 57 def nice @nice end |
#nspid ⇒ Array (readonly)
28 29 30 |
# File 'lib/libosctl/os_process.rb', line 28 def nspid @nspid end |
#num_threads ⇒ Integer (readonly)
60 61 62 |
# File 'lib/libosctl/os_process.rb', line 60 def num_threads @num_threads end |
#opts ⇒ Object (readonly, protected)
Returns the value of attribute opts.
189 190 191 |
# File 'lib/libosctl/os_process.rb', line 189 def opts @opts end |
#path ⇒ Object (readonly, protected)
Returns the value of attribute path.
189 190 191 |
# File 'lib/libosctl/os_process.rb', line 189 def path @path end |
#pgrp ⇒ Integer (readonly)
Process group ID
25 26 27 |
# File 'lib/libosctl/os_process.rb', line 25 def pgrp @pgrp end |
#pid ⇒ Integer (readonly)
Process ID
17 18 19 |
# File 'lib/libosctl/os_process.rb', line 17 def pid @pid end |
#ppid ⇒ Integer (readonly)
Parent process ID
21 22 23 |
# File 'lib/libosctl/os_process.rb', line 21 def ppid @ppid end |
#rgid ⇒ Integer (readonly)
37 38 39 |
# File 'lib/libosctl/os_process.rb', line 37 def rgid @rgid end |
#rss ⇒ Integer (readonly)
Resident set size in bytes
54 55 56 |
# File 'lib/libosctl/os_process.rb', line 54 def rss @rss end |
#ruid ⇒ Integer (readonly)
31 32 33 |
# File 'lib/libosctl/os_process.rb', line 31 def ruid @ruid end |
#start_time ⇒ Time (readonly)
Time when the process was started
72 73 74 |
# File 'lib/libosctl/os_process.rb', line 72 def start_time @start_time end |
#state ⇒ String (readonly)
43 44 45 |
# File 'lib/libosctl/os_process.rb', line 43 def state @state end |
#sys_time ⇒ Integer (readonly)
Number of seconds this process was scheduled in kernel mode
68 69 70 |
# File 'lib/libosctl/os_process.rb', line 68 def sys_time @sys_time end |
#user_time ⇒ Integer (readonly)
Number of seconds this process was scheduled in user mode
64 65 66 |
# File 'lib/libosctl/os_process.rb', line 64 def user_time @user_time end |
#vmsize ⇒ Integer (readonly)
Virtual memory size in bytes
50 51 52 |
# File 'lib/libosctl/os_process.rb', line 50 def vmsize @vmsize end |
Class Method Details
.system_start_time ⇒ Object
9 10 11 12 13 |
# File 'lib/libosctl/os_process.rb', line 9 def self.system_start_time @system_start_time ||= Time.now - File.read('/proc/uptime').strip.split.first.to_i @system_start_time end |
Instance Method Details
#cache(key) ⇒ Object (protected)
266 267 268 269 270 271 272 |
# File 'lib/libosctl/os_process.rb', line 266 def cache(key) if @cache.has_key?(key) @cache[key] else @cache[key] = yield end end |
#cmdline ⇒ String
Read /proc/<pid>/cmdline
175 176 177 178 179 |
# File 'lib/libosctl/os_process.rb', line 175 def cmdline cache(:cmdline) do volatile { File.read(File.join(path, 'cmdline')).gsub("\0", ' ').strip } end end |
#ct_egid ⇒ Integer?
169 170 171 |
# File 'lib/libosctl/os_process.rb', line 169 def ct_egid uns_host_to_ns('gid', egid) end |
#ct_euid ⇒ Integer?
164 165 166 |
# File 'lib/libosctl/os_process.rb', line 164 def ct_euid uns_host_to_ns('uid', euid) end |
#ct_id ⇒ Array?
Return container pool and id as a tuple or nil
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/libosctl/os_process.rb', line 117 def ct_id cache(:ct_id) do volatile do File.open(File.join(path, 'cgroup'), 'r') do |f| # It's not enough to check the first cgroup, it can happen that # the process remains only in some cgroups that belong to # the container, e.g. on an incorrect shutdown. f.each_line do |line| begin _id, _subsys, path = line.split(':') rescue ArgumentError # We have a kernel bug in 5.10.147.7, which malforms # /proc/<pid>/cgroup contents, raising: # # invalid byte sequence in US-ASCII (ArgumentError) # break end next if %r{^/osctl/pool\.([^/]+)} !~ path pool = ::Regexp.last_match(1) next if %r{ct\.([^/]+)/user-owned(/|$)} !~ path ctid = ::Regexp.last_match(1) return [pool, ctid] end end nil end end end |
#ct_pid ⇒ Integer
Return PID as seen in the container’s PID namespace
111 112 113 |
# File 'lib/libosctl/os_process.rb', line 111 def ct_pid nspid[1] end |
#ct_rgid ⇒ Integer?
159 160 161 |
# File 'lib/libosctl/os_process.rb', line 159 def ct_rgid uns_host_to_ns('gid', rgid) end |
#ct_ruid ⇒ Integer?
154 155 156 |
# File 'lib/libosctl/os_process.rb', line 154 def ct_ruid uns_host_to_ns('uid', ruid) end |
#flush ⇒ Object
Flush cache and read fresh information from ‘/proc`
182 183 184 185 |
# File 'lib/libosctl/os_process.rb', line 182 def flush @cache.clear @id_maps.clear end |
#grandparent ⇒ OsProcess
105 106 107 |
# File 'lib/libosctl/os_process.rb', line 105 def grandparent parent.parent end |
#id_map(type) ⇒ Object (protected)
242 243 244 |
# File 'lib/libosctl/os_process.rb', line 242 def id_map(type) @id_maps[type] ||= parse_id_map(type) end |
#parent ⇒ OsProcess
100 101 102 |
# File 'lib/libosctl/os_process.rb', line 100 def parent self.class.new(ppid, **opts) end |
#parse ⇒ Object
Menually invoke parsing of ‘/proc/<pid>/stat` and `/proc/<pid>/status`
92 93 94 95 96 97 |
# File 'lib/libosctl/os_process.rb', line 92 def parse volatile do parse_stat parse_status end end |
#parse_id_map(type) ⇒ Object (protected)
246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/libosctl/os_process.rb', line 246 def parse_id_map(type) volatile do id_map = OsCtl::Lib::IdMap.new File.open(File.join(path, "#{type}_map"), 'r') do |f| f.each_line do |line| id_map.add_from_string(line, separator: ' ') end end id_map end end |
#parse_stat ⇒ Object (protected)
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/libosctl/os_process.rb', line 191 def parse_stat File.open(File.join(path, 'stat'), 'r') do |f| line = f.readline fields = line[line.rindex(')') + 1..].split # The third field in /proc/<pid>/stat (State) is the first in here, i.e. # substract 3 from field index documented in man proc to get # the appropriate field @state = fields[0] @ppid = fields[1].to_i @pgrp = fields[2].to_i @user_time = fields[11].to_i / TICS_PER_SECOND @sys_time = fields[12].to_i / TICS_PER_SECOND @nice = fields[16].to_i @num_threads = fields[17].to_i @start_time = self.class.system_start_time + (fields[19].to_i / TICS_PER_SECOND) @vmsize = fields[20].to_i @rss = fields[21].to_i * PAGE_SIZE end end |
#parse_status ⇒ Object (protected)
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/libosctl/os_process.rb', line 212 def parse_status File.open(File.join(path, 'status'), 'r') do |f| f.each_line do |line| colon = line.index(':') next if colon.nil? k = line[0..(colon - 1)].strip v = line[(colon + 1)..].strip case k when 'NSpid' @nspid = v.split.map(&:to_i) when 'Uid' @ruid, @euid, @svuid, @fsuid = v.split.map(&:to_i) when 'Gid' @rgid, @egid, @svgid, @fsgid = v.split.map(&:to_i) when 'Name' @name = v end end end end |
#uns_host_to_ns(type, host_id) ⇒ Object (protected)
238 239 240 |
# File 'lib/libosctl/os_process.rb', line 238 def uns_host_to_ns(type, host_id) id_map(type).host_to_ns(host_id) end |
#volatile ⇒ Object (protected)
260 261 262 263 264 |
# File 'lib/libosctl/os_process.rb', line 260 def volatile yield rescue Errno::ENOENT, Errno::ESRCH raise Exceptions::OsProcessNotFound, pid end |