mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 16:37:19 +09:00
cgroup-util: modernize cg_get_keyed_attribute()
- assert on supplied keys being unique - Reject duplicate attributes with -EBADMSG - Rename 'ret_values' to just 'values', given we don't allocate the array - Remove now unused cg_get_keyed_attribute_graceful()
This commit is contained in:
@@ -1777,56 +1777,61 @@ int cg_get_owner(const char *path, uid_t *ret_uid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cg_get_keyed_attribute_full(
|
||||
int cg_get_keyed_attribute(
|
||||
const char *controller,
|
||||
const char *path,
|
||||
const char *attribute,
|
||||
char **keys,
|
||||
char **ret_values,
|
||||
CGroupKeyMode mode) {
|
||||
char * const *keys,
|
||||
char **values) {
|
||||
|
||||
_cleanup_free_ char *filename = NULL, *contents = NULL;
|
||||
const char *p;
|
||||
size_t n, i, n_done = 0;
|
||||
char **v;
|
||||
size_t n;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(attribute);
|
||||
|
||||
/* Reads one or more fields of a cgroup v2 keyed attribute file. The 'keys' parameter should be an strv with
|
||||
* all keys to retrieve. The 'ret_values' parameter should be passed as string size with the same number of
|
||||
* all keys to retrieve. The 'values' parameter should be passed as string size with the same number of
|
||||
* entries as 'keys'. On success each entry will be set to the value of the matching key.
|
||||
*
|
||||
* If the attribute file doesn't exist at all returns ENOENT, if any key is not found returns ENXIO. If mode
|
||||
* is set to GG_KEY_MODE_GRACEFUL we ignore missing keys and return those that were parsed successfully. */
|
||||
* If the attribute file doesn't exist at all returns ENOENT, if any key is not found returns ENXIO. */
|
||||
|
||||
r = cg_get_path(controller, path, attribute, &filename);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = read_full_file(filename, &contents, NULL);
|
||||
r = read_full_file(filename, &contents, /* ret_size = */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
n = strv_length(keys);
|
||||
if (n == 0) /* No keys to retrieve? That's easy, we are done then */
|
||||
return 0;
|
||||
assert(strv_is_uniq(keys));
|
||||
|
||||
/* Let's build this up in a temporary array for now in order not to clobber the return parameter on failure */
|
||||
v = newa0(char*, n);
|
||||
char **v = newa0(char*, n);
|
||||
size_t n_done = 0;
|
||||
|
||||
for (p = contents; *p;) {
|
||||
const char *w = NULL;
|
||||
for (const char *p = contents; *p;) {
|
||||
const char *w;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
if (!v[i]) {
|
||||
w = first_word(p, keys[i]);
|
||||
if (w)
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
w = first_word(p, keys[i]);
|
||||
if (w)
|
||||
break;
|
||||
}
|
||||
|
||||
if (w) {
|
||||
size_t l;
|
||||
if (v[i]) { /* duplicate entry? */
|
||||
r = -EBADMSG;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
size_t l = strcspn(w, NEWLINE);
|
||||
|
||||
l = strcspn(w, NEWLINE);
|
||||
v[i] = strndup(w, l);
|
||||
if (!v[i]) {
|
||||
r = -ENOMEM;
|
||||
@@ -1835,7 +1840,7 @@ int cg_get_keyed_attribute_full(
|
||||
|
||||
n_done++;
|
||||
if (n_done >= n)
|
||||
goto done;
|
||||
break;
|
||||
|
||||
p = w + l;
|
||||
} else
|
||||
@@ -1844,21 +1849,17 @@ int cg_get_keyed_attribute_full(
|
||||
p += strspn(p, NEWLINE);
|
||||
}
|
||||
|
||||
if (mode & CG_KEY_MODE_GRACEFUL)
|
||||
goto done;
|
||||
if (n_done < n) {
|
||||
r = -ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
r = -ENXIO;
|
||||
memcpy(values, v, sizeof(char*) * n);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
free_many_charp(v, n);
|
||||
return r;
|
||||
|
||||
done:
|
||||
memcpy(ret_values, v, sizeof(char*) * n);
|
||||
if (mode & CG_KEY_MODE_GRACEFUL)
|
||||
return n_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cg_mask_to_string(CGroupMask mask, char **ret) {
|
||||
|
||||
@@ -226,31 +226,9 @@ int cg_is_delegated_fd(int fd);
|
||||
|
||||
int cg_has_coredump_receive(const char *path);
|
||||
|
||||
typedef enum {
|
||||
CG_KEY_MODE_GRACEFUL = 1 << 0,
|
||||
} CGroupKeyMode;
|
||||
|
||||
int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value);
|
||||
int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret);
|
||||
int cg_get_keyed_attribute_full(const char *controller, const char *path, const char *attribute, char **keys, char **values, CGroupKeyMode mode);
|
||||
|
||||
static inline int cg_get_keyed_attribute(
|
||||
const char *controller,
|
||||
const char *path,
|
||||
const char *attribute,
|
||||
char **keys,
|
||||
char **ret_values) {
|
||||
return cg_get_keyed_attribute_full(controller, path, attribute, keys, ret_values, 0);
|
||||
}
|
||||
|
||||
static inline int cg_get_keyed_attribute_graceful(
|
||||
const char *controller,
|
||||
const char *path,
|
||||
const char *attribute,
|
||||
char **keys,
|
||||
char **ret_values) {
|
||||
return cg_get_keyed_attribute_full(controller, path, attribute, keys, ret_values, CG_KEY_MODE_GRACEFUL);
|
||||
}
|
||||
int cg_get_keyed_attribute(const char *controller, const char *path, const char *attribute, char * const *keys, char **values);
|
||||
|
||||
int cg_get_attribute_as_uint64(const char *controller, const char *path, const char *attribute, uint64_t *ret);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user