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 /*
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 */
scan_shares_files(unsigned int * shares_pointer)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
read_file(char * filepath,int action,unsigned int * value)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
error_function(char * msg1,char * msg2)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
read_shares_file(char * filepath)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
write_to_file(char * file,const char * mode,unsigned int value)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
signal_handler_alarm(int signal)210 void signal_handler_alarm(int signal)
211 {
212 timer_expired = 1;
213 }
214