class Puppet::Util::AtFork::Solaris
Solaris implementation of the Puppet::Util::AtFork handler. The callbacks defined in this implementation ensure the forked process runs in a different contract than the parent process. This is necessary in order for the child process to be able to survive termination of the contract its parent process runs in. This is needed notably for an agent run executed by a puppet agent service to be able to restart that service without being killed in the process as a consequence of running in the same contract as the service, as all processes in the contract are killed when the contract is terminated during the service restart.
Constants
- CTD_COMMON
- CTFS_PR_LATEST
- CTFS_PR_ROOT
- CTFS_PR_TEMPLATE
- CT_PR_EV_HWERR
- CT_PR_PGRPONLY
Public Instance Methods
child()
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 158 def child 159 deactivate_contract_template(false) 160 end
parent()
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 153 def parent 154 deactivate_contract_template(true) 155 abandon_latest_child_contract 156 end
prepare()
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 149 def prepare 150 activate_new_contract_template 151 end
Private Instance Methods
abandon_latest_child_contract()
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 130 def abandon_latest_child_contract 131 ctid = get_latest_child_contract_id 132 return if ctid.nil? 133 134 begin 135 ctl = File.open(File.join(CTFS_PR_ROOT, ctid.to_s, %q(ctl)), File::WRONLY) 136 137 begin 138 raise_if_error { ct_ctl_abandon(ctl.fileno) } 139 ensure 140 ctl.close 141 end 142 rescue => detail 143 Puppet.log_exception(detail, _('Failed to abandon a child process contract')) 144 end 145 end
activate_new_contract_template()
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 64 def activate_new_contract_template 65 begin 66 tmpl = File.open(CTFS_PR_TEMPLATE, File::RDWR) 67 68 begin 69 tmpl_fd = tmpl.fileno 70 71 raise_if_error { ct_pr_tmpl_set_param(tmpl_fd, CT_PR_PGRPONLY) } 72 raise_if_error { ct_pr_tmpl_set_fatal(tmpl_fd, CT_PR_EV_HWERR) } 73 raise_if_error { ct_tmpl_set_critical(tmpl_fd, 0) } 74 raise_if_error { ct_tmpl_set_informative(tmpl_fd, CT_PR_EV_HWERR) } 75 76 raise_if_error { ct_tmpl_activate(tmpl_fd) } 77 rescue 78 tmpl.close 79 raise 80 end 81 82 @tmpl = tmpl 83 rescue => detail 84 Puppet.log_exception(detail, _('Failed to activate a new process contract template')) 85 end 86 end
deactivate_contract_template(parent)
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 88 def deactivate_contract_template(parent) 89 return if @tmpl.nil? 90 91 tmpl = @tmpl 92 @tmpl = nil 93 94 begin 95 raise_if_error { ct_tmpl_clear(tmpl.fileno) } 96 rescue => detail 97 msg = if parent 98 _('Failed to deactivate process contract template in the parent process') 99 else 100 _('Failed to deactivate process contract template in the child process') 101 end 102 Puppet.log_exception(detail, msg) 103 exit(1) 104 ensure 105 tmpl.close 106 end 107 end
get_latest_child_contract_id()
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 109 def get_latest_child_contract_id 110 begin 111 stat = File.open(CTFS_PR_LATEST, File::RDONLY) 112 113 begin 114 stathdl = Fiddle::Pointer.new(0) 115 116 raise_if_error { ct_status_read(stat.fileno, CTD_COMMON, stathdl.ref) } 117 ctid = ct_status_get_id(stathdl) 118 ct_status_free(stathdl) 119 ensure 120 stat.close 121 end 122 123 ctid 124 rescue => detail 125 Puppet.log_exception(detail, _('Failed to get latest child process contract id')) 126 nil 127 end 128 end
raise_if_error() { || ... }
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 57 def raise_if_error(&block) 58 unless (e = yield) == 0 59 e = SystemCallError.new(nil, e) 60 raise e, e.message, caller 61 end 62 end