From c81248e53bd43a2132ce0b0a5aee4951c8618b6f Mon Sep 17 00:00:00 2001
From: Jan Chaloupka <jchaloup@redhat.com>
Date: Thu, 7 Aug 2014 07:17:23 +0200
Subject: [PATCH] retry to set control file
---
src/api.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/src/api.c b/src/api.c
index ae8396e..03c8068 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1432,6 +1432,8 @@ static int cg_set_control_value(char *path, const char *val)
return 0;
}
+
+
/** cgroup_modify_cgroup modifies the cgroup control files.
* struct cgroup *cgroup: The name will be the cgroup to be modified.
* The values will be the values to be modified, those not mentioned
@@ -1449,6 +1451,9 @@ int cgroup_modify_cgroup(struct cgroup *cgroup)
int i;
int error = 0;
int ret;
+ int retry_list[CG_CONTROLLER_MAX];
+ int retry_index;
+ struct control_value **cvalues;
if (!cgroup_initialized)
return ECGROUPNOTINITIALIZED;
@@ -1469,6 +1474,8 @@ int cgroup_modify_cgroup(struct cgroup *cgroup)
if (!cg_build_path(cgroup->name, base,
cgroup->controller[i]->name))
continue;
+
+ retry_index = -1;
for (j = 0; j < cgroup->controller[i]->index; j++) {
ret = asprintf(&path, "%s%s", base,
cgroup->controller[i]->values[j]->name);
@@ -1485,12 +1492,40 @@ int cgroup_modify_cgroup(struct cgroup *cgroup)
* the user as fatal */
if (error && !cgroup->controller[i]->values[j]->dirty) {
error = 0;
+ /* Let's retry to set it in the second round */
+ ++retry_index;
+ retry_list[retry_index] = j;
continue;
}
if (error)
goto err;
cgroup->controller[i]->values[j]->dirty = false;
}
+ if (retry_index > -1) {
+ for (j = 0; j <= retry_index; j++) {
+ cvalues = cgroup->controller[i]->values;
+ ret = asprintf(&path, "%s%s", base,
+ cvalues[retry_list[j]]->name);
+ if (ret < 0) {
+ last_errno = errno;
+ error = ECGOTHER;
+ goto err;
+ }
+ error = cg_set_control_value(path,
+ cvalues[retry_list[j]]->value);
+ free(path);
+ path = NULL;
+ /* don't consider error in files directly
+ * written by the user as fatal */
+ if (error && !cvalues[retry_list[j]]->dirty) {
+ error = 0;
+ continue;
+ }
+ if (error)
+ goto err;
+ cvalues[retry_list[j]]->dirty = false;
+ }
+ }
}
err:
return error;
--
1.9.3