cregit-Linux how code gets into the kernel

Release 4.7 tools/laptop/freefall/freefall.c

/* Disk protection for HP/DELL machines.
 *
 * Copyright 2008 Eric Piel
 * Copyright 2009 Pavel Machek <pavel@ucw.cz>
 * Copyright 2012 Sonal Santan
 * Copyright 2014 Pali Rohár <pali.rohar@gmail.com>
 *
 * GPLv2.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <signal.h>
#include <sys/mman.h>
#include <sched.h>
#include <syslog.h>


static int noled;

static char unload_heads_path[64];

static char device_path[32];

static const char app_name[] = "FREE FALL";


static int set_unload_heads_path(char *device) { if (strlen(device) <= 5 || strncmp(device, "/dev/", 5) != 0) return -EINVAL; strncpy(device_path, device, sizeof(device_path) - 1); snprintf(unload_heads_path, sizeof(unload_heads_path) - 1, "/sys/block/%s/device/unload_heads", device+5); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
frans popfrans pop5376.81%125.00%
pali roharpali rohar1115.94%125.00%
pavel machekpavel machek34.35%125.00%
stefan weilstefan weil22.90%125.00%
Total69100.00%4100.00%


static int valid_disk(void) { int fd = open(unload_heads_path, O_RDONLY); if (fd < 0) { perror(unload_heads_path); return 0; } close(fd); return 1; }

Contributors

PersonTokensPropCommitsCommitProp
frans popfrans pop4197.62%150.00%
pali roharpali rohar12.38%150.00%
Total42100.00%2100.00%


static void write_int(char *path, int i) { char buf[1024]; int fd = open(path, O_RDWR); if (fd < 0) { perror("open"); exit(1); } sprintf(buf, "%d", i); if (write(fd, buf, strlen(buf)) != strlen(buf)) { perror("write"); exit(1); } close(fd); }

Contributors

PersonTokensPropCommitsCommitProp
pavel machekpavel machek9198.91%150.00%
pali roharpali rohar11.09%150.00%
Total92100.00%2100.00%


static void set_led(int on) { if (noled) return; write_int("/sys/class/leds/hp::hddprotect/brightness", on); }

Contributors

PersonTokensPropCommitsCommitProp
pavel machekpavel machek1571.43%150.00%
pali roharpali rohar628.57%150.00%
Total21100.00%2100.00%


static void protect(int seconds) { const char *str = (seconds == 0) ? "Unparked" : "Parked"; write_int(unload_heads_path, seconds*1000); syslog(LOG_INFO, "%s %s disk head\n", str, device_path); }

Contributors

PersonTokensPropCommitsCommitProp
pali roharpali rohar2761.36%133.33%
pavel machekpavel machek1636.36%133.33%
frans popfrans pop12.27%133.33%
Total44100.00%3100.00%


static int on_ac(void) { /* /sys/class/power_supply/AC0/online */ return 1; }

Contributors

PersonTokensPropCommitsCommitProp
pavel machekpavel machek758.33%150.00%
pali roharpali rohar541.67%150.00%
Total12100.00%2100.00%


static int lid_open(void) { /* /proc/acpi/button/lid/LID/state */ return 1; }

Contributors

PersonTokensPropCommitsCommitProp
pavel machekpavel machek758.33%150.00%
pali roharpali rohar541.67%150.00%
Total12100.00%2100.00%


static void ignore_me(int signum) { protect(0); set_led(0); }

Contributors

PersonTokensPropCommitsCommitProp
pavel machekpavel machek1684.21%150.00%
pali roharpali rohar315.79%150.00%
Total19100.00%2100.00%


int main(int argc, char **argv) { int fd, ret; struct stat st; struct sched_param param; if (argc == 1) ret = set_unload_heads_path("/dev/sda"); else if (argc == 2) ret = set_unload_heads_path(argv[1]); else ret = -EINVAL; if (ret || !valid_disk()) { fprintf(stderr, "usage: %s <device> (default: /dev/sda)\n", argv[0]); exit(1); } fd = open("/dev/freefall", O_RDONLY); if (fd < 0) { perror("/dev/freefall"); return EXIT_FAILURE; } if (stat("/sys/class/leds/hp::hddprotect/brightness", &st)) noled = 1; if (daemon(0, 0) != 0) { perror("daemon"); return EXIT_FAILURE; } openlog(app_name, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); param.sched_priority = sched_get_priority_max(SCHED_FIFO); sched_setscheduler(0, SCHED_FIFO, &param); mlockall(MCL_CURRENT|MCL_FUTURE); signal(SIGALRM, ignore_me); for (;;) { unsigned char count; ret = read(fd, &count, sizeof(count)); alarm(0); if ((ret == -1) && (errno == EINTR)) { /* Alarm expired, time to unpark the heads */ continue; } if (ret != sizeof(count)) { perror("read"); break; } protect(21); set_led(1); if (1 || on_ac() || lid_open()) alarm(2); else alarm(20); } closelog(); close(fd); return EXIT_SUCCESS; }

Contributors

PersonTokensPropCommitsCommitProp
pavel machekpavel machek15450.66%125.00%
frans popfrans pop6521.38%125.00%
pali roharpali rohar4815.79%125.00%
christian thaeterchristian thaeter3712.17%125.00%
Total304100.00%4100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
pavel machekpavel machek33949.78%233.33%
frans popfrans pop16624.38%116.67%
pali roharpali rohar13119.24%116.67%
christian thaeterchristian thaeter436.31%116.67%
stefan weilstefan weil20.29%116.67%
Total681100.00%6100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}