// libbpf
#include <bpf/bpf.h>
+#include <pakfire/ctx.h>
#include <pakfire/cgroup.h>
#include <pakfire/logging.h>
-#include <pakfire/pakfire.h>
#include <pakfire/path.h>
#include <pakfire/string.h>
#include <pakfire/util.h>
PAKFIRE_CGROUP_CONTROLLER_IO;
struct pakfire_cgroup {
- struct pakfire* pakfire;
+ struct pakfire_ctx* ctx;
int nrefs;
// Store the root path
}
if (r)
- ERROR(cgroup->pakfire, "Could not determine cgroup root: %m\n");
+ CTX_ERROR(cgroup->ctx, "Could not determine cgroup root: %m\n");
return r;
}
// Determine the path of the parent
r = pakfire_path_dirname(path, cgroup->path);
if (r) {
- ERROR(cgroup->pakfire, "Could not determine path for parent cgroup: %m\n");
+ CTX_ERROR(cgroup->ctx, "Could not determine path for parent cgroup: %m\n");
return NULL;
}
*path = '\0';
// Open the cgroup
- r = pakfire_cgroup_open(&parent, cgroup->pakfire, path, 0);
+ r = pakfire_cgroup_open(&parent, cgroup->ctx, path, 0);
if (r) {
- ERROR(cgroup->pakfire, "Could not open parent cgroup: %m\n");
+ CTX_ERROR(cgroup->ctx, "Could not open parent cgroup: %m\n");
parent = NULL;
}
}
static void pakfire_cgroup_free(struct pakfire_cgroup* cgroup) {
- DEBUG(cgroup->pakfire, "Releasing cgroup %s at %p\n",
+ CTX_DEBUG(cgroup->ctx, "Releasing cgroup %s at %p\n",
pakfire_cgroup_name(cgroup), cgroup);
// Close the file descriptors
- if (cgroup->fd > 0)
+ if (cgroup->fd >= 0)
close(cgroup->fd);
- if (cgroup->devicesfd > 0)
+ if (cgroup->devicesfd >= 0)
close(cgroup->devicesfd);
-
- pakfire_unref(cgroup->pakfire);
+ if (cgroup->ctx)
+ pakfire_ctx_unref(cgroup->ctx);
free(cgroup);
}
r = bpf_prog_load(BPF_PROG_TYPE_CGROUP_DEVICE, NULL, "GPL",
program, sizeof(program) / sizeof(*program), &opts);
if (r < 0) {
- ERROR(cgroup->pakfire, "Could not load BPF program: %m\n");
+ CTX_ERROR(cgroup->ctx, "Could not load BPF program: %m\n");
return r;
}
r = bpf_prog_attach(cgroup->devicesfd, cgroup->fd,
BPF_CGROUP_DEVICE, BPF_F_ALLOW_MULTI);
if (r) {
- ERROR(cgroup->pakfire, "Could not attach BPF program to cgroup: %m\n");
+ CTX_ERROR(cgroup->ctx, "Could not attach BPF program to cgroup: %m\n");
return r;
}
static int pakfire_cgroup_open_root(struct pakfire_cgroup* cgroup) {
int fd = open(cgroup->root, O_DIRECTORY|O_PATH|O_CLOEXEC);
if (fd < 0) {
- ERROR(cgroup->pakfire, "Could not open %s: %m\n", cgroup->root);
+ CTX_ERROR(cgroup->ctx, "Could not open %s: %m\n", cgroup->root);
return -1;
}
char path[PATH_MAX];
int r;
- DEBUG(cgroup->pakfire, "Trying to create cgroup %s\n", pakfire_cgroup_name(cgroup));
+ CTX_DEBUG(cgroup->ctx, "Trying to create cgroup %s\n", pakfire_cgroup_name(cgroup));
// Compose the absolute path
r = pakfire_path_append(path, cgroup->root, cgroup->path);
// Exit on all other errors
default:
- ERROR(cgroup->pakfire, "Could not open cgroup %s: %m\n",
+ CTX_ERROR(cgroup->ctx, "Could not open cgroup %s: %m\n",
pakfire_cgroup_name(cgroup));
goto ERROR;
}
// Open cgroup.procs
int fd = openat(cgroup->fd, "cgroup.procs", O_CLOEXEC);
if (fd < 0) {
- ERROR(cgroup->pakfire, "%s: Could not open %s: %m\n",
+ CTX_ERROR(cgroup->ctx, "%s: Could not open %s: %m\n",
pakfire_cgroup_name(cgroup), path);
goto ERROR;
}
// Check if this cgroup has been destroyed already
if (!cgroup->fd) {
- ERROR(cgroup->pakfire, "Trying to read from destroyed cgroup\n");
+ CTX_ERROR(cgroup->ctx, "Trying to read from destroyed cgroup\n");
return -1;
}
// Open the file
int fd = openat(cgroup->fd, path, O_CLOEXEC);
if (fd < 0) {
- DEBUG(cgroup->pakfire, "Could not open %s/%s: %m\n",
+ CTX_DEBUG(cgroup->ctx, "Could not open %s/%s: %m\n",
pakfire_cgroup_name(cgroup), path);
goto ERROR;
}
// Read file content into buffer
bytes_read = read(fd, buffer, length);
if (bytes_read < 0) {
- DEBUG(cgroup->pakfire, "Could not read from %s/%s: %m\n",
+ CTX_DEBUG(cgroup->ctx, "Could not read from %s/%s: %m\n",
pakfire_cgroup_name(cgroup), path);
goto ERROR;
}
// Check if this cgroup has been destroyed already
if (!cgroup->fd) {
- ERROR(cgroup->pakfire, "Trying to write to destroyed cgroup\n");
+ CTX_ERROR(cgroup->ctx, "Trying to write to destroyed cgroup\n");
errno = EPERM;
return 1;
}
// Open the file
int fd = openat(cgroup->fd, path, O_WRONLY|O_CLOEXEC);
if (fd < 0) {
- DEBUG(cgroup->pakfire, "Could not open %s/%s for writing: %m\n",
+ CTX_DEBUG(cgroup->ctx, "Could not open %s/%s for writing: %m\n",
pakfire_cgroup_name(cgroup), path);
return 1;
}
// Check if content was written okay
if (bytes_written < 0) {
- DEBUG(cgroup->pakfire, "Could not write to %s/%s: %m\n",
+ CTX_DEBUG(cgroup->ctx, "Could not write to %s/%s: %m\n",
pakfire_cgroup_name(cgroup), path);
r = 1;
}
char* token = strtok_r(buffer, " \n", &p);
while (token) {
- DEBUG(cgroup->pakfire, "Found controller '%s'\n", token);
+ CTX_DEBUG(cgroup->ctx, "Found controller '%s'\n", token);
// Try finding this controller
int controller = pakfire_cgroup_find_controller_by_name(token);
// Find all enabled controllers
const int enabled_controllers = pakfire_cgroup_enabled_controllers(cgroup);
if (enabled_controllers < 0) {
- ERROR(cgroup->pakfire, "Could not fetch enabled controllers: %m\n");
+ CTX_ERROR(cgroup->ctx, "Could not fetch enabled controllers: %m\n");
goto ERROR;
}
// Exit if everything is already enabled
if (!controllers) {
- DEBUG(cgroup->pakfire, "All controllers are already enabled\n");
+ CTX_DEBUG(cgroup->ctx, "All controllers are already enabled\n");
return 0;
}
// Find all available controllers
const int available_controllers = pakfire_cgroup_available_controllers(cgroup);
if (available_controllers < 0) {
- ERROR(cgroup->pakfire, "Could not fetch available controllers: %m\n");
+ CTX_ERROR(cgroup->ctx, "Could not fetch available controllers: %m\n");
goto ERROR;
}
// Are all controllers we need available, yet?
if (controllers & ~available_controllers) {
- DEBUG(cgroup->pakfire, "Not all controllers are available, yet\n");
+ CTX_DEBUG(cgroup->ctx, "Not all controllers are available, yet\n");
parent = pakfire_cgroup_parent(cgroup);
// Fetch name
const char* name = pakfire_cgroup_controller_name(controller);
- DEBUG(cgroup->pakfire, "Enabling controller %s in cgroup %s\n",
+ CTX_DEBUG(cgroup->ctx, "Enabling controller %s in cgroup %s\n",
name, pakfire_cgroup_name(cgroup));
// Try enabling the controller (this will succeed if it already is enabled)
r = pakfire_cgroup_write(cgroup, "cgroup.subtree_control", "+%s\n", name);
if (r) {
- ERROR(cgroup->pakfire, "Could not enable controller %s in cgroup %s\n",
+ CTX_ERROR(cgroup->ctx, "Could not enable controller %s in cgroup %s\n",
name, pakfire_cgroup_name(cgroup));
goto ERROR;
}
If the cgroup doesn't exist, it will be created including any parent cgroups.
*/
int pakfire_cgroup_open(struct pakfire_cgroup** cgroup,
- struct pakfire* pakfire, const char* path, int flags) {
+ struct pakfire_ctx* ctx, const char* path, int flags) {
int r = 1;
// Allocate the cgroup struct
if (!c)
return 1;
- DEBUG(pakfire, "Allocated cgroup %s at %p\n", path, c);
+ CTX_DEBUG(ctx, "Allocated cgroup %s at %p\n", path, c);
- // Keep a reference to pakfire
- c->pakfire = pakfire_ref(pakfire);
+ // Store a reference to the context
+ c->ctx = pakfire_ctx_ref(ctx);
// Initialize reference counter
c->nrefs = 1;
return 1;
// Open the child group
- return pakfire_cgroup_open(child, cgroup->pakfire, path, flags);
+ return pakfire_cgroup_open(child, cgroup->ctx, path, flags);
}
static int pakfire_cgroup_procs_callback(struct pakfire_cgroup* cgroup,
}
static int send_sigkill(struct pakfire_cgroup* cgroup, const pid_t pid, void* data) {
- DEBUG(cgroup->pakfire, "Sending signal SIGKILL to PID %d\n", pid);
+ CTX_DEBUG(cgroup->ctx, "Sending signal SIGKILL to PID %d\n", pid);
int r = kill(pid, SIGKILL);
if (r < 0 && errno != ESRCH) {
- ERROR(cgroup->pakfire, "Could not send signal SIGKILL to PID %d: %m\n", pid);
+ CTX_ERROR(cgroup->ctx, "Could not send signal SIGKILL to PID %d: %m\n", pid);
return r;
}
Immediately kills all processes in this cgroup
*/
static int pakfire_cgroup_killall(struct pakfire_cgroup* cgroup) {
- DEBUG(cgroup->pakfire, "%s: Killing all processes\n", pakfire_cgroup_name(cgroup));
+ CTX_DEBUG(cgroup->ctx, "%s: Killing all processes\n", pakfire_cgroup_name(cgroup));
// Do we have support for cgroup.kill?
int r = pakfire_cgroup_access(cgroup, "cgroup.kill", F_OK, 0);
return 1;
}
- DEBUG(cgroup->pakfire, "Destroying cgroup %s\n", pakfire_cgroup_name(cgroup));
+ CTX_DEBUG(cgroup->ctx, "Destroying cgroup %s\n", pakfire_cgroup_name(cgroup));
// Kill everything in this group
r = pakfire_cgroup_killall(cgroup);
// Delete the directory
r = unlinkat(fd, cgroup->path, AT_REMOVEDIR);
if (r)
- ERROR(cgroup->pakfire, "Could not destroy cgroup: %m\n");
+ CTX_ERROR(cgroup->ctx, "Could not destroy cgroup: %m\n");
// Close fd
close(fd);
if (r)
return r;
- DEBUG(cgroup->pakfire, "%s: Setting guaranteed memory to %zu byte(s)\n",
+ CTX_DEBUG(cgroup->ctx, "%s: Setting guaranteed memory to %zu byte(s)\n",
pakfire_cgroup_name(cgroup), mem);
// Set value
r = pakfire_cgroup_write(cgroup, "memory.min", "%zu\n", mem);
if (r)
- ERROR(cgroup->pakfire, "%s: Could not set guaranteed memory: %m\n",
+ CTX_ERROR(cgroup->ctx, "%s: Could not set guaranteed memory: %m\n",
pakfire_cgroup_name(cgroup));
return r;
if (r)
return r;
- DEBUG(cgroup->pakfire, "%s: Setting memory limit to %zu byte(s)\n",
+ CTX_DEBUG(cgroup->ctx, "%s: Setting memory limit to %zu byte(s)\n",
pakfire_cgroup_name(cgroup), mem);
// Set value
r = pakfire_cgroup_write(cgroup, "memory.max", "%zu\n", mem);
if (r)
- ERROR(cgroup->pakfire, "%s: Could not set memory limit: %m\n",
+ CTX_ERROR(cgroup->ctx, "%s: Could not set memory limit: %m\n",
pakfire_cgroup_name(cgroup));
return r;
if (r)
return r;
- DEBUG(cgroup->pakfire, "%s: Setting PID limit to %zu\n",
+ CTX_DEBUG(cgroup->ctx, "%s: Setting PID limit to %zu\n",
pakfire_cgroup_name(cgroup), limit);
// Set value
r = pakfire_cgroup_write(cgroup, "pids.max", "%zu\n", limit);
if (r)
- ERROR(cgroup->pakfire, "%s: Could not set PID limit: %m\n",
+ CTX_ERROR(cgroup->ctx, "%s: Could not set PID limit: %m\n",
pakfire_cgroup_name(cgroup));
return r;
void* data, char* line) {
char* p = NULL;
- DEBUG(cgroup->pakfire, "Parsing line: %s\n", line);
+ CTX_DEBUG(cgroup->ctx, "Parsing line: %s\n", line);
char key[NAME_MAX];
unsigned long val = 0;
// Ignore the rest
default:
- DEBUG(cgroup->pakfire, "%s: Unknown value in cgroup stats (%d): %s\n",
+ CTX_DEBUG(cgroup->ctx, "%s: Unknown value in cgroup stats (%d): %s\n",
pakfire_cgroup_name(cgroup), i, elem);
break;
}
// Check if we parsed both fields
if (i < 2) {
- ERROR(cgroup->pakfire, "Could not parse line\n");
+ CTX_ERROR(cgroup->ctx, "Could not parse line\n");
return 1;
}
char buffer[BUFFER_SIZE];
- DEBUG(cgroup->pakfire, "%s: Reading stats from %s\n", pakfire_cgroup_name(cgroup), path);
+ CTX_DEBUG(cgroup->ctx, "%s: Reading stats from %s\n", pakfire_cgroup_name(cgroup), path);
// Open the file
r = pakfire_cgroup_read(cgroup, path, buffer, sizeof(buffer));
}
}
- DEBUG(cgroup->pakfire, "Unknown key for CPU stats: %s = %lu\n", key, val);
+ CTX_DEBUG(cgroup->ctx, "Unknown key for CPU stats: %s = %lu\n", key, val);
return 0;
}
}
// Log any unknown keys
- DEBUG(cgroup->pakfire, "Unknown key for memory stats: %s = %lu\n", key, val);
+ CTX_DEBUG(cgroup->ctx, "Unknown key for memory stats: %s = %lu\n", key, val);
return 0;
}
ERROR:
if (r)
- ERROR(cgroup->pakfire, "%s: Could not read cgroup stats: %m\n",
+ CTX_ERROR(cgroup->ctx, "%s: Could not read cgroup stats: %m\n",
pakfire_cgroup_name(cgroup));
return r;
return 1;
}
- DEBUG(cgroup->pakfire, "%s: Total CPU time usage: %lu\n",
+ CTX_DEBUG(cgroup->ctx, "%s: Total CPU time usage: %lu\n",
pakfire_cgroup_name(cgroup), stats->cpu.usage_usec);
return 0;