107 static int autoshutdown_en;
108 static int do_idlecheck;
109 static int got_sighup;
110 static int estar_v2_prop;
111 static int estar_v3_prop;
112 static int log_power_cycles_error = 0;
113 static int log_system_board_date_error = 0;
114 static int log_no_autoshutdown_warning = 0;
115 static mutex_t poweroff_mutex;
116
117 static char *autoshutdown_cmd[] = {
118 "/usr/bin/sys-suspend",
119 "-n", "-d", ":0", NULL
120 };
121
122 static char *power_button_cmd[] = {
123 "/usr/bin/sys-suspend",
124 "-h", "-d", ":0", NULL
125 };
126
127 static char *autoS3_cmd[] = {
128 "/usr/bin/sys-suspend",
129 "-n", "-d", ":0", NULL
130 };
131
132 static char pidpath[] = PIDPATH;
133 static char scratch[PATH_MAX];
134 static char *prog;
135
136 /* Local Functions */
137 static void alarm_handler(int);
138 static void thaw_handler(int);
139 static void kill_handler(int);
140 static void work_handler(int);
141 static void check_shutdown(time_t *, hrtime_t *);
142 static void check_idleness(time_t *, hrtime_t *);
143 static int last_system_activity(hrtime_t *);
144 static int run_idlecheck(void);
145 static void set_alarm(time_t);
146 static int poweroff(const char *, char **);
147 static int is_ok2shutdown(time_t *);
148 static int get_prom(int, prom_node_t, char *, char *, size_t);
149 static void power_button_monitor(void *);
150 static int open_pidfile(char *);
151 static int write_pidfile(int, pid_t);
152 static int read_cpr_config(void);
153 static void system_activity_monitor(void);
154 static void autos3_monitor(void);
155 static void do_attach(void);
156 static void *attach_devices(void *);
157 static int powerd_debug;
158
159 /* PRINTFLIKE1 */
160 static void
161 logerror(const char *fmt, ...)
162 {
163 va_list args;
164
165 va_start(args, fmt);
166 if (broadcast)
167 vsyslog(LOG_ERR, fmt, args);
168 va_end(args);
169 }
170
171
172 static void
173 estrcpy(char *dst, char *src, size_t dlen)
174 {
307 (void *(*)(void *))power_button_monitor, NULL,
308 THR_DAEMON, NULL) != 0) {
309 logerror("Unable to monitor system's power button.");
310 }
311 }
312
313 do_attach();
314
315 /*
316 * Create a new thread to monitor system activity and suspend
317 * system if idle.
318 */
319 if (powerd_debug)
320 logerror("powerd starting system activity monitor.");
321 if (thr_create(NULL, NULL,
322 (void *(*)(void *))system_activity_monitor, NULL,
323 THR_DAEMON, NULL) != 0) {
324 logerror("Unable to create thread to monitor system activity.");
325 }
326
327 /*
328 * Create a new thread to handle autos3 trigger
329 */
330 if (powerd_debug)
331 logerror("powerd starting autos3 monitor.");
332 if (thr_create(NULL, NULL,
333 (void *(*)(void *))autos3_monitor, NULL, THR_DAEMON, NULL) != 0) {
334 logerror("Unable to create thread to monitor autos3 activity.");
335 }
336
337 /*
338 * Block until we receive an explicit terminate signal
339 */
340 (void) sigsuspend(&sigmask);
341
342 return (1);
343 }
344
345 static void
346 system_activity_monitor(void)
347 {
348 struct sigaction act;
349 sigset_t sigmask;
350
351 /*
352 * Setup for gathering system's statistic.
353 */
354 sysstat_init();
355
370 /*
371 * Invoke work_handler with a dummy SIGHUP signal to read
372 * cpr config file, get autoshutdown properties and schedule
373 * an alarm if needed.
374 */
375 work_handler(SIGHUP);
376
377 /*
378 * Wait for signal to read file
379 */
380 (void) thr_sigsetmask(0, 0, &sigmask);
381 (void) sigdelset(&sigmask, SIGHUP);
382 (void) sigdelset(&sigmask, SIGALRM);
383 (void) sigdelset(&sigmask, SIGTHAW);
384 (void) thr_sigsetmask(SIG_SETMASK, &sigmask, NULL);
385 do {
386 (void) sigsuspend(&sigmask);
387 } while (errno == EINTR);
388 }
389
390 static void
391 autos3_monitor(void)
392 {
393 struct pollfd poll_fd;
394 srn_event_info_t srn_event; /* contains suspend type */
395 int fd, ret;
396
397 fd = open(SRN, O_RDWR|O_EXCL|O_NDELAY);
398 if (fd == -1) {
399 logerror("Unable to open %s: %s", SRN, strerror(errno));
400 thr_exit((void *)(intptr_t)errno);
401 }
402
403 /*
404 * Tell device we want the special sauce
405 */
406 ret = ioctl(fd, SRN_IOC_AUTOSX, NULL);
407 if (ret == -1) {
408 logerror("Ioctl SRN_IOC_AUTOSX failed: %s", strerror(errno));
409 (void) close(fd);
430 if (ret == -1) {
431 logerror("ioctl error: %s", strerror(errno));
432 (void) close(fd);
433 thr_exit((void *)(intptr_t)errno);
434 }
435 switch (srn_event.ae_type) {
436 case 3: /* S3 */
437 if (powerd_debug)
438 logerror("ioctl returns type: %d",
439 srn_event.ae_type);
440 break;
441 default:
442 logerror("Unsupported target state %d",
443 srn_event.ae_type);
444 continue;
445 }
446 (void) poweroff("AutoS3", autoS3_cmd);
447 continue;
448 }
449 }
450
451 static int
452 read_cpr_config(void)
453 {
454 int asfd;
455
456 if ((asfd = open(CPR_CONFIG, O_RDONLY)) < 0) {
457 logerror("Unable to open CPR config file '%s'", CPR_CONFIG);
458 return (-1);
459 }
460
461 if (read(asfd, (void *)&asinfo, sizeof (asinfo)) != sizeof (asinfo)) {
462 logerror("Unable to read CPR config file '%s'", CPR_CONFIG);
463 (void) close(asfd);
464 return (-1);
465 }
466
467 (void) close(asfd);
468
469 return (0);
|
107 static int autoshutdown_en;
108 static int do_idlecheck;
109 static int got_sighup;
110 static int estar_v2_prop;
111 static int estar_v3_prop;
112 static int log_power_cycles_error = 0;
113 static int log_system_board_date_error = 0;
114 static int log_no_autoshutdown_warning = 0;
115 static mutex_t poweroff_mutex;
116
117 static char *autoshutdown_cmd[] = {
118 "/usr/bin/sys-suspend",
119 "-n", "-d", ":0", NULL
120 };
121
122 static char *power_button_cmd[] = {
123 "/usr/bin/sys-suspend",
124 "-h", "-d", ":0", NULL
125 };
126
127 #ifdef __x86
128 static char *autoS3_cmd[] = {
129 "/usr/bin/sys-suspend",
130 "-n", "-d", ":0", NULL
131 };
132 #endif
133
134 static char pidpath[] = PIDPATH;
135 static char scratch[PATH_MAX];
136 static char *prog;
137
138 /* Local Functions */
139 static void alarm_handler(int);
140 static void thaw_handler(int);
141 static void kill_handler(int);
142 static void work_handler(int);
143 static void check_shutdown(time_t *, hrtime_t *);
144 static void check_idleness(time_t *, hrtime_t *);
145 static int last_system_activity(hrtime_t *);
146 static int run_idlecheck(void);
147 static void set_alarm(time_t);
148 static int poweroff(const char *, char **);
149 static int is_ok2shutdown(time_t *);
150 static int get_prom(int, prom_node_t, char *, char *, size_t);
151 static void power_button_monitor(void *);
152 static int open_pidfile(char *);
153 static int write_pidfile(int, pid_t);
154 static int read_cpr_config(void);
155 static void system_activity_monitor(void);
156 #ifdef __x86
157 static void autos3_monitor(void);
158 #endif
159 static void do_attach(void);
160 static void *attach_devices(void *);
161 static int powerd_debug;
162
163 /* PRINTFLIKE1 */
164 static void
165 logerror(const char *fmt, ...)
166 {
167 va_list args;
168
169 va_start(args, fmt);
170 if (broadcast)
171 vsyslog(LOG_ERR, fmt, args);
172 va_end(args);
173 }
174
175
176 static void
177 estrcpy(char *dst, char *src, size_t dlen)
178 {
311 (void *(*)(void *))power_button_monitor, NULL,
312 THR_DAEMON, NULL) != 0) {
313 logerror("Unable to monitor system's power button.");
314 }
315 }
316
317 do_attach();
318
319 /*
320 * Create a new thread to monitor system activity and suspend
321 * system if idle.
322 */
323 if (powerd_debug)
324 logerror("powerd starting system activity monitor.");
325 if (thr_create(NULL, NULL,
326 (void *(*)(void *))system_activity_monitor, NULL,
327 THR_DAEMON, NULL) != 0) {
328 logerror("Unable to create thread to monitor system activity.");
329 }
330
331 #ifdef __x86
332 /*
333 * Create a new thread to handle autos3 trigger
334 */
335 if (powerd_debug)
336 logerror("powerd starting autos3 monitor.");
337 if (thr_create(NULL, NULL,
338 (void *(*)(void *))autos3_monitor, NULL, THR_DAEMON, NULL) != 0) {
339 logerror("Unable to create thread to monitor autos3 activity.");
340 }
341 #endif
342
343 /*
344 * Block until we receive an explicit terminate signal
345 */
346 (void) sigsuspend(&sigmask);
347
348 return (1);
349 }
350
351 static void
352 system_activity_monitor(void)
353 {
354 struct sigaction act;
355 sigset_t sigmask;
356
357 /*
358 * Setup for gathering system's statistic.
359 */
360 sysstat_init();
361
376 /*
377 * Invoke work_handler with a dummy SIGHUP signal to read
378 * cpr config file, get autoshutdown properties and schedule
379 * an alarm if needed.
380 */
381 work_handler(SIGHUP);
382
383 /*
384 * Wait for signal to read file
385 */
386 (void) thr_sigsetmask(0, 0, &sigmask);
387 (void) sigdelset(&sigmask, SIGHUP);
388 (void) sigdelset(&sigmask, SIGALRM);
389 (void) sigdelset(&sigmask, SIGTHAW);
390 (void) thr_sigsetmask(SIG_SETMASK, &sigmask, NULL);
391 do {
392 (void) sigsuspend(&sigmask);
393 } while (errno == EINTR);
394 }
395
396 #ifdef __x86
397 static void
398 autos3_monitor(void)
399 {
400 struct pollfd poll_fd;
401 srn_event_info_t srn_event; /* contains suspend type */
402 int fd, ret;
403
404 fd = open(SRN, O_RDWR|O_EXCL|O_NDELAY);
405 if (fd == -1) {
406 logerror("Unable to open %s: %s", SRN, strerror(errno));
407 thr_exit((void *)(intptr_t)errno);
408 }
409
410 /*
411 * Tell device we want the special sauce
412 */
413 ret = ioctl(fd, SRN_IOC_AUTOSX, NULL);
414 if (ret == -1) {
415 logerror("Ioctl SRN_IOC_AUTOSX failed: %s", strerror(errno));
416 (void) close(fd);
437 if (ret == -1) {
438 logerror("ioctl error: %s", strerror(errno));
439 (void) close(fd);
440 thr_exit((void *)(intptr_t)errno);
441 }
442 switch (srn_event.ae_type) {
443 case 3: /* S3 */
444 if (powerd_debug)
445 logerror("ioctl returns type: %d",
446 srn_event.ae_type);
447 break;
448 default:
449 logerror("Unsupported target state %d",
450 srn_event.ae_type);
451 continue;
452 }
453 (void) poweroff("AutoS3", autoS3_cmd);
454 continue;
455 }
456 }
457 #endif
458
459 static int
460 read_cpr_config(void)
461 {
462 int asfd;
463
464 if ((asfd = open(CPR_CONFIG, O_RDONLY)) < 0) {
465 logerror("Unable to open CPR config file '%s'", CPR_CONFIG);
466 return (-1);
467 }
468
469 if (read(asfd, (void *)&asinfo, sizeof (asinfo)) != sizeof (asinfo)) {
470 logerror("Unable to read CPR config file '%s'", CPR_CONFIG);
471 (void) close(asfd);
472 return (-1);
473 }
474
475 (void) close(asfd);
476
477 return (0);
|