api.c: support for setting multiline values in control files
- resolves: #647107
This commit is contained in:
parent
ff467ce17a
commit
7cc67002c9
@ -0,0 +1,150 @@
|
|||||||
|
From 691430206f1104b752b0e52386f317e639137788 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Chaloupka <jchaloup@redhat.com>
|
||||||
|
Date: Mon, 15 Sep 2014 13:29:39 +0200
|
||||||
|
Subject: [PATCH] api.c: support for setting multiline values in control files
|
||||||
|
|
||||||
|
As of now, libcgroup does not support multiline values setting from configuration files. i.e. values in a form:
|
||||||
|
|
||||||
|
net_prio.ifpriomap="lo 7
|
||||||
|
eth0 66
|
||||||
|
eth1 5
|
||||||
|
eth2 4
|
||||||
|
eth3 3";
|
||||||
|
|
||||||
|
Thus, setting of more network interfaces can not be done from configuration file. Or
|
||||||
|
|
||||||
|
devices.allow="a *:* w
|
||||||
|
c 8:* r";
|
||||||
|
|
||||||
|
thus setting list of allow devices can not be set as well. The only way is to set it from userspace, e.g.:
|
||||||
|
# echo "lo 7" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap
|
||||||
|
# echo "eth 0" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap
|
||||||
|
# echo "eth 1" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap
|
||||||
|
# echo "eth 2" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap
|
||||||
|
# echo "eth 3" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap
|
||||||
|
|
||||||
|
This patch allows setting of multiline variables.
|
||||||
|
|
||||||
|
How this support works:
|
||||||
|
Multiline value is broken in lines and each line is set by write (man 2 write) syscall (without bufferring).
|
||||||
|
This implies change of fopen with open, fclose with close.
|
||||||
|
There is no control on multiline value, thus "eth0\n \t\n" can be set. However, setting
|
||||||
|
of " \t" will fail as write command returns -1. Thus administrator has to set correct
|
||||||
|
multiline values.
|
||||||
|
|
||||||
|
Tested on virtual machine with fedora and rhel with network interface lo, eth0-eth3. Configuration file:
|
||||||
|
|
||||||
|
# cat /etc/cgconfig.conf
|
||||||
|
group testGroup {
|
||||||
|
net_prio {
|
||||||
|
net_prio.ifpriomap="lo 7
|
||||||
|
eth0 66
|
||||||
|
eth1 5
|
||||||
|
eth2 4
|
||||||
|
eth3 3";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
net_prio has to be created before:
|
||||||
|
# modprobe netprio_cgroup
|
||||||
|
# mkdir /sys/fs/cgroup/net_prio
|
||||||
|
# mount -t cgroup -onet_prio none /sys/fs/cgroup/net_prio
|
||||||
|
|
||||||
|
Changelog:
|
||||||
|
test of success of strdup call
|
||||||
|
free str_val before return (str_val is changing in while cycle,
|
||||||
|
thus str_start_val points to the start of str_val before while)
|
||||||
|
|
||||||
|
Signed-off-by: Jan Chaloupka <jchaloup@redhat.com>
|
||||||
|
---
|
||||||
|
src/api.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------
|
||||||
|
1 file changed, 44 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/api.c b/src/api.c
|
||||||
|
index 5751b8f..d6c9d3a 100644
|
||||||
|
--- a/src/api.c
|
||||||
|
+++ b/src/api.c
|
||||||
|
@@ -1495,13 +1495,18 @@ static int cg_create_control_group(const char *path)
|
||||||
|
*/
|
||||||
|
static int cg_set_control_value(char *path, const char *val)
|
||||||
|
{
|
||||||
|
- FILE *control_file = NULL;
|
||||||
|
+ int ctl_file;
|
||||||
|
+ char *str_val;
|
||||||
|
+ char *str_val_start;
|
||||||
|
+ char *pos;
|
||||||
|
+ size_t len;
|
||||||
|
+
|
||||||
|
if (!cg_test_mounted_fs())
|
||||||
|
return ECGROUPNOTMOUNTED;
|
||||||
|
|
||||||
|
- control_file = fopen(path, "r+e");
|
||||||
|
+ ctl_file = open(path, O_RDWR | O_CLOEXEC);
|
||||||
|
|
||||||
|
- if (!control_file) {
|
||||||
|
+ if (ctl_file == -1) {
|
||||||
|
if (errno == EPERM) {
|
||||||
|
/*
|
||||||
|
* We need to set the correct error value, does the
|
||||||
|
@@ -1512,6 +1517,7 @@ static int cg_set_control_value(char *path, const char *val)
|
||||||
|
*/
|
||||||
|
char *path_dir_end;
|
||||||
|
char *tasks_path;
|
||||||
|
+ FILE *control_file;
|
||||||
|
|
||||||
|
path_dir_end = strrchr(path, '/');
|
||||||
|
if (path_dir_end == NULL)
|
||||||
|
@@ -1543,15 +1549,47 @@ static int cg_set_control_value(char *path, const char *val)
|
||||||
|
return ECGROUPVALUENOTEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (fprintf(control_file, "%s", val) < 0) {
|
||||||
|
+ /* Split the multiline value into lines. */
|
||||||
|
+ /* One line is a special case of multiline value. */
|
||||||
|
+ str_val = strdup(val);
|
||||||
|
+ if (str_val == NULL) {
|
||||||
|
last_errno = errno;
|
||||||
|
- fclose(control_file);
|
||||||
|
+ close(ctl_file);
|
||||||
|
return ECGOTHER;
|
||||||
|
}
|
||||||
|
- if (fclose(control_file) < 0) {
|
||||||
|
+
|
||||||
|
+ str_val_start = str_val;
|
||||||
|
+ pos = str_val;
|
||||||
|
+
|
||||||
|
+ do {
|
||||||
|
+ str_val = pos;
|
||||||
|
+ pos = strchr(str_val, '\n');
|
||||||
|
+
|
||||||
|
+ if (pos) {
|
||||||
|
+ *pos = '\0';
|
||||||
|
+ ++pos;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ len = strlen(str_val);
|
||||||
|
+ if (len > 0) {
|
||||||
|
+ if (write(ctl_file, str_val, len) == -1) {
|
||||||
|
+ last_errno = errno;
|
||||||
|
+ free(str_val_start);
|
||||||
|
+ close(ctl_file);
|
||||||
|
+ return ECGOTHER;
|
||||||
|
+ }
|
||||||
|
+ } else
|
||||||
|
+ cgroup_warn("Warning: skipping empty line for %s\n",
|
||||||
|
+ path);
|
||||||
|
+ } while(pos);
|
||||||
|
+
|
||||||
|
+ if (close(ctl_file)) {
|
||||||
|
last_errno = errno;
|
||||||
|
+ free(str_val_start);
|
||||||
|
return ECGOTHER;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ free(str_val_start);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
1.9.3
|
||||||
|
|
@ -5,7 +5,7 @@
|
|||||||
Summary: Library to control and monitor control groups
|
Summary: Library to control and monitor control groups
|
||||||
Name: libcgroup
|
Name: libcgroup
|
||||||
Version: 0.41
|
Version: 0.41
|
||||||
Release: 5%{?dist}
|
Release: 6%{?dist}
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
Group: Development/Libraries
|
Group: Development/Libraries
|
||||||
URL: http://libcg.sourceforge.net/
|
URL: http://libcg.sourceforge.net/
|
||||||
@ -18,6 +18,7 @@ Patch2: libcgroup-0.40.rc1-coverity.patch
|
|||||||
Patch3: libcgroup-0.40.rc1-fread.patch
|
Patch3: libcgroup-0.40.rc1-fread.patch
|
||||||
Patch4: libcgroup-0.40.rc1-templates-fix.patch
|
Patch4: libcgroup-0.40.rc1-templates-fix.patch
|
||||||
Patch5: libcgroup-0.41-lex.patch
|
Patch5: libcgroup-0.41-lex.patch
|
||||||
|
Patch6: libcgroup-0.41-api.c-support-for-setting-multiline-values-in-contro.patch
|
||||||
|
|
||||||
BuildRequires: byacc, coreutils, flex, pam-devel, systemd-units
|
BuildRequires: byacc, coreutils, flex, pam-devel, systemd-units
|
||||||
Requires(pre): shadow-utils
|
Requires(pre): shadow-utils
|
||||||
@ -65,6 +66,7 @@ provide scripts to manage that configuration.
|
|||||||
%patch3 -p1 -b .fread
|
%patch3 -p1 -b .fread
|
||||||
%patch4 -p1 -b .templates-fix
|
%patch4 -p1 -b .templates-fix
|
||||||
%patch5 -p2 -b .lex
|
%patch5 -p2 -b .lex
|
||||||
|
%patch6 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%configure --enable-pam-module-dir=%{_libdir}/security \
|
%configure --enable-pam-module-dir=%{_libdir}/security \
|
||||||
@ -165,6 +167,10 @@ getent group cgred >/dev/null || groupadd -r cgred
|
|||||||
%{_libdir}/pkgconfig/libcgroup.pc
|
%{_libdir}/pkgconfig/libcgroup.pc
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Sep 23 2014 jchaloup <jchaloup@redhat.com> - 0.41-6
|
||||||
|
- resolves: #647107
|
||||||
|
api.c: support for setting multiline values in control files
|
||||||
|
|
||||||
* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.41-5
|
* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.41-5
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user