a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * CDDL HEADER START
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * The contents of this file are subject to the terms of the
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Common Development and Distribution License (the "License").
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * You may not use this file except in compliance with the License.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * or http://www.opensolaris.org/os/licensing.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * See the License for the specific language governing permissions
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * and limitations under the License.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * When distributing Covered Code, include this CDDL HEADER in each
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * If applicable, add the following below this CDDL HEADER, with the
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * fields enclosed by brackets "[]" replaced with your own identifying
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * information: Portions Copyright [yyyy] [name of copyright owner]
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * CDDL HEADER END
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Use is subject to license terms.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Copyright (c) 2010, Intel Corporation.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * All rights reserved.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/param.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/stat.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/types.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/sysevent/eventdefs.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <sys/sysevent/dr.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <stdio.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <stdlib.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <unistd.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <signal.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <syslog.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <string.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <strings.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <fcntl.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <errno.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <time.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <config_admin.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <libscf.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <libsysevent.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include <stdarg.h>
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/* Signal handler type */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liutypedef void (sig_handler_t)(int);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#define ACPIHPD_PID_FILE "/var/run/acpihpd.pid" /* lock file path */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/* Program Name */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuchar *g_prog_name;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint g_debuglevel = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int s_pid_fd;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic sysevent_handle_t *s_acpihpd_hdl;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int daemon_init(void);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic void daemon_quit(int);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int set_sig_handler(int, sig_handler_t *);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int acpihpd_init(void);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic void acpihpd_fini(void);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic void acpihpd_event(sysevent_t *);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuextern void notify_hotplug(sysevent_t *ev);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuvoid debug_print(int, const char *, ...);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuint
a31148363f598def767ac48c5d82e1572e44b935Gerry Liumain(int argc, char *argv[])
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int c;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Get Program Name */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if ((g_prog_name = strrchr(argv[0], '/')) == NULL) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu g_prog_name = argv[0];
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu } else {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu g_prog_name++;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu while ((c = getopt(argc, argv, ":d:")) != -1) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu switch (c) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case 'd':
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu g_debuglevel = atoi(optarg);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if ((g_debuglevel < 0) || (g_debuglevel > 2)) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu g_debuglevel = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case ':':
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu syslog(LOG_ERR,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu "missed argument for option %c.", optopt);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case '?':
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu syslog(LOG_ERR, "unrecognized option %c.", optopt);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu s_acpihpd_hdl = NULL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Check the daemon running lock and initialize the signal */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (daemon_init() != 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(0, "%s could not startup!", g_prog_name);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu exit(SMF_EXIT_ERR_FATAL);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Subscribe to the hotplug event */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (acpihpd_init() != 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(0, "%s could not startup!", g_prog_name);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu daemon_quit(SMF_EXIT_ERR_FATAL);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(2, "daemon is running.");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*CONSTCOND*/
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu while (1) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) pause();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (SMF_EXIT_OK);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudaemon_init(void)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int i, ret;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu pid_t pid;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu char pid_str[32];
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (geteuid() != 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(0, "must be root to execute %s", g_prog_name);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if ((pid = fork()) < 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (pid > 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Parent to exit. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu exit(SMF_EXIT_OK);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) setsid();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) chdir("/");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) umask(0);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) closefrom(0);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) open("/dev/null", O_RDONLY);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) open("/dev/null", O_WRONLY);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) dup(1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) openlog(g_prog_name, LOG_PID, LOG_DAEMON);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Create the lock file for singleton
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if ((s_pid_fd = open(ACPIHPD_PID_FILE, O_RDWR | O_CREAT, 0644)) < 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(0, "could not create pid file: %s",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu strerror(errno));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (lockf(s_pid_fd, F_TLOCK, 0L) < 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (errno == EACCES || errno == EAGAIN) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(0, "another acpihpd is already running");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu } else {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(0, "could not lock pid file");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) ftruncate(s_pid_fd, 0);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu i = sprintf(pid_str, "%ld", (long)getpid());
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu while ((ret = write(s_pid_fd, pid_str, i)) != i) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (errno == EINTR) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu continue;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (ret < 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(0, "pid file write failed: %s",
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu strerror(errno));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (set_sig_handler(SIGTERM, (sig_handler_t *)daemon_quit) != 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(2, "could not set signal handler(SIGTERM)");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (set_sig_handler(SIGQUIT, (sig_handler_t *)daemon_quit) != 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(2, "could not set signal handler(SIGQUIT)");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (set_sig_handler(SIGINT, (sig_handler_t *)daemon_quit) != 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(2, "could not set signal handler(SIGINT)");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (set_sig_handler(SIGCHLD, SIG_IGN) != 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(2, "could not set signal handler(SIGCHLD)");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (0);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic void
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudaemon_quit(int signo)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int status = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu id_t pgid;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(1, "daemon quit [signal#:%d].", signo);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu acpihpd_fini();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) set_sig_handler(SIGTERM, SIG_IGN);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu pgid = getpgrp();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) kill(-pgid, SIGTERM);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) close(s_pid_fd);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) unlink(ACPIHPD_PID_FILE);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (signo < 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu status = signo;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu _exit(status);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuset_sig_handler(int sig, sig_handler_t *handler)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu struct sigaction act;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu act.sa_handler = handler;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu act.sa_flags = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (sig == SIGCHLD && handler == SIG_IGN) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu act.sa_flags |= SA_NOCLDWAIT;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu (void) sigemptyset(&act.sa_mask);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (sigaction(sig, &act, NULL) < 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (0);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic int
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuacpihpd_init(void)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu const char *subclass = ESC_DR_REQ;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(2, "acpihpd_init");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if ((s_acpihpd_hdl = sysevent_bind_handle(acpihpd_event)) == NULL) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(2, "could not bind to sysevent.");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (-1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (sysevent_subscribe_event(s_acpihpd_hdl, EC_DR, &subclass, 1) != 0) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(2, "could not subscribe an event.");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sysevent_unbind_handle(s_acpihpd_hdl);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu s_acpihpd_hdl = NULL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (-1);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return (0);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic void
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuacpihpd_fini(void)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(2, "acpihpd_fini");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (s_acpihpd_hdl != NULL) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sysevent_unsubscribe_event(s_acpihpd_hdl, EC_DR);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu sysevent_unbind_handle(s_acpihpd_hdl);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liustatic void
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuacpihpd_event(sysevent_t *ev)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu debug_print(2, "*** got an event ***");
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu /* Inform cfgadm of the hot-plug event. */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu notify_hotplug(ev);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuvoid
a31148363f598def767ac48c5d82e1572e44b935Gerry Liudebug_print(int level, const char *fmt, ...)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu va_list ap;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu int pri, pr_out = 0;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (level <= g_debuglevel) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu switch (level) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case 0:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu pri = LOG_ERR;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu pr_out = 1;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case 1:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu pri = LOG_NOTICE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu pr_out = 1;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case 2:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu pri = LOG_DEBUG;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu pr_out = 1;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (pr_out) {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu va_start(ap, fmt);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu vsyslog(pri, fmt, ap);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu va_end(ap);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}