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