提交 9305c04d 编写于 作者: L LiFeng

lcr: adapt kata base on next_openeuler

Change-Id: Ie878be72e463273b1a007087ab08f8a9b51d44ab
Signed-off-by: NLiFeng <lifeng68@huawei.com>
上级 d97a1aae
......@@ -5,7 +5,7 @@ include(cmake/set_build_flags.cmake)
option(VERSION "set lcr version" ON)
if (VERSION STREQUAL "ON")
set(LCR_VERSION "1.0.18")
set(LCR_VERSION "1.0.19")
endif()
option(DEBUG "set lcr gcc option" ON)
......
%global _version 1.0.18
%global _release 20200105.223545.git6259bd3e
%global _version 1.0.19
%global _release 20200121.043807.gita1f42840
Name: lcr
Version: %{_version}
Release: %{_release}
......
......@@ -1000,7 +1000,7 @@ err_out:
return node;
}
static bool is_system_container(const oci_runtime_spec *container)
bool is_system_container(const oci_runtime_spec *container)
{
size_t i = 0;
for (i = 0; container->annotations != NULL && i < container->annotations->len; i++) {
......
......@@ -107,4 +107,7 @@ struct lcr_list *trans_annotations(const json_map_string_string *anno);
*/
struct lcr_list *get_needed_lxc_conf();
#endif /* __LCR_CONF_H */
bool is_system_container(const oci_runtime_spec *container);
#endif /*__LCR_CONF_H*/
此差异已折叠。
......@@ -144,7 +144,7 @@ void lcr_containers_info_free(struct lcr_container_info **info_arr, size_t size)
* param rootfs : the path of rootfs used for the container
* param oci_config_data : json string of oci config data
*/
bool lcr_create(const char *name, const char *lcrpath, const char *rootfs, const void *oci_config_data);
bool lcr_create(const char *name, const char *lcrpath, void *oci_config);
/*
* Start a container
......@@ -180,11 +180,6 @@ struct lcr_start_request {
uint32_t start_timeout;
const char *container_pidfile;
const char *exit_fifo;
uid_t uid;
gid_t gid;
gid_t *additional_gids;
size_t additional_gids_len;
};
bool lcr_start(const struct lcr_start_request *request);
......@@ -290,7 +285,6 @@ void lcr_free_errmsg();
bool lcr_get_container_pids(const char *name, const char *lcrpath, pid_t **pids, size_t *pids_len);
bool translate_spec(const struct lxc_container *c, const char *oci_json_data, const char *container_rootfs);
bool lcr_resize(const char *name, const char *lcrpath, unsigned int height, unsigned int width);
bool lcr_exec_resize(const char *name, const char *lcrpath, const char *suffix, unsigned int height,
unsigned int width);
......
......@@ -30,6 +30,7 @@
#include "log.h"
#include "error.h"
#include "oci_runtime_spec.h"
#include "lcrcontainer_extend.h"
// Cgroup Item Definition
#define CGROUP_BLKIO_WEIGHT "blkio.weight"
......@@ -67,90 +68,6 @@ static inline void add_array_kv(char **array, size_t total, size_t *pos, const c
add_array_elem(array, total, pos, v);
}
static int make_sure_linux(oci_runtime_spec *oci_spec)
{
if (oci_spec->linux == NULL) {
oci_spec->linux = util_common_calloc_s(sizeof(oci_runtime_config_linux));
if (oci_spec->linux == NULL) {
return -1;
}
}
return 0;
}
static int make_sure_linux_resources(oci_runtime_spec *oci_spec)
{
int ret = 0;
ret = make_sure_linux(oci_spec);
if (ret < 0) {
return -1;
}
if (oci_spec->linux->resources == NULL) {
oci_spec->linux->resources = util_common_calloc_s(sizeof(oci_runtime_config_linux_resources));
if (oci_spec->linux->resources == NULL) {
return -1;
}
}
return 0;
}
static int make_sure_linux_resources_blkio(oci_runtime_spec *oci_spec)
{
int ret = 0;
ret = make_sure_linux_resources(oci_spec);
if (ret < 0) {
return -1;
}
if (oci_spec->linux->resources->block_io == NULL) {
oci_spec->linux->resources->block_io =
util_common_calloc_s(sizeof(oci_runtime_config_linux_resources_block_io));
if (oci_spec->linux->resources->block_io == NULL) {
return -1;
}
}
return 0;
}
static int make_sure_linux_resources_cpu(oci_runtime_spec *oci_spec)
{
int ret = 0;
ret = make_sure_linux_resources(oci_spec);
if (ret < 0) {
return -1;
}
if (oci_spec->linux->resources->cpu == NULL) {
oci_spec->linux->resources->cpu = util_common_calloc_s(sizeof(oci_runtime_config_linux_resources_cpu));
if (oci_spec->linux->resources->cpu == NULL) {
return -1;
}
}
return 0;
}
static int make_sure_linux_resources_mem(oci_runtime_spec *oci_spec)
{
int ret = 0;
ret = make_sure_linux_resources(oci_spec);
if (ret < 0) {
return -1;
}
if (oci_spec->linux->resources->memory == NULL) {
oci_spec->linux->resources->memory = util_common_calloc_s(sizeof(oci_runtime_config_linux_resources_memory));
if (oci_spec->linux->resources->memory == NULL) {
return -1;
}
}
return 0;
}
static bool update_resources_cpuset_mems(struct lxc_container *c, const struct lcr_cgroup_resources *cr)
{
bool ret = false;
......@@ -416,284 +333,9 @@ err_out:
return ret;
}
static bool save_container_to_disk(const struct lxc_container *c, const oci_runtime_spec *container)
{
bool bret = true;
char *json_container = NULL;
struct parser_context ctr = { 0 };
parser_error err = NULL;
if (c == NULL || container == NULL) {
return false;
}
ctr.options = OPT_PARSE_STRICT;
ctr.stderr = stderr;
json_container = oci_runtime_spec_generate_json(container, &ctr, &err);
if (json_container == NULL) {
ERROR("Can not generate json: %s", err);
bret = false;
goto err_out;
}
if (!translate_spec(c, json_container, NULL)) {
bret = false;
goto err_out;
}
err_out:
free(json_container);
free(err);
return bret;
}
static int merge_cgroup_resources_cpu_shares(oci_runtime_spec *c, const struct lcr_cgroup_resources *cr)
{
if (cr->cpu_shares != 0) {
if (make_sure_linux_resources_cpu(c) != 0) {
return -1;
}
c->linux->resources->cpu->shares = cr->cpu_shares;
}
return 0;
}
static int merge_cgroup_resources_cpu_period(oci_runtime_spec *c, const struct lcr_cgroup_resources *cr)
{
if (cr->cpu_period != 0) {
if (make_sure_linux_resources_cpu(c) != 0) {
return -1;
}
c->linux->resources->cpu->period = cr->cpu_period;
}
return 0;
}
static int merge_cgroup_resources_cpu_quota(oci_runtime_spec *c, const struct lcr_cgroup_resources *cr)
{
if (cr->cpu_quota != 0) {
if (make_sure_linux_resources_cpu(c) != 0) {
return -1;
}
c->linux->resources->cpu->quota = (int64_t)(cr->cpu_quota);
}
return 0;
}
static int merge_cgroup_resources_cpuset_cpus(oci_runtime_spec *c, const struct lcr_cgroup_resources *cr)
{
if (cr->cpuset_cpus != NULL && strcmp(cr->cpuset_cpus, "") != 0) {
if (make_sure_linux_resources_cpu(c) != 0) {
return -1;
}
free(c->linux->resources->cpu->cpus);
c->linux->resources->cpu->cpus = util_strdup_s(cr->cpuset_cpus);
}
return 0;
}
static int merge_cgroup_resources_cpuset_mems(oci_runtime_spec *c, const struct lcr_cgroup_resources *cr)
{
if (cr->cpuset_mems != NULL && strcmp(cr->cpuset_mems, "") != 0) {
if (make_sure_linux_resources_cpu(c) != 0) {
return -1;
}
free(c->linux->resources->cpu->mems);
c->linux->resources->cpu->mems = util_strdup_s(cr->cpuset_mems);
}
return 0;
}
static bool merge_cgroup_resources_cpu(oci_runtime_spec *c, const struct lcr_cgroup_resources *cr)
{
bool ret = true;
if (merge_cgroup_resources_cpu_shares(c, cr) != 0) {
ret = false;
goto out;
}
if (merge_cgroup_resources_cpu_period(c, cr) != 0) {
ret = false;
goto out;
}
if (merge_cgroup_resources_cpu_quota(c, cr) != 0) {
ret = false;
goto out;
}
if (merge_cgroup_resources_cpuset_cpus(c, cr) != 0) {
ret = false;
goto out;
}
if (merge_cgroup_resources_cpuset_mems(c, cr) != 0) {
ret = false;
goto out;
}
out:
return ret;
}
static int merge_cgroup_resources_mem_limit(oci_runtime_spec *c, const struct lcr_cgroup_resources *cr)
{
if (cr->memory_limit != 0) {
if (make_sure_linux_resources_mem(c) != 0) {
return -1;
}
c->linux->resources->memory->limit = (int64_t)(cr->memory_limit);
}
return 0;
}
static int merge_cgroup_resources_mem_reservation(oci_runtime_spec *c, const struct lcr_cgroup_resources *cr)
{
if (cr->memory_reservation != 0) {
if (make_sure_linux_resources_mem(c) != 0) {
return -1;
}
c->linux->resources->memory->reservation = (int64_t)(cr->memory_reservation);
}
return 0;
}
static int merge_cgroup_resources_mem_swap(oci_runtime_spec *c, const struct lcr_cgroup_resources *cr)
{
if (cr->memory_swap != 0) {
if (make_sure_linux_resources_mem(c) != 0) {
return -1;
}
c->linux->resources->memory->swap = (int64_t)(cr->memory_swap);
}
return 0;
}
static int merge_cgroup_resources_kernel_memory_limit(oci_runtime_spec *c, const struct lcr_cgroup_resources *cr)
{
if (cr->kernel_memory_limit != 0) {
if (make_sure_linux_resources_mem(c) != 0) {
return -1;
}
c->linux->resources->memory->kernel = (int64_t)(cr->kernel_memory_limit);
}
return 0;
}
static bool merge_cgroup_resources_mem(oci_runtime_spec *c, const struct lcr_cgroup_resources *cr)
{
bool ret = true;
if (merge_cgroup_resources_mem_limit(c, cr) != 0) {
ret = false;
goto out;
}
if (merge_cgroup_resources_mem_reservation(c, cr) != 0) {
ret = false;
goto out;
}
if (merge_cgroup_resources_mem_swap(c, cr) != 0) {
ret = false;
goto out;
}
if (merge_cgroup_resources_kernel_memory_limit(c, cr) != 0) {
ret = false;
goto out;
}
out:
return ret;
}
static int merge_cgroup_resources_blkio_weight(oci_runtime_spec *c, const struct lcr_cgroup_resources *cr)
{
if (cr->blkio_weight != 0) {
if (make_sure_linux_resources_blkio(c) != 0) {
return -1;
}
c->linux->resources->block_io->weight = (int)(cr->blkio_weight);
}
return 0;
}
static bool merge_cgroup_resources(oci_runtime_spec *c, const struct lcr_cgroup_resources *cr)
{
bool ret = true;
if (c == NULL || cr == NULL) {
return false;
}
if (merge_cgroup_resources_blkio_weight(c, cr) != 0) {
ret = false;
goto out;
}
ret = merge_cgroup_resources_cpu(c, cr);
if (!ret) {
goto out;
}
ret = merge_cgroup_resources_mem(c, cr);
if (!ret) {
goto out;
}
out:
return ret;
}
bool do_update(struct lxc_container *c, const char *name, const char *lcrpath, const struct lcr_cgroup_resources *cr)
{
int rc = 0;
bool bret = false;
bool restore = false;
char *config_json_file = NULL;
oci_runtime_spec *container = NULL;
oci_runtime_spec *backupcontainer = NULL;
struct parser_context ctr = { OPT_PARSE_STRICT, stderr };
parser_error err = NULL;
rc = asprintf(&config_json_file, "%s/%s/%s", lcrpath, name, OCICONFIGFILE);
if (rc < 0) {
SYSERROR("Failed to allocated memory");
return false;
}
backupcontainer = oci_runtime_spec_parse_file(config_json_file, &ctr, &err);
if (backupcontainer == NULL) {
ERROR("Can not parse %s: %s", OCICONFIGFILE, err);
goto out_free;
}
container = oci_runtime_spec_parse_file(config_json_file, &ctr, &err);
if (container == NULL) {
ERROR("Can not parse %s: %s", OCICONFIGFILE, err);
goto out_free;
}
if (!merge_cgroup_resources(container, cr)) {
ERROR("Failed to merge cgroup resources");
goto out_free;
}
if (!save_container_to_disk(c, container)) {
ERROR("Failed to save config to disk");
restore = true;
goto restore;
}
// If container is not running, update config file is enough,
// resources will be updated when the container is started again.
......@@ -702,24 +344,13 @@ bool do_update(struct lxc_container *c, const char *name, const char *lcrpath, c
if (c->is_running(c)) {
if (!update_resources(c, cr) && c->is_running(c)) {
ERROR("Filed to update cgroup resources");
restore = true;
goto restore;
goto out_free;
}
}
bret = true;
restore:
if (restore && !save_container_to_disk(c, backupcontainer)) {
ERROR("Failed to restore");
bret = false;
}
out_free:
free_oci_runtime_spec(backupcontainer);
free_oci_runtime_spec(container);
free(config_json_file);
free(err);
if (bret) {
clear_error_message(&g_lcr_error);
}
......
......@@ -33,6 +33,7 @@
#include "utils.h"
#include "log.h"
#include "conf.h"
#include "oci_runtime_hooks.h"
static struct lxc_container *lcr_new_container(const char *name, const char *path)
{
......@@ -188,29 +189,12 @@ out:
return ret ? 0 : -1;
}
static int trans_rootfs_linux(struct lcr_list *lcr_conf, const char *container_rootfs, oci_runtime_spec *container,
static int trans_rootfs_linux(struct lcr_list *lcr_conf, oci_runtime_spec *container,
char **seccomp)
{
int ret = -1;
struct lcr_list *node = NULL;
/* merge the rootfs config */
if (container_rootfs != NULL) {
if (!container->root) {
container->root = util_common_calloc_s(sizeof(oci_runtime_spec_root));
if (!container->root) {
ERROR("Out of memory");
goto out;
}
}
if (container->root->path) {
free(container->root->path);
}
container->root->path = util_strdup_s(container_rootfs);
}
/* lxc.rootfs
* lxc.rootfs.options
*/
......@@ -682,7 +666,7 @@ out:
return ret;
}
struct lcr_list *lcr_oci2lcr(const struct lxc_container *c, const char *container_rootfs, oci_runtime_spec *container,
struct lcr_list *lcr_oci2lcr(const struct lxc_container *c, oci_runtime_spec *container,
char **seccomp)
{
struct lcr_list *lcr_conf = NULL;
......@@ -698,7 +682,7 @@ struct lcr_list *lcr_oci2lcr(const struct lxc_container *c, const char *containe
goto out_free;
}
if (trans_rootfs_linux(lcr_conf, container_rootfs, container, seccomp)) {
if (trans_rootfs_linux(lcr_conf, container, seccomp)) {
goto out_free;
}
......@@ -896,3 +880,211 @@ out_free:
return bret;
}
static int lcr_write_file(const char *path, const char *data, size_t len)
{
char *real_path = NULL;
int fd = -1;
int ret = -1;
if (path == NULL || strlen(path) == 0 || data == NULL || len == 0) {
return -1;
}
if (util_ensure_path(&real_path, path) < 0) {
ERROR("Failed to ensure path %s", path);
goto out_free;
}
fd = util_open(real_path, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, CONFIG_FILE_MODE);
if (fd == -1) {
ERROR("Create file %s failed", real_path);
lcr_set_error_message(LCR_ERR_RUNTIME, "Create file %s failed", real_path);
goto out_free;
}
if (write(fd, data, len) == -1) {
ERROR("write data to %s failed: %s", real_path, strerror(errno));
goto out_free;
}
ret = 0;
out_free:
if (fd != -1) {
close(fd);
}
free(real_path);
return ret;
}
static bool lcr_write_ocihooks(const char *path, const oci_runtime_spec_hooks *hooks)
{
bool ret = false;
struct parser_context ctx = { OPT_PARSE_STRICT, stderr };
parser_error err = NULL;
char *json_hooks = oci_runtime_spec_hooks_generate_json(hooks, &ctx, &err);
if (json_hooks == NULL) {
ERROR("Failed to generate json: %s", err);
goto out_free;
}
if (lcr_write_file(path, json_hooks, strlen(json_hooks)) == -1) {
ERROR("write json hooks failed: %s", strerror(errno));
goto out_free;
}
ret = true;
out_free:
free(err);
free(json_hooks);
return ret;
}
static bool lcr_save_ocihooks(const char *name, const char *lcrpath, const oci_runtime_spec_hooks *hooks)
{
const char *path = lcrpath ? lcrpath : LCRPATH;
char ocihook[PATH_MAX] = { 0 };
char *bundle = NULL;
bool bret = false;
int nret = 0;
if (name == NULL) {
ERROR("Missing name");
return false;
}
bundle = lcr_get_bundle(path, name);
if (bundle == NULL) {
return false;
}
nret = snprintf(ocihook, sizeof(ocihook), "%s/%s", bundle, OCIHOOKSFILE);
if (nret < 0 || (size_t)nret >= sizeof(ocihook)) {
ERROR("Failed to print string");
goto out_free;
}
bret = lcr_write_ocihooks(ocihook, hooks);
out_free:
free(bundle);
return bret;
}
/*
*Get the file path that needs to be mount
*/
static bool mount_get_bundle_file(char **bundle, const char *container_name, const char *lcrpath, const char *filename)
{
const char *path = lcrpath ? lcrpath : LCRPATH;
int nret = 0;
size_t len = 0;
if (strlen(container_name) > (((SIZE_MAX - strlen(path)) - strlen(filename)) - 3)) {
return false;
}
/* bundle = lcrpath + '/' + container_name + '/' + filename + '\0' */
len = strlen(path) + strlen(container_name) + strlen(filename) + 3;
*bundle = util_common_calloc_s(len);
if (*bundle == NULL) {
return false;
}
nret = snprintf(*bundle, len, "%s/%s/%s", path, container_name, filename);
if (nret < 0 || (size_t)nret >= len) {
return false;
}
return true;
}
static bool copy_host_file_to_bundle(const struct lxc_container *c, const char *rootfs, const char *filename)
{
char *bundle = NULL;
char full_path[PATH_MAX] = { 0 };
bool ret = true;
int nret;
nret = snprintf(full_path, sizeof(full_path), "%s%s%s", rootfs, "/etc/", filename);
if (nret < 0 || (size_t)nret >= sizeof(full_path)) {
goto out_free;
}
ret = mount_get_bundle_file(&bundle, c->name, c->config_path, filename);
if (!ret) {
goto out_free;
}
ret = util_copy_file(full_path, bundle, NETWORK_MOUNT_FILE_MODE);
if (!ret) {
goto out_free;
}
out_free:
free(bundle);
return ret;
}
static bool init_system_container_network(const struct lxc_container *c, const char *rootfs)
{
if (!copy_host_file_to_bundle(c, rootfs, "hostname")) {
ERROR("Failed to copy hostname from rootfs to container bundle");
return false;
}
if (!copy_host_file_to_bundle(c, rootfs, "hosts")) {
ERROR("Failed to copy hosts from rootfs to container bundle");
return false;
}
if (!copy_host_file_to_bundle(c, rootfs, "resolv.conf")) {
ERROR("Failed to copy resolv.conf from rootfs to container bundle");
return false;
}
return true;
}
bool translate_spec(const struct lxc_container *c, oci_runtime_spec *container)
{
bool ret = false;
struct lcr_list *lcr_conf = NULL;
char *seccomp_conf = NULL;
INFO("Translate new specification file");
if (is_system_container(container)) {
if (!init_system_container_network(c, container->root->path)) {
goto out_free_conf;
}
}
lcr_conf = lcr_oci2lcr(c, container, &seccomp_conf);
if (lcr_conf == NULL) {
ERROR("Translate configuration failed");
goto out_free_conf;
}
if (container->hooks != NULL && !lcr_save_ocihooks(c->name, c->config_path, container->hooks)) {
ERROR("Failed to save %s", OCIHOOKSFILE);
goto out_free_conf;
}
if (!lcr_save_spec(c->name, c->config_path, lcr_conf, seccomp_conf)) {
ERROR("Failed to save configuration");
goto out_free_conf;
}
ret = true;
out_free_conf:
lcr_free_config(lcr_conf);
free(lcr_conf);
free(seccomp_conf);
return ret;
}
......@@ -58,15 +58,10 @@ bool container_parse(const char *oci_filename, const char *oci_json_data, oci_ru
/*
* Translate oci specification to lcr configuration.
* You should pass oci_filename or oci_spec to this function.
* param oci_filename : oci spec filename, in json format
* param oci_json_data : json string of oci config data
* param new_container : return newest oci_runtime_spec struct
* param seccomp : return seccomp parsed from oci spec
* You should pass oci_filename or oci_spec to this function.
* return: a linked list
*/
struct lcr_list *lcr_oci2lcr(const struct lxc_container *c, const char *container_rootfs,
oci_runtime_spec *new_container,
struct lcr_list *lcr_oci2lcr(const struct lxc_container *c, oci_runtime_spec *container,
char **seccomp);
/*
......@@ -83,6 +78,7 @@ int lcr_containers_info_get(const char *lcrpath, struct lcr_container_info **inf
char *lcr_get_bundle(const char *lcrpath, const char *name);
bool translate_spec(const struct lxc_container *c, oci_runtime_spec *container);
#ifdef __cplusplus
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册