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 (at) linux.vnet.ibm.com */ 30 /* */ 31 /* History: */ 32 /* Created- 15/02/2008 -Sudhir Kumar <skumar (at) linux.vnet.ibm.com> */ 33 /* */ 34 /******************************************************************************/ 35 36 #include "libcontrollers.h" 37 38 /* 39 * Function: scan_shares_file() 40 * This function scans all the shares files under the mountpoint 41 * of the controller and returns the total added shares of all 42 * the groups (currently excludes default group) ?? 43 */ 44 int scan_shares_files(unsigned int *shares_pointer) 45 { 46 struct stat statbuffer; 47 DIR *dp; 48 char *path_pointer; 49 50 /* 51 * Check if we can get stat of the file 52 */ 53 if (lstat(fullpath, &statbuffer) < 0) { 54 error_function("Can not read stat for file ", fullpath); 55 return -1; 56 } 57 58 if (S_ISDIR(statbuffer.st_mode) == 0) { /* not a directory */ 59 /* 60 * We run all user tasks in the created groups and not default groups. So 61 * exclude the shares of default group. FLAG to ensure dir_pointer is non NULL 62 */ 63 if ((FLAG == 1) 64 && (strcmp(fullpath, "/dev/cpuctl/cpu.shares") != 0) 65 && (strcmp(dir_pointer->d_name, "cpu.shares") == 0)) { 66 *shares_pointer += read_shares_file(fullpath); 67 } 68 return 0; 69 } 70 71 /* 72 * Now it's a directory. let the path_pointer point to the end 73 * of fullpath to append new files names 74 */ 75 76 path_pointer = fullpath + strlen(fullpath); 77 *path_pointer++ = '/'; 78 *path_pointer = 0; 79 80 if ((dp = opendir(fullpath)) == NULL) { /* Error in opening directory */ 81 error_function("Can't open ", fullpath); 82 return -1; 83 } 84 /* 85 * search all groups recursively and get total shares 86 */ 87 88 while ((dir_pointer = readdir(dp)) != NULL) { /* Error in reading directory */ 89 if ((strcmp(dir_pointer->d_name, ".") == 0) 90 || (strcmp(dir_pointer->d_name, "..") == 0)) 91 continue; /* ignore current and parent directory */ 92 93 FLAG = 1; 94 strcpy(path_pointer, dir_pointer->d_name); /* append name to fullpath */ 95 96 if ((retval = scan_shares_files(shares_pointer)) != 0) 97 break; 98 } 99 100 /* 101 * This directory is searched fully. let us go back to parent directory again 102 */ 103 104 path_pointer[-1] = 0; 105 106 if (closedir(dp) < 0) { 107 error_function("Could not close dir ", fullpath); 108 return -1; 109 } 110 return 0; 111 } 112 113 /* 114 * Function: read_file () 115 * This function is written keeping in mind the support 116 * to read other files also if required in future. 117 * Each file under a group contains some diff parameter/s 118 */ 119 120 int read_file(char *filepath, int action, unsigned int *value) 121 { 122 int num_line = 0; 123 FILE *fp; 124 int tmp; 125 switch (action) { 126 case GET_SHARES: 127 tmp = read_shares_file(filepath); 128 if (tmp == -1) 129 return -1; 130 *value = (unsigned int)tmp; 131 break; 132 133 case GET_TASKS: 134 fp = fopen(filepath, "r"); 135 if (fp == NULL) { 136 error_function("Could not open file", filepath); 137 return -1; 138 } 139 while (fgets(target, LINE_MAX, fp) != NULL) 140 num_line++; 141 *value = (unsigned int)num_line; 142 if (fclose(fp)) { 143 error_function("Could not close file", filepath); 144 return -1; 145 } 146 break; 147 148 default: 149 error_function("Wrong action type passed to fun read_file for ", 150 filepath); 151 return -1; 152 } 153 return 0; 154 } 155 156 /* 157 * Function: error_function() 158 * Prints error message and returns -1 159 */ 160 161 static inline void error_function(char *msg1, char *msg2) 162 { 163 fprintf(stdout, "ERROR: %s ", msg1); 164 fprintf(stdout, "%s\n", msg2); 165 } 166 167 /* Function: read_shares_file() 168 * Reads shares value from a given shares file and writes them to 169 * the given pointer location. Returns 0 if success 170 */ 171 172 int read_shares_file(char *filepath) 173 { 174 FILE *fp; 175 unsigned int shares; 176 fp = fopen(filepath, "r"); 177 if (fp == NULL) { 178 error_function("Could not open file", filepath); 179 return -1; 180 } 181 fscanf(fp, "%u", &shares); 182 if (fclose(fp)) { 183 error_function("Could not close file", filepath); 184 return -1; 185 } 186 return shares; 187 } 188 189 /* Function: write_to_file() 190 * writes value to shares file or pid to tasks file 191 */ 192 193 int write_to_file(char *file, const char *mode, unsigned int value) 194 { 195 FILE *fp; 196 fp = fopen(file, mode); 197 if (fp == NULL) { 198 error_function("in opening file for writing:", file); 199 return -1; 200 } 201 fprintf(fp, "%u\n", value); 202 fclose(fp); 203 return 0; 204 } 205 206 /* Function: signal_handler_alarm() 207 * signal handler for the new action 208 */ 209 210 void signal_handler_alarm(int signal) 211 { 212 timer_expired = 1; 213 } 214