Commit 72add155 by Serge Hallyn

Fix up c8bf519d to fit our coding style

Also reduce the number of mallocs. Signed-off-by: 's avatarSerge Hallyn <serge@hallyn.com>
parent da7a897e
...@@ -1895,64 +1895,48 @@ static int cgfsng_set(const char *filename, const char *value, const char *name, ...@@ -1895,64 +1895,48 @@ static int cgfsng_set(const char *filename, const char *value, const char *name,
} }
/* /*
* Called from setup_limits - here we have the container's cgroup_data because * take devices cgroup line
* we created the cgroups * /dev/foo rwx
* and convert it to a valid
* type major:minor mode
* line. Return <0 on error. Dest is a preallocated buffer
* long enough to hold the output.
*/ */
static int lxc_cgroup_set_data(const char *filename, const char *value, struct cgfsng_handler_data *d) static int convert_devpath(const char *invalue, char *dest)
{ {
char *subsystem = NULL, *p; char *p, *path, *mode, type = 0;
int ret = -1; struct stat sb;
struct hierarchy *h; unsigned long minor, major;
char converted_value[50]; // "b|c <2^64-1>:<2^64-1> r|w|m" = 47 chars max int n_parts, ret;
dev_t dev;
subsystem = alloca(strlen(filename) + 1); path = must_copy_string(invalue);
strcpy(subsystem, filename);
if ((p = strchr(subsystem, '.')) != NULL)
*p = '\0';
if (strcmp("devices.allow", filename) == 0 && value[0] == '/') { /*
char *to_split1 = strdup(value); * read path followed by mode; ignore any trailing text.
if (to_split1 == NULL) { * A ' # comment' would be legal. Technically other text
ret = -ENOMEM; * is not legal, we could check for that if we cared to
} else { */
char *saveptr = NULL; for (n_parts = 1, p = path; *p && n_parts < 3; p++) {
size_t n_parts = 0; if (*p == ' ') {
while (strtok_r(n_parts ? NULL : to_split1, " ", &saveptr) != NULL) { *p = '\0';
++n_parts; mode = p + 1;
n_parts++;
while (*p == ' ')
p++;
} }
free(to_split1);
if (n_parts == 2) {
size_t i;
char **parts = malloc(sizeof(char*) * n_parts);
if (parts == NULL) {
ret = -ENOMEM;
} else {
ret = 0;
// We can't reuse to_split1 here, because strtok_r modifies its first argument
char *to_split2 = strdup(value);
if (to_split2 == NULL) {
ret = -ENOMEM;
} else {
for (i = 0; i < n_parts; ++i) {
char *part = strtok_r(i ? NULL : to_split2, " ", &saveptr);
char *subpart = strdup(part);
if (subpart == NULL) {
ret = -ENOMEM;
} }
parts[i] = subpart; if (n_parts == 1) {
ret = -EINVAL;
goto out;
} }
free(to_split2);
if (ret >= 0) { ret = stat(path, &sb);
const char *path = parts[0]; if (ret < 0)
const char *mode = parts[1]; goto out;
struct stat sb; dev = sb.st_rdev;
stat(path, &sb);
dev_t dev = sb.st_rdev;
char type = 0;
mode_t m = sb.st_mode & S_IFMT; mode_t m = sb.st_mode & S_IFMT;
switch (m) { switch (m) {
case S_IFBLK: case S_IFBLK:
...@@ -1966,42 +1950,52 @@ static int lxc_cgroup_set_data(const char *filename, const char *value, struct c ...@@ -1966,42 +1950,52 @@ static int lxc_cgroup_set_data(const char *filename, const char *value, struct c
if (type == 0) { if (type == 0) {
ERROR("Unsupported device type %i for %s", m, path); ERROR("Unsupported device type %i for %s", m, path);
ret = -EINVAL; ret = -EINVAL;
} else { goto out;
unsigned long major = MAJOR(dev), minor = MINOR(dev); }
ret = snprintf(converted_value, 50, major = MAJOR(dev), minor = MINOR(dev);
ret = snprintf(dest, 50,
"%c %lu:%lu %s", type, major, minor, mode); "%c %lu:%lu %s", type, major, minor, mode);
if (ret < 0 || ret >= 50) { if (ret < 0 || ret >= 50) {
ERROR("Error on configuration value \"%c %lu:%lu %s\" (max 50 chars)", ERROR("Error on configuration value \"%c %lu:%lu %s\" (max 50 chars)",
type, major, minor, mode); type, major, minor, mode);
ret = -ENAMETOOLONG; ret = -ENAMETOOLONG;
goto out;
} }
} ret = 0;
}
for (i = 0; i < n_parts; ++i) { out:
char *subpart = parts[i]; free(path);
if (subpart != NULL) {
free(subpart);
}
}
free(parts);
}
}
} else {
strcpy(converted_value, value);
}
}
if (ret <= 0) {
return ret; return ret;
} }
} else {
strcpy(converted_value, value); /*
* Called from setup_limits - here we have the container's cgroup_data because
* we created the cgroups
*/
static int lxc_cgroup_set_data(const char *filename, const char *value, struct cgfsng_handler_data *d)
{
char *subsystem = NULL, *p;
int ret = 0;
struct hierarchy *h;
char converted_value[50]; // "b|c <2^64-1>:<2^64-1> r|w|m" = 47 chars max
subsystem = alloca(strlen(filename) + 1);
strcpy(subsystem, filename);
if ((p = strchr(subsystem, '.')) != NULL)
*p = '\0';
if (strcmp("devices.allow", filename) == 0 && value[0] == '/') {
ret = convert_devpath(value, converted_value);
if (ret < 0)
return ret;
value = converted_value;
} }
h = get_hierarchy(subsystem); h = get_hierarchy(subsystem);
if (h) { if (h) {
char *fullpath = must_make_path(h->fullcgpath, filename, NULL); char *fullpath = must_make_path(h->fullcgpath, filename, NULL);
ret = lxc_write_to_file(fullpath, converted_value, strlen(converted_value), false); ret = lxc_write_to_file(fullpath, value, strlen(value), false);
free(fullpath); free(fullpath);
} }
return ret; return ret;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment