/* * tmon.c Thermal Monitor (TMON) main function and entry point * * Copyright (C) 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 or later as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Author: Jacob Pan * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "tmon.h" unsigned long ticktime = 1; /* seconds */ unsigned long no_control = 1; /* monitoring only or use cooling device for * temperature control. */ double time_elapsed = 0.0; unsigned long target_temp_user = 65; /* can be select by tui later */ int dialogue_on; int tmon_exit; static short daemon_mode; static int logging; /* for recording thermal data to a file */ static int debug_on; FILE *tmon_log; /*cooling device used for the PID controller */ char ctrl_cdev[CDEV_NAME_SIZE] = "None"; int target_thermal_zone; /* user selected target zone instance */ static void start_daemon_mode(void); pthread_t event_tid; pthread_mutex_t input_lock; void usage() { printf("Usage: tmon [OPTION...]\n"); printf(" -c, --control cooling device in control\n"); printf(" -d, --daemon run as daemon, no TUI\n"); printf(" -g, --debug debug message in syslog\n"); printf(" -h, --help show this help message\n"); printf(" -l, --log log data to /var/tmp/tmon.log\n"); printf(" -t, --time-interval sampling time interval, > 1 sec.\n"); printf(" -T, --target-temp initial target temperature\n"); printf(" -v, --version show version\n"); printf(" -z, --zone target thermal zone id\n"); exit(0); } void version() { printf("TMON version %s\n", VERSION); exit(EXIT_SUCCESS); } static void tmon_cleanup(void) { syslog(LOG_INFO, "TMON exit cleanup\n"); fflush(stdout); refresh(); if (tmon_log) fclose(tmon_log); if (event_tid) { pthread_mutex_lock(&input_lock); pthread_cancel(event_tid); pthread_mutex_unlock(&input_lock); pthread_mutex_destroy(&input_lock); } closelog(); /* relax control knobs, undo throttling */ set_ctrl_state(0); keypad(stdscr, FALSE); echo(); nocbreak(); close_windows(); endwin(); free_thermal_data(); exit(1); } static void tmon_sig_handler(int sig) { syslog(LOG_INFO, "TMON caught signal %d\n", sig); refresh(); switch (sig) { case SIGTERM: printf("sigterm, exit and clean up\n"); fflush(stdout); break; case SIGKILL: printf("sigkill, exit and clean up\n"); fflush(stdout); break; case SIGINT: printf("ctrl-c, exit and clean up\n"); fflush(stdout); break; default: break; } tmon_exit = true; } static void start_syslog(void) { if (debug_on) setlogmask(LOG_UPTO(LOG_DEBUG)); else setlogmask(LOG_UPTO(LOG_ERR)); openlog("tmon.log", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL0); syslog(LOG_NOTICE, "TMON started by User %d", getuid()); } static void prepare_logging(void) { int i; struct stat logstat; if (!logging) return; /* open local data log file */ tmon_log = fopen(TMON_LOG_FILE, "w+"); if (!tmon_log) { syslog(LOG_ERR, "failed to open log file %s\n", TMON_LOG_FILE); return; } if (lstat(TMON_LOG_FILE, &logstat) < 0) { syslog(LOG_ERR, "Unable to stat log file %s\n", TMON_LOG_FILE); fclose(tmon_log); tmon_log = NULL; return; } /* The log file must be a regular file owned by us */ if (S_ISLNK(logstat.st_mode)) { syslog(LOG_ERR, "Log file is a symlink. Will not log\n"); fclose(tmon_log); tmon_log = NULL; return; } if (logstat.st_uid != getuid()) { syslog(LOG_ERR, "We don't own the log file. Not logging\n"); fclose(tmon_log); tmon_log = NULL; return; } fprintf(tmon_log, "#----------- THERMAL SYSTEM CONFIG -------------\n"); for (i = 0; i < ptdata.nr_tz_sensor; i++) { char binding_str[33]; /* size of long + 1 */ int j; memset(binding_str, 0, sizeof(binding_str)); for (j = 0; j < 32; j++) binding_str[j] = (ptdata.tzi[i].cdev_binding & 1< 0) /* kill parent */ exit(EXIT_SUCCESS); /* disable TUI, it may not be necessary, but saves some resource */ disable_tui(); /* change the file mode mask */ umask(S_IWGRP | S_IWOTH); /* new SID for the daemon process */ sid = setsid(); if (sid < 0) exit(EXIT_FAILURE); /* change working directory */ if ((chdir("/")) < 0) exit(EXIT_FAILURE); sleep(10); close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); }