/* Copyright 2016 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#define _GNU_SOURCE /* For asprintf */

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "container_cgroup.h"

static const char *cgroup_names[NUM_CGROUP_TYPES] = {
	"cpu", "cpuacct", "devices", "freezer",
};

static int open_cgroup_file(const char *cgroup_path, const char *name)
{
	int fd;
	char *path = NULL;

	if (asprintf(&path, "%s/%s", cgroup_path, name) < 0)
		return -errno;

	fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0664);
	if (fd == -1)
		fd = -errno;
	free(path);
	return fd;
}

static int write_cgroup_file(const char *cgroup_path, const char *name,
			     const char *str)
{
	int fd;
	int rc = 0;

	fd = open_cgroup_file(cgroup_path, name);
	if (fd < 0)
		return fd;
	const char *buffer = str;
	size_t len = strlen(str);
	if (write(fd, buffer, len) != len)
		rc = -errno;
	close(fd);
	return rc;
}

static int write_cgroup_file_int(const char *cgroup_path, const char *name,
				 const int value)
{
	char *str = NULL;
	int rc;

	if (asprintf(&str, "%d", value) < 0)
		return -errno;

	rc = write_cgroup_file(cgroup_path, name, str);
	free(str);
	return rc;
}

static int freeze(const struct container_cgroup *cg)
{
	return write_cgroup_file(cg->cgroup_paths[CGROUP_FREEZER],
				 "freezer.state", "FROZEN\n");
}

static int thaw(const struct container_cgroup *cg)
{
	return write_cgroup_file(cg->cgroup_paths[CGROUP_FREEZER],
				 "freezer.state", "THAWED\n");
}

static int deny_all_devices(const struct container_cgroup *cg)
{
	return write_cgroup_file(cg->cgroup_paths[CGROUP_DEVICES],
				 "devices.deny", "a\n");
}

static int add_device(const struct container_cgroup *cg, int major, int minor,
		      int read, int write, int modify, char type)
{
	char *perm_string = NULL;
	int rc;

	if (type != 'b' && type != 'c')
		return -EINVAL;
	if (!read && !write)
		return -EINVAL;

	if (minor >= 0) {
		if (asprintf(&perm_string, "%c %d:%d %s%s%s\n",
			     type, major, minor,
			     read ? "r" : "", write ? "w" : "",
			     modify ? "m" : "") < 0)
			return -errno;
	} else {
		/* Set perms for all devices with this major number. */
		if (asprintf(&perm_string, "%c %d:* %s%s%s\n",
			     type, major,
			     read ? "r" : "", write ? "w" : "",
			     modify ? "m" : "") < 0)
			return -errno;
	}
	rc = write_cgroup_file(cg->cgroup_paths[CGROUP_DEVICES],
			      "devices.allow", perm_string);
	free(perm_string);
	return rc;
}

static int set_cpu_shares(const struct container_cgroup *cg, int shares)
{
	return write_cgroup_file_int(cg->cgroup_paths[CGROUP_CPU],
				     "cpu.shares", shares);
}

static int set_cpu_quota(const struct container_cgroup *cg, int quota)
{
	return write_cgroup_file_int(cg->cgroup_paths[CGROUP_CPU],
				     "cpu.cfs_quota_us", quota);
}

static int set_cpu_period(const struct container_cgroup *cg, int period)
{
	return write_cgroup_file_int(cg->cgroup_paths[CGROUP_CPU],
				     "cpu.cfs_period_us", period);
}

static int set_cpu_rt_runtime(const struct container_cgroup *cg, int rt_runtime)
{
	return write_cgroup_file_int(cg->cgroup_paths[CGROUP_CPU],
				     "cpu.rt_runtime_us", rt_runtime);
}

static int set_cpu_rt_period(const struct container_cgroup *cg, int rt_period)
{
	return write_cgroup_file_int(cg->cgroup_paths[CGROUP_CPU],
				     "cpu.rt_period_us", rt_period);
}

static const struct cgroup_ops cgroup_ops = {
	.freeze = freeze,
	.thaw = thaw,
	.deny_all_devices = deny_all_devices,
	.add_device = add_device,
	.set_cpu_shares = set_cpu_shares,
	.set_cpu_quota = set_cpu_quota,
	.set_cpu_period = set_cpu_period,
	.set_cpu_rt_runtime = set_cpu_rt_runtime,
	.set_cpu_rt_period = set_cpu_rt_period,
};

static int create_cgroup_as_owner(const char *cgroup_path, uid_t cgroup_owner)
{
	int mkdir_rc;

	/*
	 * If running as root and the cgroup owner is a user, create the cgroup
	 * as that user.
	 */
	if (getuid() == 0 && cgroup_owner != 0) {
		if (seteuid(cgroup_owner))
			return -errno;
		/*
		 * CAUTION: Make sure that no return path forgets to set the
		 * user back to root from here.
		 */
		mkdir_rc = mkdir(cgroup_path, S_IRWXU | S_IRWXG);

		if (seteuid(0))
			return -errno;
	} else {
		mkdir_rc = mkdir(cgroup_path, S_IRWXU | S_IRWXG);
	}

	if (mkdir_rc < 0 && errno != EEXIST)
		return -errno;

	return 0;
}

struct container_cgroup *container_cgroup_new(const char *name,
					      const char *cgroup_root,
					      const char *cgroup_parent,
					      uid_t cgroup_owner)
{
	int i;
	struct container_cgroup *cg;

	cg = calloc(1, sizeof(*cg));
	if (!cg)
		return NULL;

	for (i = 0; i < NUM_CGROUP_TYPES; ++i) {
		if (cgroup_parent) {
			if (asprintf(&cg->cgroup_paths[i], "%s/%s/%s/%s",
				     cgroup_root, cgroup_names[i],
				     cgroup_parent, name) < 0)
				goto error_free_cg;
		} else {
			if (asprintf(&cg->cgroup_paths[i], "%s/%s/%s",
				     cgroup_root, cgroup_names[i], name) < 0)
				goto error_free_cg;
		}

		if (create_cgroup_as_owner(cg->cgroup_paths[i], cgroup_owner))
			goto error_free_cg;

		if (asprintf(&cg->cgroup_tasks_paths[i], "%s/tasks",
			     cg->cgroup_paths[i]) < 0)
			goto error_free_cg;
	}

	cg->name = strdup(name);
	if (!cg->name)
		goto error_free_cg;
	cg->ops = &cgroup_ops;

	return cg;

error_free_cg:
	container_cgroup_destroy(cg);
	return NULL;
}

void container_cgroup_destroy(struct container_cgroup *cg)
{
	int i;

	free(cg->name);
	for (i = 0; i < NUM_CGROUP_TYPES; ++i) {
		if (!cg->cgroup_paths[i])
			continue;
		rmdir(cg->cgroup_paths[i]);
		free(cg->cgroup_paths[i]);
		free(cg->cgroup_tasks_paths[i]);
	}
	free(cg);
}

