Re: [systemd-devel] implies "MemoryAccounting=true"

2013-08-29 Thread Gao feng
On 08/28/2013 07:45 PM, Zbigniew Jędrzejewski-Szmek wrote:
> On Mon, Aug 26, 2013 at 11:19:54AM +0800, Gao feng wrote:
>> Hi
>>
>> The SYSTEMD.CGROUP(5) said if MemoryLimit=bytes is set for unit, it
>> implies MemeoryAccounting=true for this unit.
>>
>> But seems systemd didn't implement this hint. CPUShares & BlockIO have
>> the same problem, this is a shortage? patch needed?
> Hm, without looking at code actually, I thought that this
> is basically a limitation/requirement of the cgroup controller:
> if a memory share is assigned, memory accounting will be performed
> by the kernelfor it to work.
> 

seems you are right, thanks!

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 3/3] systemcl: add support for setting BlockIORead/WriteBandwidth for unit

2013-08-29 Thread Gao feng
This patch allows user to set up BlockIOReadBandwidth and BlockIOWriteBandwidth
for unit through systemctl. Such as

systemctl set-property sshd.service BlockIOReadBandwidth="/dev/sda 10"
systemctl set-property sshd.service BlockIOWriteBandwidth="/dev/sda 20"
---
 src/systemctl/systemctl.c | 37 +
 1 file changed, 37 insertions(+)

diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 4ea301a..bd9abdb 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3750,6 +3750,43 @@ static int append_assignment(DBusMessageIter *iter, 
const char *assignment) {
 if (!dbus_message_iter_close_container(&sub, &sub2))
 return log_oom();
 
+} else if (streq(field, "BlockIOReadBandwidth") || streq(field, 
"BlockIOWriteBandwidth")) {
+DBusMessageIter sub2;
+
+if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, 
"a(st)", &sub) ||
+!dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, 
"(st)", &sub2))
+return log_oom();
+
+if (!isempty(eq)) {
+const char *path, *bandwidth;
+DBusMessageIter sub3;
+uint64_t u;
+char *e;
+
+e = strchr(eq, ' ');
+if (e) {
+path = strndupa(eq, e - eq);
+bandwidth = e+1;
+} else {
+path = eq;
+bandwidth = "";
+}
+
+r = safe_atou64(bandwidth, &u);
+if (r < 0) {
+log_error("Failed to parse %s value %s.", 
field, bandwidth);
+return -EINVAL;
+}
+if (!dbus_message_iter_open_container(&sub2, 
DBUS_TYPE_STRUCT, NULL, &sub3) ||
+!dbus_message_iter_append_basic(&sub3, 
DBUS_TYPE_STRING, &path) ||
+!dbus_message_iter_append_basic(&sub3, 
DBUS_TYPE_UINT64, &u) ||
+!dbus_message_iter_close_container(&sub2, &sub3))
+return log_oom();
+}
+
+if (!dbus_message_iter_close_container(&sub, &sub2))
+return log_oom();
+
 } else {
 log_error("Unknown assignment %s.", assignment);
 return -EINVAL;
-- 
1.8.3.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH 2/3] cgroup: setup BlockIORead/WriteBandwidth in bus_cgroup_set_property

2013-08-29 Thread Gao feng
This patch adds the support for setting up BlockIORead/WriteBandwidth
in bus_cgroup_set_property.
---
 src/core/dbus-cgroup.c | 101 +
 1 file changed, 101 insertions(+)

diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
index c0e2371..4ef203d 100644
--- a/src/core/dbus-cgroup.c
+++ b/src/core/dbus-cgroup.c
@@ -307,6 +307,107 @@ int bus_cgroup_set_property(
 }
 
 return 1;
