mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Initial s390-tools-2.0.0 import
This commit is based on the s390-tools-1.39.0 version. Changes on top of s390-tools-1.39.0: - Add MIT license to all source files - Add LICENSE file - Transform REAMDE to README.md (markdown) - Add AUTHORS.md file - Add CONTRIBUTING.md file - Move changelog from README to CHANGELOG.md file Reviewed-by: Stefan Haberland <sth@linux.vnet.ibm.com> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
This commit is contained in:
+157
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* cpuplugd - Linux for System z Hotplug Daemon
|
||||
*
|
||||
* /proc info functions
|
||||
*
|
||||
* Copyright IBM Corp. 2007, 2017
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "cpuplugd.h"
|
||||
|
||||
/*
|
||||
* Return current load average and runnable processes based on /proc/loadavg
|
||||
*
|
||||
* Example: 0.20 0.18 0.12 1/80 11206
|
||||
*
|
||||
* The first three columns measure CPU utilization of the last 1, 5,
|
||||
* and 15 minute periods.
|
||||
* The fourth column shows the number of currently running processes
|
||||
* and the total number of processes.
|
||||
* The last column displays the last process ID used.
|
||||
*/
|
||||
void get_loadavg_runnable(double *loadavg, double *runnable)
|
||||
{
|
||||
FILE *filp;
|
||||
double dummy;
|
||||
int rc;
|
||||
|
||||
filp = fopen("/proc/loadavg", "r");
|
||||
if (!filp)
|
||||
cpuplugd_exit("cannot open kernel loadaverage "
|
||||
"statistics: %s\n", strerror(errno));
|
||||
rc = fscanf(filp, "%lf %lf %lf %lf/", loadavg, &dummy, &dummy,
|
||||
runnable);
|
||||
if (rc != 4)
|
||||
cpuplugd_exit("cannot parse kernel loadaverage "
|
||||
"statistics: %s\n", strerror(errno));
|
||||
fclose(filp);
|
||||
return;
|
||||
}
|
||||
|
||||
void proc_cpu_read(char *procinfo)
|
||||
{
|
||||
FILE *filp;
|
||||
unsigned int rc, onumcpus;
|
||||
unsigned long user, nice, system, idle, iowait, irq, softirq, steal,
|
||||
guest, guest_nice, total_ticks;
|
||||
double loadavg, runnable;
|
||||
|
||||
guest = guest_nice = 0; /* set to 0 if not present in kernel */
|
||||
filp = fopen("/proc/stat", "r");
|
||||
if (!filp)
|
||||
cpuplugd_exit("/proc/stat open failed: %s\n", strerror(errno));
|
||||
rc = fscanf(filp, "cpu %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", &user,
|
||||
&nice, &system, &idle, &iowait, &irq, &softirq, &steal,
|
||||
&guest, &guest_nice);
|
||||
|
||||
get_loadavg_runnable(&loadavg, &runnable);
|
||||
onumcpus = get_num_online_cpus();
|
||||
total_ticks = user + nice + system + idle + iowait + irq + softirq +
|
||||
steal + guest + guest_nice;
|
||||
|
||||
rc = snprintf(procinfo, cpustat_size, "onumcpus %d\nloadavg %f\n"
|
||||
"runnable_proc %f\nuser %ld\nnice %ld\nsystem %ld\n"
|
||||
"idle %ld\niowait %ld\nirq %ld\nsoftirq %ld\nsteal %ld\n"
|
||||
"guest %ld\nguest_nice %ld\ntotal_ticks %ld\n",
|
||||
onumcpus, loadavg, runnable, user, nice, system, idle,
|
||||
iowait, irq, softirq, steal, guest, guest_nice,
|
||||
total_ticks);
|
||||
if (rc >= cpustat_size)
|
||||
cpuplugd_exit("cpustat buffer too small: need %d, have %ld "
|
||||
"(bytes)\n", rc, cpustat_size);
|
||||
fclose(filp);
|
||||
return;
|
||||
}
|
||||
|
||||
void proc_read(char *procinfo, char *path, unsigned long size)
|
||||
{
|
||||
size_t bytes_read;
|
||||
FILE *filp;
|
||||
|
||||
filp = fopen(path, "r");
|
||||
if (!filp)
|
||||
cpuplugd_exit("%s open failed: %s\n", path, strerror(errno));
|
||||
|
||||
bytes_read = fread(procinfo, 1, size, filp);
|
||||
if (bytes_read == 0)
|
||||
cpuplugd_exit("%s read failed\n", path);
|
||||
if (bytes_read == size)
|
||||
cpuplugd_exit("procinfo buffer too small for %s\n", path);
|
||||
|
||||
procinfo[bytes_read] = '\0';
|
||||
fclose(filp);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long proc_read_size(char *path)
|
||||
{
|
||||
FILE *filp;
|
||||
char buf[PROCINFO_LINE];
|
||||
char *linep, *linep_offset;
|
||||
unsigned long size;
|
||||
|
||||
filp = fopen(path, "r");
|
||||
if (!filp)
|
||||
cpuplugd_exit("%s open failed: %s\n", path, strerror(errno));
|
||||
|
||||
size = 0;
|
||||
while ((linep = fgets(buf, sizeof(buf), filp))) {
|
||||
if (!(linep_offset = strchr(linep, '\n')))
|
||||
cpuplugd_exit("buf too small for line\n");
|
||||
size = size + linep_offset - linep + 1;
|
||||
}
|
||||
fclose(filp);
|
||||
return size;
|
||||
}
|
||||
|
||||
double get_proc_value(char *procinfo, char *name, char separator)
|
||||
{
|
||||
char buf[PROCINFO_LINE];
|
||||
char *proc_offset;
|
||||
unsigned long proc_length, name_length;
|
||||
double value;
|
||||
int found;
|
||||
|
||||
value = -1;
|
||||
found = 0;
|
||||
name_length = strlen(name);
|
||||
while ((proc_offset = strchr(procinfo, separator))) {
|
||||
proc_length = proc_offset - procinfo;
|
||||
/*
|
||||
* proc_read_size() made sure that proc_length < PROCINFO_LINE
|
||||
*/
|
||||
memcpy(buf, procinfo, proc_length);
|
||||
buf[proc_length] = '\0';
|
||||
procinfo = proc_offset + 1;
|
||||
if (strncmp(buf, name, MAX(proc_length, name_length)) == 0) {
|
||||
errno = 0;
|
||||
value = strtod(procinfo, NULL);
|
||||
if (errno)
|
||||
cpuplugd_exit("strtod failed\n");
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
proc_offset = strchr(procinfo, '\n');
|
||||
procinfo = proc_offset + 1;
|
||||
}
|
||||
if (!found)
|
||||
cpuplugd_exit("Symbol %s not found, check your config file\n",
|
||||
name);
|
||||
return value;
|
||||
}
|
||||
Reference in New Issue
Block a user