bool attach_nbd(char *src, struct lxc_conf *conf) { __do_free char *orig; char *p, path[50]; int i = 0; orig = must_copy_string(src); /* if path is followed by a partition, drop that for now */ p = strchr(orig, ':'); if (p) *p = '\0'; for (;;) { sprintf(path, "/dev/nbd%d", i); if (!file_exists(path)) return false; if (nbd_busy(i)) { i++; continue; } if (!clone_attach_nbd(path, orig)) return false; conf->nbd_idx = i; return true; } }
static bool store_hierarchy(char *stridx, char *h) { int idx = atoi(stridx); size_t needed_len = (idx + 1) * sizeof(char *); if (idx < 0 || idx > 30) { fprintf(stderr, "Error: corrupt /proc/self/cgroup\n"); return false; } if (!hierarchies) { hierarchies = malloc(needed_len); memset(hierarchies, 0, needed_len); num_hierarchies = idx + 1; } else if (idx >= num_hierarchies) { char **tmp; size_t old_len = (num_hierarchies + 1) * sizeof(char *); do { tmp = malloc(needed_len); } while (!tmp); memset(tmp, 0, needed_len); memcpy(tmp, hierarchies, old_len); free(hierarchies); hierarchies = tmp; num_hierarchies = idx + 1; } if (hierarchies[idx]) { fprintf(stderr, "Error: corrupt /proc/self/cgroup\n"); return false; } hierarchies[idx] = must_copy_string(h); return true; }
struct cgfs_files *cgfs_get_key(const char *controller, const char *cgroup, const char *file) { size_t len; char *fnam, *tmpc = find_mounted_controller(controller); struct stat sb; struct cgfs_files *newkey; int ret; if (!tmpc) return false; if (file && *file == '/') file++; if (file && index(file, '/')) return NULL; /* basedir / tmpc / cgroup / file \0 */ len = strlen(basedir) + strlen(tmpc) + strlen(cgroup) + 3; if (file) len += strlen(file) + 1; fnam = alloca(len); snprintf(fnam, len, "%s/%s/%s%s%s", basedir, tmpc, cgroup, file ? "/" : "", file ? file : ""); ret = stat(fnam, &sb); if (ret < 0) return NULL; do { newkey = malloc(sizeof(struct cgfs_files)); } while (!newkey); if (file) newkey->name = must_copy_string(file); else if (rindex(cgroup, '/')) newkey->name = must_copy_string(rindex(cgroup, '/')); else newkey->name = must_copy_string(cgroup); newkey->uid = sb.st_uid; newkey->gid = sb.st_gid; newkey->mode = sb.st_mode; return newkey; }
/* * append an entry to the clist. Do not fail. * *clist must be NULL the first time we are called. * * We also handle named subsystems here. Any controller which is not a * kernel subsystem, we prefix 'name='. Any which is both a kernel and * named subsystem, we refuse to use because we're not sure which we * have here. (TODO - we could work around this in some cases by just * remounting to be unambiguous, or by comparing mountpoint contents * with current cgroup) * * The last entry will always be NULL. */ static void must_append_controller(char **klist, char **nlist, char ***clist, char *entry) { int newentry; char *copy; if (string_in_list(klist, entry) && string_in_list(nlist, entry)) { ERROR("Refusing to use ambiguous controller '%s'", entry); ERROR("It is both a named and kernel subsystem"); return; } newentry = append_null_to_list((void ***)clist); if (strncmp(entry, "name=", 5) == 0) copy = must_copy_string(entry); else if (string_in_list(klist, entry)) copy = must_copy_string(entry); else copy = must_prefix_named(entry); (*clist)[newentry] = copy; }
bool lxc_string_in_list(const char *needle, const char *haystack, char _sep) { __do_free char *str = NULL; char *token; char sep[2] = { _sep, '\0' }; if (!haystack || !needle) return 0; str = must_copy_string(haystack); lxc_iterate_parts(token, str, sep) if (strcmp(needle, token) == 0) return 1; return 0; }