cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dslm.c (3682B)


      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
     24int 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 */
     29static 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
     49static 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
     58static char *myctime(time_t time)
     59{
     60    char *ts = ctime(&time);
     61    ts[strlen(ts) - 1] = 0;
     62
     63    return ts;
     64}
     65
     66static 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
    121static void ender(int s)
    122{
    123    endit = 1;
    124}
    125
    126static void usage(void)
    127{
    128    puts("usage: dslm [-w <time>] <disk>");
    129    exit(0);
    130}
    131
    132int 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}