1 /******************************************************************************/ 2 /* */ 3 /* Copyright (c) International Business Machines Corp., 2007 */ 4 /* */ 5 /* This program is free software; you can redistribute it and/or modify */ 6 /* it under the terms of the GNU General Public License as published by */ 7 /* the Free Software Foundation; either version 2 of the License, or */ 8 /* (at your option) any later version. */ 9 /* */ 10 /* This program is distributed in the hope that it will be useful, */ 11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ 13 /* the GNU General Public License for more details. */ 14 /* */ 15 /* You should have received a copy of the GNU General Public License */ 16 /* along with this program; if not, write to the Free Software */ 17 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 18 /* */ 19 /******************************************************************************/ 20 21 /******************************************************************************/ 22 /* */ 23 /* File: libcontrollers.c */ 24 /* */ 25 /* Description: This file contains the definitions for the functions/apis */ 26 /* for the controllers library. This library is used by the */ 27 /* controllers testcases. */ 28 /* */ 29 /* Author: Sudhir Kumar skumar@linux.vnet.ibm.com */ 30 /* */ 31 /* History: */ 32 /* Created- 15/02/2008 -Sudhir Kumar <skumar@linux.vnet.ibm.com> */ 33 /* */ 34 /******************************************************************************/ 35 36 #include "libcontrollers.h" 37 38 char fullpath[PATH_MAX]; 39 int FLAG; 40 volatile int timer_expired = 0; 41 int retval; 42 unsigned int current_shares; 43 unsigned int total_shares; 44 unsigned int *shares_pointer; 45 struct dirent *dir_pointer; 46 47 /* 48 * Function: scan_shares_file() 49 * This function scans all the shares files under the mountpoint 50 * of the controller and returns the total added shares of all 51 * the groups (currently excludes default group) ?? 52 */ scan_shares_files(unsigned int * shares_pointer)53 int scan_shares_files(unsigned int *shares_pointer) 54 { 55 struct stat statbuffer; 56 DIR *dp; 57 char *path_pointer; 58 59 /* 60 * Check if we can get stat of the file 61 */ 62 if (lstat(fullpath, &statbuffer) < 0) { 63 error_function("Can not read stat for file ", fullpath); 64 return -1; 65 } 66 67 if (S_ISDIR(statbuffer.st_mode) == 0) { /* not a directory */ 68 /* 69 * We run all user tasks in the created groups and not default groups. So 70 * exclude the shares of default group. FLAG to ensure dir_pointer is non NULL 71 */ 72 if ((FLAG == 1) 73 && (strcmp(fullpath, "/dev/cpuctl/cpu.shares") != 0) 74 && (strcmp(dir_pointer->d_name, "cpu.shares") == 0)) { 75 *shares_pointer += read_shares_file(fullpath); 76 } 77 return 0; 78 } 79 80 /* 81 * Now it's a directory. let the path_pointer point to the end 82 * of fullpath to append new files names 83 */ 84 85 path_pointer = fullpath + strlen(fullpath); 86 *path_pointer++ = '/'; 87 *path_pointer = 0; 88 89 if ((dp = opendir(fullpath)) == NULL) { /* Error in opening directory */ 90 error_function("Can't open ", fullpath); 91 return -1; 92 } 93 /* 94 * search all groups recursively and get total shares 95 */ 96 97 while ((dir_pointer = readdir(dp)) != NULL) { /* Error in reading directory */ 98 if ((strcmp(dir_pointer->d_name, ".") == 0) 99 || (strcmp(dir_pointer->d_name, "..") == 0)) 100 continue; /* ignore current and parent directory */ 101 102 FLAG = 1; 103 strcpy(path_pointer, dir_pointer->d_name); /* append name to fullpath */ 104 105 if ((retval = scan_shares_files(shares_pointer)) != 0) 106 break; 107 } 108 109 /* 110 * This directory is searched fully. let us go back to parent directory again 111 */ 112 113 path_pointer[-1] = 0; 114 115 if (closedir(dp) < 0) { 116 error_function("Could not close dir ", fullpath); 117 return -1; 118 } 119 return 0; 120 } 121 122 /* 123 * Function: read_file () 124 * This function is written keeping in mind the support 125 * to read other files also if required in future. 126 * Each file under a group contains some diff parameter/s 127 */ 128 read_file(char * filepath,int action,unsigned int * value)129 int read_file(char *filepath, int action, unsigned int *value) 130 { 131 int num_line = 0; 132 FILE *fp; 133 int tmp; 134 size_t len; 135 char *target = NULL; 136 137 switch (action) { 138 case GET_SHARES: 139 tmp = read_shares_file(filepath); 140 if (tmp == -1) 141 return -1; 142 *value = (unsigned int)tmp; 143 break; 144 145 case GET_TASKS: 146 fp = fopen(filepath, "r"); 147 if (fp == NULL) { 148 error_function("Could not open file", filepath); 149 return -1; 150 } 151 while (getline(&target, &len, fp) != -1) 152 num_line++; 153 free(target); 154 *value = (unsigned int)num_line; 155 if (fclose(fp)) { 156 error_function("Could not close file", filepath); 157 return -1; 158 } 159 break; 160 161 default: 162 error_function("Wrong action type passed to fun read_file for ", 163 filepath); 164 return -1; 165 } 166 return 0; 167 } 168 169 /* 170 * Function: error_function() 171 * Prints error message and returns -1 172 */ 173 error_function(char * msg1,char * msg2)174 static inline void error_function(char *msg1, char *msg2) 175 { 176 fprintf(stdout, "ERROR: %s ", msg1); 177 fprintf(stdout, "%s\n", msg2); 178 } 179 180 /* Function: read_shares_file() 181 * Reads shares value from a given shares file and writes them to 182 * the given pointer location. Returns 0 if success 183 */ 184 read_shares_file(char * filepath)185 int read_shares_file(char *filepath) 186 { 187 FILE *fp; 188 unsigned int shares; 189 fp = fopen(filepath, "r"); 190 if (fp == NULL) { 191 error_function("Could not open file", filepath); 192 return -1; 193 } 194 fscanf(fp, "%u", &shares); 195 if (fclose(fp)) { 196 error_function("Could not close file", filepath); 197 return -1; 198 } 199 return shares; 200 } 201 202 /* Function: write_to_file() 203 * writes value to shares file or pid to tasks file 204 */ 205 write_to_file(char * file,const char * mode,unsigned int value)206 int write_to_file(char *file, const char *mode, unsigned int value) 207 { 208 FILE *fp; 209 fp = fopen(file, mode); 210 if (fp == NULL) { 211 error_function("in opening file for writing:", file); 212 return -1; 213 } 214 fprintf(fp, "%u\n", value); 215 fclose(fp); 216 return 0; 217 } 218 219 /* Function: signal_handler_alarm() 220 * signal handler for the new action 221 */ 222 signal_handler_alarm(int signal)223 void signal_handler_alarm(int signal) 224 { 225 timer_expired = 1; 226 } 227