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 157 def child 158 deactivate_contract_template(false) 159 end
parent()
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 152 def parent 153 deactivate_contract_template(true) 154 abandon_latest_child_contract 155 end
prepare()
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 148 def prepare 149 activate_new_contract_template 150 end
Private Instance Methods
abandon_latest_child_contract()
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 129 def abandon_latest_child_contract 130 ctid = get_latest_child_contract_id 131 return if ctid.nil? 132 133 begin 134 ctl = File.open(File.join(CTFS_PR_ROOT, ctid.to_s, %q(ctl)), File::WRONLY) 135 136 begin 137 raise_if_error { ct_ctl_abandon(ctl.fileno) } 138 ensure 139 ctl.close 140 end 141 rescue => detail 142 Puppet.log_exception(detail, _('Failed to abandon a child process contract')) 143 end 144 end
activate_new_contract_template()
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 63 def activate_new_contract_template 64 begin 65 tmpl = File.open(CTFS_PR_TEMPLATE, File::RDWR) 66 67 begin 68 tmpl_fd = tmpl.fileno 69 70 raise_if_error { ct_pr_tmpl_set_param(tmpl_fd, CT_PR_PGRPONLY) } 71 raise_if_error { ct_pr_tmpl_set_fatal(tmpl_fd, CT_PR_EV_HWERR) } 72 raise_if_error { ct_tmpl_set_critical(tmpl_fd, 0) } 73 raise_if_error { ct_tmpl_set_informative(tmpl_fd, CT_PR_EV_HWERR) } 74 75 raise_if_error { ct_tmpl_activate(tmpl_fd) } 76 rescue 77 tmpl.close 78 raise 79 end 80 81 @tmpl = tmpl 82 rescue => detail 83 Puppet.log_exception(detail, _('Failed to activate a new process contract template')) 84 end 85 end
deactivate_contract_template(parent)
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 87 def deactivate_contract_template(parent) 88 return if @tmpl.nil? 89 90 tmpl = @tmpl 91 @tmpl = nil 92 93 begin 94 raise_if_error { ct_tmpl_clear(tmpl.fileno) } 95 rescue => detail 96 msg = if parent 97 _('Failed to deactivate process contract template in the parent process') 98 else 99 _('Failed to deactivate process contract template in the child process') 100 end 101 Puppet.log_exception(detail, msg) 102 exit(1) 103 ensure 104 tmpl.close 105 end 106 end
get_latest_child_contract_id()
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 108 def get_latest_child_contract_id 109 begin 110 stat = File.open(CTFS_PR_LATEST, File::RDONLY) 111 112 begin 113 stathdl = Fiddle::Pointer.new(0) 114 115 raise_if_error { ct_status_read(stat.fileno, CTD_COMMON, stathdl.ref) } 116 ctid = ct_status_get_id(stathdl) 117 ct_status_free(stathdl) 118 ensure 119 stat.close 120 end 121 122 ctid 123 rescue => detail 124 Puppet.log_exception(detail, _('Failed to get latest child process contract id')) 125 nil 126 end 127 end
raise_if_error() { || ... }
click to toggle source
# File lib/puppet/util/at_fork/solaris.rb 56 def raise_if_error(&block) 57 unless (e = yield) == 0 58 e = SystemCallError.new(nil, e) 59 raise e, e.message, caller 60 end 61 end