root/tools/laptop/dslm/dslm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_powermode
  2. state_name
  3. myctime
  4. measure
  5. ender
  6. usage
  7. main

   1 /*
   2  * dslm.c
   3  * Simple Disk Sleep Monitor
   4  *  by Bartek Kania
   5  * Licensed under the GPL
   6  */
   7 #include <unistd.h>
   8 #include <stdlib.h>
   9 #include <stdio.h>
  10 #include <fcntl.h>
  11 #include <errno.h>
  12 #include <time.h>
  13 #include <string.h>
  14 #include <signal.h>
  15 #include <sys/ioctl.h>
  16 #include <linux/hdreg.h>
  17 
  18 #ifdef DEBUG
  19 #define D(x) x
  20 #else
  21 #define D(x)
  22 #endif
  23 
  24 int endit = 0;
  25 
  26 /* Check if the disk is in powersave-mode
  27  * Most of the code is stolen from hdparm.
  28  * 1 = active, 0 = standby/sleep, -1 = unknown */
  29 static int check_powermode(int fd)
  30 {
  31     unsigned char args[4] = {WIN_CHECKPOWERMODE1,0,0,0};
  32     int state;
  33 
  34     if (ioctl(fd, HDIO_DRIVE_CMD, &args)
  35         && (args[0] = WIN_CHECKPOWERMODE2) /* try again with 0x98 */
  36         && ioctl(fd, HDIO_DRIVE_CMD, &args)) {
  37         if (errno != EIO || args[0] != 0 || args[1] != 0) {
  38             state = -1; /* "unknown"; */
  39         } else
  40             state = 0; /* "sleeping"; */
  41     } else {
  42         state = (args[2] == 255) ? 1 : 0;
  43     }
  44     D(printf(" drive state is:  %d\n", state));
  45 
  46     return state;
  47 }
  48 
  49 static char *state_name(int i)
  50 {
  51     if (i == -1) return "unknown";
  52     if (i == 0) return "sleeping";
  53     if (i == 1) return "active";
  54 
  55     return "internal error";
  56 }
  57 
  58 static char *myctime(time_t time)
  59 {
  60     char *ts = ctime(&time);
  61     ts[strlen(ts) - 1] = 0;
  62 
  63     return ts;
  64 }
  65 
  66 static void measure(int fd)
  67 {
  68     time_t start_time;
  69     int last_state;
  70     time_t last_time;
  71     int curr_state;
  72     time_t curr_time = 0;
  73     time_t time_diff;
  74     time_t active_time = 0;
  75     time_t sleep_time = 0;
  76     time_t unknown_time = 0;
  77     time_t total_time = 0;
  78     int changes = 0;
  79     float tmp;
  80 
  81     printf("Starting measurements\n");
  82 
  83     last_state = check_powermode(fd);
  84     start_time = last_time = time(0);
  85     printf("  System is in state %s\n\n", state_name(last_state));
  86 
  87     while(!endit) {
  88         sleep(1);
  89         curr_state = check_powermode(fd);
  90 
  91         if (curr_state != last_state || endit) {
  92             changes++;
  93             curr_time = time(0);
  94             time_diff = curr_time - last_time;
  95 
  96             if (last_state == 1) active_time += time_diff;
  97             else if (last_state == 0) sleep_time += time_diff;
  98             else unknown_time += time_diff;
  99 
 100             last_state = curr_state;
 101             last_time = curr_time;
 102 
 103             printf("%s: State-change to %s\n", myctime(curr_time),
 104                    state_name(curr_state));
 105         }
 106     }
 107     changes--; /* Compensate for SIGINT */
 108 
 109     total_time = time(0) - start_time;
 110     printf("\nTotal running time:  %lus\n", curr_time - start_time);
 111     printf(" State changed %d times\n", changes);
 112 
 113     tmp = (float)sleep_time / (float)total_time * 100;
 114     printf(" Time in sleep state:   %lus (%.2f%%)\n", sleep_time, tmp);
 115     tmp = (float)active_time / (float)total_time * 100;
 116     printf(" Time in active state:  %lus (%.2f%%)\n", active_time, tmp);
 117     tmp = (float)unknown_time / (float)total_time * 100;
 118     printf(" Time in unknown state: %lus (%.2f%%)\n", unknown_time, tmp);
 119 }
 120 
 121 static void ender(int s)
 122 {
 123     endit = 1;
 124 }
 125 
 126 static void usage(void)
 127 {
 128     puts("usage: dslm [-w <time>] <disk>");
 129     exit(0);
 130 }
 131 
 132 int main(int argc, char **argv)
 133 {
 134     int fd;
 135     char *disk = 0;
 136     int settle_time = 60;
 137 
 138     /* Parse the simple command-line */
 139     if (argc == 2)
 140         disk = argv[1];
 141     else if (argc == 4) {
 142         settle_time = atoi(argv[2]);
 143         disk = argv[3];
 144     } else
 145         usage();
 146 
 147     if (!(fd = open(disk, O_RDONLY|O_NONBLOCK))) {
 148         printf("Can't open %s, because: %s\n", disk, strerror(errno));
 149         exit(-1);
 150     }
 151 
 152     if (settle_time) {
 153         printf("Waiting %d seconds for the system to settle down to "
 154                "'normal'\n", settle_time);
 155         sleep(settle_time);
 156     } else
 157         puts("Not waiting for system to settle down");
 158 
 159     signal(SIGINT, ender);
 160 
 161     measure(fd);
 162 
 163     close(fd);
 164 
 165     return 0;
 166 }

/* [<][>][^][v][top][bottom][index][help] */