1 Star 0 Fork 44

firstadream/lxc

forked from src-openEuler/lxc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0004-refactor-patch-code-of-lxccontianer-and-so-on.patch 77.34 KB
一键复制 编辑 原始数据 按行查看 历史
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947
From 281d09f2dcd4dfd105b41d8da558d4a126ca190b Mon Sep 17 00:00:00 2001
From: WangFengTu <[email protected]>
Date: Mon, 18 Jul 2022 14:14:14 +0800
Subject: [PATCH] refactor patch code of lxccontianer and so on
Signed-off-by: WangFengTu <[email protected]>
---
src/lxc/af_unix.h | 6 +
src/lxc/cgroups/cgroup.h | 13 +
src/lxc/confile.c | 639 +++++++++++++++++++++++++++
src/lxc/lxccontainer.c | 898 +++++++++++++++++++++++++++++++++++++-
src/lxc/lxclock.c | 31 ++
src/lxc/mainloop.c | 16 +
src/lxc/path.c | 655 +++++++++++++++++++++++++++
src/lxc/storage/dir.c | 34 ++
src/lxc/storage/loop.c | 48 +-
src/lxc/storage/storage.c | 31 +-
10 files changed, 2367 insertions(+), 4 deletions(-)
create mode 100644 src/lxc/path.c
diff --git a/src/lxc/af_unix.h b/src/lxc/af_unix.h
index 5a1482c..be26ff0 100644
--- a/src/lxc/af_unix.h
+++ b/src/lxc/af_unix.h
@@ -41,4 +41,10 @@ extern int lxc_unix_connect(struct sockaddr_un *addr);
extern int lxc_unix_connect_type(struct sockaddr_un *addr, int type);
extern int lxc_socket_set_timeout(int fd, int rcv_timeout, int snd_timeout);
+#ifdef HAVE_ISULAD
+extern int lxc_abstract_unix_recv_fds_timeout(int fd, int *recvfds, int num_recvfds,
+ void *data, size_t size, unsigned int timeout);
+extern int lxc_named_unix_open(const char *path, int type, int flags);
+extern int lxc_named_unix_connect(const char *path);
+#endif
#endif /* __LXC_AF_UNIX_H */
diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h
index c5bf794..4791112 100644
--- a/src/lxc/cgroups/cgroup.h
+++ b/src/lxc/cgroups/cgroup.h
@@ -109,6 +109,11 @@ struct cgroup_ops {
char *container_cgroup;
char *monitor_cgroup;
+#ifdef HAVE_ISULAD
+ int errfd;
+ bool no_controller;
+#endif
+
/* @hierarchies
* - A NULL-terminated array of struct hierarchy, one per legacy
* hierarchy. No duplicates. First sufficient, writeable mounted
@@ -146,14 +151,22 @@ struct cgroup_ops {
*/
cgroup_layout_t cgroup_layout;
+#ifdef HAVE_ISULAD
+ int (*data_init)(struct cgroup_ops *ops, struct lxc_conf *conf);
+ bool (*payload_destroy)(struct cgroup_ops *ops, struct lxc_handler *handler);
+#else
int (*data_init)(struct cgroup_ops *ops);
void (*payload_destroy)(struct cgroup_ops *ops, struct lxc_handler *handler);
+#endif
void (*monitor_destroy)(struct cgroup_ops *ops, struct lxc_handler *handler);
bool (*monitor_create)(struct cgroup_ops *ops, struct lxc_handler *handler);
bool (*monitor_enter)(struct cgroup_ops *ops, struct lxc_handler *handler);
bool (*payload_create)(struct cgroup_ops *ops, struct lxc_handler *handler);
bool (*payload_enter)(struct cgroup_ops *ops, struct lxc_handler *handler);
const char *(*get_cgroup)(struct cgroup_ops *ops, const char *controller);
+#ifdef HAVE_ISULAD
+ const char *(*get_cgroup_full_path)(struct cgroup_ops *ops, const char *controller);
+#endif
bool (*escape)(const struct cgroup_ops *ops, struct lxc_conf *conf);
int (*num_hierarchies)(struct cgroup_ops *ops);
bool (*get_hierarchies)(struct cgroup_ops *ops, int n, char ***out);
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 4c27e7d..22d7255 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -147,6 +147,19 @@ lxc_config_define(tty_dir);
lxc_config_define(uts_name);
lxc_config_define(sysctl);
lxc_config_define(proc);
+#ifdef HAVE_ISULAD
+lxc_config_define(init_args);
+lxc_config_define(init_groups);
+lxc_config_define(populate_device);
+lxc_config_define(umask);
+lxc_config_define(rootfs_masked_paths);
+lxc_config_define(rootfs_ro_paths);
+lxc_config_define(systemd);
+lxc_config_define(console_log_driver);
+lxc_config_define(console_syslog_tag);
+lxc_config_define(console_syslog_facility);
+lxc_config_define(selinux_mount_context);
+#endif
/*
* Important Note:
@@ -259,6 +272,19 @@ static struct lxc_config_t config_jump_table[] = {
{ "lxc.uts.name", set_config_uts_name, get_config_uts_name, clr_config_uts_name, },
{ "lxc.sysctl", set_config_sysctl, get_config_sysctl, clr_config_sysctl, },
{ "lxc.proc", set_config_proc, get_config_proc, clr_config_proc, },
+#ifdef HAVE_ISULAD
+ { "lxc.isulad.init.args", set_config_init_args, get_config_init_args, clr_config_init_args, },
+ { "lxc.isulad.init.groups", set_config_init_groups, get_config_init_groups, clr_config_init_groups, },
+ { "lxc.isulad.populate.device", set_config_populate_device, get_config_populate_device, clr_config_populate_device, },
+ { "lxc.isulad.umask", set_config_umask, get_config_umask, clr_config_umask, },
+ { "lxc.isulad.rootfs.maskedpaths", set_config_rootfs_masked_paths, get_config_rootfs_masked_paths, clr_config_rootfs_masked_paths, },
+ { "lxc.isulad.rootfs.ropaths", set_config_rootfs_ro_paths, get_config_rootfs_ro_paths, clr_config_rootfs_ro_paths, },
+ { "lxc.isulad.systemd", set_config_systemd, get_config_systemd, clr_config_systemd, },
+ { "lxc.console.logdriver", set_config_console_log_driver, get_config_console_log_driver, clr_config_console_log_driver, },
+ { "lxc.console.syslog_tag", set_config_console_syslog_tag, get_config_console_syslog_tag, clr_config_console_syslog_tag, },
+ { "lxc.console.syslog_facility", set_config_console_syslog_facility, get_config_console_syslog_facility, clr_config_console_syslog_facility, },
+ { "lxc.selinux.mount_context", set_config_selinux_mount_context, get_config_selinux_mount_context, clr_config_selinux_mount_context, },
+#endif
};
static const size_t config_jump_table_size = sizeof(config_jump_table) / sizeof(struct lxc_config_t);
@@ -1348,6 +1374,10 @@ static int set_config_environment(const char *key, const char *value,
{
struct lxc_list *list_item = NULL;
+#ifdef HAVE_ISULAD
+ char *replaced = NULL;
+#endif
+
if (lxc_config_value_empty(value))
return lxc_clear_environment(lxc_conf);
@@ -1368,7 +1398,16 @@ static int set_config_environment(const char *key, const char *value,
env_var[1] = env_val;
list_item->elem = lxc_string_join("=", env_var, false);
} else {
+#ifdef HAVE_ISULAD
+ /* isulad: recover space replaced by SPACE_MAGIC_STR */
+ replaced = lxc_string_replace(SPACE_MAGIC_STR, " ", value);
+ if(!replaced)
+ goto on_error;
+
+ list_item->elem = replaced;
+#else
list_item->elem = strdup(value);
+#endif
}
if (!list_item->elem)
@@ -2291,11 +2330,14 @@ static int set_config_console_rotate(const char *key, const char *value,
if (lxc_safe_uint(value, &lxc_conf->console.log_rotate) < 0)
return -1;
+#ifndef HAVE_ISULAD
+ /* isulad: support rotate muti-files */
if (lxc_conf->console.log_rotate > 1) {
ERROR("The \"lxc.console.rotate\" config key can only be set "
"to 0 or 1");
return -1;
}
+#endif
return 0;
}
@@ -2581,6 +2623,11 @@ static int set_config_rootfs_options(const char *key, const char *value,
int ret;
struct lxc_rootfs *rootfs = &lxc_conf->rootfs;
+#ifdef HAVE_ISULAD
+ ret = parse_mntopts(value, &mflags, &pflags, &mdata);
+ if (ret < 0)
+ return -EINVAL;
+#else
ret = parse_mntopts(value, &mflags, &mdata);
if (ret < 0)
return -EINVAL;
@@ -2590,6 +2637,7 @@ static int set_config_rootfs_options(const char *key, const char *value,
free(mdata);
return -EINVAL;
}
+#endif
ret = set_config_string_item(&opts, value);
if (ret < 0) {
@@ -2722,6 +2770,54 @@ struct parse_line_conf {
bool from_include;
};
+#ifdef HAVE_ISULAD
+// escape_string_decode compress some escape characters
+static char *escape_string_decode(const char *src)
+{
+ size_t src_end = 0;
+ size_t dst_end = 0;
+ size_t len = 0;
+ char *dst = NULL;
+
+ if (src == NULL) {
+ return NULL;
+ }
+
+ len = strlen(src);
+ if (len == 0) {
+ return NULL;
+ }
+
+ dst = calloc(1, len + 1);
+ if (dst == NULL) {
+ ERROR("Out of memory");
+ return NULL;
+ }
+
+ while(src_end < len) {
+ if (src[src_end] == '\\') {
+ switch (src[++src_end])
+ {
+ case 'r': dst[dst_end] = '\r'; break;
+ case 'n': dst[dst_end] = '\n'; break;
+ case 'f': dst[dst_end] = '\f'; break;
+ case 'b': dst[dst_end] = '\b'; break;
+ case 't': dst[dst_end] = '\t'; break;
+ case '\\': dst[dst_end] = '\\'; break;
+ // default do not decode
+ default: dst[dst_end++] = '\\'; dst[dst_end] = src[src_end]; break;
+ }
+ } else {
+ dst[dst_end] = src[src_end];
+ }
+ dst_end++;
+ src_end++;
+ }
+
+ return dst;
+}
+#endif
+
static int parse_line(char *buffer, void *data)
{
char *dot, *key, *line, *linep, *value;
@@ -2730,6 +2826,9 @@ static int parse_line(char *buffer, void *data)
int ret = 0;
char *dup = buffer;
struct parse_line_conf *plc = data;
+#ifdef HAVE_ISULAD
+ char *value_decode = NULL;
+#endif
/* If there are newlines in the config file we should keep them. */
empty_line = lxc_is_line_empty(dup);
@@ -2796,10 +2895,21 @@ static int parse_line(char *buffer, void *data)
goto on_error;
}
+#ifdef HAVE_ISULAD
+ value_decode = escape_string_decode(value);
+ if (value_decode == NULL) {
+ ERROR("Value %s decode failed", value);
+ }
+ ret = config->set(key, value_decode ? value_decode: value, plc->conf, NULL);
+#else
ret = config->set(key, value, plc->conf, NULL);
+#endif
on_error:
free(linep);
+#ifdef HAVE_ISULAD
+ free(value_decode);
+#endif
return ret;
}
@@ -2912,6 +3022,12 @@ bool lxc_config_define_load(struct lxc_list *defines, struct lxc_container *c)
lxc_list_for_each(it, defines) {
struct new_config_item *new_item = it->elem;
+#ifdef HAVE_ISULAD
+ if (strcmp(new_item->key, LXC_IMAGE_OCI_KEY) == 0) {
+ c->set_oci_type(c, true);
+ continue;
+ }
+#endif
bret = c->set_config_item(c, new_item->key, new_item->val);
if (!bret)
break;
@@ -6098,3 +6214,526 @@ int lxc_list_net(struct lxc_conf *c, const char *key, char *retv, int inlen)
return fulllen;
}
+
+#ifdef HAVE_ISULAD
+/* isulad: set config for init args */
+static int set_config_init_args(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ int ret = 0;
+ char **tmp = NULL;
+ char *new_value = NULL;
+
+ ret = set_config_string_item(&new_value, value);
+ if (ret || !new_value)
+ return ret;
+
+ tmp = (char **)realloc(lxc_conf->init_argv, (lxc_conf->init_argc + 1) * sizeof(char *));
+ if (!tmp) {
+ ERROR("Out of memory");
+ free(new_value);
+ return -1;
+ }
+
+ lxc_conf->init_argv = tmp;
+
+ lxc_conf->init_argv[lxc_conf->init_argc] = new_value;
+ lxc_conf->init_argc++;
+
+ return 0;
+}
+
+/* isulad: get config init args */
+static int get_config_init_args(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ int i, len, fulllen = 0;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ for (i = 0; i < c->init_argc; i++) {
+ strprint(retv, inlen, "%s", c->init_argv[i]);
+ }
+
+ return fulllen;
+}
+
+/* isulad: clr config init args*/
+static inline int clr_config_init_args(const char *key, struct lxc_conf *c,
+ void *data)
+{
+ return lxc_clear_init_args(c);
+}
+
+/* isulad: set config for init groups */
+static int set_config_init_groups(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ char *groups = NULL;
+ char *token = NULL;
+ int ret = -1;
+
+ if (lxc_config_value_empty(value))
+ return lxc_clear_init_groups(lxc_conf);
+
+ groups = strdup(value);
+ if (!groups)
+ return -1;
+
+ /* In case several capability keep is specified in a single line
+ * split these caps in a single element for the list.
+ */
+ lxc_iterate_parts(token, groups, " \t") {
+ gid_t *tmp = NULL;
+ if (lxc_mem_realloc((void **)&tmp, (lxc_conf->init_groups_len + 1) * sizeof(gid_t), lxc_conf->init_groups,
+ (lxc_conf->init_groups_len) * sizeof(gid_t)) != 0) {
+ ERROR("Out of memory");
+ goto on_error;
+ }
+ lxc_conf->init_groups = tmp;
+ tmp[lxc_conf->init_groups_len] = atoll(token);
+ lxc_conf->init_groups_len++;
+ }
+
+ ret = 0;
+
+on_error:
+ free(groups);
+
+ return ret;
+}
+
+/* isulad: get config init groups */
+static int get_config_init_groups(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ int i, len, fulllen = 0;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ for (i = 0; i < c->init_groups_len; i++) {
+ strprint(retv, inlen, "%u\n", c->init_groups[i]);
+ }
+
+ return fulllen;
+}
+
+/* isulad: clr config init args*/
+static inline int clr_config_init_groups(const char *key, struct lxc_conf *c,
+ void *data)
+{
+ return lxc_clear_init_groups(c);
+}
+
+/* isulad: set config for populate device */
+static int set_config_populate_device(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ int ret = 0, major = 0, minor = 0;
+ uid_t uid = (uid_t)-1;
+ gid_t gid = (gid_t)-1;
+ char name[4096] = {0}; /* MAX dev path name */
+ char type[3] = {0};
+ char *replace_value = NULL;
+ mode_t filemode = 0;
+ struct lxc_list *iter = NULL;
+ struct lxc_list *dev_list = NULL;
+ struct lxc_populate_devs *dev_elem = NULL;
+
+ if (lxc_config_value_empty(value))
+ return lxc_clear_populate_devices(lxc_conf);
+
+ /* lxc.populate.device = PATH_IN_CONTAINER:DEVICETYPE:MAJOR:MINOR:MODE:UID:GID
+ * For e.g. lxc.populate.device = /dev/sda:b:8:0:0666:0:0
+ */
+ ret = sscanf(value, "%4095[^:]:%2[^:]:%i:%i:%i:%u:%u", name, type, &major, &minor, &filemode, &uid, &gid);
+ if (ret != 7)
+ return -1;
+
+ /* find existing list element */
+ lxc_list_for_each(iter, &lxc_conf->populate_devs) {
+ dev_elem = iter->elem;
+
+ if (strcmp(name, dev_elem->name) != 0)
+ continue;
+
+ replace_value = safe_strdup(type);
+
+ free(dev_elem->type);
+ dev_elem->type = replace_value;
+ dev_elem->file_mode = filemode;
+ dev_elem->maj = major;
+ dev_elem->min = minor;
+ dev_elem->uid = (uid_t)uid;
+ dev_elem->gid = (gid_t)gid;
+ return 0;
+ }
+
+ /* allocate list element */
+ dev_list = malloc(sizeof(*dev_list));
+ if (dev_list == NULL)
+ goto on_error;
+
+ lxc_list_init(dev_list);
+
+ dev_elem = malloc(sizeof(*dev_elem));
+ if (dev_elem == NULL)
+ goto on_error;
+ memset(dev_elem, 0, sizeof(*dev_elem));
+
+ dev_elem->name = safe_strdup(name);
+
+ dev_elem->type = safe_strdup(type);
+
+ dev_elem->file_mode = filemode;
+ dev_elem->maj = major;
+ dev_elem->min = minor;
+ dev_elem->uid = (uid_t)uid;
+ dev_elem->gid = (gid_t)gid;
+
+ lxc_list_add_elem(dev_list, dev_elem);
+
+ lxc_list_add_tail(&lxc_conf->populate_devs, dev_list);
+
+ return 0;
+
+on_error:
+ free(dev_list);
+ if (dev_elem) {
+ free(dev_elem->name);
+ free(dev_elem->type);
+ free(dev_elem);
+ }
+ return -1;
+}
+
+/* isulad: get config populate device
+ * If you ask for 'lxc.populate.device', then all populate device
+ * entries will be printed, in 'lxc.populate.device = path_in_container:type:major:minor:mode:uid:gid' format.
+ * For e.g. lxc.populate.device = /dev/sda:b:8:0:0666:0:0
+ */
+static int get_config_populate_device(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ int len;
+ struct lxc_list *it = NULL;
+ int fulllen = 0;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ lxc_list_for_each(it, &c->populate_devs) {
+ struct lxc_populate_devs *elem = it->elem;
+ strprint(retv, inlen, "lxc.populate.device = %s:%s:%d:%d:%o:%u:%u\n",
+ elem->name, elem->type, elem->maj,
+ elem->min, elem->file_mode, elem->uid, elem->gid);
+ }
+
+ return fulllen;
+}
+
+/* isulad: clr config populate devices*/
+static inline int clr_config_populate_device(const char *key, struct lxc_conf *c,
+ void *data)
+{
+ return lxc_clear_populate_devices(c);
+}
+
+/* isulad: set config for umask */
+static int set_config_umask(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ if (lxc_config_value_empty(value)) {
+ ERROR("Empty umask");
+ return -1;
+ }
+
+ if (strcmp(value, "normal") == 0) {
+ lxc_conf->umask = 0022;
+ return 0;
+ } else if (strcmp(value, "secure") == 0) {
+ lxc_conf->umask = 0027;
+ return 0;
+ } else {
+ ERROR("Invalid native umask: %s", value);
+ return -1;
+ }
+}
+
+/* isulad add: get umask value*/
+static int get_config_umask(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ return lxc_get_conf_size_t(c, retv, inlen, c->umask);
+}
+
+/* isulad add: clear umask value */
+static inline int clr_config_umask(const char *key, struct lxc_conf *c,
+ void *data)
+{
+ c->umask = 0027;
+ return 0;
+}
+
+/* isulad: set config for rootfs masked paths */
+static int set_config_rootfs_masked_paths(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ struct lxc_list *list_item = NULL;
+
+ if (lxc_config_value_empty(value))
+ return lxc_clear_rootfs_masked_paths(lxc_conf);
+
+ list_item = malloc(sizeof(*list_item));
+ if (list_item == NULL)
+ goto on_error;
+
+ list_item->elem = safe_strdup(value);
+
+ lxc_list_add_tail(&lxc_conf->rootfs.maskedpaths, list_item);
+
+ return 0;
+
+on_error:
+ free(list_item);
+
+ return -1;
+}
+
+// isulad: get config rootfs masked paths
+static int get_config_rootfs_masked_paths(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ int len, fulllen = 0;
+ struct lxc_list *it = NULL;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ lxc_list_for_each(it, &c->rootfs.maskedpaths) {
+ strprint(retv, inlen, "%s\n", (char *)it->elem);
+ }
+
+ return fulllen;
+}
+
+/* isulad: set config for rootfs ro paths */
+static int set_config_rootfs_ro_paths(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ struct lxc_list *list_item = NULL;
+
+ if (lxc_config_value_empty(value))
+ return lxc_clear_rootfs_ro_paths(lxc_conf);
+
+ list_item = malloc(sizeof(*list_item));
+ if (list_item == NULL)
+ goto on_error;
+
+ list_item->elem = safe_strdup(value);
+
+ lxc_list_add_tail(&lxc_conf->rootfs.ropaths, list_item);
+
+ return 0;
+
+on_error:
+ free(list_item);
+
+ return -1;
+}
+
+// isulad: get config rootfs ro paths
+static int get_config_rootfs_ro_paths(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ int len, fulllen = 0;
+ struct lxc_list *it = NULL;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ lxc_list_for_each(it, &c->rootfs.ropaths) {
+ strprint(retv, inlen, "%s\n", (char *)it->elem);
+ }
+
+ return fulllen;
+}
+
+/* isulad: clr config rootfs masked paths */
+static inline int clr_config_rootfs_masked_paths(const char *key, struct lxc_conf *c,
+ void *data)
+{
+ return lxc_clear_rootfs_masked_paths(c);
+}
+
+/* isulad: clr config rootfs ro paths */
+static inline int clr_config_rootfs_ro_paths(const char *key, struct lxc_conf *c,
+ void *data)
+{
+ return lxc_clear_rootfs_ro_paths(c);
+}
+
+/* isulad: set config for systemd */
+static int set_config_systemd(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ if (lxc_config_value_empty(value)) {
+ ERROR("Empty umask");
+ return -1;
+ }
+ lxc_conf->systemd = strdup(value);
+ return 0;
+}
+
+/* isulad add: get systemd value*/
+static int get_config_systemd(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ return lxc_get_conf_str(retv, inlen, c->systemd);
+}
+
+/* isulad add: clear systemd value */
+static inline int clr_config_systemd(const char *key, struct lxc_conf *c,
+ void *data)
+{
+ free(c->systemd);
+ c->systemd = NULL;
+ return 0;
+}
+
+static int set_config_console_log_driver(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ return set_config_string_item(&lxc_conf->console.log_driver, value);
+}
+
+static int set_config_console_syslog_tag(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ if (value == NULL) {
+ return -1;
+ }
+ return set_config_string_item(&lxc_conf->console.log_syslog_tag, value);
+}
+
+static int parse_facility(const char *facility)
+{
+#define FACILITIES_LEN 20
+ const char *facility_keys[FACILITIES_LEN] = {
+ "kern", "user", "mail", "daemon", "auth",
+ "syslog", "lpr", "news", "uucp", "cron", "authpriv", "ftp",
+ "local0", "local1", "local2", "local3", "local4", "local5", "local6", "local7"
+ };
+ const int facilities[FACILITIES_LEN] = {
+ LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH, LOG_SYSLOG,
+ LOG_LPR, LOG_NEWS, LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_FTP,
+ LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4,
+ LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7
+ };
+ int i = 0;
+
+ if (facility == NULL) {
+ return -1;
+ }
+
+ for (; i < FACILITIES_LEN; i++) {
+ if (strcmp(facility, facility_keys[i]) == 0) {
+ return facilities[i];
+ }
+ }
+
+ return -1;
+}
+
+static int set_config_console_syslog_facility(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ int facility;
+
+ facility = parse_facility(value);
+ if (facility < 0) {
+ NOTICE("Invalid facility: %s", value);
+ facility = LOG_DAEMON;
+ }
+
+ lxc_conf->console.log_syslog_facility = facility;
+ return 0;
+}
+
+static int set_config_selinux_mount_context(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ if (value != NULL && strcmp(value, "unconfined_t") == 0) {
+ return set_config_string_item(&lxc_conf->lsm_se_mount_context, NULL);
+ }
+
+ return set_config_string_item(&lxc_conf->lsm_se_mount_context, value);
+}
+
+static int get_config_console_log_driver(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ return lxc_get_conf_str(retv, inlen, c->console.log_driver);
+}
+
+static int get_config_console_syslog_tag(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ return lxc_get_conf_str(retv, inlen, c->console.log_syslog_tag);
+}
+
+static int get_config_console_syslog_facility(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ return lxc_get_conf_int(c, retv, inlen, c->console.log_syslog_facility);
+}
+
+static int get_config_selinux_mount_context(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ return lxc_get_conf_str(retv, inlen, c->lsm_se_mount_context);
+}
+
+static inline int clr_config_console_log_driver(const char *key,
+ struct lxc_conf *c, void *data)
+{
+ free(c->console.log_driver);
+ c->console.log_driver = NULL;
+ return 0;
+}
+
+static inline int clr_config_console_syslog_tag(const char *key,
+ struct lxc_conf *c, void *data)
+{
+ free(c->console.log_syslog_tag);
+ c->console.log_syslog_tag= NULL;
+ return 0;
+}
+
+static inline int clr_config_console_syslog_facility(const char *key,
+ struct lxc_conf *c, void *data)
+{
+ c->console.log_syslog_facility = LOG_DAEMON;
+ return 0;
+}
+
+static inline int clr_config_selinux_mount_context(const char *key,
+ struct lxc_conf *c, void *data)
+{
+ free(c->lsm_se_mount_context);
+ c->lsm_se_mount_context = NULL;
+ return 0;
+}
+#endif
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index aac6214..3f75184 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -62,6 +62,10 @@
#include "utils.h"
#include "version.h"
+#ifdef HAVE_ISULAD
+#include "exec_commands.h"
+#endif
+
#if HAVE_OPENSSL
#include <openssl/evp.h>
#endif
@@ -83,6 +87,11 @@
lxc_log_define(lxccontainer, lxc);
+#ifdef HAVE_ISULAD
+typedef bool (*func_is_io_stat_read)(const char *value);
+typedef bool (*func_is_io_stat_write)(const char *value);
+#endif
+
static bool do_lxcapi_destroy(struct lxc_container *c);
static const char *lxcapi_get_config_path(struct lxc_container *c);
#define do_lxcapi_get_config_path(c) lxcapi_get_config_path(c)
@@ -281,6 +290,13 @@ static void lxc_container_free(struct lxc_container *c)
free(c->config_path);
c->config_path = NULL;
+#ifdef HAVE_ISULAD
+ free(c->exit_fifo);
+ c->exit_fifo = NULL;
+ free(c->ocihookfile);
+ c->ocihookfile = NULL;
+#endif
+
free(c);
}
@@ -519,6 +535,7 @@ static bool do_lxcapi_freeze(struct lxc_container *c)
return true;
}
+
WRAP_API(bool, lxcapi_freeze)
static bool do_lxcapi_unfreeze(struct lxc_container *c)
@@ -623,6 +640,66 @@ static bool load_config_locked(struct lxc_container *c, const char *fname)
return true;
}
+#ifdef HAVE_ISULAD
+static bool load_ocihooks_locked(struct lxc_container *c)
+{
+ parser_error err = NULL;
+ oci_runtime_spec_hooks *hooks = NULL;
+
+ if (!c->lxc_conf)
+ c->lxc_conf = lxc_conf_init();
+
+ if (!c->lxc_conf)
+ return false;
+
+ hooks = oci_runtime_spec_hooks_parse_file(c->ocihookfile, NULL, &err);
+ if (!hooks) {
+ fprintf(stderr, "parse oci hooks config failed: %s\n", err);
+ free(err);
+ return true;
+ }
+ c->lxc_conf->ocihooks = hooks;
+
+ if (err)
+ free(err);
+ return true;
+}
+
+/*
+ * isulad: set oci hook file path
+ * */
+static bool set_oci_hook_config_filename(struct lxc_container *c)
+{
+#define OCI_HOOK_JSON_FILE_NAME "ocihooks.json"
+ char *newpath = NULL;
+ int len, ret;
+
+ if (!c->config_path)
+ return false;
+
+ /* $lxc_path + "/" + c->name + "/" + "config" + '\0' */
+ if (strlen(c->config_path) + strlen(c->name) > SIZE_MAX - strlen(OCI_HOOK_JSON_FILE_NAME) - 3)
+ return false;
+ len = strlen(c->config_path) + strlen(c->name) + strlen(OCI_HOOK_JSON_FILE_NAME) + 3;
+
+ newpath = malloc(len);
+ if (newpath == NULL)
+ return false;
+
+ ret = snprintf(newpath, len, "%s/%s/%s", c->config_path, c->name, OCI_HOOK_JSON_FILE_NAME);
+ if (ret < 0 || ret >= len) {
+ fprintf(stderr, "Error printing out config file name\n");
+ free(newpath);
+ return false;
+ }
+
+ free(c->ocihookfile);
+ c->ocihookfile = newpath;
+
+ return true;
+}
+#endif
+
static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file)
{
int lret;
@@ -656,6 +733,11 @@ static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file)
ret = load_config_locked(c, fname);
+#ifdef HAVE_ISULAD
+ if (ret && file_exists(c->ocihookfile))
+ ret = load_ocihooks_locked(c);
+#endif
+
if (need_disklock)
container_disk_unlock(c);
else
@@ -855,6 +937,33 @@ static bool wait_on_daemonized_start(struct lxc_handler *handler, int pid)
return true;
}
+#ifdef HAVE_ISULAD
+/* isulad: use init argv as init cmd */
+static char **use_init_args(char **init_argv, size_t init_args)
+{
+ size_t i;
+ int nargs = 0;
+ char **argv;
+
+ if (!init_argv)
+ return NULL;
+
+ do {
+ argv = malloc(sizeof(char *));
+ } while (!argv);
+
+ argv[0] = NULL;
+ for (i = 0; i < init_args; i++)
+ push_arg(&argv, init_argv[i], &nargs);
+
+ if (nargs == 0) {
+ free(argv);
+ return NULL;
+ }
+ return argv;
+}
+#endif
+
static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const argv[])
{
int ret;
@@ -865,6 +974,11 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
NULL,
};
char **init_cmd = NULL;
+#ifdef HAVE_ISULAD
+ int keepfds[] = {-1, -1, -1, -1, -1};
+ ssize_t size_read;
+ char errbuf[BUFSIZ + 1] = {0};
+#endif
/* container does exist */
if (!c)
@@ -911,6 +1025,16 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
argv = init_cmd = split_init_cmd(conf->init_cmd);
}
+#ifdef HAVE_ISULAD
+ if (!argv) {
+ argv = init_cmd = use_init_args(conf->init_argv, conf->init_argc);
+ }
+
+ if (c->image_type_oci) {
+ handler->image_type_oci = true;
+ }
+#endif
+
/* ... otherwise use default_args. */
if (!argv) {
if (useinit) {
@@ -930,10 +1054,23 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
char title[2048];
pid_t pid_first, pid_second;
+#ifdef HAVE_ISULAD
+ //isulad: pipdfd for get error message of child or grandchild process.
+ if (pipe2(conf->errpipe, O_CLOEXEC) != 0) {
+ SYSERROR("Failed to init errpipe");
+ free_init_cmd(init_cmd);
+ lxc_put_handler(handler);
+ return false;
+ }
+#endif
+
pid_first = fork();
if (pid_first < 0) {
free_init_cmd(init_cmd);
lxc_put_handler(handler);
+#ifdef HAVE_ISULAD
+ lxc_close_error_pipe(conf->errpipe);
+#endif
return false;
}
@@ -943,11 +1080,25 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
* the PID file, child will do the free and unlink.
*/
c->pidfile = NULL;
+#ifdef HAVE_ISULAD
+ close(conf->errpipe[1]);
+ conf->errpipe[1] = -1;
+#endif
/* Wait for container to tell us whether it started
* successfully.
*/
started = wait_on_daemonized_start(handler, pid_first);
+#ifdef HAVE_ISULAD
+ if (!started) {
+ size_read = read(conf->errpipe[0], errbuf, BUFSIZ);
+ if (size_read > 0) {
+ conf->errmsg = safe_strdup(errbuf);
+ }
+ }
+ close(conf->errpipe[0]);
+ conf->errpipe[0] = -1;
+#endif
free_init_cmd(init_cmd);
lxc_put_handler(handler);
@@ -983,6 +1134,9 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
if (pid_second != 0) {
free_init_cmd(init_cmd);
lxc_put_handler(handler);
+#ifdef HAVE_ISULAD
+ lxc_close_error_pipe(conf->errpipe);
+#endif
_exit(EXIT_SUCCESS);
}
@@ -995,7 +1149,18 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
_exit(EXIT_FAILURE);
}
+#ifdef HAVE_ISULAD
+ keepfds[0] = handler->conf->maincmd_fd;
+ keepfds[1] = handler->state_socket_pair[0];
+ keepfds[2] = handler->state_socket_pair[1];
+ keepfds[4] = conf->errpipe[1];
+ close(conf->errpipe[0]);
+ conf->errpipe[0] = -1;
+ ret = lxc_check_inherited(conf, true, keepfds,
+ sizeof(keepfds) / sizeof(keepfds[0]));
+#else
ret = inherit_fds(handler, true);
+#endif
if (ret < 0)
_exit(EXIT_FAILURE);
@@ -1028,6 +1193,9 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
if (w < 0 || (size_t)w >= sizeof(pidstr)) {
free_init_cmd(init_cmd);
lxc_put_handler(handler);
+#ifdef HAVE_ISULAD
+ lxc_close_error_pipe(conf->errpipe);
+#endif
SYSERROR("Failed to write monitor pid to \"%s\"", c->pidfile);
@@ -1041,6 +1209,9 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
if (ret < 0) {
free_init_cmd(init_cmd);
lxc_put_handler(handler);
+#ifdef HAVE_ISULAD
+ lxc_close_error_pipe(conf->errpipe);
+#endif
SYSERROR("Failed to write monitor pid to \"%s\"", c->pidfile);
@@ -1051,6 +1222,19 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
}
}
+#ifdef HAVE_ISULAD
+ /* isulad: open exit fifo */
+ if (c->exit_fifo) {
+ conf->exit_fd = lxc_open(c->exit_fifo, O_WRONLY | O_NONBLOCK | O_CLOEXEC, 0);
+ if (conf->exit_fd < 0) {
+ ERROR("Failed to open exit fifo %s: %s.", c->exit_fifo, strerror(errno));
+ lxc_put_handler(handler);
+ ret = 1;
+ goto on_error;
+ }
+ }
+#endif
+
conf->reboot = REBOOT_NONE;
/* Unshare the mount namespace if requested */
@@ -1082,19 +1266,53 @@ reboot:
}
}
+#ifdef HAVE_ISULAD
+ keepfds[0] = handler->conf->maincmd_fd;
+ keepfds[1] = handler->state_socket_pair[0];
+ keepfds[2] = handler->state_socket_pair[1];
+
+ /* keep exit fifo fd */
+ if (conf->exit_fd >= 0) {
+ keepfds[3] = conf->exit_fd;
+ }
+ /* isulad: keep errpipe fd */
+ if (c->daemonize)
+ keepfds[4] = conf->errpipe[1];
+
+ ret = lxc_check_inherited(conf, c->daemonize, keepfds,
+ sizeof(keepfds) / sizeof(keepfds[0]));
+ if (ret < 0) {
+ lxc_put_handler(handler);
+ ret = 1;
+ goto on_error;
+ }
+#else
ret = inherit_fds(handler, c->daemonize);
if (ret < 0) {
lxc_put_handler(handler);
ret = 1;
goto on_error;
}
+#endif
+#ifndef HAVE_ISULAD
if (useinit)
ret = lxc_execute(c->name, argv, 1, handler, c->config_path,
c->daemonize, &c->error_num);
else
ret = lxc_start(argv, handler, c->config_path, c->daemonize,
&c->error_num);
+#else
+ if (useinit) {
+ ret = lxc_execute(c->name, argv, 1, handler, c->config_path,
+ c->daemonize, &c->error_num, c->start_timeout);
+ } else {
+ handler->disable_pty = c->disable_pty;
+ handler->open_stdin = c->open_stdin;
+ ret = lxc_start(argv, handler, c->config_path, c->daemonize,
+ &c->error_num, c->start_timeout);
+ }
+#endif
if (conf->reboot == REBOOT_REQ) {
INFO("Container requested reboot");
@@ -1185,6 +1403,9 @@ WRAP_API(bool, lxcapi_stop)
static int do_create_container_dir(const char *path, struct lxc_conf *conf)
{
+#ifdef HAVE_ISULAD
+ __do_free char *p = NULL;
+#endif
int lasterr;
int ret = -1;
@@ -1200,8 +1421,16 @@ static int do_create_container_dir(const char *path, struct lxc_conf *conf)
ret = 0;
}
+#ifdef HAVE_ISULAD
+ p = must_copy_string(path);
+#endif
+
if (!lxc_list_empty(&conf->id_map)) {
+#ifdef HAVE_ISULAD
+ ret = chown_mapped_root(p, conf);
+#else
ret = chown_mapped_root(path, conf);
+#endif
if (ret < 0)
ret = -1;
}
@@ -2048,7 +2277,12 @@ WRAP_API_1(bool, lxcapi_reboot2, int)
static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
{
__do_close int pidfd = -EBADF, state_client_fd = -EBADF;
+#ifdef HAVE_ISULAD
+ // isulad: keep default signal the same as docker
+ int haltsignal = SIGTERM;
+#else
int haltsignal = SIGPWR;
+#endif
pid_t pid = -1;
lxc_state_t states[MAX_STATE] = {0};
int killret, ret;
@@ -2067,9 +2301,10 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
/* Detect whether we should send SIGRTMIN + 3 (e.g. systemd). */
if (c->lxc_conf && c->lxc_conf->haltsignal)
haltsignal = c->lxc_conf->haltsignal;
+#ifndef HAVE_ISULAD
else if (task_blocks_signal(pid, (SIGRTMIN + 3)))
haltsignal = (SIGRTMIN + 3);
-
+#endif
/*
* Add a new state client before sending the shutdown signal so
@@ -2938,6 +3173,21 @@ static int lxc_unlink_exec_wrapper(void *data)
return unlink(arg);
}
+#ifdef HAVE_ISULAD
+static void container_sock_dir_delete(const char *name)
+{
+ __do_free char *sock_dir = NULL;
+
+ sock_dir = generate_named_unix_sock_dir(name);
+ if (sock_dir == NULL) {
+ ERROR("Failed to generate exec unix sock dir");
+ return;
+ }
+
+ (void)lxc_rmdir_onedev(sock_dir, NULL);
+}
+#endif
+
static bool container_destroy(struct lxc_container *c,
struct lxc_storage *storage)
{
@@ -2948,8 +3198,19 @@ static bool container_destroy(struct lxc_container *c,
bool bret = false;
int ret = 0;
+#ifdef HAVE_ISULAD
+ if (!c)
+ return false;
+ // isulad: if container is not defined, we need to remove disk lock file
+ // which is created in lxc_container_new.
+ if (!do_lxcapi_is_defined(c)) {
+ container_disk_removelock(c);
+ return false;
+ }
+#else
if (!c || !do_lxcapi_is_defined(c))
return false;
+#endif
conf = c->lxc_conf;
if (container_disk_lock(c))
@@ -3069,8 +3330,20 @@ static bool container_destroy(struct lxc_container *c,
if (ret < 0) {
ERROR("Failed to destroy directory \"%s\" for \"%s\"", path,
c->name);
+#ifdef HAVE_ISULAD
+ char msg[BUFSIZ] = { 0 };
+ ret = snprintf(msg, BUFSIZ, "Failed to destroy directory \"%s\": %s", path, errno ? strerror(errno) : "error");
+ if (ret < 0 || ret >= BUFSIZ) {
+ ERROR("Sprintf failed");
+ goto out;
+ }
+ c->error_string = safe_strdup(msg);
+#endif
goto out;
}
+#ifdef HAVE_ISULAD
+ container_sock_dir_delete(c->name);
+#endif
INFO("Destroyed directory \"%s\" for \"%s\"", path, c->name);
on_success:
@@ -3081,6 +3354,11 @@ out:
free(path);
container_disk_unlock(c);
+#ifdef HAVE_ISULAD
+ if (bret && container_disk_removelock(c)) {
+ bret = false;
+ }
+#endif
return bret;
}
@@ -4030,8 +4308,13 @@ static int lxcapi_attach(struct lxc_container *c,
current_config = c->lxc_conf;
+#ifdef HAVE_ISULAD
+ ret = lxc_attach(c, exec_function, exec_payload, options,
+ attached_process, &c->lxc_conf->errmsg);
+#else
ret = lxc_attach(c, exec_function, exec_payload, options,
attached_process);
+#endif
current_config = NULL;
return ret;
}
@@ -4051,7 +4334,11 @@ static int do_lxcapi_attach_run_wait(struct lxc_container *c,
command.program = (char *)program;
command.argv = (char **)argv;
+#ifdef HAVE_ISULAD
+ ret = lxc_attach(c, lxc_attach_run_command, &command, options, &pid, NULL);
+#else
ret = lxc_attach(c, lxc_attach_run_command, &command, options, &pid);
+#endif
if (ret < 0)
return ret;
@@ -5230,7 +5517,561 @@ static int do_lxcapi_seccomp_notify_fd(struct lxc_container *c)
WRAP_API(int, lxcapi_seccomp_notify_fd)
+#ifdef HAVE_ISULAD
+/* isulad add set console fifos*/
+static bool do_lxcapi_set_terminal_default_fifos(struct lxc_container *c, const char *in, const char *out, const char *err)
+{
+ struct lxc_conf *conf = NULL;
+
+ if (!c || !c->lxc_conf)
+ return false;
+ if (container_mem_lock(c)) {
+ ERROR("Error getting mem lock");
+ return false;
+ }
+
+ conf = c->lxc_conf;
+ if (in) {
+ if (conf->console.init_fifo[0])
+ free(conf->console.init_fifo[0]);
+ conf->console.init_fifo[0] = safe_strdup(in);
+ }
+ if (out) {
+ if (conf->console.init_fifo[1])
+ free(conf->console.init_fifo[1]);
+ conf->console.init_fifo[1] = safe_strdup(out);
+ }
+ if (err) {
+ if (conf->console.init_fifo[2])
+ free(conf->console.init_fifo[2]);
+ conf->console.init_fifo[2] = safe_strdup(err);
+ }
+
+ container_mem_unlock(c);
+ return true;
+}
+
+WRAP_API_3(bool, lxcapi_set_terminal_default_fifos, const char *, const char *, const char *)
+
+/* isulad add set info file path */
+static bool do_lxcapi_set_container_info_file(struct lxc_container *c, const char *info_file)
+{
+ struct lxc_conf *conf = NULL;
+
+ if (!c || !c->lxc_conf || !info_file)
+ return false;
+ if (container_mem_lock(c)) {
+ ERROR("Error getting mem lock");
+ return false;
+ }
+
+ conf = c->lxc_conf;
+ if (conf->container_info_file)
+ free(conf->container_info_file);
+ conf->container_info_file = safe_strdup(info_file);
+
+ container_mem_unlock(c);
+ return true;
+}
+
+WRAP_API_1(bool, lxcapi_set_container_info_file, const char *)
+
+static bool do_lxcapi_want_disable_pty(struct lxc_container *c, bool state)
+{
+ if (!c || !c->lxc_conf)
+ return false;
+
+ if (container_mem_lock(c))
+ return false;
+
+ c->disable_pty = state;
+
+ container_mem_unlock(c);
+
+ return true;
+}
+
+WRAP_API_1(bool, lxcapi_want_disable_pty, bool)
+
+static bool do_lxcapi_want_open_stdin(struct lxc_container *c, bool state)
+{
+ if (!c || !c->lxc_conf)
+ return false;
+
+ if (container_mem_lock(c))
+ return false;
+
+ c->open_stdin = state;
+
+ container_mem_unlock(c);
+
+ return true;
+}
+
+WRAP_API_1(bool, lxcapi_want_open_stdin, bool)
+
+/* isulad add clean resources */
+static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_fifo, const char *out_fifo, const char *err_fifo)
+{
+ bool ret = true;
+
+ if (!c || !c->lxc_conf)
+ return false;
+ if (container_mem_lock(c)) {
+ ERROR("Error getting mem lock");
+ return false;
+ }
+
+ if (lxc_cmd_set_terminal_fifos(c->name, c->config_path, in_fifo, out_fifo, err_fifo)) {
+ ERROR("Error set console fifos");
+ ret = false;
+ }
+
+ container_mem_unlock(c);
+ return ret;
+}
+
+WRAP_API_3(bool, lxcapi_add_terminal_fifo, const char *, const char *, const char *)
+
+static bool do_lxcapi_set_terminal_winch(struct lxc_container *c, unsigned int height, unsigned int width)
+{
+ bool ret = true;
+
+ if (!c || !c->lxc_conf)
+ return false;
+ if (container_mem_lock(c)) {
+ ERROR("Error getting mem lock");
+ return false;
+ }
+
+ if (lxc_cmd_set_terminal_winch(c->name, c->config_path, height, width)) {
+ ERROR("Error set terminal winch");
+ ret = false;
+ }
+
+ container_mem_unlock(c);
+ return ret;
+}
+
+WRAP_API_2(bool, lxcapi_set_terminal_winch, unsigned int, unsigned int)
+
+static bool do_lxcapi_set_exec_terminal_winch(struct lxc_container *c, const char *suffix, unsigned int height, unsigned int width)
+{
+ bool ret = true;
+
+ if (!c || !c->lxc_conf)
+ return false;
+ if (container_mem_lock(c)) {
+ ERROR("Error getting mem lock");
+ return false;
+ }
+
+ if (lxc_exec_cmd_set_terminal_winch(c->name, c->config_path, suffix, height, width)) {
+ ERROR("Error set terminal winch");
+ ret = false;
+ }
+
+ container_mem_unlock(c);
+ return ret;
+}
+
+WRAP_API_3(bool, lxcapi_set_exec_terminal_winch, const char *, unsigned int, unsigned int)
+
+/* isulad add clean resources */
+static bool do_lxcapi_clean_container_resource(struct lxc_container *c, pid_t pid)
+{
+ int ret;
+
+ if (!c)
+ return false;
+
+ ret = do_lxcapi_clean_resource(c->name, c->config_path, c->lxc_conf, pid);
+ if (ret)
+ ERROR("Failed to clean container %s resource", c->name);
+ return ret == 0;
+
+}
+
+WRAP_API_1(bool, lxcapi_clean_container_resource, pid_t)
+
+/* isulad get coantainer pids */
+static bool do_lxcapi_get_container_pids(struct lxc_container *c, pid_t **pids,size_t *pids_len)
+{
+ int ret;
+
+ if (!c)
+ return false;
+
+ ret = do_lxcapi_get_pids(c->name, c->config_path, c->lxc_conf, pids,pids_len);
+ if (ret)
+ ERROR("Failed to get container %s pids", c->name);
+ return ret == 0;
+
+}
+
+WRAP_API_2(bool, lxcapi_get_container_pids, pid_t **,size_t *)
+
+/* isulad add start timeout */
+static bool do_lxcapi_set_start_timeout(struct lxc_container *c, unsigned int start_timeout)
+{
+ if (!c || !c->lxc_conf)
+ return false;
+ if (container_mem_lock(c)) {
+ ERROR("Error getting mem lock");
+ return false;
+ }
+ c->start_timeout = start_timeout;
+ container_mem_unlock(c);
+ return true;
+}
+
+WRAP_API_1(bool, lxcapi_set_start_timeout, unsigned int)
+
+/* isulad add set image type */
+static bool do_lxcapi_set_oci_type(struct lxc_container *c, bool image_type_oci)
+{
+ if (!c || !c->lxc_conf)
+ return false;
+ if (container_mem_lock(c)) {
+ ERROR("Error getting mem lock");
+ return false;
+ }
+ c->image_type_oci = image_type_oci;
+ container_mem_unlock(c);
+ return true;
+}
+
+WRAP_API_1(bool, lxcapi_set_oci_type, bool)
+
+static uint64_t metrics_get_ull(struct lxc_container *c, struct cgroup_ops *cgroup_ops, const char *item)
+{
+ char buf[81] = {0};
+ int len = 0;
+ uint64_t val = 0;
+
+ len = cgroup_ops->get(cgroup_ops, item, buf, sizeof(buf) - 1, c->name, c->config_path);
+ if (len <= 0) {
+ DEBUG("unable to read cgroup item %s", item);
+ return 0;
+ }
+
+ val = strtoull(buf, NULL, 0);
+ return val;
+}
+
+static uint64_t metrics_get_ull_with_max(struct lxc_container *c, struct cgroup_ops *cgroup_ops, const char *item)
+{
+ char buf[81] = {0};
+ int len = 0;
+ uint64_t val = 0;
+
+ len = cgroup_ops->get(cgroup_ops, item, buf, sizeof(buf) - 1, c->name, c->config_path);
+ if (len <= 0) {
+ DEBUG("unable to read cgroup item %s", item);
+ return 0;
+ }
+
+ if (strcmp(buf, "max") == 0) {
+ return ULONG_MAX;
+ }
+
+ val = strtoull(buf, NULL, 0);
+ return val;
+}
+
+static inline bool is_blk_metrics_read(const char *value)
+{
+ return strcmp(value, "Read") == 0;
+}
+
+static inline bool is_blk_metrics_write(const char *value)
+{
+ return strcmp(value, "Write") == 0;
+}
+
+static inline bool is_blk_metrics_total(const char *value)
+{
+ return strcmp(value, "Total") == 0;
+}
+
+static void metrics_get_blk_stats(struct lxc_container *c, struct cgroup_ops *cgroup_ops, const char *item, struct lxc_blkio_metrics *stats)
+{
+ char *buf = NULL;
+ int i = 0;
+ int len = 0;
+ int ret = 0;
+ char **lines = NULL;
+ char **cols = NULL;
+
+ len = cgroup_ops->get(cgroup_ops, item, NULL, 0, c->name, c->config_path);
+ if (len <= 0) {
+ DEBUG("unable to read cgroup item %s", item);
+ return;
+ }
+
+ buf = malloc(len + 1);
+ (void)memset(buf, 0, len + 1);
+ ret = cgroup_ops->get(cgroup_ops, item, buf, len, c->name, c->config_path);
+ if (ret <= 0) {
+ DEBUG("unable to read cgroup item %s", item);
+ goto out;
+ }
+
+ lines = lxc_string_split_and_trim(buf, '\n');
+ if (lines == NULL) {
+ goto out;
+ }
+
+ (void)memset(stats, 0, sizeof(struct lxc_blkio_metrics));
+
+ for (i = 0; lines[i]; i++) {
+ cols = lxc_string_split_and_trim(lines[i], ' ');
+ if (cols == NULL) {
+ goto err_out;
+ }
+ if (lxc_array_len((void **)cols) == 3) {
+ if (is_blk_metrics_read(cols[1])) {
+ stats->read += strtoull(cols[2], NULL, 0);
+ } else if (is_blk_metrics_write(cols[1])) {
+ stats->write += strtoull(cols[2], NULL, 0);
+ }
+ }
+ if (lxc_array_len((void **)cols) == 2 && is_blk_metrics_total(cols[0])) {
+ stats->total = strtoull(cols[1], NULL, 0);
+ }
+
+ lxc_free_array((void **)cols, free);
+ }
+err_out:
+ lxc_free_array((void **)lines, free);
+out:
+ free(buf);
+ return;
+}
+
+static void metrics_get_io_stats_v2(struct lxc_container *c, struct cgroup_ops *cgroup_ops, const char *item, struct lxc_blkio_metrics *stats, func_is_io_stat_read is_io_stat_read, func_is_io_stat_write is_io_stat_write)
+{
+ char *buf = NULL;
+ int i = 0;
+ int j = 0;
+ int len = 0;
+ int ret = 0;
+ char **lines = NULL;
+ char **cols = NULL;
+ char **kv = NULL;
+
+ len = cgroup_ops->get(cgroup_ops, item, NULL, 0, c->name, c->config_path);
+ if (len <= 0) {
+ DEBUG("unable to read cgroup item %s", item);
+ return;
+ }
+
+ buf = malloc(len + 1);
+ (void)memset(buf, 0, len + 1);
+ ret = cgroup_ops->get(cgroup_ops, item, buf, len, c->name, c->config_path);
+ if (ret <= 0) {
+ DEBUG("unable to read cgroup item %s", item);
+ goto out;
+ }
+
+ lines = lxc_string_split_and_trim(buf, '\n');
+ if (lines == NULL) {
+ goto out;
+ }
+
+ (void)memset(stats, 0, sizeof(struct lxc_blkio_metrics));
+ // line example:
+ // 259:0 rbytes=0 wbytes=12288 rios=0 wios=4 dbytes=0 dios=0
+ for (i = 0; lines[i]; i++) {
+ cols = lxc_string_split_and_trim(lines[i], ' ');
+ if (cols == NULL || lxc_array_len((void **)cols) < 2) {
+ goto err_out;
+ }
+ len = lxc_array_len((void **)cols);
+ for (j = 1; j < len; j++) {
+ kv = lxc_string_split(cols[j], '=');
+ if (kv == NULL || lxc_array_len((void **)kv) != 2) {
+ lxc_free_array((void **)kv, free);
+ continue;
+ }
+ if (is_io_stat_read(kv[0])) {
+ stats->read += strtoull(kv[1], NULL, 0);
+ } else if (is_io_stat_write(kv[0])) {
+ stats->write += strtoull(kv[1], NULL, 0);
+ }
+ lxc_free_array((void **)kv, free);
+ }
+ lxc_free_array((void **)cols, free);
+ }
+
+ stats->total = stats->read + stats->write;
+
+err_out:
+ lxc_free_array((void **)lines, free);
+out:
+ free(buf);
+ return;
+}
+
+static uint64_t metrics_match_get_ull(struct lxc_container *c, struct cgroup_ops *cgroup_ops, const char *item, const char *match, int column)
+{
+#define BUFSIZE 4096
+ char buf[BUFSIZE] = {0};
+ int i = 0;
+ int j = 0;
+ int len = 0;
+ uint64_t val = 0;
+ char **lines = NULL;
+ char **cols = NULL;
+ size_t matchlen = 0;
+
+ len = cgroup_ops->get(cgroup_ops, item, buf, sizeof(buf) - 1, c->name, c->config_path);
+ if (len <= 0) {
+ DEBUG("unable to read cgroup item %s", item);
+ goto err_out;
+ }
+
+ lines = lxc_string_split_and_trim(buf, '\n');
+ if (lines == NULL) {
+ goto err_out;
+ }
+
+ matchlen = strlen(match);
+ for (i = 0; lines[i]; i++) {
+ if (strncmp(lines[i], match, matchlen) != 0) {
+ continue;
+ }
+
+ cols = lxc_string_split_and_trim(lines[i], ' ');
+ if (cols == NULL) {
+ goto err1;
+ }
+ for (j = 0; cols[j]; j++) {
+ if (j == column) {
+ val = strtoull(cols[j], NULL, 0);
+ break;
+ }
+ }
+ lxc_free_array((void **)cols, free);
+ break;
+ }
+err1:
+ lxc_free_array((void **)lines, free);
+err_out:
+ return val;
+}
+
+static bool is_io_stat_rbytes(const char *value)
+{
+ return strcmp(value, "rbytes") == 0;
+}
+
+static bool is_io_stat_wbytes(const char *value)
+{
+ return strcmp(value, "wbytes") == 0;
+}
+
+static bool is_io_stat_rios(const char *value)
+{
+ return strcmp(value, "rios") == 0;
+}
+
+static bool is_io_stat_wios(const char *value)
+{
+ return strcmp(value, "wios") == 0;
+}
+
+static bool unified_metrics_get(struct lxc_container *c, struct cgroup_ops *cgroup_ops, struct lxc_container_metrics *metrics)
+{
+ // cpu
+ metrics->cpu_use_nanos = metrics_match_get_ull(c, cgroup_ops, "cpu.stat", "usage_usec", 1) * 1000;
+ metrics->cpu_use_user = metrics_match_get_ull(c, cgroup_ops, "cpu.stat", "user_usec", 1) * 1000;
+ metrics->cpu_use_sys = metrics_match_get_ull(c, cgroup_ops, "cpu.stat", "system_usec", 1) * 1000;
+
+ // io
+ metrics_get_io_stats_v2(c, cgroup_ops, "io.stat", &metrics->io_service_bytes, is_io_stat_rbytes, is_io_stat_wbytes);
+ metrics_get_io_stats_v2(c, cgroup_ops, "io.stat", &metrics->io_serviced, is_io_stat_rios, is_io_stat_wios);
+
+ // memory
+ metrics->mem_used = metrics_get_ull(c, cgroup_ops, "memory.current");
+ metrics->mem_limit = metrics_get_ull_with_max(c, cgroup_ops, "memory.max");
+ metrics->inactive_file_total = metrics_match_get_ull(c, cgroup_ops, "memory.stat", "inactive_file", 1);
+ metrics->cache = metrics_match_get_ull(c, cgroup_ops, "memory.stat", "file", 1);
+ metrics->cache_total = metrics->cache;
+
+ // cgroup v2 does not support kernel memory
+ metrics->kmem_used = 0;
+ metrics->kmem_limit = 0;
+
+ // pids
+ metrics->pids_current = metrics_get_ull(c, cgroup_ops, "pids.current");
+
+ return true;
+}
+
+/* isulad add get container metrics */
+static bool do_lxcapi_get_container_metrics(struct lxc_container *c, struct lxc_container_metrics *metrics)
+{
+ call_cleaner(cgroup_exit) struct cgroup_ops *cgroup_ops = NULL;
+ const char *state = NULL;
+ if (c == NULL || c->lxc_conf == NULL || metrics == NULL) {
+ return false;
+ }
+
+ state = c->state(c);
+ metrics->state = state;
+
+ if (!is_stopped(c)) {
+ metrics->init = c->init_pid(c);
+ } else {
+ metrics->init = -1;
+ }
+
+ cgroup_ops = cgroup_init(c->lxc_conf);
+ if (cgroup_ops == NULL) {
+ return false;
+ }
+
+ if (cgroup_ops->cgroup_layout == CGROUP_LAYOUT_UNIFIED) {
+ return unified_metrics_get(c, cgroup_ops, metrics);
+ }
+
+ metrics->cpu_use_nanos = metrics_get_ull(c, cgroup_ops, "cpuacct.usage");
+ metrics->pids_current = metrics_get_ull(c, cgroup_ops, "pids.current");
+
+ metrics->cpu_use_user = metrics_match_get_ull(c, cgroup_ops, "cpuacct.stat", "user", 1);
+ metrics->cpu_use_sys = metrics_match_get_ull(c, cgroup_ops, "cpuacct.stat", "system", 1);
+
+ // Try to read CFQ stats available on all CFQ enabled kernels first
+ metrics_get_blk_stats(c, cgroup_ops, "blkio.io_serviced_recursive", &metrics->io_serviced);
+ if (metrics->io_serviced.read == 0 && metrics->io_serviced.write == 0 && metrics->io_serviced.total == 0) {
+ metrics_get_blk_stats(c, cgroup_ops, "blkio.throttle.io_service_bytes", &metrics->io_service_bytes);
+ metrics_get_blk_stats(c, cgroup_ops, "blkio.throttle.io_serviced", &metrics->io_serviced);
+ } else {
+ metrics_get_blk_stats(c, cgroup_ops, "blkio.io_service_bytes_recursive", &metrics->io_service_bytes);
+ }
+
+ metrics->mem_used = metrics_get_ull(c, cgroup_ops, "memory.usage_in_bytes");
+ metrics->mem_limit = metrics_get_ull(c, cgroup_ops, "memory.limit_in_bytes");
+ metrics->kmem_used = metrics_get_ull(c, cgroup_ops, "memory.kmem.usage_in_bytes");
+ metrics->kmem_limit = metrics_get_ull(c, cgroup_ops, "memory.kmem.limit_in_bytes");
+
+ metrics->cache = metrics_match_get_ull(c, cgroup_ops, "memory.stat", "cache", 1);
+ metrics->cache_total = metrics_match_get_ull(c, cgroup_ops, "memory.stat", "total_cache", 1);
+ metrics->inactive_file_total = metrics_match_get_ull(c, cgroup_ops, "memory.stat", "total_inactive_file", 1);
+
+ return true;
+}
+
+WRAP_API_1(bool, lxcapi_get_container_metrics, struct lxc_container_metrics *)
+
+#endif
+
+#ifdef HAVE_ISULAD
+static struct lxc_container *do_lxc_container_new(const char *name, const char *configpath, bool load_config)
+#else
struct lxc_container *lxc_container_new(const char *name, const char *configpath)
+#endif
{
struct lxc_container *c;
size_t len;
@@ -5283,10 +6124,24 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
goto err;
}
+#ifdef HAVE_ISULAD
+ if (!set_oci_hook_config_filename(c)) {
+ fprintf(stderr, "Error allocating oci hooks file pathname\n");
+ goto err;
+ }
+
+ if (load_config && file_exists(c->configfile)) {
+ if (!lxcapi_load_config(c, NULL)) {
+ fprintf(stderr, "Failed to load config for %s\n", name);
+ goto err;
+ }
+ }
+#else
if (file_exists(c->configfile) && !lxcapi_load_config(c, NULL)) {
fprintf(stderr, "Failed to load config for %s\n", name);
goto err;
}
+#endif
rc = ongoing_create(c);
switch (rc) {
@@ -5310,6 +6165,9 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
c->daemonize = true;
c->pidfile = NULL;
+#ifdef HAVE_ISULAD
+ c->image_type_oci = false;
+#endif
/* Assign the member functions. */
c->is_defined = lxcapi_is_defined;
@@ -5371,7 +6229,20 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
c->mount = lxcapi_mount;
c->umount = lxcapi_umount;
c->seccomp_notify_fd = lxcapi_seccomp_notify_fd;
-
+#ifdef HAVE_ISULAD
+ c->set_container_info_file = lxcapi_set_container_info_file;
+ c->set_terminal_init_fifos = lxcapi_set_terminal_default_fifos;
+ c->add_terminal_fifos = lxcapi_add_terminal_fifo;
+ c->set_terminal_winch = lxcapi_set_terminal_winch;
+ c->set_exec_terminal_winch = lxcapi_set_exec_terminal_winch;
+ c->want_disable_pty = lxcapi_want_disable_pty;
+ c->want_open_stdin = lxcapi_want_open_stdin;
+ c->clean_container_resource = lxcapi_clean_container_resource;
+ c->get_container_pids = lxcapi_get_container_pids;
+ c->set_start_timeout = lxcapi_set_start_timeout;
+ c->set_oci_type = lxcapi_set_oci_type;
+ c->get_container_metrics = lxcapi_get_container_metrics;
+#endif
return c;
err:
@@ -5379,6 +6250,19 @@ err:
return NULL;
}
+#ifdef HAVE_ISULAD
+// isulad: new container without load config to save time
+struct lxc_container *lxc_container_without_config_new(const char *name, const char *configpath)
+{
+ return do_lxc_container_new(name, configpath, false);
+}
+
+struct lxc_container *lxc_container_new(const char *name, const char *configpath)
+{
+ return do_lxc_container_new(name, configpath, true);
+}
+#endif
+
int lxc_get_wait_states(const char **states)
{
int i;
@@ -5557,11 +6441,21 @@ int list_active_containers(const char *lxcpath, char ***nret,
continue;
}
+#ifdef HAVE_ISULAD
+ if (ct_name && ct_name_cnt) {
+ if (array_contains(&ct_name, p, ct_name_cnt)) {
+ if (is_hashed)
+ free(p);
+ continue;
+ }
+ }
+#else
if (array_contains(&ct_name, p, ct_name_cnt)) {
if (is_hashed)
free(p);
continue;
}
+#endif
if (!add_to_array(&ct_name, p, ct_name_cnt)) {
if (is_hashed)
diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c
index 318e5bf..ce6f889 100644
--- a/src/lxc/lxclock.c
+++ b/src/lxc/lxclock.c
@@ -179,6 +179,10 @@ struct lxc_lock *lxc_newlock(const char *lxcpath, const char *name)
l->u.f.fd = -1;
on_error:
+#ifdef HAVE_ISULAD
+ if (l == NULL)
+ fprintf(stderr, "Failed to create lock for %s, path %s\n", name, lxcpath);
+#endif
return l;
}
@@ -370,3 +374,30 @@ void container_disk_unlock(struct lxc_container *c)
lxcunlock(c->slock);
lxcunlock(c->privlock);
}
+
+#ifdef HAVE_ISULAD
+static int lxc_removelock(struct lxc_lock *l)
+{
+ int ret = 0;
+
+ if (l->type == LXC_LOCK_FLOCK) {
+ ret = unlink(l->u.f.fname);
+ if (ret && errno != ENOENT) {
+ SYSERROR("Error unlink %s", l->u.f.fname);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+int container_disk_removelock(struct lxc_container *c)
+{
+ int ret;
+
+ ret = lxc_removelock(c->slock);
+ if (ret)
+ return ret;
+ return lxc_removelock(c->privlock);
+}
+#endif
diff --git a/src/lxc/mainloop.c b/src/lxc/mainloop.c
index d5ae2a6..c47f31b 100644
--- a/src/lxc/mainloop.c
+++ b/src/lxc/mainloop.c
@@ -150,3 +150,19 @@ void lxc_mainloop_close(struct lxc_epoll_descr *descr)
close_prot_errno_disarm(descr->epfd);
}
+
+#ifdef HAVE_ISULAD
+int isulad_safe_mainloop(struct lxc_epoll_descr *descr, int timeout_ms)
+{
+ int ret;
+
+ ret = lxc_mainloop(descr, timeout_ms);
+
+ // There are stdout and stderr channels, and two epolls should be performed to prevent
+ // one of the channels from exiting first, causing the other channel to not receive data,
+ // resulting in data loss
+ (void)lxc_mainloop(descr, 100);
+
+ return ret;
+}
+#endif
diff --git a/src/lxc/path.c b/src/lxc/path.c
new file mode 100644
index 0000000..46256cb
--- /dev/null
+++ b/src/lxc/path.c
@@ -0,0 +1,655 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/******************************************************************************
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020. Allrights reserved
+ * Description: isulad utils
+ * Author: lifeng
+ * Create: 2020-04-11
+******************************************************************************/
+#include <unistd.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <libgen.h>
+
+#include "path.h"
+#include "log.h"
+#include "isulad_utils.h"
+
+lxc_log_define(lxc_path_ui, lxc);
+
+#define ISSLASH(C) ((C) == '/')
+#define IS_ABSOLUTE_FILE_NAME(F) (ISSLASH ((F)[0]))
+#define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F))
+
+bool specify_current_dir(const char *path)
+{
+ char *basec = NULL, *bname = NULL;
+ bool res = false;
+
+ basec = safe_strdup(path);
+
+ bname = basename(basec);
+ if (bname == NULL) {
+ free(basec);
+ ERROR("Out of memory");
+ return false;
+ }
+ res = !strcmp(bname, ".");
+ free(basec);
+ return res;
+}
+
+bool has_traling_path_separator(const char *path)
+{
+ return path && strlen(path) && (path[strlen(path) - 1] == '/');
+}
+
+// PreserveTrailingDotOrSeparator returns the given cleaned path
+// and appends a trailing `/.` or `/` if its corresponding original
+// path ends with a trailing `/.` or `/`. If the cleaned
+// path already ends in a `.` path segment, then another is not added. If the
+// clean path already ends in a path separator, then another is not added.
+char *preserve_trailing_dot_or_separator(const char *cleanedpath,
+ const char *originalpath)
+{
+ char *respath = NULL;
+ size_t len;
+
+ if (strlen(cleanedpath) > (SIZE_MAX - 3)) {
+ return NULL;
+ }
+
+ len = strlen(cleanedpath) + 3;
+ respath = malloc(len);
+ if (respath == NULL) {
+ ERROR("Out of memory");
+ return NULL;
+ }
+ memset(respath, 0x00, len);
+ strcat(respath, cleanedpath);
+
+ if (!specify_current_dir(cleanedpath) && specify_current_dir(originalpath)) {
+ if (!has_traling_path_separator(respath))
+ strcat(respath, "/");
+ strcat(respath, ".");
+ }
+
+ if (!has_traling_path_separator(respath) &&
+ has_traling_path_separator(originalpath))
+ strcat(respath, "/");
+
+ return respath;
+}
+
+
+// Split splits path immediately following the final Separator,
+// separating it into a directory and file name component.
+// If there is no Separator in path, Split returns an empty dir
+// and file set to path.
+// The returned values have the property that path = dir+file.
+bool filepath_split(const char *path, char **dir, char **base)
+{
+ ssize_t i;
+ size_t len;
+
+ len = strlen(path);
+ if (len >= PATH_MAX) {
+ ERROR("Invalid path");
+ return false;
+ }
+ i = len - 1;
+ while (i >= 0 && path[i] != '/')
+ i--;
+
+ *dir = malloc(i + 2);
+ if (*dir == NULL) {
+ ERROR("Out of memory");
+ return false;
+ }
+ memcpy(*dir, path, i + 1);
+ *(*dir + i + 1) = '\0';
+
+ *base = safe_strdup(path + i + 1);
+
+ return true;
+}
+
+
+static bool do_clean_path_continue(const char *endpos, const char *stpos, const char *respath, char **dst)
+{
+ if (endpos - stpos == 1 && stpos[0] == '.') {
+ return true;
+ } else if (endpos - stpos == 2 && stpos[0] == '.' && stpos[1] == '.') {
+ char *dest = *dst;
+ if (dest <= respath + 1) {
+ return true;
+ }
+ for (--dest; dest > respath && !ISSLASH(dest[-1]); --dest) {
+ *dst = dest;
+ return true;
+ }
+ *dst = dest;
+ return true;
+ }
+ return false;
+}
+
+int do_clean_path(const char *respath, const char *limit_respath,
+ const char *stpos, char **dst)
+{
+ char *dest = *dst;
+ const char *endpos = NULL;
+
+ for (endpos = stpos; *stpos; stpos = endpos) {
+ while (ISSLASH(*stpos)) {
+ ++stpos;
+ }
+
+ for (endpos = stpos; *endpos && !ISSLASH(*endpos); ++endpos) {
+ }
+
+ if (endpos - stpos == 0) {
+ break;
+ } else if (do_clean_path_continue(endpos, stpos, respath, &dest)) {
+ continue;
+ }
+
+ if (!ISSLASH(dest[-1])) {
+ *dest++ = '/';
+ }
+
+ if (dest + (endpos - stpos) >= limit_respath) {
+ ERROR("Path is too long");
+ if (dest > respath + 1) {
+ dest--;
+ }
+ *dest = '\0';
+ return -1;
+ }
+
+ memcpy(dest, stpos, (size_t)(endpos - stpos));
+ dest += endpos - stpos;
+ *dest = '\0';
+ }
+ *dst = dest;
+ return 0;
+}
+
+char *cleanpath(const char *path, char *realpath, size_t realpath_len)
+{
+ char *respath = NULL;
+ char *dest = NULL;
+ const char *stpos = NULL;
+ const char *limit_respath = NULL;
+
+ if (path == NULL || path[0] == '\0' || \
+ realpath == NULL || (realpath_len < PATH_MAX)) {
+ return NULL;
+ }
+
+ respath = realpath;
+
+ memset(respath, 0, realpath_len);
+ limit_respath = respath + PATH_MAX;
+
+ if (!IS_ABSOLUTE_FILE_NAME(path)) {
+ if (!getcwd(respath, PATH_MAX)) {
+ ERROR("Failed to getcwd");
+ respath[0] = '\0';
+ goto error;
+ }
+ dest = strchr(respath, '\0');
+ if (dest == NULL) {
+ ERROR("Failed to get the end of respath");
+ goto error;
+ }
+ if (strlen(path) > (PATH_MAX - strlen(respath) - 1)) {
+ ERROR("Path is too long");
+ goto error;
+ }
+ strcat(respath, path);
+ stpos = path;
+ } else {
+ dest = respath;
+ *dest++ = '/';
+ stpos = path;
+ }
+
+ if (do_clean_path(respath, limit_respath, stpos, &dest)) {
+ goto error;
+ }
+
+ if (dest > respath + 1 && ISSLASH(dest[-1])) {
+ --dest;
+ }
+ *dest = '\0';
+
+ return respath;
+
+error:
+ return NULL;
+}
+
+static int do_path_realloc(const char *start, const char *end,
+ char **rpath, char **dest, const char **rpath_limit)
+{
+ long long dest_offset = *dest - *rpath;
+ char *new_rpath = NULL;
+ size_t new_size;
+ int nret = 0;
+ size_t gap = 0;
+
+ if (*dest + (end - start) < *rpath_limit) {
+ return 0;
+ }
+
+ gap = (size_t)(end - start) + 1;
+ new_size = (size_t)(*rpath_limit - *rpath);
+ if (new_size > SIZE_MAX - gap) {
+ ERROR("Out of range!");
+ return -1;
+ }
+
+ if (gap > PATH_MAX) {
+ new_size += gap;
+ } else {
+ new_size += PATH_MAX;
+ }
+ nret = lxc_mem_realloc((void **)&new_rpath, new_size, *rpath, PATH_MAX);
+ if (nret) {
+ ERROR("Failed to realloc memory for files limit variables");
+ return -1;
+ }
+ *rpath = new_rpath;
+ *rpath_limit = *rpath + new_size;
+
+ *dest = *rpath + dest_offset;
+
+ return 0;
+}
+
+static int do_get_symlinks_copy_buf(const char *buf, const char *prefix, size_t prefix_len,
+ char **rpath, char **dest)
+{
+ if (IS_ABSOLUTE_FILE_NAME(buf)) {
+ if (prefix_len) {
+ memcpy(*rpath, prefix, prefix_len);
+ }
+ *dest = *rpath + prefix_len;
+ *(*dest)++ = '/';
+ } else {
+ if (*dest > *rpath + prefix_len + 1) {
+ for (--(*dest); *dest > *rpath && !ISSLASH((*dest)[-1]); --(*dest)) {
+ continue;
+ }
+ }
+ }
+ return 0;
+}
+
+static int do_get_symlinks(const char **fullpath, const char *prefix, size_t prefix_len,
+ char **rpath, char **dest, const char **end,
+ int *num_links, char **extra_buf)
+{
+ char *buf = NULL;
+ size_t len;
+ ssize_t n;
+ int ret = -1;
+
+ if (++(*num_links) > MAXSYMLINKS) {
+ ERROR("Too many links in '%s'", *fullpath);
+ goto out;
+ }
+
+ buf = lxc_common_calloc_s(PATH_MAX);
+ if (buf == NULL) {
+ ERROR("Out of memory");
+ goto out;
+ }
+
+ n = readlink(*rpath, buf, PATH_MAX - 1);
+ if (n < 0) {
+ goto out;
+ }
+ buf[n] = '\0';
+
+ if (*extra_buf == NULL) {
+ *extra_buf = lxc_common_calloc_s(PATH_MAX);
+ if (*extra_buf == NULL) {
+ ERROR("Out of memory");
+ goto out;
+ }
+ }
+
+ len = strlen(*end);
+ if (len >= PATH_MAX - n) {
+ ERROR("Path is too long");
+ goto out;
+ }
+
+ memmove(&(*extra_buf)[n], *end, len + 1);
+ memcpy(*extra_buf, buf, (size_t)n);
+
+ *fullpath = *end = *extra_buf;
+
+ if (do_get_symlinks_copy_buf(buf, prefix, prefix_len, rpath, dest) != 0) {
+ goto out;
+ }
+
+ ret = 0;
+out:
+ free(buf);
+ return ret;
+}
+
+static bool do_eval_symlinks_in_scope_is_symlink(const char *path)
+{
+ struct stat st;
+
+ if (lstat(path, &st) < 0) {
+ return true;
+ }
+
+ if (!S_ISLNK(st.st_mode)) {
+ return true;
+ }
+ return false;
+}
+
+static void do_eval_symlinks_skip_slash(const char **start, const char **end)
+{
+ while (ISSLASH(**start)) {
+ ++(*start);
+ }
+
+ for (*end = *start; **end && !ISSLASH(**end); ++(*end)) {
+ }
+}
+
+static inline void skip_dest_traling_slash(char **dest, char **rpath, size_t prefix_len)
+{
+ if (*dest > *rpath + prefix_len + 1) {
+ for (--(*dest); *dest > *rpath && !ISSLASH((*dest)[-1]); --(*dest)) {
+ continue;
+ }
+ }
+}
+
+static inline bool is_current_char(const char c)
+{
+ return c == '.';
+}
+
+static inline bool is_specify_current(const char *end, const char *start)
+{
+ return (end - start == 1) && is_current_char(start[0]);
+}
+
+static inline bool is_specify_parent(const char *end, const char *start)
+{
+ return (end - start == 2) && is_current_char(start[0]) && is_current_char(start[1]);
+}
+
+static int do_eval_symlinks_in_scope(const char *fullpath, const char *prefix,
+ size_t prefix_len,
+ char **rpath, char **dest, const char *rpath_limit)
+{
+ const char *start = NULL;
+ const char *end = NULL;
+ char *extra_buf = NULL;
+ int nret = 0;
+ int num_links = 0;
+
+ start = fullpath + prefix_len;
+ for (end = start; *start; start = end) {
+ do_eval_symlinks_skip_slash(&start, &end);
+ if (end - start == 0) {
+ break;
+ } else if (is_specify_current(end, start)) {
+ ;
+ } else if (is_specify_parent(end, start)) {
+ skip_dest_traling_slash(dest, rpath, prefix_len);
+ } else {
+ if (!ISSLASH((*dest)[-1])) {
+ *(*dest)++ = '/';
+ }
+
+ nret = do_path_realloc(start, end, rpath, dest, &rpath_limit);
+ if (nret != 0) {
+ nret = -1;
+ goto out;
+ }
+
+ memcpy(*dest, start, (size_t)(end - start));
+ *dest += end - start;
+ **dest = '\0';
+
+ if (do_eval_symlinks_in_scope_is_symlink(*rpath)) {
+ continue;
+ }
+
+ nret = do_get_symlinks(&fullpath, prefix, prefix_len, rpath, dest, &end, &num_links, &extra_buf);
+ if (nret != 0) {
+ nret = -1;
+ goto out;
+ }
+ }
+ }
+out:
+ free(extra_buf);
+ return nret;
+}
+static char *eval_symlinks_in_scope(const char *fullpath, const char *rootpath)
+{
+ char resroot[PATH_MAX] = {0};
+ char *root = NULL;
+ char *rpath = NULL;
+ char *dest = NULL;
+ char *prefix = NULL;
+ const char *rpath_limit = NULL;
+ size_t prefix_len;
+
+ if (fullpath == NULL || rootpath == NULL) {
+ return NULL;
+ }
+
+ root = cleanpath(rootpath, resroot, sizeof(resroot));
+ if (root == NULL) {
+ ERROR("Failed to get cleaned path");
+ return NULL;
+ }
+
+ if (!strcmp(fullpath, root)) {
+ return safe_strdup(fullpath);
+ }
+
+ if (strstr(fullpath, root) == NULL) {
+ ERROR("Path '%s' is not in '%s'", fullpath, root);
+ return NULL;
+ }
+
+ rpath = lxc_common_calloc_s(PATH_MAX);
+ if (rpath == NULL) {
+ ERROR("Out of memory");
+ goto out;
+ }
+ rpath_limit = rpath + PATH_MAX;
+
+ prefix = root;
+ prefix_len = (size_t)strlen(prefix);
+ if (!strcmp(prefix, "/")) {
+ prefix_len = 0;
+ }
+
+ dest = rpath;
+ if (prefix_len) {
+ memcpy(rpath, prefix, prefix_len);
+ dest += prefix_len;
+ }
+ *dest++ = '/';
+
+ if (do_eval_symlinks_in_scope(fullpath, prefix, prefix_len, &rpath, &dest,
+ rpath_limit)) {
+ goto out;
+ }
+
+ if (dest > rpath + prefix_len + 1 && ISSLASH(dest[-1])) {
+ --dest;
+ }
+ *dest = '\0';
+ return rpath;
+
+out:
+ free(rpath);
+ return NULL;
+}
+
+// FollowSymlinkInScope is a wrapper around evalSymlinksInScope that returns an
+// absolute path. This function handles paths in a platform-agnostic manner.
+char *follow_symlink_in_scope(const char *fullpath, const char *rootpath)
+{
+ char resfull[PATH_MAX] = {0}, *full = NULL;
+ char resroot[PATH_MAX] = {0}, *root = NULL;
+
+ full = cleanpath(fullpath, resfull, PATH_MAX);
+ if (!full) {
+ ERROR("Failed to get cleaned path");
+ return NULL;
+ }
+
+ root = cleanpath(rootpath, resroot, PATH_MAX);
+ if (!root) {
+ ERROR("Failed to get cleaned path");
+ return NULL;
+ }
+
+ return eval_symlinks_in_scope(full, root);
+}
+
+// GetResourcePath evaluates `path` in the scope of the container's rootpath, with proper path
+// sanitisation. Symlinks are all scoped to the rootpath of the container, as
+// though the container's rootpath was `/`.
+//
+// The BaseFS of a container is the host-facing path which is bind-mounted as
+// `/` inside the container. This method is essentially used to access a
+// particular path inside the container as though you were a process in that
+// container.
+int get_resource_path(const char *rootpath, const char *path,
+ char **scopepath)
+{
+ char resolved[PATH_MAX] = {0}, *cleanedpath = NULL;
+ char *fullpath = NULL;
+ size_t len;
+
+ if (!rootpath || !path || !scopepath)
+ return -1;
+
+ *scopepath = NULL;
+
+ cleanedpath = cleanpath(path, resolved, PATH_MAX);
+ if (!cleanedpath) {
+ ERROR("Failed to get cleaned path");
+ return -1;
+ }
+
+ len = strlen(rootpath) + strlen(cleanedpath) + 1;
+ fullpath = malloc(len);
+ if (!fullpath) {
+ ERROR("Out of memory");
+ return -1;
+ }
+ snprintf(fullpath, len, "%s%s", rootpath, cleanedpath);
+
+ *scopepath = follow_symlink_in_scope(fullpath, rootpath);
+
+ free(fullpath);
+ return 0;
+}
+
+// Rel returns a relative path that is lexically equivalent to targpath when
+// joined to basepath with an intervening separator. That is,
+// Join(basepath, Rel(basepath, targpath)) is equivalent to targpath itself.
+// On success, the returned path will always be relative to basepath,
+// even if basepath and targpath share no elements.
+// An error is returned if targpath can't be made relative to basepath or if
+// knowing the current working directory would be necessary to compute it.
+// Rel calls Clean on the result.
+char *path_relative(const char *basepath, const char *targpath)
+{
+ char resbase[PATH_MAX] = {0}, *base = NULL;
+ char restarg[PATH_MAX] = {0}, *targ = NULL;
+ size_t bl = 0, tl = 0, b0 = 0, bi = 0, t0 = 0, ti = 0;
+
+ base = cleanpath(basepath, resbase, PATH_MAX);
+ if (!base) {
+ ERROR("Failed to get cleaned path");
+ return NULL;
+ }
+
+ targ = cleanpath(targpath, restarg, PATH_MAX);
+ if (!targ) {
+ ERROR("Failed to get cleaned path");
+ return NULL;
+ }
+
+ if (strcmp(base, targ) == 0)
+ return safe_strdup(".");
+
+ bl = strlen(base);
+ tl = strlen(targ);
+ while(true) {
+ while(bi < bl && !ISSLASH(base[bi]))
+ bi++;
+ while(ti < tl && !ISSLASH(targ[ti]))
+ ti++;
+ //not the same string
+ if (((bi - b0) != (ti - t0)) || strncmp(base + b0, targ + t0, bi - b0))
+ break;
+ if (bi < bl)
+ bi++;
+ if (ti < tl)
+ ti++;
+ b0 = bi;
+ t0 = ti;
+ }
+
+ if (b0 != bl) {
+ // Base elements left. Must go up before going down.
+ int seps = 0, i;
+ size_t ncopyed = 0, seps_size;
+ char *buf = NULL;
+
+ for (bi = b0; bi < bl; bi++) {
+ if (ISSLASH(base[bi]))
+ seps++;
+ }
+ //strlen(..) + strlen(/..) + '\0'
+ seps_size = 2 + seps * 3 + 1;
+ if (t0 != tl)
+ seps_size += 1 + tl - t0;
+
+ buf = calloc(seps_size, 1);
+ if (!buf) {
+ ERROR("Out of memory");
+ return NULL;
+ }
+ buf[ncopyed++] = '.';
+ buf[ncopyed++] = '.';
+ for (i = 0; i < seps; i++) {
+ buf[ncopyed++] = '/';
+ buf[ncopyed++] = '.';
+ buf[ncopyed++] = '.';
+ }
+ if (t0 != tl) {
+ buf[ncopyed++] = '/';
+ memcpy(buf + ncopyed, targ + t0, tl - t0 + 1);
+ }
+ return buf;
+ }
+
+ return safe_strdup(targ + t0);
+}
\ No newline at end of file
diff --git a/src/lxc/storage/dir.c b/src/lxc/storage/dir.c
index 18a10a4..dc642a4 100644
--- a/src/lxc/storage/dir.c
+++ b/src/lxc/storage/dir.c
@@ -94,6 +94,9 @@ int dir_create(struct lxc_storage *bdev, const char *dest, const char *n,
int dir_destroy(struct lxc_storage *orig)
{
+#ifdef HAVE_ISULAD
+ // isulad: do not destroy rootfs for directory, it should be managed by caller
+#else
int ret;
const char *src;
@@ -102,6 +105,7 @@ int dir_destroy(struct lxc_storage *orig)
ret = lxc_rmdir_onedev(src, NULL);
if (ret < 0)
return log_error_errno(ret, errno, "Failed to delete \"%s\"", src);
+#endif
return 0;
}
@@ -124,6 +128,35 @@ bool dir_detect(const char *path)
return false;
}
+#ifdef HAVE_ISULAD
+int dir_mount(struct lxc_storage *bdev)
+{
+ __do_free char *mntdata = NULL;
+ unsigned long mntflags = 0, pflags = 0;
+ int ret;
+ const char *src;
+
+ if (strcmp(bdev->type, "dir"))
+ return -22;
+
+ if (!bdev->src || !bdev->dest)
+ return -22;
+
+ ret = parse_mntopts(bdev->mntopts, &mntflags, &pflags, &mntdata);
+ if (ret < 0)
+ return log_error_errno(ret, errno, "Failed to parse mount options \"%s\"", bdev->mntopts);
+
+ src = lxc_storage_get_path(bdev->src, bdev->type);
+
+ ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC | (mntflags & ~MS_RDONLY) | pflags, mntdata);
+ if (ret < 0) {
+ return log_error_errno(-errno, errno, "Failed to mount \"%s\" on \"%s\"", src, bdev->dest);
+ }
+ TRACE("Mounted \"%s\" on \"%s\"", src, bdev->dest);
+
+ return 0;
+}
+#else
int dir_mount(struct lxc_storage *bdev)
{
__do_free char *mntdata = NULL;
@@ -166,6 +199,7 @@ int dir_mount(struct lxc_storage *bdev)
src ? src : "(none)", bdev->dest ? bdev->dest : "(none)", mntdata, mflags, pflags);
return 0;
}
+#endif
int dir_umount(struct lxc_storage *bdev)
{
diff --git a/src/lxc/storage/loop.c b/src/lxc/storage/loop.c
index eebc1b6..3a97c1d 100644
--- a/src/lxc/storage/loop.c
+++ b/src/lxc/storage/loop.c
@@ -21,6 +21,9 @@
#include "memory_utils.h"
#include "storage.h"
#include "storage_utils.h"
+#ifdef HAVE_ISULAD
+#include "lxclock.h"
+#endif
#include "utils.h"
lxc_log_define(loop, lxc);
@@ -216,7 +219,13 @@ bool loop_detect(const char *path)
int loop_mount(struct lxc_storage *bdev)
{
+#ifdef HAVE_ISULAD
+ int ret = 0;
+ int loopfd, lret;
+ struct lxc_lock *l = NULL;
+#else
int ret, loopfd;
+#endif
char loname[PATH_MAX];
const char *src;
@@ -226,13 +235,35 @@ int loop_mount(struct lxc_storage *bdev)
if (!bdev->src || !bdev->dest)
return -22;
+#ifdef HAVE_ISULAD
+ /* isulad: do lock before mount, so we can avoid use loop which is used by
+ * other starting contianers */
+ l = lxc_newlock("mount_lock", "mount_lock");
+ if (!l) {
+ SYSERROR("create file lock error when mount fs");
+ return -1;
+ }
+
+ lret = lxclock(l, 0);
+ if (lret) {
+ SYSERROR("try to lock failed when mount fs");
+ ret = -1;
+ goto out;
+ }
+#endif
+
/* skip prefix */
src = lxc_storage_get_path(bdev->src, bdev->type);
loopfd = lxc_prepare_loop_dev(src, loname, LO_FLAGS_AUTOCLEAR);
if (loopfd < 0) {
ERROR("Failed to prepare loop device for loop file \"%s\"", src);
+#ifdef HAVE_ISULAD
+ ret = -1;
+ goto out;
+#else
return -1;
+#endif
}
DEBUG("Prepared loop device \"%s\"", loname);
@@ -241,14 +272,29 @@ int loop_mount(struct lxc_storage *bdev)
ERROR("Failed to mount rootfs \"%s\" on \"%s\" via loop device \"%s\"",
bdev->src, bdev->dest, loname);
close(loopfd);
+#ifdef HAVE_ISULAD
+ ret = -1;
+ goto out;
+#else
return -1;
+#endif
}
bdev->lofd = loopfd;
DEBUG("Mounted rootfs \"%s\" on \"%s\" via loop device \"%s\"",
bdev->src, bdev->dest, loname);
-
+#ifdef HAVE_ISULAD
+out:
+ lret = lxcunlock(l);
+ if (lret) {
+ SYSERROR("try to unlock failed when mount fs");
+ ret = -1;
+ }
+ lxc_putlock(l);
+ return ret;
+#else
return 0;
+#endif
}
int loop_umount(struct lxc_storage *bdev)
diff --git a/src/lxc/storage/storage.c b/src/lxc/storage/storage.c
index 3f1b713..371513d 100644
--- a/src/lxc/storage/storage.c
+++ b/src/lxc/storage/storage.c
@@ -41,6 +41,9 @@
#include "storage_utils.h"
#include "utils.h"
#include "zfs.h"
+#ifdef HAVE_ISULAD
+#include "block.h"
+#endif
#ifndef HAVE_STRLCPY
#include "include/strlcpy.h"
@@ -94,6 +97,22 @@ static const struct lxc_storage_ops loop_ops = {
.can_backup = true,
};
+#ifdef HAVE_ISULAD
+/* block */
+static const struct lxc_storage_ops blk_ops = {
+ .detect = &blk_detect,
+ .mount = &blk_mount,
+ .umount = &blk_umount,
+ .clone_paths = NULL,
+ .destroy = &blk_destroy,
+ .create = NULL,
+ .copy = NULL,
+ .snapshot = NULL,
+ .can_snapshot = false,
+ .can_backup = true,
+};
+#endif
+
/* lvm */
static const struct lxc_storage_ops lvm_ops = {
.detect = &lvm_detect,
@@ -179,6 +198,10 @@ static const struct lxc_storage_type bdevs[] = {
{ .name = "overlayfs", .ops = &ovl_ops, },
{ .name = "loop", .ops = &loop_ops, },
{ .name = "nbd", .ops = &nbd_ops, },
+#ifdef HAVE_ISULAD
+ //isulad: block device
+ { .name = "blk", .ops = &blk_ops, }
+#endif
};
static const size_t numbdevs = sizeof(bdevs) / sizeof(struct lxc_storage_type);
@@ -570,9 +593,15 @@ bool storage_destroy(struct lxc_conf *conf)
int destroy_rv = 0;
r = storage_init(conf);
+#ifdef HAVE_ISULAD
+ if (r == NULL) {
+ WARN("%s 's storage init failed, the storage may be deleted already", conf->name);
+ return true;
+ }
+#else
if (!r)
return ret;
-
+#endif
destroy_rv = r->ops->destroy(r);
if (destroy_rv == 0)
ret = true;
--
2.25.1
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/firstadream/lxc.git
[email protected]:firstadream/lxc.git
firstadream
lxc
lxc
master

搜索帮助