samples/cgroup/memcg_event_listener.c

Source file repositories/reference/linux-study-clean/samples/cgroup/memcg_event_listener.c

File Facts

System
Linux kernel
Corpus path
samples/cgroup/memcg_event_listener.c
Extension
.c
Size
7205 bytes
Lines
329
Domain
Support Tooling And Documentation
Bucket
samples
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct memcg_counters {
	long low;
	long high;
	long max;
	long oom;
	long oom_kill;
	long oom_group_kill;
};

struct memcg_events {
	struct memcg_counters counters;
	char path[PATH_MAX];
	int inotify_fd;
	int inotify_wd;
};

static void print_memcg_counters(const struct memcg_counters *counters)
{
	printf("MEMCG events:\n");
	printf("\tlow: %ld\n", counters->low);
	printf("\thigh: %ld\n", counters->high);
	printf("\tmax: %ld\n", counters->max);
	printf("\toom: %ld\n", counters->oom);
	printf("\toom_kill: %ld\n", counters->oom_kill);
	printf("\toom_group_kill: %ld\n", counters->oom_group_kill);
}

static int get_memcg_counter(char *line, const char *name, long *counter)
{
	size_t len = strlen(name);
	char *endptr;
	long tmp;

	if (memcmp(line, name, len)) {
		warnx("Counter line %s has wrong name, %s is expected",
		      line, name);
		return -EINVAL;
	}

	/* skip the whitespace delimiter */
	len += 1;

	errno = 0;
	tmp = strtol(&line[len], &endptr, 10);
	if (((tmp == LONG_MAX || tmp == LONG_MIN) && errno == ERANGE) ||
	    (errno && !tmp)) {
		warnx("Failed to parse: %s", &line[len]);
		return -ERANGE;
	}

	if (endptr == &line[len]) {
		warnx("Not digits were found in line %s", &line[len]);
		return -EINVAL;
	}

	if (!(*endptr == '\0' || (*endptr == '\n' && *++endptr == '\0'))) {
		warnx("Further characters after number: %s", endptr);
		return -EINVAL;
	}

	*counter = tmp;

	return 0;
}

static int read_memcg_events(struct memcg_events *events, bool show_diff)
{
	FILE *fp = fopen(events->path, "re");
	size_t i;
	int ret = 0;
	bool any_new_events = false;
	char *line = NULL;
	size_t len = 0;
	struct memcg_counters new_counters;
	struct memcg_counters *counters = &events->counters;
	struct {
		const char *name;
		long *new;
		long *old;
	} map[] = {
		{
			.name = "low",
			.new = &new_counters.low,
			.old = &counters->low,
		},
		{
			.name = "high",
			.new = &new_counters.high,
			.old = &counters->high,
		},

Annotation

Implementation Notes