diff options
author | Balbir Singh <balbir@linux.vnet.ibm.com> | 2009-02-16 13:34:12 +0000 |
---|---|---|
committer | Balbir Singh <balbir@linux.vnet.ibm.com> | 2009-02-16 13:34:12 +0000 |
commit | dedcfa480ee21b9bb87964eb1e2665fe6a200b4c (patch) | |
tree | 61e4516a1f28071d8cb6604f8adb330eb598d3a0 /api.c | |
parent | b4ca5d9b4a38994aa71fbdb14fd5d65c81bf5216 (diff) | |
download | libcg-dedcfa480ee21b9bb87964eb1e2665fe6a200b4c.tar.gz libcg-dedcfa480ee21b9bb87964eb1e2665fe6a200b4c.tar.xz libcg-dedcfa480ee21b9bb87964eb1e2665fe6a200b4c.zip |
This patch store the last errno value to last_errno value and add
cgroup_add_last_errno procedure to show this number.
Use this procedure to show the cause of the error when ECGOTHER is returned.
[balbir@linux.vnet.ibm.com: fix last_errno in config.c]
Signed-off-by: Ivana Varekova <varekova@redhat.com>
Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com>
git-svn-id: https://libcg.svn.sourceforge.net/svnroot/libcg/trunk@329 4f4bb910-9a46-0410-90c8-c897d4f1cd53
Diffstat (limited to 'api.c')
-rw-r--r-- | api.c | 70 |
1 files changed, 62 insertions, 8 deletions
@@ -49,6 +49,16 @@ #define VERSION(ver) #ver /* + * The errno which happend the last time (have to be thread specific) + */ +__thread int last_errno; + +#define MAXLEN 256 + +/* the value have to be thread specific */ +__thread char errtext[MAXLEN]; + +/* * Remember to bump this up for major API changes. */ const static char cg_version[] = VERSION(PACKAGE_VERSION); @@ -94,6 +104,7 @@ char *cgroup_strerror_codes[] = { "Cgroup parsing failed", "Cgroup, rules file does not exist", "Cgroup mounting failed", + "The config file can not be opend", }; static int cg_chown_file(FTS *fts, FTSENT *ent, uid_t owner, gid_t group) @@ -294,14 +305,15 @@ static int cgroup_parse_rules(bool cache, uid_t muid, gid_t mgid) dbg("Failed to open configuration file %s with" " error: %s\n", CGRULES_CONF_FILE, strerror(errno)); - ret = errno; + last_errno = errno; goto finish; } buff = calloc(CGROUP_RULE_MAXLINE, sizeof(char)); if (!buff) { dbg("Out of memory? Error: %s\n", strerror(errno)); - ret = errno; + last_errno = errno; + ret = ECGOTHER; goto close_unlock; } @@ -442,7 +454,8 @@ static int cgroup_parse_rules(bool cache, uid_t muid, gid_t mgid) newrule = calloc(1, sizeof(struct cgroup_rule)); if (!newrule) { dbg("Out of memory? Error: %s\n", strerror(errno)); - ret = errno; + last_errno = errno; + ret = ECGOTHER; goto cleanup; } @@ -565,6 +578,7 @@ int cgroup_init() */ buf = malloc(FILENAME_MAX); if (!buf) { + last_errno = errno; ret = ECGOTHER; goto unlock_exit; } @@ -777,11 +791,13 @@ int cgroup_attach_task_pid(struct cgroup *cgroup, pid_t tid) dbg("Error writing tid %d to %s:%s\n", tid, path, strerror(errno)); fclose(tasks); + last_errno = errno; return ECGOTHER; } ret = fflush(tasks); if (ret) { + last_errno = errno; dbg("Error writing tid %d to %s:%s\n", tid, path, strerror(errno)); fclose(tasks); @@ -822,6 +838,7 @@ int cgroup_attach_task_pid(struct cgroup *cgroup, pid_t tid) } ret = fprintf(tasks, "%d", tid); if (ret < 0) { + last_errno = errno; dbg("Error writing tid %d to %s:%s\n", tid, path, strerror(errno)); fclose(tasks); @@ -829,6 +846,7 @@ int cgroup_attach_task_pid(struct cgroup *cgroup, pid_t tid) } ret = fflush(tasks); if (ret) { + last_errno = errno; dbg("Error writing tid %d to %s:%s\n", tid, path, strerror(errno)); fclose(tasks); @@ -872,12 +890,16 @@ static int cg_mkdir_p(const char *path) buf = getcwd(cwd, FILENAME_MAX); - if (!buf) + if (!buf) { + last_errno = errno; return ECGOTHER; + } real_path = strdup(path); - if (!real_path) + if (!real_path) { + last_errno = errno; return ECGOTHER; + } do { while (real_path[j] != '\0' && real_path[j] != '/') @@ -892,6 +914,7 @@ static int cg_mkdir_p(const char *path) ret = mkdir(str, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); wd = strdup(str); if (!wd) { + last_errno = errno; ret = ECGOTHER; break; } @@ -1030,6 +1053,7 @@ int cgroup_modify_cgroup(struct cgroup *cgroup) ret = asprintf(&path, "%s%s", base, cgroup->controller[i]->values[j]->name); if (ret < 0) { + last_errno = errno; error = ECGOTHER; goto err; } @@ -1175,6 +1199,7 @@ int cgroup_create_cgroup(struct cgroup *cgroup, int ignore_ownership) base = strdup(path); if (!base) { + last_errno = errno; error = ECGOTHER; goto err; } @@ -1191,6 +1216,7 @@ int cgroup_create_cgroup(struct cgroup *cgroup, int ignore_ownership) ret = asprintf(&path, "%s%s", base, cgroup->controller[k]->values[j]->name); if (ret < 0) { + last_errno = errno; error = ECGOTHER; goto err; } @@ -1215,12 +1241,14 @@ int cgroup_create_cgroup(struct cgroup *cgroup, int ignore_ownership) free(path); ret = asprintf(&path, "%s/tasks", base); if (ret < 0) { + last_errno = errno; error = ECGOTHER; goto err; } error = chown(path, cgroup->tasks_uid, cgroup->tasks_gid); if (error) { + last_errno = errno; error = ECGOTHER; goto err; } @@ -1403,6 +1431,7 @@ int cgroup_delete_cgroup(struct cgroup *cgroup, int ignore_migration) cgroup->controller[i]->name)) continue; error = rmdir(path); + last_errno = errno; } open_err: if (ignore_migration) { @@ -1411,8 +1440,10 @@ open_err: cgroup->controller[i]->name)) continue; error = rmdir(path); - if (error < 0 && errno == ENOENT) + if (error < 0 && errno == ENOENT) { + last_errno = errno; error = 0; + } } } if (error) @@ -1441,8 +1472,10 @@ static int cg_rd_ctrl_file(char *subsys, char *cgroup, char *file, char **value) return ECGROUPVALUENOTEXIST; *value = malloc(CG_VALUE_MAX); - if (!*value) + if (!*value) { + last_errno = errno; return ECGOTHER; + } /* * using %as crashes when we try to read from files like @@ -1596,11 +1629,13 @@ int cgroup_get_cgroup(struct cgroup *cgroup) ret = asprintf(&control_path, "%s/tasks", path); if (ret < 0) { + last_errno = errno; error = ECGOTHER; goto unlock_error; } if (stat(control_path, &stat_buffer)) { + last_errno = errno; free(control_path); error = ECGOTHER; goto unlock_error; @@ -1620,6 +1655,7 @@ int cgroup_get_cgroup(struct cgroup *cgroup) dir = opendir(path); if (!dir) { + last_errno = errno; error = ECGOTHER; goto unlock_error; } @@ -1739,8 +1775,10 @@ static int cg_prepare_controller_array(char *cstr, char *controllers[]) if (temp) { controllers[j] = strdup(temp); - if (!controllers[j]) + if (!controllers[j]) { + last_errno = errno; return ECGOTHER; + } } j++; } while (temp); @@ -2137,6 +2175,7 @@ int cgroup_get_current_controller_path(pid_t pid, const char *controller, */ if (ret != 3 || ret == EOF) { dbg("read failed for pid_cgroup_fd ret %d\n", ret); + last_errno = errno; ret = ECGOTHER; goto done; } @@ -2147,6 +2186,7 @@ int cgroup_get_current_controller_path(pid_t pid, const char *controller, == 0) { *current_path = strdup(cgroup_path); if (!*current_path) { + last_errno = errno; ret = ECGOTHER; goto done; } @@ -2168,5 +2208,19 @@ cleanup_path: char *cgroup_strerror(int code) { assert((code >= ECGROUPNOTCOMPILED) && (code < ECGSENTINEL)); + if (code == ECGOTHER) { + snprintf(errtext, MAXLEN, "%s: error message: %s", + cgroup_strerror_codes[code % ECGROUPNOTCOMPILED], + strerror(cgroup_get_last_errno())); + return errtext; + } return cgroup_strerror_codes[code % ECGROUPNOTCOMPILED]; } + +/** + * Return last errno, which caused ECGOTHER error. + */ +int cgroup_get_last_errno() +{ + return last_errno; +} |