mirror of
https://github.com/sirpdboy/sirpdboy-package.git
synced 2025-01-05 10:27:11 +08:00
up cpulimit 0.3.2
This commit is contained in:
parent
6fd4d1c241
commit
91276a6f01
@ -1,9 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=cpulimit
|
||||
PKG_VERSION:=0.2
|
||||
PKG_RELEASE:=1
|
||||
#PKG_REV:=cabeb9947ccddd9a6e6ba14503e2a33063ac1b21
|
||||
PKG_VERSION:=0.3.2
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
#PKG_SOURCE_PROTO:=git
|
||||
#PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||
@ -16,8 +15,8 @@ include $(INCLUDE_DIR)/package.mk
|
||||
define Package/cpulimit
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=cpulimit
|
||||
URL:=https://github.com/opsengine/cpulimit.git
|
||||
TITLE:=CPU usage limiter
|
||||
URL:=https://github.com/denji/cpulimit
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
|
@ -1,9 +1,10 @@
|
||||
BINDIR ?= $(PREFIX)/bin
|
||||
BIN_TARGET = cpulimit
|
||||
CC ?= gcc
|
||||
CFLAGS ?= -O2 -Wall -g -D_GNU_SOURCE
|
||||
CC ?= gcc
|
||||
CFLAGS ?= -Os -Wall -g -D_GNU_SOURCE
|
||||
HELP2MAN := $(shell which help2man)
|
||||
LIBS = list.o process_iterator.o process_group.o
|
||||
MANDIR ?= $(PREFIX)/share/man/man1
|
||||
MAN_NAME := "CPU Utilization Limiter"
|
||||
MAN_SEC := 1
|
||||
MAN_SRC := $(shell git remote get-url origin)
|
||||
@ -20,14 +21,21 @@ endif
|
||||
|
||||
all:: $(TARGETS) $(LIBS)
|
||||
|
||||
static:
|
||||
$(MAKE) all CFLAGS="$(CFLAGS) --static"
|
||||
static: $(TARGETS) $(LIBS)
|
||||
$(MAKE) all CFLAGS="$(CFLAGS) --static" CC="musl-gcc"
|
||||
touch static
|
||||
|
||||
strip: $(BIN_TARGET)
|
||||
$(STRIP) $<
|
||||
touch strip
|
||||
|
||||
install: $(TARGETS)
|
||||
$(SUDO) install $^ $(BINDIR)
|
||||
$(SUDO) install -D $(BIN_TARGET) $(BINDIR)/$(BIN_TARGET)
|
||||
$(SUDO) install -D $(MAN_TARGET) $(MANDIR)/$(MAN_TARGET)
|
||||
touch install
|
||||
|
||||
static_install: static strip install
|
||||
touch static_install
|
||||
|
||||
$(BIN_TARGET): cpulimit.c $(LIBS)
|
||||
$(CC) -o cpulimit cpulimit.c $(LIBS) $(CFLAGS)
|
||||
@ -45,5 +53,5 @@ process_group.o: process_group.c process_group.h process_iterator.o list.o
|
||||
$(CC) -c process_group.c $(CFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f *~ *.o $(TARGETS)
|
||||
rm -f *~ *.o static strip install static_install $(TARGETS)
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
* This is a simple program to limit the cpu usage of a process
|
||||
* If you modify this code, send me a copy please
|
||||
*
|
||||
* Get the latest version at: http://github.com/opsengine/cpulimit
|
||||
* Get the latest version at: http://github.com/denji/cpulimit
|
||||
*
|
||||
*/
|
||||
|
||||
@ -38,8 +38,11 @@
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
/* This breaks under musl and isn't necessary under glibc
|
||||
#ifndef __sun__
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
*/
|
||||
#include <sys/resource.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
@ -67,14 +70,9 @@
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
//control time slot in microseconds
|
||||
//each slot is splitted in a working slice and a sleeping slice
|
||||
//TODO: make it adaptive, based on the actual system load
|
||||
#define TIME_SLOT 100000
|
||||
|
||||
#define MAX_PRIORITY -10
|
||||
|
||||
#define VERSION "0.3"
|
||||
#define VERSION "0.3.2"
|
||||
|
||||
/* GLOBAL VARIABLES */
|
||||
|
||||
@ -121,6 +119,7 @@ static void print_usage(FILE *stream, int exit_code) {
|
||||
fprintf(stream, "Usage: %s [OPTIONS...] TARGET\n", program_name);
|
||||
fprintf(stream, " OPTIONS\n");
|
||||
fprintf(stream, " -l, --limit=N percentage of cpu allowed from 0 to %d (required)\n", 100*NCPU);
|
||||
fprintf(stream, " -c, --chunk-size=N enforce CPU limit in N microsecond chunks\n");
|
||||
fprintf(stream, " -v, --verbose show control statistics\n");
|
||||
fprintf(stream, " -V, --version show program version number\n");
|
||||
fprintf(stream, " -z, --lazy exit if there is no target process, or if it dies\n");
|
||||
@ -193,7 +192,7 @@ int get_pid_max() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void limit_process(pid_t pid, double limit, int include_children, float minimum_cpu_usage) {
|
||||
void limit_process(pid_t pid, double limit, int include_children, float minimum_cpu_usage, int chunk_size) {
|
||||
//slice of the slot in which the process is allowed to run
|
||||
struct timespec twork;
|
||||
//slice of the slot in which the process is stopped
|
||||
@ -258,13 +257,13 @@ void limit_process(pid_t pid, double limit, int include_children, float minimum_
|
||||
//it's the 1st cycle, initialize workingrate
|
||||
pcpu = limit;
|
||||
workingrate = limit;
|
||||
twork.tv_nsec = TIME_SLOT * limit * 1000;
|
||||
twork.tv_nsec = chunk_size * limit * 1000;
|
||||
} else {
|
||||
//adjust workingrate
|
||||
workingrate = MIN(workingrate / pcpu * limit, 1);
|
||||
twork.tv_nsec = TIME_SLOT * 1000 * workingrate;
|
||||
twork.tv_nsec = chunk_size * 1000 * workingrate;
|
||||
}
|
||||
tsleep.tv_nsec = TIME_SLOT * 1000 - twork.tv_nsec;
|
||||
tsleep.tv_nsec = chunk_size * 1000 - twork.tv_nsec;
|
||||
|
||||
if (verbose) {
|
||||
if (c%200==0) {
|
||||
@ -339,6 +338,7 @@ int main(int argc, char **argv) {
|
||||
pid_t pid = 0;
|
||||
float minimum_cpu_usage=0;
|
||||
int include_children = 0;
|
||||
int chunk_size = 100000;
|
||||
|
||||
//get program name
|
||||
#ifdef __sun__
|
||||
@ -356,14 +356,15 @@ int main(int argc, char **argv) {
|
||||
int next_option;
|
||||
int option_index = 0;
|
||||
//A string listing valid short options letters
|
||||
const char *short_options = "+p:e:l:vVzim:h";
|
||||
const char *short_options = "+p:e:l:c:vVzim:h";
|
||||
//An array describing valid long options
|
||||
const struct option long_options[] = {
|
||||
{ "pid", required_argument, NULL, 'p' },
|
||||
{ "exe", required_argument, NULL, 'e' },
|
||||
{ "limit", required_argument, NULL, 'l' },
|
||||
{ "chunk-size", required_argument, NULL, 'c' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "lazy", no_argument, NULL, 'z' },
|
||||
{ "include-children", no_argument, NULL, 'i' },
|
||||
{ "minimum-limited-cpu", no_argument, NULL, 'm' },
|
||||
@ -386,12 +387,15 @@ int main(int argc, char **argv) {
|
||||
perclimit = atoi(optarg);
|
||||
limit_ok = 1;
|
||||
break;
|
||||
case 'c':
|
||||
chunk_size = atoi(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
case 'V':
|
||||
print_version(stdout, 0);
|
||||
break;
|
||||
case 'V':
|
||||
print_version(stdout, 0);
|
||||
break;
|
||||
case 'z':
|
||||
lazy = 1;
|
||||
break;
|
||||
@ -435,6 +439,12 @@ int main(int argc, char **argv) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (0 > chunk_size || chunk_size > 1000000) {
|
||||
fprintf(stderr,"Error: chunk size must be in the range 0-1000000\n");
|
||||
print_usage(stderr, 1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int command_mode = optind < argc;
|
||||
if (exe_ok + pid_ok + command_mode == 0) {
|
||||
fprintf(stderr,"Error: You must specify one target process, either by name, pid, or command line\n");
|
||||
@ -513,7 +523,7 @@ int main(int argc, char **argv) {
|
||||
if (verbose) {
|
||||
printf("Limiting process %d\n",child);
|
||||
}
|
||||
limit_process(child, limit, include_children, minimum_cpu_usage);
|
||||
limit_process(child, limit, include_children, minimum_cpu_usage, chunk_size);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
@ -548,7 +558,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
printf("Process %d found\n", pid);
|
||||
//control
|
||||
limit_process(pid, limit, include_children, minimum_cpu_usage);
|
||||
limit_process(pid, limit, include_children, minimum_cpu_usage, chunk_size);
|
||||
}
|
||||
if (lazy) {
|
||||
break;
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __sun__
|
||||
#include <libgen.h>
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
#include "process_iterator.h"
|
||||
|
@ -23,9 +23,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef __sun__
|
||||
#include <procfs.h>
|
||||
#include <procfs.h>
|
||||
#elif !defined __APPLE__
|
||||
#include <sys/procfs.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/procfs.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include "process_iterator.h"
|
||||
@ -46,7 +47,7 @@
|
||||
|
||||
#elif defined __sun__
|
||||
|
||||
#include "process_iterator_solaris.c"
|
||||
#include "process_iterator_solaris.c"
|
||||
|
||||
#else
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Copyright (C) 2016 by Jim Mason <jmason at ibinx dot com>
|
||||
*
|
||||
* Adapted from process_iterator_linux.c
|
||||
* Copyright (C) 2005-2012, by: Angelo Marletta <angelo dot marletta at gmail dot com>
|
||||
* Copyright (C) 2005-2012, by: Angelo Marletta <angelo dot marletta at gmail dot com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -22,97 +22,114 @@
|
||||
*/
|
||||
|
||||
int init_process_iterator(struct process_iterator *it, struct process_filter *filter) {
|
||||
// open a directory stream to /proc directory
|
||||
if (!(it->dip = opendir("/proc"))) {
|
||||
perror("opendir");
|
||||
return -1;
|
||||
}
|
||||
it->filter = filter;
|
||||
return 0;
|
||||
// open a directory stream to /proc directory
|
||||
if (!(it->dip = opendir("/proc"))) {
|
||||
perror("opendir");
|
||||
return -1;
|
||||
}
|
||||
it->filter = filter;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_process_info(pid_t pid, struct process *p) {
|
||||
psinfo_t psinfo;
|
||||
char statfile[32];
|
||||
psinfo_t psinfo;
|
||||
char statfile[32];
|
||||
|
||||
p->pid = pid;
|
||||
sprintf(statfile, "/proc/%ld/psinfo", (long)pid);
|
||||
FILE *fd = fopen(statfile, "r");
|
||||
if (!fd) return -1;
|
||||
if (!fread(&psinfo, sizeof(psinfo), 1, fd)) {
|
||||
fclose(fd);
|
||||
return -1;
|
||||
}
|
||||
fclose(fd);
|
||||
p->pid = pid;
|
||||
sprintf(statfile, "/proc/%ld/psinfo", (long)pid);
|
||||
FILE *fd = fopen(statfile, "r");
|
||||
if (!fd) {
|
||||
return -1;
|
||||
}
|
||||
if (!fread(&psinfo, sizeof(psinfo), 1, fd)) {
|
||||
fclose(fd);
|
||||
return -1;
|
||||
}
|
||||
fclose(fd);
|
||||
|
||||
p->ppid = psinfo.pr_ppid;
|
||||
p->cputime = psinfo.pr_time.tv_sec * 1.0e03 + psinfo.pr_time.tv_nsec / 1.0e06;
|
||||
p->starttime = psinfo.pr_start.tv_sec * 1.0e03 + psinfo.pr_start.tv_nsec / 1.0e06;
|
||||
strcpy(p->command, psinfo.pr_psargs);
|
||||
p->ppid = psinfo.pr_ppid;
|
||||
p->cputime = psinfo.pr_time.tv_sec * 1.0e03 + psinfo.pr_time.tv_nsec / 1.0e06;
|
||||
p->starttime = psinfo.pr_start.tv_sec * 1.0e03 + psinfo.pr_start.tv_nsec / 1.0e06;
|
||||
strcpy(p->command, psinfo.pr_psargs);
|
||||
|
||||
return 0;
|
||||
/**
|
||||
* per proc(4):
|
||||
*
|
||||
* If the process is a zombie, pr_nlwp, pr_nzomb, and
|
||||
* pr_lwp.pr_lwpid are zero and the other fields of pr_lwp
|
||||
* are undefined
|
||||
*
|
||||
* In this case, we'll return -1 to the caller
|
||||
*/
|
||||
return psinfo.pr_nlwp?0:-1;
|
||||
}
|
||||
|
||||
static pid_t getppid_of(pid_t pid) {
|
||||
psinfo_t psinfo;
|
||||
char statfile[32];
|
||||
psinfo_t psinfo;
|
||||
char statfile[32];
|
||||
|
||||
sprintf(statfile, "/proc/%ld/psinfo", (long)pid);
|
||||
FILE *fd = fopen(statfile, "r");
|
||||
if (!fd) return -1;
|
||||
if (!fread(&psinfo, sizeof(psinfo), 1, fd)) {
|
||||
fclose(fd);
|
||||
return -1;
|
||||
}
|
||||
fclose(fd);
|
||||
sprintf(statfile, "/proc/%ld/psinfo", (long)pid);
|
||||
FILE *fd = fopen(statfile, "r");
|
||||
if (!fd) {
|
||||
return -1;
|
||||
}
|
||||
if (!fread(&psinfo, sizeof(psinfo), 1, fd)) {
|
||||
fclose(fd);
|
||||
return -1;
|
||||
}
|
||||
fclose(fd);
|
||||
|
||||
return psinfo.pr_ppid;
|
||||
return psinfo.pr_ppid;
|
||||
}
|
||||
|
||||
static int is_child_of(pid_t child_pid, pid_t parent_pid) {
|
||||
int ppid = child_pid;
|
||||
while(ppid > 1 && ppid != parent_pid)
|
||||
ppid = getppid_of(ppid);
|
||||
return ppid == parent_pid;
|
||||
int ppid = child_pid;
|
||||
while (ppid > 1 && ppid != parent_pid) {
|
||||
ppid = getppid_of(ppid);
|
||||
}
|
||||
return ppid == parent_pid;
|
||||
}
|
||||
|
||||
int get_next_process(struct process_iterator *it, struct process *p) {
|
||||
if (!it->dip) {
|
||||
// end of processes
|
||||
return -1;
|
||||
}
|
||||
if (!it->dip) {
|
||||
// end of processes
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (it->filter->pid != 0 && !it->filter->include_children) {
|
||||
int ret = read_process_info(it->filter->pid, p);
|
||||
closedir(it->dip);
|
||||
it->dip = NULL;
|
||||
return ret;
|
||||
}
|
||||
if (it->filter->pid != 0 && !it->filter->include_children) {
|
||||
int ret = read_process_info(it->filter->pid, p);
|
||||
closedir(it->dip);
|
||||
it->dip = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// read in from /proc and seek for process dirs
|
||||
struct dirent *dit;
|
||||
while ((dit = readdir(it->dip))) {
|
||||
p->pid = atoi(dit->d_name);
|
||||
if (it->filter->pid != 0 && it->filter->pid != p->pid && !is_child_of(p->pid, it->filter->pid)) continue;
|
||||
read_process_info(p->pid, p);
|
||||
break;
|
||||
}
|
||||
// read in from /proc and seek for process dirs
|
||||
struct dirent *dit;
|
||||
while ((dit = readdir(it->dip))) {
|
||||
p->pid = atoi(dit->d_name);
|
||||
if (it->filter->pid != 0 && it->filter->pid != p->pid && !is_child_of(p->pid, it->filter->pid)) {
|
||||
continue;
|
||||
}
|
||||
if (!read_process_info(p->pid, p)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dit) {
|
||||
// end of processes
|
||||
closedir(it->dip);
|
||||
it->dip = NULL;
|
||||
return -1;
|
||||
}
|
||||
if (!dit) {
|
||||
// end of processes
|
||||
closedir(it->dip);
|
||||
it->dip = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int close_process_iterator(struct process_iterator *it) {
|
||||
if (it->dip && closedir(it->dip) == -1) {
|
||||
perror("closedir");
|
||||
return 1;
|
||||
}
|
||||
it->dip = NULL;
|
||||
return 0;
|
||||
if (it->dip && closedir(it->dip) == -1) {
|
||||
perror("closedir");
|
||||
return 1;
|
||||
}
|
||||
it->dip = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
@ -5,42 +5,11 @@
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-cpulimit
|
||||
PKG_VERSION=1.0
|
||||
PKG_RELEASE:=2
|
||||
LUCI_TITLE:=cpulimit configuration module
|
||||
LUCI_DEPENDS:=+cpulimit
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=luci
|
||||
CATEGORY:=LuCI
|
||||
SUBMENU:=3. Applications
|
||||
DEPENDS:=+cpulimit
|
||||
TITLE:=LuCI support for cpulimit
|
||||
PKGARCH:=all
|
||||
endef
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
#!/bin/sh
|
||||
rm -f /tmp/luci-indexcache /tmp/luci-modulecache
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/cpulimit
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/config $(1)/usr/lib/lua/luci
|
||||
$(CP) ./luasrc/* $(1)/usr/lib/lua/luci
|
||||
$(INSTALL_CONF) ./root/etc/config/cpulimit $(1)/etc/config
|
||||
$(INSTALL_BIN) ./root/etc/init.d/cpulimit $(1)/etc/init.d
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) ./root/usr/bin/cpulimit.sh $(1)/usr/bin
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
|
||||
po2lmo ./po/zh-cn/cpulimit.po $(1)/usr/lib/lua/luci/i18n/cpulimit.zh-cn.lmo
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
@ -18,7 +18,7 @@ end
|
||||
limit = s:option(Value, "limit", translate("limit"))
|
||||
limit.optional = false
|
||||
limit.rmempty = false
|
||||
limit.default="50"
|
||||
limit.default="30"
|
||||
limit:value("100","100%")
|
||||
limit:value("90","90%")
|
||||
limit:value("80","80%")
|
||||
|
13
luci-app-cpulimit/root/etc/uci-defaults/luci-app-cpulimit
Normal file
13
luci-app-cpulimit/root/etc/uci-defaults/luci-app-cpulimit
Normal file
@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@cpulimit[-1]
|
||||
add ucitrack cpulimit
|
||||
set ucitrack.@cpulimit[-1].init=cpulimit
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
/etc/init.d/cpulimit enable
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
@ -20,6 +20,8 @@ killall -9 cpulimit
|
||||
# do
|
||||
# killall cpulimit>/dev/null 2>&1
|
||||
# done
|
||||
|
||||
# pgrep -f cpulimit | xargs kill -9 >/dev/null 2>&1
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
|
Loading…
Reference in New Issue
Block a user