4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 #include <sys/param.h>
30 #include <sys/types.h>
31 #include <sys/sysevent/eventdefs.h>
32 #include <sys/sysevent/dr.h>
43 #include <config_admin.h>
44 #include <libsysevent.h>
47 /* Signal handler type */
48 typedef void (SigHandler
)(int);
49 /* oplhpd process id file descriptor */
53 char *oplhpd_prog_name
= "";
56 #define OPLHPD_DEV_DIR "/devices" /* device base dir */
57 #define OPLHPD_PID_FILE "/var/run/oplhpd.pid" /* lock file path */
58 #define OPLHPD_PROG_NAME oplhpd_prog_name
60 /* Event handler to get information */
61 static sysevent_handle_t
*oplhpd_hdl
;
67 void quit_daemon(int signo
);
68 SigHandler
*set_sig_handler(int sig
, SigHandler
*handler
);
69 void init_daemon(void);
70 void oplhpd_init(void);
71 void oplhpd_fini(void);
72 static void oplhpd_event(sysevent_t
*ev
);
74 extern void notify_scf_of_hotplug(sysevent_t
*ev
);
78 * Terminate and Quit Daemon Process.
79 * signo = 0 ... normal quit
80 * > 0 ... signaled quit
81 * < 0 ... failure quit
84 quit_daemon(int signo
)
89 syslog(LOG_DEBUG
, "*** quit daemon [pid:%d, signal#:%d].\n",
92 (void) set_sig_handler(SIGTERM
, SIG_IGN
);
94 (void) kill(-pgid
, SIGTERM
);
97 (void) unlink(OPLHPD_PID_FILE
); /* clean up lock file */
106 * Setting the signal handler utility
109 set_sig_handler(int sig
, SigHandler
*handler
)
111 struct sigaction act
, oact
;
113 act
.sa_handler
= handler
;
115 if (sig
== SIGCHLD
&& handler
== SIG_IGN
) {
116 act
.sa_flags
|= SA_NOCLDWAIT
;
118 (void) sigemptyset(&act
.sa_mask
);
119 (void) sigemptyset(&oact
.sa_mask
);
120 if (sigaction(sig
, &act
, &oact
) < 0) {
124 return (oact
.sa_handler
);
128 * Setup oplhpd daemon
139 if (geteuid() != 0) {
140 syslog(LOG_ERR
, "must be root to execute %s\n",
148 if ((pid
= fork()) < 0) {
149 perror("fork failed");
160 (void) open("/dev/null", O_RDONLY
);
161 (void) open("/dev/null", O_WRONLY
);
164 (void) openlog(OPLHPD_PROG_NAME
, LOG_PID
, LOG_DAEMON
);
167 * Create the lock file for singletonize
169 if ((pid_fd
= open(OPLHPD_PID_FILE
, O_RDWR
| O_CREAT
, 0644)) < 0) {
170 syslog(LOG_ERR
, "could not create pid file: %s",
174 if (lockf(pid_fd
, F_TLOCK
, 0L) < 0) {
175 if (errno
== EACCES
|| errno
== EAGAIN
) {
176 syslog(LOG_ERR
, "another oplhpd is already running");
178 syslog(LOG_ERR
, "could not lock pid file");
183 (void) ftruncate(pid_fd
, 0);
184 i
= sprintf(pid_str
, "%d\n", getpid());
185 while ((ret
= write(pid_fd
, pid_str
, i
)) != i
) {
186 if (errno
== EINTR
) {
190 syslog(LOG_ERR
, "pid file write fail: %s",
197 * Set signal handlers
199 (void) set_sig_handler(SIGTERM
, (SigHandler
*)quit_daemon
);
200 (void) set_sig_handler(SIGQUIT
, (SigHandler
*)quit_daemon
);
201 (void) set_sig_handler(SIGINT
, (SigHandler
*)quit_daemon
);
202 (void) set_sig_handler(SIGCHLD
, SIG_IGN
);
206 oplhpd_event(sysevent_t
*ev
)
209 * Inform the SCF of the change in the state of the pci hot plug
212 notify_scf_of_hotplug(ev
);
217 * Initialization for hotplug event.
218 * - Bind event handler.
219 * - Subscribe the handler to the hotplug event.
224 const char *subclass
= ESC_DR_AP_STATE_CHANGE
;
226 syslog(LOG_DEBUG
, "oplhpd_init");
228 oplhpd_hdl
= sysevent_bind_handle(oplhpd_event
);
229 if (oplhpd_hdl
== NULL
) {
230 syslog(LOG_ERR
, "event handler bind fail");
234 if (sysevent_subscribe_event(oplhpd_hdl
, EC_DR
, &subclass
, 1) != 0) {
235 syslog(LOG_ERR
, "event handler subscribe fail");
236 sysevent_unbind_handle(oplhpd_hdl
);
248 if (oplhpd_hdl
!= NULL
) {
249 sysevent_unsubscribe_event(oplhpd_hdl
, EC_DR
);
250 sysevent_unbind_handle(oplhpd_hdl
);
255 main(int argc
, char *argv
[])
259 /* Get Program Name */
260 if ((oplhpd_prog_name
= strrchr(argv
[0], '/')) == NULL
) {
261 oplhpd_prog_name
= argv
[0];
266 /* Check the daemon running lock and Initialize the signal */
269 /* Subscribe to the hotplug event */
272 /* Unsubscribe the hotplug event */