+
+} else if (streq(name, "BlockIOReadBandwidth") || streq(name, 
"BlockIOWriteBandwidth")) {
+DBusMessageIter sub;
+unsigned n = 0;
+bool read = true;
+
+if (streq(name, "BlockIOWriteBandwidth"))
+read = false;
+
+if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY ||
+dbus_message_iter_get_element_type(i) != DBUS_TYPE_STRUCT)
+return -EINVAL;
+
+dbus_message_iter_recurse(i, &sub);
+while (dbus_message_iter_get_arg_type(&sub) == 
DBUS_TYPE_STRUCT) {
+DBusMessageIter sub2;
+const char *path;
+uint64_t u64;
+CGroupBlockIODeviceBandwidth *a;
+
+dbus_message_iter_recurse(&sub, &sub2);
+
+if (bus_iter_get_basic_and_next(&sub2, 
DBUS_TYPE_STRING, &path, true) < 0 ||
+bus_iter_get_basic_and_next(&sub2, 
DBUS_TYPE_UINT64, &u64, false) < 0)
+return -EINVAL;
+
+if (mode != UNIT_CHECK) {
+CGroupBlockIODeviceBandwidth *b;
+bool exist = false;
+
+LIST_FOREACH(device_bandwidths, b, 
c->blockio_device_bandwidths) {
+if (streq(path, b->path) && read == 
b->read) {
+a = b;
+exist = true;
+break;
+}
+}
+
+if (!exist) {
+a = new0(CGroupBlockIODeviceBandwidth, 
1);
+if (!a)
+return -ENOMEM;
+
+a->read = read;
+a->path = strdup(path);
+if (!a->path) {
+free(a);
+return -ENOMEM;
+}
+}
+
+a->bandwidth = u64;
+
+if (!exist)
+
LIST_PREPEND(CGroupBlockIODeviceBandwidth, device_bandwidths,
+ 
c->blockio_device_bandwidths, a);
+}
+
+n++;
+dbus_message_iter_next(&sub);
+}
+
+if (mode != UNIT_CHECK) {
+_cleanup_free_ char *buf = NULL;
+_cleanup_fclose_ FILE *f = NULL;
+CGroupBlockIODeviceBandwidth *a;
+CGroupBlockIODeviceBandwidth *next;
+size_t size = 0;
+
+if (n == 0) {
+LIST_FOREACH_SAFE(device_bandwidths, a, next, 
c->blockio_device_bandwidths) {
+if (a->read == read) {
+
LIST_REMOVE(CGroupBlockIODeviceBandwidth, device_bandwidths, 
c->blockio_device_bandwidths, a);
+free(a->path);
+free(a);
+}
+}
+}
+
+f = open_memstream(&buf, &size);
+if (!f)
+return -ENOMEM;
+
+if (read) {
+fputs("BlockIOReadBandwidth=\n", f);
+LIST_FOREACH(device_bandwidths, a, 
c->blockio_device_bandwidths)
+if (a->read)
+fprintf(f, 
"BlockIOReadBandwidth=%s %" PRIu64 "\n", a->path, a->bandwidth);
+} else {
+fputs("BlockIOWriteBandwidth=\n", f);
+LIST_FOREACH(device_bandwidths, a, 
c->blockio_device_bandwidths)
+if (!a->read)

[systemd-devel] [PATCH 1/3] blkio bandwidth: don't clean up all of entries in blockio_device_bandwidths list

2013-08-29 Thread Gao feng
if we get BlockIOReadBandwidth="", we should only remove the
read-bandwidth-entries in blockio_device_bandwidths list.
---
 src/core/load-fragment.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 4714687..6f316cc 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -2205,6 +2205,7 @@ int config_parse_blockio_bandwidth(
 CGroupContext *c = data;
 const char *bandwidth;
 off_t bytes;
+bool read;
 size_t n;
 int r;
 
@@ -2212,9 +2213,18 @@ int config_parse_blockio_bandwidth(
 assert(lvalue);
 assert(rvalue);
 
+read = streq("BlockIOReadBandwidth", lvalue);
+
 if (isempty(rvalue)) {
-while (c->blockio_device_bandwidths)
-cgroup_context_free_blockio_device_bandwidth(c, 
c->blockio_device_bandwidths);
+CGroupBlockIODeviceBandwidth *next;
+
+LIST_FOREACH_SAFE (device_bandwidths, b, next, 
c->blockio_device_bandwidths) {
+if (b->read == read) {
+LIST_REMOVE(CGroupBlockIODeviceBandwidth, 
device_bandwidths, c->blockio_device_bandwidths, b);
+free(b->path);
+free(b);
+}
+}
 
 return 0;
 }
@@ -2253,7 +2263,7 @@ int config_parse_blockio_bandwidth(
 b->path = path;
 path = NULL;
 b->bandwidth = (uint64_t) bytes;
-b->read = streq("BlockIOReadBandwidth", lvalue);
+b->read = read;
 
 LIST_PREPEND(CGroupBlockIODeviceBandwidth, device_bandwidths, 
c->blockio_device_bandwidths, b);
 
-- 
1.8.3.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel