tizen 2.3 release
[kernel/api/system-resource.git] / src / common / cgroup.c
1 /*
2  * resourced
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 /*
21  * Cgroup creation implementation
22  */
23
24 #include "cgroup.h"
25 #include "const.h"
26 #include "macro.h"
27 #include "resourced.h"
28 #include "trace.h"
29 #include "file-helper.h"
30
31 #include <dirent.h>
32 #include <errno.h>
33 #include <fcntl.h>              /*mkdirat */
34 #include <glib.h>
35 #include <limits.h>
36 #include <sys/stat.h>           /*mkdirat */
37 #include <sys/types.h>
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <time.h>               /*time function */
42 #include <unistd.h>
43 #include <sys/mount.h>
44
45 static int is_cgroup_exists(const char *cgroup_full_path)
46 {
47         struct stat stat_buf;
48         return stat(cgroup_full_path, &stat_buf) == 0;
49 }
50
51 static int create_cgroup(const char *cgroup_full_path)
52 {
53         if (mkdir (cgroup_full_path,
54                 S_IRUSR | S_IWUSR | S_IRGRP) < 0)
55                 return -errno;
56
57         return 0;
58 }
59
60 /*
61  * @desc place pid to cgroup.procs file
62  * @return 0 in case of success, errno value in case of failure
63  */
64 resourced_ret_c place_pid_to_cgroup_by_fullpath(const char *cgroup_full_path,
65         const int pid)
66 {
67         int ret = cgroup_write_node(cgroup_full_path, CGROUP_FILE_NAME,
68                 (u_int32_t)pid);
69
70         ret_value_msg_if(ret < 0, RESOURCED_ERROR_FAIL,
71                 "Failed place all pid to cgroup %s, error %s",
72                         cgroup_full_path, strerror(errno));
73         return RESOURCED_ERROR_NONE;
74 }
75
76 resourced_ret_c place_pid_to_cgroup(const char *cgroup_subsystem,
77         const char *cgroup_name, const int pid)
78 {
79         char buf[MAX_PATH_LENGTH];
80         snprintf(buf, sizeof(buf), "%s/%s", cgroup_subsystem, cgroup_name);
81         return place_pid_to_cgroup_by_fullpath(buf, pid);
82 }
83
84 int cgroup_write_node(const char *cgroup_name,
85                 const char *file_name, unsigned int value)
86 {
87         char buf[MAX_PATH_LENGTH];
88         snprintf(buf, sizeof(buf), "%s%s", cgroup_name, file_name);
89         _SD("cgroup_buf %s, value %d\n", buf, value);
90         return fwrite_int(buf, value);
91 }
92
93 int cgroup_write_node_str(const char *cgroup_name,
94                 const char *file_name, char* string)
95 {
96         char buf[MAX_PATH_LENGTH];
97         snprintf(buf, sizeof(buf), "%s%s", cgroup_name, file_name);
98         _SD("cgroup_buf %s, string %s\n", buf, string);
99         return fwrite_str(buf, string);
100 }
101
102 int cgroup_read_node(const char *cgroup_name,
103                 const char *file_name, unsigned int *value)
104 {
105         char buf[MAX_PATH_LENGTH];
106         snprintf(buf, sizeof(buf), "%s%s", cgroup_name, file_name);
107         _SD("cgroup_buf %s, value %d\n", buf, *value);
108         return fread_int(buf, value);
109 }
110
111 int make_cgroup_subdir(char* parentdir, char* cgroup_name, int *exists)
112 {
113         int cgroup_exists = 0, ret = 0;
114         char buf[MAX_PATH_LENGTH];
115
116         ret = snprintf(buf, sizeof(buf), "%s/%s", parentdir, cgroup_name);
117         ret_value_msg_if(ret > sizeof(buf), RESOURCED_ERROR_FAIL,
118                 "Not enought buffer size for %s%s", parentdir, cgroup_name);
119
120         cgroup_exists = is_cgroup_exists(buf);
121         if (!cgroup_exists) {
122                 ret = create_cgroup(buf);
123                 ret_value_msg_if(ret < 0, RESOURCED_ERROR_FAIL,
124                         "cpu cgroup create fail : err %d, name %s", errno,
125                                 cgroup_name);
126         }
127
128         if (exists)
129                 *exists = cgroup_exists;
130
131         return RESOURCED_ERROR_NONE;
132 }
133
134 int mount_cgroup_subsystem(char* source, char* mount_point, char* opts)
135 {
136         return mount(source, mount_point, "cgroup",
137                     MS_NODEV | MS_NOSUID | MS_NOEXEC, opts);
138 }
139