diff --git a/Utilities/Tools/CMakeLists.txt b/Utilities/Tools/CMakeLists.txt index 55048623739b9..04002ad85dae7 100644 --- a/Utilities/Tools/CMakeLists.txt +++ b/Utilities/Tools/CMakeLists.txt @@ -9,9 +9,7 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -add_subdirectory(cpulimit) install(PROGRAMS monitor-mem.sh DESTINATION share/scripts/) -install(PROGRAMS jobutils.sh DESTINATION share/scripts/) install(PROGRAMS jobutils2.sh DESTINATION share/scripts/) install(PROGRAMS grid_submit.sh DESTINATION share/scripts/) diff --git a/Utilities/Tools/cpulimit/.clang-format b/Utilities/Tools/cpulimit/.clang-format deleted file mode 100644 index a43d914ec38dd..0000000000000 --- a/Utilities/Tools/cpulimit/.clang-format +++ /dev/null @@ -1,2 +0,0 @@ -DisableFormat: true -SortIncludes: false \ No newline at end of file diff --git a/Utilities/Tools/cpulimit/CMakeLists.txt b/Utilities/Tools/cpulimit/CMakeLists.txt deleted file mode 100644 index f1109c65fdb69..0000000000000 --- a/Utilities/Tools/cpulimit/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2019-2020 CERN and copyright holders of ALICE O2. -# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -# All rights not expressly granted are reserved. -# -# This software is distributed under the terms of the GNU General Public -# License v3 (GPL Version 3), copied verbatim in the file "COPYING". -# -# In applying this license CERN does not waive the privileges and immunities -# granted to it by virtue of its status as an Intergovernmental Organization -# or submit itself to any jurisdiction. - -add_executable(cpulimit - cpulimit.c list.c process_group.c process_iterator.c) -target_compile_definitions(cpulimit PUBLIC _GNU_SOURCE) - -install(TARGETS cpulimit DESTINATION share/scripts/) diff --git a/Utilities/Tools/cpulimit/README b/Utilities/Tools/cpulimit/README deleted file mode 100644 index 20f543f9491ee..0000000000000 --- a/Utilities/Tools/cpulimit/README +++ /dev/null @@ -1,2 +0,0 @@ -These sources have been copied from https://github.com/opsengine/cpulimit -commit f4d2682804931e. \ No newline at end of file diff --git a/Utilities/Tools/cpulimit/cpulimit.c b/Utilities/Tools/cpulimit/cpulimit.c deleted file mode 100644 index e35a1565253e7..0000000000000 --- a/Utilities/Tools/cpulimit/cpulimit.c +++ /dev/null @@ -1,529 +0,0 @@ -/** - * - * cpulimit - a CPU limiter for Linux - * - * Copyright (C) 2005-2012, by: Angelo Marletta - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - ************************************************************** - * - * 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 - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__APPLE__) -#include -#endif -#include -#include -#include - -#if defined(__APPLE__) || defined(__FREEBSD__) -#include -#endif - -#include "process_group.h" -#include "list.h" - -#ifdef HAVE_SYS_SYSINFO_H -#include -#endif - -//some useful macro -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif -#ifndef MAX -#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 - -/* GLOBAL VARIABLES */ - -//the "family" -struct process_group pgroup; -//pid of cpulimit -pid_t cpulimit_pid; -//name of this program (maybe cpulimit...) -char *program_name; - -//number of cpu -int NCPU; - -/* CONFIGURATION VARIABLES */ - -//verbose mode -int verbose = 0; -//lazy mode (exits if there is no process) -int lazy = 0; - -//SIGINT and SIGTERM signal handler -static void quit(int sig) -{ - //let all the processes continue if stopped - struct list_node *node = NULL; - if (pgroup.proclist != NULL) - { - for (node = pgroup.proclist->first; node != NULL; node = node->next) { - struct process *p = (struct process*)(node->data); - kill(p->pid, SIGCONT); - } - close_process_group(&pgroup); - } - //fix ^C little problem - printf("\r"); - fflush(stdout); - exit(0); -} - -//return t1-t2 in microseconds (no overflow checks, so better watch out!) -static inline unsigned long timediff(const struct timeval *t1,const struct timeval *t2) -{ - return (t1->tv_sec - t2->tv_sec) * 1000000 + (t1->tv_usec - t2->tv_usec); -} - -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, " -v, --verbose show control statistics\n"); - fprintf(stream, " -z, --lazy exit if there is no target process, or if it dies\n"); - fprintf(stream, " -i, --include-children limit also the children processes\n"); - fprintf(stream, " -h, --help display this help and exit\n"); - fprintf(stream, " TARGET must be exactly one of these:\n"); - fprintf(stream, " -p, --pid=N pid of the process (implies -z)\n"); - fprintf(stream, " -e, --exe=FILE name of the executable program file or path name\n"); - fprintf(stream, " COMMAND [ARGS] run this command and limit it (implies -z)\n"); - fprintf(stream, "\nReport bugs to .\n"); - exit(exit_code); -} - -static void increase_priority() { - //find the best available nice value - int old_priority = getpriority(PRIO_PROCESS, 0); - int priority = old_priority; - while (setpriority(PRIO_PROCESS, 0, priority-1) == 0 && priority>MAX_PRIORITY) { - priority--; - } - if (priority != old_priority) { - if (verbose) { printf("Priority changed to %d\n", priority); } - } - else { - if (verbose) { printf("Warning: Cannot change priority. Run as root or renice for best results.\n"); } - } -} - -/* Get the number of CPUs */ -static int get_ncpu() { - int ncpu; -#ifdef _SC_NPROCESSORS_ONLN - ncpu = sysconf(_SC_NPROCESSORS_ONLN); -#elif defined __APPLE__ - int mib[2] = {CTL_HW, HW_NCPU}; - size_t len = sizeof(ncpu); - sysctl(mib, 2, &ncpu, &len, NULL, 0); -#elif defined _GNU_SOURCE - ncpu = get_nprocs(); -#else - ncpu = -1; -#endif - return ncpu; -} - -int get_pid_max() -{ -#ifdef __linux__ - //read /proc/sys/kernel/pid_max - static char buffer[1024]; - FILE *fd = fopen("/proc/sys/kernel/pid_max", "r"); - if (fd==NULL) { return -1; } - if (fgets(buffer, sizeof(buffer), fd)==NULL) { - fclose(fd); - return -1; - } - fclose(fd); - return atoi(buffer); -#elif defined __FreeBSD__ - return 99998; -#elif defined __APPLE__ - return 99998; -#endif -} - -void limit_process(pid_t pid, double limit, int include_children) -{ - //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 - struct timespec tsleep; - //when the last twork has started - struct timeval startwork; - //when the last twork has finished - struct timeval endwork; - //initialization - memset(&twork, 0, sizeof(struct timespec)); - memset(&tsleep, 0, sizeof(struct timespec)); - memset(&startwork, 0, sizeof(struct timeval)); - memset(&endwork, 0, sizeof(struct timeval)); - //last working time in microseconds - unsigned long workingtime = 0; - //generic list item - struct list_node *node; - //counter - int c = 0; - - //get a better priority - increase_priority(); - - //build the family - init_process_group(&pgroup, pid, include_children); - - if (verbose) { printf("Members in the process group owned by %d: %d\n", pgroup.target_pid, pgroup.proclist->count); } - - //rate at which we are keeping active the processes (range 0-1) - //1 means that the process are using all the twork slice - double workingrate = -1; - while(1) { - update_process_group(&pgroup); - - if (pgroup.proclist->count==0) { - if (verbose) { printf("No more processes.\n"); } - break; - } - - //total cpu actual usage (range 0-1) - //1 means that the processes are using 100% cpu - double pcpu = -1; - - //estimate how much the controlled processes are using the cpu in the working interval - for (node = pgroup.proclist->first; node != NULL; node = node->next) { - struct process *proc = (struct process*)(node->data); - if (proc->cpu_usage < 0) { - continue; - } - if (pcpu < 0) { pcpu = 0; } - pcpu += proc->cpu_usage; - } - - //adjust work and sleep time slices - if (pcpu < 0) { - //it's the 1st cycle, initialize workingrate - pcpu = limit; - workingrate = limit; - twork.tv_nsec = TIME_SLOT * limit * 1000; - } - else { - //adjust workingrate - workingrate = MIN(workingrate / pcpu * limit, 1); - twork.tv_nsec = TIME_SLOT * 1000 * workingrate; - } - tsleep.tv_nsec = TIME_SLOT * 1000 - twork.tv_nsec; - - if (verbose) { - if (c%200==0) { - printf("\n%%CPU\twork quantum\tsleep quantum\tactive rate\n"); - } - if (c%10==0 && c>0) { - printf("%0.2lf%%\t%6ld us\t%6ld us\t%0.2lf%%\n", pcpu*100, twork.tv_nsec/1000, tsleep.tv_nsec/1000, workingrate*100); - } - } - - //resume processes - node = pgroup.proclist->first; - while (node != NULL) - { - struct list_node *next_node = node->next; - struct process *proc = (struct process*)(node->data); - if (kill(proc->pid,SIGCONT) != 0) { - //process is dead, remove it from family - if (verbose) { fprintf(stderr, "SIGCONT failed. Process %d dead!\n", proc->pid); } - //remove process from group - delete_node(pgroup.proclist, node); - remove_process(&pgroup, proc->pid); - } - node = next_node; - } - - //now processes are free to run (same working slice for all) - gettimeofday(&startwork, NULL); - nanosleep(&twork, NULL); - gettimeofday(&endwork, NULL); - workingtime = timediff(&endwork, &startwork); - - long delay = workingtime - twork.tv_nsec/1000; - if (c>0 && delay>10000) { - //delay is too much! signal to user? - //fprintf(stderr, "%d %ld us\n", c, delay); - } - - if (tsleep.tv_nsec>0) { - //stop processes only if tsleep>0 - node = pgroup.proclist->first; - while (node != NULL) - { - struct list_node *next_node = node->next; - struct process *proc = (struct process*)(node->data); - if (kill(proc->pid,SIGSTOP)!=0) { - //process is dead, remove it from family - if (verbose) { fprintf(stderr, "SIGSTOP failed. Process %d dead!\n", proc->pid); } - //remove process from group - delete_node(pgroup.proclist, node); - remove_process(&pgroup, proc->pid); - } - node = next_node; - } - //now the processes are sleeping - nanosleep(&tsleep,NULL); - } - c++; - } - close_process_group(&pgroup); -} - -int main(int argc, char **argv) { - //argument variables - const char *exe = NULL; - int perclimit = 0; - int exe_ok = 0; - int pid_ok = 0; - int limit_ok = 0; - pid_t pid = 0; - int include_children = 0; - - //get program name - char *p = (char*)strrchr(argv[0], '/'); - program_name = p==NULL ? argv[0] : (p+1); - //get current pid - cpulimit_pid = getpid(); - //get cpu count - NCPU = get_ncpu(); - - //parse arguments - int next_option; - int option_index = 0; - //A string listing valid short options letters - const char* short_options = "+p:e:l:vzih"; - //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' }, - { "verbose", no_argument, NULL, 'v' }, - { "lazy", no_argument, NULL, 'z' }, - { "include-children", no_argument, NULL, 'i' }, - { "help", no_argument, NULL, 'h' }, - { 0, 0, 0, 0 } - }; - - do { - next_option = getopt_long(argc, argv, short_options,long_options, &option_index); - switch(next_option) { - case 'p': - pid = atoi(optarg); - pid_ok = 1; - break; - case 'e': - exe = optarg; - exe_ok = 1; - break; - case 'l': - perclimit = atoi(optarg); - limit_ok = 1; - break; - case 'v': - verbose = 1; - break; - case 'z': - lazy = 1; - break; - case 'i': - include_children = 1; - break; - case 'h': - print_usage(stdout, 1); - break; - case '?': - print_usage(stderr, 1); - break; - case -1: - break; - default: - abort(); - } - } while(next_option != -1); - - if (pid_ok && (pid <= 1 || pid >= get_pid_max())) { - fprintf(stderr,"Error: Invalid value for argument PID\n"); - print_usage(stderr, 1); - exit(1); - } - if (pid != 0) { - lazy = 1; - } - - if (!limit_ok) { - fprintf(stderr,"Error: You must specify a cpu limit percentage\n"); - print_usage(stderr, 1); - exit(1); - } - double limit = perclimit / 100.0; - if (limit<0 || limit >NCPU) { - fprintf(stderr,"Error: limit must be in the range 0-%d00\n", NCPU); - 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"); - print_usage(stderr, 1); - exit(1); - } - - if (exe_ok + pid_ok + command_mode > 1) { - fprintf(stderr,"Error: You must specify exactly one target process, either by name, pid, or command line\n"); - print_usage(stderr, 1); - exit(1); - } - - //all arguments are ok! - signal(SIGINT, quit); - signal(SIGTERM, quit); - - //print the number of available cpu - if (verbose) { printf("%d cpu detected\n", NCPU); } - - if (command_mode) { - int i; - //executable file - const char *cmd = argv[optind]; - //command line arguments - char **cmd_args = (char**)malloc((argc-optind + 1) * sizeof(char*)); - if (cmd_args==NULL) { exit(2); } - for (i=0; i 0) { - //parent - int status_process; - int status_limiter; - waitpid(child, &status_process, 0); - waitpid(limiter, &status_limiter, 0); - if (WIFEXITED(status_process)) { - if (verbose) { printf("Process %d terminated with exit status %d\n", child, (int)WEXITSTATUS(status_process)); } - exit(WEXITSTATUS(status_process)); - } - printf("Process %d terminated abnormally\n", child); - exit(status_process); - } - else { - //limiter code - if (verbose) { printf("Limiting process %d\n",child); } - limit_process(child, limit, include_children); - exit(0); - } - } - } - - while(1) { - //look for the target process..or wait for it - pid_t ret = 0; - if (pid_ok) { - //search by pid - ret = find_process_by_pid(pid); - if (ret == 0) { - printf("No process found\n"); - } - else if (ret < 0) { - printf("Process found but you aren't allowed to control it\n"); - } - } - else { - //search by file or path name - ret = find_process_by_name(exe); - if (ret == 0) { - printf("No process found\n"); - } - else if (ret < 0) { - printf("Process found but you aren't allowed to control it\n"); - } - else { - pid = ret; - } - } - if (ret > 0) { - if (ret == cpulimit_pid) { - printf("Target process %d is cpulimit itself! Aborting because it makes no sense\n", ret); - exit(1); - } - printf("Process %d found\n", pid); - //control - limit_process(pid, limit, include_children); - } - if (lazy) { break; } - sleep(2); - }; - - exit(0); -} diff --git a/Utilities/Tools/cpulimit/list.c b/Utilities/Tools/cpulimit/list.c deleted file mode 100644 index 2ac36708d4a08..0000000000000 --- a/Utilities/Tools/cpulimit/list.c +++ /dev/null @@ -1,148 +0,0 @@ -/** - * - * cpulimit - a CPU limiter for Linux - * - * Copyright (C) 2005-2012, by: Angelo Marletta - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include "list.h" - -#define EMPTYLIST NULL - -void init_list(struct list *l,int keysize) { - l->first=l->last=NULL; - l->keysize=keysize; - l->count=0; -} - -struct list_node *add_elem(struct list *l,void *elem) { - struct list_node *newnode=(struct list_node*)malloc(sizeof(struct list_node)); - newnode->data=elem; - newnode->previous=l->last; - newnode->next=NULL; - if (l->count==0) { - l->first=l->last=newnode; - } - else { - l->last->next=newnode; - l->last=newnode; - } - l->count++; - return newnode; -} - -void delete_node(struct list *l,struct list_node *node) { - if (l->count==1) { - l->first=l->last=NULL; - } - else if (node==l->first) { - node->next->previous=NULL; - l->first=node->next; - } - else if (node==l->last) { - node->previous->next=NULL; - l->last=node->previous; - } - else { - node->previous->next=node->next; - node->next->previous=node->previous; - } - l->count--; - free(node); -} - -void destroy_node(struct list *l,struct list_node *node) { - free(node->data); - node->data=NULL; - delete_node(l,node); -} - -int is_empty_list(struct list *l) { - return (l->count==0?TRUE:FALSE); -} - -int get_list_count(struct list *l) { - return l->count; -} - -void *first_elem(struct list *l) { - return l->first->data; -} - -struct list_node *first_node(struct list *l) { - return l->first; -} - -void *last_elem(struct list *l) { - return l->last->data; -} - -struct list_node *last_node(struct list *l) { - return l->last; -} - -struct list_node *xlocate_node(struct list *l,void *elem,int offset,int length) { - struct list_node *tmp; - tmp=l->first; - while(tmp!=NULL) { - if(!memcmp((char*)tmp->data+offset,elem,length==0?l->keysize:length)) { return (tmp); } - tmp=tmp->next; - } - return EMPTYLIST; -} - -struct list_node *locate_node(struct list *l,void *elem) { - return(xlocate_node(l,elem,0,0)); -} - -void *xlocate_elem(struct list *l,void *elem,int offset,int length) { - struct list_node *node=xlocate_node(l,elem,offset,length); - return(node==NULL?NULL:node->data); -} - -void *locate_elem(struct list *l,void *elem) { - return(xlocate_elem(l,elem,0,0)); -} - -void clear_list(struct list *l) { - while(l->first!=EMPTYLIST) { - struct list_node *tmp; - tmp=l->first; - l->first=l->first->next; - free(tmp); - tmp=NULL; - } - l->last=EMPTYLIST; - l->count=0; -} - -void destroy_list(struct list *l) { - while(l->first!=EMPTYLIST) { - struct list_node *tmp; - tmp=l->first; - l->first=l->first->next; - free(tmp->data); - tmp->data=NULL; - free(tmp); - tmp=NULL; - } - l->last=EMPTYLIST; - l->count=0; -} diff --git a/Utilities/Tools/cpulimit/list.h b/Utilities/Tools/cpulimit/list.h deleted file mode 100644 index 0b43a2b39c0f3..0000000000000 --- a/Utilities/Tools/cpulimit/list.h +++ /dev/null @@ -1,138 +0,0 @@ -/** - * - * cpulimit - a CPU limiter for Linux - * - * Copyright (C) 2005-2012, by: Angelo Marletta - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __LIST__ - -#define __LIST__ - -#ifndef TRUE - #define TRUE 1 - #define FALSE 0 -#endif - -struct list_node { - //pointer to the content of the node - void *data; - //pointer to previous node - struct list_node *previous; - //pointer to next node - struct list_node *next; -}; - -struct list { - //first node - struct list_node *first; - //last node - struct list_node *last; - //size of the search key in bytes - int keysize; - //element count - int count; -}; - -/* - * Initialize a list, with a specified key size - */ -void init_list(struct list *l,int keysize); - -/* - * Add a new element at the end of the list - * return the pointer to the new node - */ -struct list_node *add_elem(struct list *l,void *elem); - -/* - * Delete a node - */ -void delete_node(struct list *l,struct list_node *node); - -/* - * Delete a node from the list, even the content pointed by it - * Use only when the content is a dynamically allocated pointer - */ -void destroy_node(struct list *l,struct list_node *node); - -/* - * Check whether a list is empty or not - */ -int is_empty_list(struct list *l); - -/* - * Return the element count of the list - */ -int get_list_count(struct list *l); - -/* - * Return the first element (content of the node) from the list - */ -void *first_elem(struct list *l); - -/* - * Return the first node from the list - */ -struct list_node *first_node(struct list *l); - -/* - * Return the last element (content of the node) from the list - */ -void *last_elem(struct list *l); - -/* - * Return the last node from the list - */ -struct list_node *last_node(struct list *l); - -/* - * Search an element of the list by content - * the comparison is done from the specified offset and for a specified length - * if offset=0, the comparison starts from the address pointed by data - * if length=0, default keysize is used for length - * if the element is found, return the node address - * else return NULL - */ -struct list_node *xlocate_node(struct list *l,void *elem,int offset,int length); - -/* - * The same of xlocate_node(), but return the content of the node - */ -void *xlocate_elem(struct list *l,void *elem,int offset,int length); - -/* - * The same of calling xlocate_node() with offset=0 and length=0 - */ -struct list_node *locate_node(struct list *l,void *elem); - -/* - * The same of locate_node, but return the content of the node - */ -void *locate_elem(struct list *l,void *elem); - -/* - * Delete all the elements in the list - */ -void clear_list(struct list *l); - -/* - * Delete every element in the list, and free the memory pointed by all the node data - */ -void destroy_list(struct list *l); - -#endif diff --git a/Utilities/Tools/cpulimit/process_group.c b/Utilities/Tools/cpulimit/process_group.c deleted file mode 100644 index c5343e32bd9a1..0000000000000 --- a/Utilities/Tools/cpulimit/process_group.c +++ /dev/null @@ -1,219 +0,0 @@ -/** - * - * cpulimit - a CPU limiter for Linux - * - * Copyright (C) 2005-2012, by: Angelo Marletta - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#if defined(__APPLE__) || defined(__FREEBSD__) -#include -#endif - -#include -#include -#include -#include -#include - -#include - -#include "process_iterator.h" -#include "process_group.h" -#include "list.h" - -// look for a process by pid -// search_pid : pid of the wanted process -// return: pid of the found process, if successful -// negative pid, if the process does not exist or if the signal fails -int find_process_by_pid(pid_t pid) -{ - return (kill(pid,0)==0) ? pid : -pid; -} - -// look for a process with a given name -// process: the name of the wanted process. it can be an absolute path name to the executable file -// or just the file name -// return: pid of the found process, if it is found -// 0, if it's not found -// negative pid, if it is found but it's not possible to control it -int find_process_by_name(const char *process_name) -{ - //pid of the target process - pid_t pid = -1; - - //process iterator - struct process_iterator it; - struct process proc; - struct process_filter filter; - filter.pid = 0; - filter.include_children = 0; - init_process_iterator(&it, &filter); - while (get_next_process(&it, &proc) != -1) - { - //process found - if (strncmp(basename(proc.command), process_name, strlen(process_name))==0 && kill(pid,SIGCONT)==0) { - //process is ok! - pid = proc.pid; - break; - } - } - if (close_process_iterator(&it) != 0) { - exit(1); - } - if (pid >= 0) { - //ok, the process was found - return pid; - } - else { - //process not found - return 0; - } -} - -int init_process_group(struct process_group *pgroup, int target_pid, int include_children) -{ - //hashtable initialization - memset(&pgroup->proctable, 0, sizeof(pgroup->proctable)); - pgroup->target_pid = target_pid; - pgroup->include_children = include_children; - pgroup->proclist = (struct list*)malloc(sizeof(struct list)); - init_list(pgroup->proclist, 4); - memset(&pgroup->last_update, 0, sizeof(pgroup->last_update)); - update_process_group(pgroup); - return 0; -} - -int close_process_group(struct process_group *pgroup) -{ - int i; - int size = sizeof(pgroup->proctable) / sizeof(struct process*); - for (i=0; iproctable[i] != NULL) { - //free() history for each process - destroy_list(pgroup->proctable[i]); - free(pgroup->proctable[i]); - pgroup->proctable[i] = NULL; - } - } - clear_list(pgroup->proclist); - free(pgroup->proclist); - pgroup->proclist = NULL; - return 0; -} - -void remove_terminated_processes(struct process_group *pgroup) -{ - //TODO -} - -//return t1-t2 in microseconds (no overflow checks, so better watch out!) -static inline unsigned long timediff(const struct timeval *t1,const struct timeval *t2) -{ - return (t1->tv_sec - t2->tv_sec) * 1000000 + (t1->tv_usec - t2->tv_usec); -} - -//parameter in range 0-1 -#define ALFA 0.08 -#define MIN_DT 20 - -void update_process_group(struct process_group *pgroup) -{ - struct process_iterator it; - struct process tmp_process; - struct process_filter filter; - struct timeval now; - gettimeofday(&now, NULL); - //time elapsed from previous sample (in ms) - long dt = timediff(&now, &pgroup->last_update) / 1000; - filter.pid = pgroup->target_pid; - filter.include_children = pgroup->include_children; - init_process_iterator(&it, &filter); - clear_list(pgroup->proclist); - init_list(pgroup->proclist, 4); - - while (get_next_process(&it, &tmp_process) != -1) - { -// struct timeval t; -// gettimeofday(&t, NULL); -// printf("T=%ld.%ld PID=%d PPID=%d START=%d CPUTIME=%d\n", t.tv_sec, t.tv_usec, tmp_process.pid, tmp_process.ppid, tmp_process.starttime, tmp_process.cputime); - int hashkey = pid_hashfn(tmp_process.pid); - if (pgroup->proctable[hashkey] == NULL) - { - //empty bucket - pgroup->proctable[hashkey] = malloc(sizeof(struct list)); - struct process *new_process = malloc(sizeof(struct process)); - tmp_process.cpu_usage = -1; - memcpy(new_process, &tmp_process, sizeof(struct process)); - init_list(pgroup->proctable[hashkey], 4); - add_elem(pgroup->proctable[hashkey], new_process); - add_elem(pgroup->proclist, new_process); - } - else - { - //existing bucket - struct process *p = (struct process*)locate_elem(pgroup->proctable[hashkey], &tmp_process); - if (p == NULL) - { - //process is new. add it - struct process *new_process = malloc(sizeof(struct process)); - tmp_process.cpu_usage = -1; - memcpy(new_process, &tmp_process, sizeof(struct process)); - add_elem(pgroup->proctable[hashkey], new_process); - add_elem(pgroup->proclist, new_process); - } - else - { - assert(tmp_process.pid == p->pid); - assert(tmp_process.starttime == p->starttime); - add_elem(pgroup->proclist, p); - if (dt < MIN_DT) { - continue; - } - //process exists. update CPU usage - double sample = 1.0 * (tmp_process.cputime - p->cputime) / dt; - if (p->cpu_usage == -1) { - //initialization - p->cpu_usage = sample; - } - else { - //usage adjustment - p->cpu_usage = (1.0-ALFA) * p->cpu_usage + ALFA * sample; - } - p->cputime = tmp_process.cputime; - } - } - } - close_process_iterator(&it); - if (dt < MIN_DT) { - return; - } - pgroup->last_update = now; -} - -int remove_process(struct process_group *pgroup, int pid) -{ - int hashkey = pid_hashfn(pid); - if (pgroup->proctable[hashkey] == NULL) { - return 1; //nothing to delete - } - struct list_node *node = (struct list_node*)locate_node(pgroup->proctable[hashkey], &pid); - if (node == NULL) { - return 2; - } - delete_node(pgroup->proctable[hashkey], node); - return 0; -} diff --git a/Utilities/Tools/cpulimit/process_group.h b/Utilities/Tools/cpulimit/process_group.h deleted file mode 100644 index 5a5b581554a80..0000000000000 --- a/Utilities/Tools/cpulimit/process_group.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * - * cpulimit - a CPU limiter for Linux - * - * Copyright (C) 2005-2012, by: Angelo Marletta - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __PROCESS_GROUP_H - -#define __PROCESS_GROUP_H - -#include "process_iterator.h" - -#include "list.h" - -#define PIDHASH_SZ 1024 -#define pid_hashfn(x) ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1)) - -struct process_group -{ - //hashtable with all the processes (array of struct list of struct process) - struct list *proctable[PIDHASH_SZ]; - struct list *proclist; - pid_t target_pid; - int include_children; - struct timeval last_update; -}; - -int init_process_group(struct process_group *pgroup, int target_pid, int include_children); - -void update_process_group(struct process_group *pgroup); - -int close_process_group(struct process_group *pgroup); - -int find_process_by_pid(pid_t pid); - -int find_process_by_name(const char *process_name); - -int remove_process(struct process_group *pgroup, int pid); - -#endif diff --git a/Utilities/Tools/cpulimit/process_iterator.c b/Utilities/Tools/cpulimit/process_iterator.c deleted file mode 100644 index 8b4019d237f2b..0000000000000 --- a/Utilities/Tools/cpulimit/process_iterator.c +++ /dev/null @@ -1,49 +0,0 @@ -/** - * - * cpulimit - a CPU limiter for Linux - * - * Copyright (C) 2005-2012, by: Angelo Marletta - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#ifndef __APPLE__ -#include -#endif -#include -#include "process_iterator.h" - -//See this link to port to other systems: http://www.steve.org.uk/Reference/Unix/faq_8.html#SEC85 - -#ifdef __linux__ - -#include "process_iterator_linux.c" - -#elif defined __FreeBSD__ - -#include "process_iterator_freebsd.c" - -#elif defined __APPLE__ - -#include "process_iterator_apple.c" - -#else - -#error Platform not supported - -#endif diff --git a/Utilities/Tools/cpulimit/process_iterator.h b/Utilities/Tools/cpulimit/process_iterator.h deleted file mode 100644 index 70520b68a6e88..0000000000000 --- a/Utilities/Tools/cpulimit/process_iterator.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * - * cpulimit - a CPU limiter for Linux - * - * Copyright (C) 2005-2012, by: Angelo Marletta - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __PROCESS_ITERATOR_H - -#define __PROCESS_ITERATOR_H - -#include -#include -#include - -//USER_HZ detection, from openssl code -#ifndef HZ -# if defined(_SC_CLK_TCK) \ - && (!defined(OPENSSL_SYS_VMS) || __CTRL_VER >= 70000000) -# define HZ ((double)sysconf(_SC_CLK_TCK)) -# else -# ifndef CLK_TCK -# ifndef _BSD_CLK_TCK_ /* FreeBSD hack */ -# define HZ 100.0 -# else /* _BSD_CLK_TCK_ */ -# define HZ ((double)_BSD_CLK_TCK_) -# endif -# else /* CLK_TCK */ -# define HZ ((double)CLK_TCK) -# endif -# endif -#endif - -#ifdef __FreeBSD__ -#include -#endif - -// process descriptor -struct process { - //pid of the process - pid_t pid; - //ppid of the process - pid_t ppid; - //start time (unix timestamp) - int starttime; - //cputime used by the process (in milliseconds) - int cputime; - //actual cpu usage estimation (value in range 0-1) - double cpu_usage; - //absolute path of the executable file - char command[PATH_MAX+1]; -}; - -struct process_filter { - int pid; - int include_children; - char program_name[PATH_MAX+1]; -}; - -struct process_iterator { -#ifdef __linux__ - DIR *dip; - int boot_time; -#elif defined __FreeBSD__ - kvm_t *kd; - struct kinfo_proc *procs; - int count; - int i; -#elif defined __APPLE__ - int i; - int count; - int *pidlist; -#endif - struct process_filter *filter; -}; - -int init_process_iterator(struct process_iterator *i, struct process_filter *filter); - -int get_next_process(struct process_iterator *i, struct process *p); - -int close_process_iterator(struct process_iterator *i); - -#endif diff --git a/Utilities/Tools/cpulimit/process_iterator_apple.c b/Utilities/Tools/cpulimit/process_iterator_apple.c deleted file mode 100644 index b878ed8c9a946..0000000000000 --- a/Utilities/Tools/cpulimit/process_iterator_apple.c +++ /dev/null @@ -1,148 +0,0 @@ -/** - * - * cpulimit - a CPU limiter for Linux - * - * Copyright (C) 2005-2012, by: Angelo Marletta - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Author: Simon Sigurdhsson - * - */ - -#include -#include -#include - -int unique_nonzero_ints(int* arr_in, int len_in, int* arr_out) { - int* source = arr_in; - if (arr_out == NULL) return -1; - if (arr_in == arr_out) { - source = malloc(sizeof(int)*len_in); - memcpy(source, arr_in, sizeof(int)*len_in); - memset(arr_out, -1, sizeof(int)*len_in); - } - int len_out = 0; - int i, j; - for (i=0; ii = 0; - /* Find out how much to allocate for it->pidlist */ - if ((it->count = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0)) <= 0) { - fprintf(stderr, "proc_listpids: %s\n", strerror(errno)); - return -1; - } - /* Allocate and populate it->pidlist */ - if ((it->pidlist = (int *)malloc((it->count)*sizeof(int))) == NULL) { - fprintf(stderr, "malloc: %s\n", strerror(errno)); - } - if ((it->count = proc_listpids(PROC_ALL_PIDS, 0, it->pidlist, it->count)) <= 0) { - fprintf(stderr, "proc_listpids: %s\n", strerror(errno)); - return -1; - } - it->count = unique_nonzero_ints(it->pidlist, it->count, it->pidlist); - it->filter = filter; - return 0; -} - -static int pti2proc(struct proc_taskallinfo *ti, struct process *process) { - int bytes; - process->pid = ti->pbsd.pbi_pid; - process->ppid = ti->pbsd.pbi_ppid; - process->starttime = ti->pbsd.pbi_start_tvsec; - process->cputime = (ti->ptinfo.pti_total_user + ti->ptinfo.pti_total_system) / 1000000; - bytes = strlen(ti->pbsd.pbi_comm); - memcpy(process->command, ti->pbsd.pbi_comm, (bytes < PATH_MAX ? bytes : PATH_MAX) + 1); - return 0; -} - -static int get_process_pti(pid_t pid, struct proc_taskallinfo *ti) { - int bytes; - bytes = proc_pidinfo(pid, PROC_PIDTASKALLINFO, 0, ti, sizeof(*ti)); - if (bytes <= 0) { - if (!(errno & (EPERM | ESRCH))) { - fprintf(stderr, "proc_pidinfo: %s\n", strerror(errno)); - } - return -1; - } else if (bytes < sizeof(ti)) { - fprintf(stderr, "proc_pidinfo: too few bytes; expected %ld, got %d\n", sizeof(ti), bytes); - return -1; - } - return 0; -} - -int get_next_process(struct process_iterator *it, struct process *p) { - if (it->i == it->count) return -1; - if (it->filter->pid != 0 && !it->filter->include_children) { - struct proc_taskallinfo ti; - if (get_process_pti(it->filter->pid, &ti) != 0) { - it->i = it->count = 0; - return -1; - } - it->i = it->count = 1; - return pti2proc(&ti, p); - } - while (it->i < it->count) { - struct proc_taskallinfo ti; - if (get_process_pti(it->pidlist[it->i], &ti) != 0) { - it->i++; - continue; - } - if (ti.pbsd.pbi_flags & PROC_FLAG_SYSTEM) { - it->i++; - continue; - } - if (it->filter->pid != 0 && it->filter->include_children) { - pti2proc(&ti, p); - it->i++; - if (p->pid != it->pidlist[it->i - 1]) // I don't know why this can happen - continue; - if (p->pid != it->filter->pid && p->ppid != it->filter->pid) - continue; - return 0; - } - else if (it->filter->pid == 0) - { - pti2proc(&ti, p); - it->i++; - return 0; - } - } - return -1; -} - -int close_process_iterator(struct process_iterator *it) { - free(it->pidlist); - it->pidlist = NULL; - it->filter = NULL; - it->count = 0; - it->i = 0; - return 0; -} diff --git a/Utilities/Tools/cpulimit/process_iterator_freebsd.c b/Utilities/Tools/cpulimit/process_iterator_freebsd.c deleted file mode 100644 index a6381123e1251..0000000000000 --- a/Utilities/Tools/cpulimit/process_iterator_freebsd.c +++ /dev/null @@ -1,119 +0,0 @@ -/** - * - * cpulimit - a CPU limiter for Linux - * - * Copyright (C) 2005-2012, by: Angelo Marletta - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include - -int init_process_iterator(struct process_iterator *it, struct process_filter *filter) { - char errbuf[_POSIX2_LINE_MAX]; - it->i = 0; - /* Open the kvm interface, get a descriptor */ - if ((it->kd = kvm_openfiles(NULL, _PATH_DEVNULL, NULL, O_RDONLY, errbuf)) == NULL) { - fprintf(stderr, "kvm_open: %s\n", errbuf); - return -1; - } - /* Get the list of processes. */ - if ((it->procs = kvm_getprocs(it->kd, KERN_PROC_PROC, 0, &it->count)) == NULL) { - kvm_close(it->kd); -// fprintf(stderr, "kvm_getprocs: %s\n", kvm_geterr(it->kd)); - return -1; - } - it->filter = filter; - return 0; -} - -static int kproc2proc(kvm_t *kd, struct kinfo_proc *kproc, struct process *proc) -{ - proc->pid = kproc->ki_pid; - proc->ppid = kproc->ki_ppid; - proc->cputime = kproc->ki_runtime / 1000; - proc->starttime = kproc->ki_start.tv_sec; - char **args = kvm_getargv(kd, kproc, sizeof(proc->command)); - if (args == NULL) return -1; - memcpy(proc->command, args[0], strlen(args[0]) + 1); - return 0; -} - -static int get_single_process(kvm_t *kd, pid_t pid, struct process *process) -{ - int count; - struct kinfo_proc *kproc = kvm_getprocs(kd, KERN_PROC_PID, pid, &count); - if (count == 0 || kproc == NULL) - { -// fprintf(stderr, "kvm_getprocs: %s\n", kvm_geterr(kd)); - return -1; - } - kproc2proc(kd, kproc, process); - return 0; -} - -int get_next_process(struct process_iterator *it, struct process *p) { - if (it->i == it->count) - { - return -1; - } - if (it->filter->pid != 0 && !it->filter->include_children) - { - if (get_single_process(it->kd, it->filter->pid, p) != 0) - { - it->i = it->count = 0; - return -1; - } - it->i = it->count = 1; - return 0; - } - while (it->i < it->count) - { - struct kinfo_proc *kproc = &(it->procs[it->i]); - if (kproc->ki_flag & P_SYSTEM) - { - // skip system processes - it->i++; - continue; - } - if (it->filter->pid != 0 && it->filter->include_children) - { - kproc2proc(it->kd, kproc, p); - it->i++; - if (p->pid != it->filter->pid && p->ppid != it->filter->pid) - continue; - return 0; - } - else if (it->filter->pid == 0) - { - kproc2proc(it->kd, kproc, p); - it->i++; - return 0; - } - } - return -1; -} - -int close_process_iterator(struct process_iterator *it) { - if (kvm_close(it->kd) == -1) { - fprintf(stderr, "kvm_getprocs: %s\n", kvm_geterr(it->kd)); - return -1; - } - return 0; -} - diff --git a/Utilities/Tools/cpulimit/process_iterator_linux.c b/Utilities/Tools/cpulimit/process_iterator_linux.c deleted file mode 100644 index d8d2cab3571da..0000000000000 --- a/Utilities/Tools/cpulimit/process_iterator_linux.c +++ /dev/null @@ -1,198 +0,0 @@ -/** - * - * cpulimit - a CPU limiter for Linux - * - * Copyright (C) 2005-2012, by: Angelo Marletta - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -static int get_boot_time() -{ - int uptime = 0; - FILE *fp = fopen ("/proc/uptime", "r"); - if (fp != NULL) - { - char buf[BUFSIZ]; - char *b = fgets(buf, BUFSIZ, fp); - if (b == buf) - { - char *end_ptr; - double upsecs = strtod(buf, &end_ptr); - uptime = (int)upsecs; - } - fclose (fp); - } - time_t now = time(NULL); - return now - uptime; -} - -static int check_proc() -{ - struct statfs mnt; - if (statfs("/proc", &mnt) < 0) { - return 0; - } - if (mnt.f_type!=0x9fa0) { - return 0; - } - return 1; -} - -int init_process_iterator(struct process_iterator *it, struct process_filter *filter) -{ - if (!check_proc()) { - fprintf(stderr, "procfs is not mounted!\nAborting\n"); - exit(-2); - } - //open a directory stream to /proc directory - if ((it->dip = opendir("/proc")) == NULL) - { - perror("opendir"); - return -1; - } - it->filter = filter; - it->boot_time = get_boot_time(); - return 0; -} - -static int read_process_info(pid_t pid, struct process *p) -{ - static char buffer[1024]; - static char statfile[32]; - static char exefile[1024]; - p->pid = pid; - //read stat file - sprintf(statfile, "/proc/%d/stat", p->pid); - FILE *fd = fopen(statfile, "r"); - if (fd==NULL) { - return -1; - } - if (fgets(buffer, sizeof(buffer), fd)==NULL) { - fclose(fd); - return -1; - } - fclose(fd); - char *token = strtok(buffer, " "); - int i; - for (i=0; i<3; i++) { - token = strtok(NULL, " "); - } - p->ppid = atoi(token); - for (i=0; i<10; i++) { - token = strtok(NULL, " "); - } - p->cputime = atoi(token) * 1000 / HZ; - token = strtok(NULL, " "); - p->cputime += atoi(token) * 1000 / HZ; - for (i=0; i<7; i++) { - token = strtok(NULL, " "); - } - p->starttime = atoi(token) / sysconf(_SC_CLK_TCK); - //read command line - sprintf(exefile,"/proc/%d/cmdline", p->pid); - fd = fopen(exefile, "r"); - if (fgets(buffer, sizeof(buffer), fd)==NULL) { - fclose(fd); - return -1; - } - fclose(fd); - strcpy(p->command, buffer); - return 0; -} - -static pid_t getppid_of(pid_t pid) -{ - char statfile[20]; - char buffer[1024]; - sprintf(statfile, "/proc/%d/stat", pid); - FILE *fd = fopen(statfile, "r"); - if (fd==NULL) { - return -1; - } - if (fgets(buffer, sizeof(buffer), fd)==NULL) { - fclose(fd); - return -1; - } - fclose(fd); - char *token = strtok(buffer, " "); - int i; - for (i=0; i<3; i++) { - token = strtok(NULL, " "); - } - return atoi(token); -} - -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 get_next_process(struct process_iterator *it, struct process *p) -{ - if (it->dip == NULL) - { - //end of processes - return -1; - } - if (it->filter->pid != 0 && !it->filter->include_children) - { - int ret = read_process_info(it->filter->pid, p); - //p->starttime += it->boot_time; - closedir(it->dip); - it->dip = NULL; - if (ret != 0) { - return -1; - } - return 0; - } - struct dirent *dit = NULL; - //read in from /proc and seek for process dirs - while ((dit = readdir(it->dip)) != NULL) { - if(strtok(dit->d_name, "0123456789") != NULL) { - continue; - } - 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); - //p->starttime += it->boot_time; - break; - } - if (dit == NULL) - { - //end of processes - closedir(it->dip); - it->dip = NULL; - return -1; - } - return 0; -} - -int close_process_iterator(struct process_iterator *it) { - if (it->dip != NULL && closedir(it->dip) == -1) { - perror("closedir"); - return 1; - } - it->dip = NULL; - return 0; -} diff --git a/prodtests/full_system_test.sh b/prodtests/full_system_test.sh index 24215276fd463..6898433b731df 100755 --- a/prodtests/full_system_test.sh +++ b/prodtests/full_system_test.sh @@ -29,7 +29,7 @@ fi # include jobutils, which notably brings # --> the taskwrapper as a simple control and monitoring tool -# (look inside the jobutils.sh file for documentation) +# (look inside the jobutils2.sh file for documentation) # --> utilities to query CPU count . ${O2_ROOT}/share/scripts/jobutils2.sh diff --git a/prodtests/full_system_test_ci_extra_tests.sh b/prodtests/full_system_test_ci_extra_tests.sh index 2d8a165f647fd..d0c4f23ef93c6 100755 --- a/prodtests/full_system_test_ci_extra_tests.sh +++ b/prodtests/full_system_test_ci_extra_tests.sh @@ -3,7 +3,7 @@ # Set of extra tests which may run after the full_system_test.sh # Particularly, they use the files generated by the full_system_test.sh # -. ${O2_ROOT}/share/scripts/jobutils.sh +. ${O2_ROOT}/share/scripts/jobutils2.sh if [ "0$O2_ROOT" == "0" ]; then eval "`alienv shell-helper`" diff --git a/prodtests/full_system_test_pipeline.sh b/prodtests/full_system_test_pipeline.sh index 235a590953d8e..bb29ea263dae0 100755 --- a/prodtests/full_system_test_pipeline.sh +++ b/prodtests/full_system_test_pipeline.sh @@ -14,9 +14,9 @@ # include jobutils, which notably brings # --> the taskwrapper as a simple control and monitoring tool -# (look inside the jobutils.sh file for documentation) +# (look inside the jobutils2.sh file for documentation) # --> utilities to query CPU count -. ${O2_ROOT}/share/scripts/jobutils.sh +. ${O2_ROOT}/share/scripts/jobutils2.sh export NEvents=${NEvents:-10} #550 for full TF (the number of PbPb events) export NEventsQED=${NEventsQED:-1000} #35000 for full TF diff --git a/prodtests/sim_challenge.sh b/prodtests/sim_challenge.sh index 8c7cfb1a024b0..f83132b812b75 100755 --- a/prodtests/sim_challenge.sh +++ b/prodtests/sim_challenge.sh @@ -8,7 +8,7 @@ # and it is advised to use that one. Some documentation can be found here: https://aliceo2group.github.io/simulation/docs/o2dpgworkflow/ # ------------ LOAD UTILITY FUNCTIONS ---------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh +. ${O2_ROOT}/share/scripts/jobutils2.sh # ----------- START WITH ACTUAL SCRIPT --------------------------- diff --git a/run/SimExamples/SimAsService_biasing1/run.sh b/run/SimExamples/SimAsService_biasing1/run.sh index 3bf8f51890fec..e038541ff6035 100755 --- a/run/SimExamples/SimAsService_biasing1/run.sh +++ b/run/SimExamples/SimAsService_biasing1/run.sh @@ -83,11 +83,11 @@ o2-sim-client.py --pid ${SERVICE2_PID} --command "--stop 1" sleep 1 # just some tmp safety-net to make sure all processes are really gone -. ${O2_ROOT}/share/scripts/jobutils.sh +. ${O2_ROOT}/share/scripts/jobutils2.sh for p in $(childprocs ${SERVICE1_PID}); do kill -9 ${p} done -. ${O2_ROOT}/share/scripts/jobutils.sh +. ${O2_ROOT}/share/scripts/jobutils2.sh for p in $(childprocs ${SERVICE2_PID}); do kill -9 ${p} done