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 [email protected] */
30 /* */
31 /* History: */
32 /* Created- 15/02/2008 -Sudhir Kumar <[email protected]> */
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