]> git.pld-linux.org Git - packages/libcgroup.git/blame - libcgroup-0.41-api.c-support-for-setting-multiline-values-in-contro.patch
- rel 5; add patches from FC
[packages/libcgroup.git] / libcgroup-0.41-api.c-support-for-setting-multiline-values-in-contro.patch
CommitLineData
9665627f
AM
1From 691430206f1104b752b0e52386f317e639137788 Mon Sep 17 00:00:00 2001
2From: Jan Chaloupka <jchaloup@redhat.com>
3Date: Mon, 15 Sep 2014 13:29:39 +0200
4Subject: [PATCH] api.c: support for setting multiline values in control files
5
6As of now, libcgroup does not support multiline values setting from configuration files. i.e. values in a form:
7
8net_prio.ifpriomap="lo 7
9eth0 66
10eth1 5
11eth2 4
12eth3 3";
13
14Thus, setting of more network interfaces can not be done from configuration file. Or
15
16devices.allow="a *:* w
17c 8:* r";
18
19thus setting list of allow devices can not be set as well. The only way is to set it from userspace, e.g.:
20# echo "lo 7" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap
21# echo "eth 0" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap
22# echo "eth 1" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap
23# echo "eth 2" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap
24# echo "eth 3" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap
25
26This patch allows setting of multiline variables.
27
28How this support works:
29Multiline value is broken in lines and each line is set by write (man 2 write) syscall (without bufferring).
30This implies change of fopen with open, fclose with close.
31There is no control on multiline value, thus "eth0\n \t\n" can be set. However, setting
32of " \t" will fail as write command returns -1. Thus administrator has to set correct
33multiline values.
34
35Tested on virtual machine with fedora and rhel with network interface lo, eth0-eth3. Configuration file:
36
37# cat /etc/cgconfig.conf
38group testGroup {
39 net_prio {
40 net_prio.ifpriomap="lo 7
41eth0 66
42eth1 5
43eth2 4
44eth3 3";
45 }
46}
47
48net_prio has to be created before:
49# modprobe netprio_cgroup
50# mkdir /sys/fs/cgroup/net_prio
51# mount -t cgroup -onet_prio none /sys/fs/cgroup/net_prio
52
53Changelog:
54 test of success of strdup call
55 free str_val before return (str_val is changing in while cycle,
56 thus str_start_val points to the start of str_val before while)
57
58Signed-off-by: Jan Chaloupka <jchaloup@redhat.com>
59---
60 src/api.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------
61 1 file changed, 44 insertions(+), 6 deletions(-)
62
63diff --git a/src/api.c b/src/api.c
64index 5751b8f..d6c9d3a 100644
65--- a/src/api.c
66+++ b/src/api.c
67@@ -1495,13 +1495,18 @@ static int cg_create_control_group(const char *path)
68 */
69 static int cg_set_control_value(char *path, const char *val)
70 {
71- FILE *control_file = NULL;
72+ int ctl_file;
73+ char *str_val;
74+ char *str_val_start;
75+ char *pos;
76+ size_t len;
77+
78 if (!cg_test_mounted_fs())
79 return ECGROUPNOTMOUNTED;
80
81- control_file = fopen(path, "r+e");
82+ ctl_file = open(path, O_RDWR | O_CLOEXEC);
83
84- if (!control_file) {
85+ if (ctl_file == -1) {
86 if (errno == EPERM) {
87 /*
88 * We need to set the correct error value, does the
89@@ -1512,6 +1517,7 @@ static int cg_set_control_value(char *path, const char *val)
90 */
91 char *path_dir_end;
92 char *tasks_path;
93+ FILE *control_file;
94
95 path_dir_end = strrchr(path, '/');
96 if (path_dir_end == NULL)
97@@ -1543,15 +1549,47 @@ static int cg_set_control_value(char *path, const char *val)
98 return ECGROUPVALUENOTEXIST;
99 }
100
101- if (fprintf(control_file, "%s", val) < 0) {
102+ /* Split the multiline value into lines. */
103+ /* One line is a special case of multiline value. */
104+ str_val = strdup(val);
105+ if (str_val == NULL) {
106 last_errno = errno;
107- fclose(control_file);
108+ close(ctl_file);
109 return ECGOTHER;
110 }
111- if (fclose(control_file) < 0) {
112+
113+ str_val_start = str_val;
114+ pos = str_val;
115+
116+ do {
117+ str_val = pos;
118+ pos = strchr(str_val, '\n');
119+
120+ if (pos) {
121+ *pos = '\0';
122+ ++pos;
123+ }
124+
125+ len = strlen(str_val);
126+ if (len > 0) {
127+ if (write(ctl_file, str_val, len) == -1) {
128+ last_errno = errno;
129+ free(str_val_start);
130+ close(ctl_file);
131+ return ECGOTHER;
132+ }
133+ } else
134+ cgroup_warn("Warning: skipping empty line for %s\n",
135+ path);
136+ } while(pos);
137+
138+ if (close(ctl_file)) {
139 last_errno = errno;
140+ free(str_val_start);
141 return ECGOTHER;
142 }
143+
144+ free(str_val_start);
145 return 0;
146 }
147
148--
1491.9.3
150
This page took 0.051082 seconds and 4 git commands to generate.