1 Star 0 Fork 44

hanshuang/lxc

forked from src-openEuler/lxc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0007-refactor-patches-on-terminal.c-start.c-and-so-on.patch 75.81 KB
一键复制 编辑 原始数据 按行查看 历史
zhangxiaoyu 提交于 2022-07-21 18:54 +08:00 . fix compile error
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726
From 06b071d6bc7683023d3131d4e428210005333c8c Mon Sep 17 00:00:00 2001
From: chengzrz <czrzrichard@gmail.com>
Date: Wed, 20 Jul 2022 15:03:45 +0800
Subject: [PATCH] refactor patches on terminal.c, start.c and so on
Signed-off-by: chengzrz <czrzrichard@gmail.com>
---
hooks/Makefile.am | 3 +
src/lxc/attach.h | 6 +
src/lxc/cgroups/cgroup.c | 4 +
src/lxc/commands_utils.h | 6 +
src/lxc/initutils.c | 4 +
src/lxc/lsm/lsm.h | 8 +
src/lxc/lxclock.h | 4 +
src/lxc/mainloop.h | 4 +
src/lxc/start.c | 958 ++++++++++++++++++++++++++++++++++++
src/lxc/storage/btrfs.c | 11 +
src/lxc/storage/overlay.c | 8 +
src/lxc/sync.h | 4 +
src/lxc/terminal.c | 990 ++++++++++++++++++++++++++++++++++++++
src/tests/Makefile.am | 4 +
src/tests/attach.c | 11 +
15 files changed, 2025 insertions(+)
diff --git a/hooks/Makefile.am b/hooks/Makefile.am
index 5ae73d7..ddfd4bc 100644
--- a/hooks/Makefile.am
+++ b/hooks/Makefile.am
@@ -10,6 +10,8 @@ hooks_SCRIPTS = \
squid-deb-proxy-client \
nvidia
+
+if !HAVE_ISULAD
binhooks_PROGRAMS = \
unmount-namespace
@@ -20,5 +22,6 @@ if IS_BIONIC
unmount_namespace_SOURCES += \
../src/include/lxcmntent.c ../src/include/lxcmntent.h
endif
+endif
EXTRA_DIST=$(hooks_SCRIPTS)
diff --git a/src/lxc/attach.h b/src/lxc/attach.h
index ef5a6c1..8316344 100644
--- a/src/lxc/attach.h
+++ b/src/lxc/attach.h
@@ -20,9 +20,15 @@ struct lxc_proc_context_info {
int ns_fd[LXC_NS_MAX];
};
+#ifdef HAVE_ISULAD
+extern int lxc_attach(struct lxc_container *container,
+ lxc_attach_exec_t exec_function, void *exec_payload,
+ lxc_attach_options_t *options, pid_t *attached_process, char **err_msg);
+#else
extern int lxc_attach(struct lxc_container *container,
lxc_attach_exec_t exec_function, void *exec_payload,
lxc_attach_options_t *options, pid_t *attached_process);
+#endif
extern int lxc_attach_remount_sys_proc(void);
diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c
index 7c94fd8..5aa2c3c 100644
--- a/src/lxc/cgroups/cgroup.c
+++ b/src/lxc/cgroups/cgroup.c
@@ -31,7 +31,11 @@ struct cgroup_ops *cgroup_init(struct lxc_conf *conf)
if (!cgroup_ops)
return log_error_errno(NULL, errno, "Failed to initialize cgroup driver");
+#ifdef HAVE_ISULAD
+ if (cgroup_ops->data_init(cgroup_ops, conf)) {
+#else
if (cgroup_ops->data_init(cgroup_ops)) {
+#endif
cgroup_exit(cgroup_ops);
return log_error_errno(NULL, errno,
"Failed to initialize cgroup data");
diff --git a/src/lxc/commands_utils.h b/src/lxc/commands_utils.h
index 3ef7920..c836ead 100644
--- a/src/lxc/commands_utils.h
+++ b/src/lxc/commands_utils.h
@@ -65,4 +65,10 @@ extern int lxc_add_state_client(int state_client_fd,
extern int lxc_cmd_connect(const char *name, const char *lxcpath,
const char *hashed_sock_name, const char *suffix);
+#ifdef HAVE_ISULAD
+extern char *generate_named_unix_sock_dir(const char *name);
+extern int generate_named_unix_sock_path(const char *container_name,
+ const char *sock_name, char *out_path, size_t len);
+#endif
+
#endif /* __LXC_COMMANDS_UTILS_H */
diff --git a/src/lxc/initutils.c b/src/lxc/initutils.c
index 5549c2e..76f0048 100644
--- a/src/lxc/initutils.c
+++ b/src/lxc/initutils.c
@@ -54,11 +54,15 @@ const char *lxc_global_config_value(const char *option_name)
{ NULL, NULL },
};
+#ifdef HAVE_ISULAD
+ static const char *values[sizeof(options) / sizeof(options[0])] = {0};
+#else
/* placed in the thread local storage pool for non-bionic targets */
#ifdef HAVE_TLS
static thread_local const char *values[sizeof(options) / sizeof(options[0])] = {0};
#else
static const char *values[sizeof(options) / sizeof(options[0])] = {0};
+#endif
#endif
/* user_config_path is freed as soon as it is used */
diff --git a/src/lxc/lsm/lsm.h b/src/lxc/lsm/lsm.h
index ee578bb..4872f55 100644
--- a/src/lxc/lsm/lsm.h
+++ b/src/lxc/lsm/lsm.h
@@ -17,6 +17,10 @@ struct lsm_drv {
char *(*process_label_get)(pid_t pid);
int (*process_label_set)(const char *label, struct lxc_conf *conf,
bool on_exec);
+#ifdef HAVE_ISULAD
+ int (*file_label_set)(const char *path, const char *label);
+ int (*relabel)(const char *path, const char *label, bool share);
+#endif
int (*keyring_label_set)(char* label);
int (*prepare)(struct lxc_conf *conf, const char *lxcpath);
void (*cleanup)(struct lxc_conf *conf, const char *lxcpath);
@@ -32,6 +36,10 @@ extern int lsm_process_label_set(const char *label, struct lxc_conf *conf,
extern int lsm_process_label_fd_get(pid_t pid, bool on_exec);
extern int lsm_process_label_set_at(int label_fd, const char *label,
bool on_exec);
+#ifdef HAVE_ISULAD
+extern int lsm_file_label_set(const char *path, const char *label);
+extern int lsm_relabel(const char *path, const char *label, bool share);
+#endif
extern void lsm_process_cleanup(struct lxc_conf *conf, const char *lxcpath);
extern int lsm_keyring_label_set(char *label);
diff --git a/src/lxc/lxclock.h b/src/lxc/lxclock.h
index 9f9bc3b..6a71d7c 100644
--- a/src/lxc/lxclock.h
+++ b/src/lxc/lxclock.h
@@ -154,4 +154,8 @@ extern int container_disk_lock(struct lxc_container *c);
*/
extern void container_disk_unlock(struct lxc_container *c);
+#ifdef HAVE_ISULAD
+int container_disk_removelock(struct lxc_container *c);
+#endif
+
#endif
diff --git a/src/lxc/mainloop.h b/src/lxc/mainloop.h
index e6ab9a6..aa41a93 100644
--- a/src/lxc/mainloop.h
+++ b/src/lxc/mainloop.h
@@ -38,4 +38,8 @@ extern void lxc_mainloop_close(struct lxc_epoll_descr *descr);
define_cleanup_function(struct lxc_epoll_descr *, lxc_mainloop_close);
+#ifdef HAVE_ISULAD
+extern int isulad_safe_mainloop(struct lxc_epoll_descr *descr, int timeout_ms);
+#endif
+
#endif
diff --git a/src/lxc/start.c b/src/lxc/start.c
index fd969c4..f82df34 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -304,7 +304,11 @@ static int setup_signal_fd(sigset_t *oldmask)
{
int ret;
sigset_t mask;
+#ifdef HAVE_ISULAD
+ const int signals[] = {SIGBUS, SIGILL, SIGSEGV, SIGWINCH, SIGTERM};
+#else
const int signals[] = {SIGBUS, SIGILL, SIGSEGV, SIGWINCH};
+#endif
/* Block everything except serious error signals. */
ret = sigfillset(&mask);
@@ -590,13 +594,27 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
TRACE("Mainloop is ready");
+#ifdef HAVE_ISULAD
+ // iSulad: close stdin pipe if we do not want open_stdin with container stdin
+ if (!handler->conf->console.open_stdin) {
+ if (handler->conf->console.pipes[0][1] > 0) {
+ close(handler->conf->console.pipes[0][1]);
+ handler->conf->console.pipes[0][1] = -1;
+ }
+ }
+#endif
+
ret = lxc_mainloop(&descr, -1);
close_prot_errno_disarm(descr.epfd);
if (ret < 0 || !handler->init_died)
goto out_mainloop_console;
if (has_console)
+#ifdef HAVE_ISULAD
+ ret = isulad_safe_mainloop(&descr_console, 100);
+#else
ret = lxc_mainloop(&descr_console, 0);
+#endif
out_mainloop_console:
if (has_console) {
@@ -637,7 +655,9 @@ struct lxc_handler *lxc_init_handler(struct lxc_handler *old,
const char *name, struct lxc_conf *conf,
const char *lxcpath, bool daemonize)
{
+#ifndef HAVE_ISULAD
int nr_keep_fds = 0;
+#endif
int ret;
struct lxc_handler *handler;
@@ -671,6 +691,12 @@ struct lxc_handler *lxc_init_handler(struct lxc_handler *old,
handler->nsfd[i] = -EBADF;
handler->name = name;
+
+#ifdef HAVE_ISULAD
+ handler->exit_code = -1; /* isulad: record exit code of container */
+ handler->image_type_oci = false;
+#endif
+
if (daemonize)
handler->transient_pid = lxc_raw_getpid();
else
@@ -691,8 +717,10 @@ struct lxc_handler *lxc_init_handler(struct lxc_handler *old,
TRACE("Created anonymous pair {%d,%d} of unix sockets",
handler->state_socket_pair[0],
handler->state_socket_pair[1]);
+#ifndef HAVE_ISULAD
handler->keep_fds[nr_keep_fds++] = handler->state_socket_pair[0];
handler->keep_fds[nr_keep_fds++] = handler->state_socket_pair[1];
+#endif
}
if (handler->conf->reboot == REBOOT_NONE) {
@@ -701,7 +729,9 @@ struct lxc_handler *lxc_init_handler(struct lxc_handler *old,
ERROR("Failed to set up command socket");
goto on_error;
}
+#ifndef HAVE_ISULAD
handler->keep_fds[nr_keep_fds++] = handler->conf->maincmd_fd;
+#endif
}
TRACE("Unix domain socket %d for command server is ready",
@@ -721,6 +751,10 @@ int lxc_init(const char *name, struct lxc_handler *handler)
int ret;
const char *loglevel;
struct lxc_conf *conf = handler->conf;
+#ifdef HAVE_ISULAD
+ conf->console.disable_pty = handler->disable_pty;
+ conf->console.open_stdin = handler->open_stdin;
+#endif
handler->monitor_pid = lxc_raw_getpid();
status_fd = open("/proc/self/status", O_RDONLY | O_CLOEXEC);
@@ -810,6 +844,9 @@ int lxc_init(const char *name, struct lxc_handler *handler)
ret = lxc_terminal_setup(conf);
if (ret < 0) {
ERROR("Failed to create console");
+#ifdef HAVE_ISULAD
+ lxc_write_error_message(conf->errpipe[1], "Failed to create console for container \"%s\".", name);
+#endif
goto out_restore_sigmask;
}
TRACE("Created console");
@@ -853,6 +890,185 @@ out_restore_sigmask:
return -1;
}
+#ifdef HAVE_ISULAD
+/* isulad: start timeout thread */
+typedef enum {
+ START_INIT,
+ START_TIMEOUT,
+ START_MAX,
+} start_timeout_t;
+
+static start_timeout_t global_timeout_state = START_INIT;
+static sem_t global_timeout_sem;
+
+struct start_timeout_conf {
+ unsigned int timeout;
+ int errfd;
+};
+
+void trim_line(char *s)
+{
+ size_t len;
+
+ len = strlen(s);
+ while ((len > 1) && (s[len - 1] == '\n'))
+ s[--len] = '\0';
+}
+
+static int _read_procs_file(const char *path, pid_t **pids, size_t *len)
+{
+ FILE *f;
+ char *line = NULL;
+ size_t sz = 0;
+ pid_t *tmp_pids = NULL;
+
+ f = fopen_cloexec(path, "r");
+ if (!f)
+ return -1;
+
+ while (getline(&line, &sz, f) != -1) {
+ pid_t pid;
+ trim_line(line);
+ pid = (pid_t)atoll(line);
+ if (lxc_mem_realloc((void **)&tmp_pids, sizeof(pid_t) * (*len + 1), *pids, sizeof(pid_t) * (*len)) != 0) {
+ free(*pids);
+ *pids = NULL;
+ ERROR("out of memory");
+ free(line);
+ fclose(f);
+ return -1;
+ }
+ *pids = tmp_pids;
+
+ (*pids)[*len] = pid;
+ (*len)++;
+ }
+
+ free(line);
+ fclose(f);
+ return 0;
+}
+
+static int _recursive_read_cgroup_procs(const char *dirpath, pid_t **pids, size_t *len)
+{
+ struct dirent *direntp = NULL;
+ DIR *dir = NULL;
+ int ret, failed = 0;
+ char pathname[PATH_MAX];
+
+ dir = opendir(dirpath);
+ if (dir == NULL) {
+ WARN("Failed to open \"%s\"", dirpath);
+ return 0;
+ }
+
+ while ((direntp = readdir(dir))) {
+ struct stat mystat;
+ int rc;
+
+ if (!strcmp(direntp->d_name, ".") ||
+ !strcmp(direntp->d_name, ".."))
+ continue;
+
+ rc = snprintf(pathname, PATH_MAX, "%s/%s", dirpath, direntp->d_name);
+ if (rc < 0 || rc >= PATH_MAX) {
+ failed = 1;
+ continue;
+ }
+
+ if (strcmp(direntp->d_name, "cgroup.procs") == 0) {
+ if (_read_procs_file(pathname, pids, len)) {
+ failed = 1;
+
+ }
+ continue;
+ }
+
+ ret = lstat(pathname, &mystat);
+ if (ret) {
+ failed = 1;
+ continue;
+ }
+
+ if (S_ISDIR(mystat.st_mode)) {
+ if (_recursive_read_cgroup_procs(pathname, pids, len) < 0)
+ failed = 1;
+ }
+ }
+
+ ret = closedir(dir);
+ if (ret) {
+ WARN("Failed to close directory \"%s\"", dirpath);
+ failed = 1;
+ }
+
+ return failed ? -1 : 0;
+}
+
+int get_all_pids(struct cgroup_ops *cg_ops, pid_t **pids, size_t *len)
+{
+ const char *devices_path = NULL;
+
+ devices_path = cg_ops->get_cgroup_full_path(cg_ops, "devices");
+ if (!file_exists(devices_path)) {
+ return 0;
+ }
+
+ return _recursive_read_cgroup_procs(devices_path, pids, len);
+}
+
+static int set_cgroup_freezer(struct cgroup_ops *cg_ops, const char *value)
+{
+ char *fullpath;
+ int ret;
+
+ fullpath = must_make_path(cg_ops->get_cgroup_full_path(cg_ops, "freezer"), "freezer.state", NULL);
+ ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666);
+ free(fullpath);
+ return ret;
+}
+
+/* isulad: kill all process in container cgroup path */
+static void signal_all_processes(struct lxc_handler *handler)
+{
+ int ret;
+ struct cgroup_ops *cg_ops = handler->cgroup_ops;
+ pid_t *pids = NULL;
+ size_t len = 0, i;
+
+ ret = set_cgroup_freezer(cg_ops, "FROZEN");
+ if (ret < 0 && errno != ENOENT) {
+ WARN("cgroup_set frozen failed");
+ }
+
+ ret = get_all_pids(cg_ops, &pids, &len);
+ if (ret < 0) {
+ WARN("failed to get all pids");
+ }
+
+ for (i = 0; i < len; i++) {
+ ret = kill(pids[i], SIGKILL);
+ if (ret < 0 && errno != ESRCH) {
+ WARN("Can not kill process (pid=%d) with SIGKILL for container %s", pids[i], handler->name);
+ }
+ }
+
+ ret = set_cgroup_freezer(cg_ops, "THAWED");
+ if (ret < 0 && errno != ENOENT) {
+ WARN("cgroup_set thawed failed");
+ }
+
+ for (i = 0; i < len; i++) {
+ ret = lxc_wait_for_pid_status(pids[i]);
+ if (ret < 0 && errno != ECHILD) {
+ WARN("Failed to wait pid %d for container %s: %s", pids[i], handler->name, strerror(errno));
+ }
+ }
+
+ free(pids);
+}
+#endif
+
void lxc_end(struct lxc_handler *handler)
{
int ret;
@@ -926,6 +1142,33 @@ void lxc_end(struct lxc_handler *handler)
lsm_process_cleanup(handler->conf, handler->lxcpath);
+#ifdef HAVE_ISULAD
+ // close maincmd fd before destroy cgroup for isulad
+ if (handler->conf->reboot == REBOOT_NONE) {
+ /* For all new state clients simply close the command socket.
+ * This will inform all state clients that the container is
+ * STOPPED and also prevents a race between a open()/close() on
+ * the command socket causing a new process to get ECONNREFUSED
+ * because we haven't yet closed the command socket.
+ */
+ close_prot_errno_disarm(handler->conf->maincmd_fd);
+ TRACE("Closed command socket");
+ }
+ int retry_count = 0;
+ int max_retry = 10;
+retry:
+ if (cgroup_ops != NULL && !cgroup_ops->payload_destroy(cgroup_ops, handler)) {
+ TRACE("Trying to kill all subprocess");
+ signal_all_processes(handler);
+ TRACE("Finished kill all subprocess");
+ if (retry_count < max_retry) {
+ usleep(100 * 1000); /* 100 millisecond */
+ retry_count++;
+ goto retry;
+ }
+ SYSERROR("Failed to destroy cgroup path for container: \"%s\"", handler->name);
+ }
+#else
if (cgroup_ops) {
cgroup_ops->payload_destroy(cgroup_ops, handler);
cgroup_ops->monitor_destroy(cgroup_ops, handler);
@@ -940,12 +1183,25 @@ void lxc_end(struct lxc_handler *handler)
*/
close_prot_errno_disarm(handler->conf->maincmd_fd);
TRACE("Closed command socket");
+ }
+#endif
+ if (handler->conf->reboot == REBOOT_NONE) {
/* This function will try to connect to the legacy lxc-monitord
* state server and only exists for backwards compatibility.
*/
lxc_monitor_send_state(name, STOPPED, handler->lxcpath);
+#ifdef HAVE_ISULAD
+ /* isuald: write exit code to exit fifo */
+ if (handler->conf->exit_fd >= 0) {
+ ret = write(handler->conf->exit_fd, &handler->exit_code, sizeof(int));
+ if (ret != sizeof(int)) {
+ SYSERROR("Failed to write to exit code to exit fifo.");
+ }
+ }
+#endif
+
/* The command socket is closed so no one can acces the command
* socket anymore so there's no need to lock it.
*/
@@ -1042,6 +1298,25 @@ static int do_start(void *data)
lxc_sync_fini_parent(handler);
+#ifdef HAVE_ISULAD
+ sigset_t mask;
+
+ /*isulad: restore default signal handlers and unblock all signals*/
+ for (int i = 1; i < NSIG; i++)
+ signal(i, SIG_DFL);
+
+ ret = sigfillset(&mask);
+ if (ret < 0) {
+ SYSERROR("Failed to fill signal mask");
+ goto out_warn_father;
+ }
+ ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
+ if (ret < 0) {
+ SYSERROR("Failed to set signal mask");
+ goto out_warn_father;
+ }
+#endif
+
if (lxc_abstract_unix_recv_fds(data_sock1, &status_fd, 1, NULL, 0) < 0) {
ERROR("Failed to receive status file descriptor to child process");
goto out_warn_father;
@@ -1155,7 +1430,11 @@ static int do_start(void *data)
* means that migration won't work, but at least we won't spew output
* where it isn't wanted.
*/
+#ifdef HAVE_ISULAD
+ if (!handler->disable_pty && handler->daemonize && !handler->conf->autodev) {
+#else
if (handler->daemonize && !handler->conf->autodev) {
+#endif
char path[PATH_MAX];
ret = snprintf(path, sizeof(path), "%s/dev/null",
@@ -1221,6 +1500,9 @@ static int do_start(void *data)
/* Setup the container, ip, names, utsname, ... */
ret = lxc_setup(handler);
if (ret < 0) {
+#ifdef HAVE_ISULAD
+ lxc_write_error_message(handler->conf->errpipe[1], "Failed to setup lxc, please check the config file.");
+#endif
ERROR("Failed to setup container \"%s\"", handler->name);
goto out_warn_father;
}
@@ -1243,12 +1525,70 @@ static int do_start(void *data)
DEBUG("Set PR_SET_NO_NEW_PRIVS to block execve() gainable privileges");
}
+#ifdef HAVE_ISULAD
+ /* isulad: dup2 pipe[0][0] to container stdin, pipe[1][1] to container stdout, pipe[2][1] to container stderr */
+ if (handler->disable_pty) {
+ if (handler->conf->console.pipes[0][1] >= 0) {
+ close(handler->conf->console.pipes[0][1]);
+ handler->conf->console.pipes[0][1] = -1;
+ }
+
+ if (handler->conf->console.pipes[0][0] >= 0) {
+ ret = dup2(handler->conf->console.pipes[0][0], STDIN_FILENO);
+ if (ret < 0)
+ goto out_warn_father;
+ }
+
+ if (handler->conf->console.pipes[1][0] >= 0) {
+ close(handler->conf->console.pipes[1][0]);
+ handler->conf->console.pipes[1][0] = -1;
+ }
+
+ if (handler->conf->console.pipes[1][1] >= 0) {
+ ret = dup2(handler->conf->console.pipes[1][1], STDOUT_FILENO);
+ if (ret < 0)
+ goto out_warn_father;
+ }
+ if (handler->conf->console.pipes[2][0] >= 0) {
+ close(handler->conf->console.pipes[2][0]);
+ handler->conf->console.pipes[2][0] = -1;
+ }
+
+ if (handler->conf->console.pipes[2][1] >= 0) {
+ ret = dup2(handler->conf->console.pipes[2][1], STDERR_FILENO);
+ if (ret < 0)
+ goto out_warn_father;
+ }
+ }
+#endif
+
/* Some init's such as busybox will set sane tty settings on stdin,
* stdout, stderr which it thinks is the console. We already set them
* the way we wanted on the real terminal, and we want init to do its
* setup on its console ie. the pty allocated in lxc_terminal_setup() so
* make sure that that pty is stdin,stdout,stderr.
*/
+#ifdef HAVE_ISULAD
+ setsid();
+ if (!handler->disable_pty && handler->conf->console.pts >= 0) {
+ /* isulad:make the given terminal as controlling terminal to avoid warning
+ * sh: cannot set terminal process group (-1): Inappropriate ioctl for device
+ * sh: no job control in this shell */
+ if (ioctl(handler->conf->console.pts, TIOCSCTTY, NULL) < 0) {
+ ERROR("Faild to make the given terminal the controlling terminal of the calling process");
+ goto out_warn_father;
+ }
+ if (handler->daemonize || !handler->conf->is_execute)
+ ret = set_stdfds(handler->conf->console.pts);
+ else
+ ret = lxc_terminal_set_stdfds(handler->conf->console.pts);
+ if (ret < 0) {
+ ERROR("Failed to redirect std{in,out,err} to pty file "
+ "descriptor %d", handler->conf->console.pts);
+ goto out_warn_father;
+ }
+ }
+#else
if (handler->conf->console.pts >= 0) {
if (handler->daemonize || !handler->conf->is_execute)
ret = set_stdfds(handler->conf->console.pts);
@@ -1260,6 +1600,7 @@ static int do_start(void *data)
goto out_warn_father;
}
}
+#endif
/* If we mounted a temporary proc, then unmount it now. */
tmp_proc_unmount(handler->conf);
@@ -1283,6 +1624,21 @@ static int do_start(void *data)
close_prot_errno_disarm(handler->sigfd);
+#ifdef HAVE_ISULAD
+ if (!handler->disable_pty && handler->conf->console.pts < 0 && handler->daemonize) {
+ if (devnull_fd < 0) {
+ devnull_fd = open_devnull();
+ if (devnull_fd < 0)
+ goto out_warn_father;
+ }
+
+ ret = set_stdfds(devnull_fd);
+ if (ret < 0) {
+ ERROR("Failed to redirect std{in,out,err} to \"/dev/null\"");
+ goto out_warn_father;
+ }
+ }
+#else
if (handler->conf->console.pts < 0 && handler->daemonize) {
if (devnull_fd < 0) {
devnull_fd = open_devnull();
@@ -1296,12 +1652,25 @@ static int do_start(void *data)
goto out_warn_father;
}
}
+#endif
close_prot_errno_disarm(devnull_fd);
+#ifndef HAVE_ISULAD
setsid();
+#endif
if (handler->conf->init_cwd) {
+#ifdef HAVE_ISULAD
+ /* try to craete workdir if not exist */
+ struct stat st;
+ if (stat(handler->conf->init_cwd, &st) < 0 && mkdir_p(handler->conf->init_cwd, 0755) < 0) {
+ SYSERROR("Try to create directory \"%s\" as workdir failed", handler->conf->init_cwd);
+ lxc_write_error_message(handler->conf->errpipe[1], "%s:%d: Failed to create workdir: %s.",
+ __FILE__, __LINE__, strerror(errno));
+ goto out_warn_father;
+ }
+#endif
ret = chdir(handler->conf->init_cwd);
if (ret < 0) {
SYSERROR("Could not change directory to \"%s\"",
@@ -1345,6 +1714,13 @@ static int do_start(void *data)
}
}
+#ifdef HAVE_ISULAD
+ if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
+ SYSERROR("Failed to keep permitted capabilities");
+ goto out_warn_father;
+ }
+#endif
+
/* The container has been setup. We can now switch to an unprivileged
* uid/gid.
*/
@@ -1358,6 +1734,13 @@ static int do_start(void *data)
if (new_gid == nsgid)
new_gid = LXC_INVALID_GID;
+#ifdef HAVE_ISULAD
+ // isulad: set env home in container
+ if (lxc_setup_env_home(new_uid) < 0) {
+ goto out_warn_father;
+ }
+#endif
+
/* Make sure that the processes STDIO is correctly owned by the user that we are switching to */
ret = fix_stdio_permissions(new_uid);
if (ret)
@@ -1371,8 +1754,16 @@ static int do_start(void *data)
#if HAVE_LIBCAP
if (lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE))
#endif
+#ifdef HAVE_ISULAD
+ /* isulad: set groups for init process, and before we set uid and gid */
+ if (!lxc_setgroups(handler->conf->init_groups_len, handler->conf->init_groups)) {
+ ERROR("Can not set groups");
+ goto out_warn_father;
+ }
+#else
if (!lxc_setgroups(0, NULL))
goto out_warn_father;
+#endif
if (!lxc_switch_uid_gid(new_uid, new_gid))
goto out_warn_father;
@@ -1383,6 +1774,19 @@ static int do_start(void *data)
goto out_warn_father;
}
+#ifdef HAVE_ISULAD
+ /* isulad: drop the cap of current process */
+ if (prctl(PR_SET_KEEPCAPS, 0) < 0) {
+ SYSERROR("Failed to clear permitted capabilities");
+ goto out_warn_father;
+ }
+
+ if (lxc_drop_caps(handler->conf)) {
+ SYSERROR("Failed to drop caps");
+ goto out_warn_father;
+ }
+#endif
+
if (handler->conf->monitor_signal_pdeath != SIGKILL) {
ret = lxc_set_death_signal(handler->conf->monitor_signal_pdeath,
handler->monitor_pid, status_fd);
@@ -1397,7 +1801,12 @@ static int do_start(void *data)
* After this call, we are in error because this ops should not return
* as it execs.
*/
+#ifdef HAVE_ISULAD
+ close_prot_errno_disarm(status_fd);
+ handler->ops->start(handler, handler->data, handler->daemonize ? handler->conf->errpipe[1] : -1);
+#else
handler->ops->start(handler, handler->data);
+#endif
out_warn_father:
/*
@@ -1529,6 +1938,94 @@ static inline int do_share_ns(void *arg)
return 0;
}
+#ifdef HAVE_ISULAD
+static int lxc_write_container_info(char *filename, pid_t pid, pid_t p_pid,
+ unsigned long long start_at, unsigned long long p_start_at)
+{
+ FILE *pid_fp = NULL;
+ int ret = 0;
+
+ pid_fp = lxc_fopen(filename, "w");
+ if (pid_fp == NULL) {
+ SYSERROR("Failed to create pidfile '%s'",filename);
+ ret = -1;
+ goto out;
+ }
+
+ if (fprintf(pid_fp, "%d %llu %d %llu\n", pid, start_at, p_pid, p_start_at) < 0) {
+ SYSERROR("Failed to write '%s'", filename);
+ ret = -1;
+ goto out;
+ }
+out:
+ if (pid_fp)
+ fclose(pid_fp);
+ pid_fp = NULL;
+ return ret;
+}
+
+static int lxc_check_container_info(char *filename, pid_t pid, pid_t p_pid,
+ unsigned long long start_at, unsigned long long p_start_at)
+{
+ int ret = 0;
+ int num;
+ char sbuf[1024] = {0}; /* bufs for stat */
+ int saved_pid; /* process id */
+ int saved_ppid; /* pid of parent process */
+ unsigned long long saved_start_time; /* start time of process -- seconds since 1-1-70 */
+ unsigned long long saved_pstart_time; /* start time of parent process -- seconds since 1-1-70 */
+
+ if ((lxc_file2str(filename, sbuf, sizeof(sbuf))) == -1) {
+ SYSERROR("Failed to read pidfile %s", filename);
+ ret = -1;
+ goto out;
+ }
+
+ num = sscanf(sbuf, "%d %Lu %d %Lu", &saved_pid, &saved_start_time, &saved_ppid, &saved_pstart_time);
+ if (num != 4) {
+ SYSERROR("Call sscanf error");
+ ret = -1;
+ goto out;
+ }
+
+ if (pid != saved_pid || p_pid != saved_ppid
+ || start_at != saved_start_time || p_start_at != saved_pstart_time) {
+ ERROR("Check container info failed");
+ ret = -1;
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+/* isuald: save pid/ppid info */
+static int lxc_save_container_info(char *filename, pid_t pid)
+{
+ int ret = 0;
+ pid_t p_pid = 0;
+ unsigned long long start_at = 0;
+ unsigned long long p_start_at = 0;
+
+ start_at = lxc_get_process_startat(pid);
+ p_pid = getpid();
+ p_start_at = lxc_get_process_startat(p_pid);
+
+ ret = lxc_write_container_info(filename, pid, p_pid, start_at, p_start_at);
+ if (ret != 0) {
+ goto out;
+ }
+
+ ret = lxc_check_container_info(filename, pid, p_pid, start_at, p_start_at);
+ if (ret != 0) {
+ goto out;
+ }
+
+out:
+ return ret;
+}
+#endif
+
/* lxc_spawn() performs crucial setup tasks and clone()s the new process which
* exec()s the requested container binary.
* Note that lxc_spawn() runs in the parent namespaces. Any operations performed
@@ -1595,7 +2092,11 @@ static int lxc_spawn(struct lxc_handler *handler)
* it readonly.
* If the container is unprivileged then skip rootfs pinning.
*/
+#ifdef HAVE_ISULAD
+ if (!wants_to_map_ids && !handler->image_type_oci) {
+#else
if (!wants_to_map_ids) {
+#endif
handler->pinfd = pin_rootfs(conf->rootfs.path);
if (handler->pinfd == -EBADF)
INFO("Failed to pin the rootfs for container \"%s\"", handler->name);
@@ -1640,6 +2141,32 @@ static int lxc_spawn(struct lxc_handler *handler)
}
TRACE("Cloned child process %d", handler->pid);
+#ifdef HAVE_ISULAD
+ /* isulad: close pipe after clone */
+ if (handler->conf->console.pipes[0][0] >= 0) {
+ close(handler->conf->console.pipes[0][0]);
+ handler->conf->console.pipes[0][0] = -1;
+ }
+
+ if (handler->conf->console.pipes[1][1] >= 0) {
+ close(handler->conf->console.pipes[1][1]);
+ handler->conf->console.pipes[1][1] = -1;
+ }
+
+ if (handler->conf->console.pipes[2][1] >= 0) {
+ close(handler->conf->console.pipes[2][1]);
+ handler->conf->console.pipes[2][1] = -1;
+ }
+
+ /* isulad: save pid/ppid info into file*/
+ if (handler->conf->container_info_file) {
+ if (lxc_save_container_info(handler->conf->container_info_file, handler->pid)) {
+ ERROR("Failed to save cloned container pid");
+ goto out_delete_net;
+ }
+ }
+#endif
+
/* Verify that we can actually make use of pidfds. */
if (!lxc_can_use_pidfd(handler->pidfd))
close_prot_errno_disarm(handler->pidfd);
@@ -1652,6 +2179,13 @@ static int lxc_spawn(struct lxc_handler *handler)
if (ret < 0)
SYSERROR("Failed to set environment variable: LXC_PID=%s", pidstr);
+#ifdef HAVE_ISULAD
+ if (handler->cgroup_ops->container_cgroup) {
+ if (setenv("LXC_CGROUP_PATH", handler->cgroup_ops->container_cgroup, 1))
+ SYSERROR("Failed to set environment variable: LXC_CGROUP_PATH=%s.", handler->cgroup_ops->container_cgroup);
+ }
+#endif
+
for (i = 0; i < LXC_NS_MAX; i++)
if (handler->ns_on_clone_flags & ns_info[i].clone_flag)
INFO("Cloned %s", ns_info[i].flag_name);
@@ -1765,7 +2299,11 @@ static int lxc_spawn(struct lxc_handler *handler)
goto out_delete_net;
if (!lxc_list_empty(&conf->limits)) {
+#ifdef HAVE_ISULAD
+ ret = setup_resource_limits(&conf->limits, handler->pid, conf->errpipe[1]);
+#else
ret = setup_resource_limits(&conf->limits, handler->pid);
+#endif
if (ret < 0) {
ERROR("Failed to setup resource limits");
goto out_delete_net;
@@ -1816,6 +2354,26 @@ static int lxc_spawn(struct lxc_handler *handler)
ERROR("Failed to run lxc.hook.start-host");
goto out_delete_net;
}
+#ifdef HAVE_ISULAD
+ /* isulad: Run oci prestart hook at here */
+ ret = run_oci_hooks(name, "oci-prestart", conf, lxcpath);
+ if (ret < 0) {
+ ERROR("Failed to run oci prestart hooks");
+ goto out_delete_net;
+ }
+
+ if (START_TIMEOUT == global_timeout_state) {
+ lxc_write_error_message(conf->errpipe[1], "Starting the container \"%s\" timeout.", name);
+ ERROR("Starting the container \"%s\" timeout.", name);
+ goto out_delete_net;
+ }
+
+ /* Tell the child to continue its initialization. We'll get
+ * LXC_SYNC_POST_OCI_PRESTART_HOOK when it is ready for us to run oci prestart hooks.
+ */
+ if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_OCI_PRESTART_HOOK))
+ goto out_delete_net;
+#endif
/* Tell the child to complete its initialization and wait for it to exec
* or return an error. (The child will never return
@@ -1859,6 +2417,22 @@ static int lxc_spawn(struct lxc_handler *handler)
if (ret < 0)
goto out_abort;
+#ifdef HAVE_ISULAD
+ /* isulad: Run oci prestart hook at here */
+ ret = run_oci_hooks(name, "oci-poststart", conf, lxcpath);
+ if (ret < 0) {
+ ERROR("Failed to run oci poststart hooks");
+ goto out_abort;
+ }
+
+ if (START_TIMEOUT == global_timeout_state) {
+ lxc_write_error_message(conf->errpipe[1], "Starting the container \"%s\" timeout.", name);
+ ERROR("Starting the container \"%s\" timeout.", name);
+ goto out_abort;
+ }
+
+#endif
+
ret = lxc_set_state(name, handler, RUNNING);
if (ret < 0) {
ERROR("Failed to set state to \"%s\"", lxc_state2str(RUNNING));
@@ -1883,9 +2457,83 @@ out_sync_fini:
return -1;
}
+#ifdef HAVE_ISULAD
+/* isulad: start timeout thread function */
+static void* wait_start_timeout(void *arg)
+{
+ struct start_timeout_conf *conf = (struct start_timeout_conf *)arg;
+
+ sem_post(&global_timeout_sem);
+
+ if (!conf || conf->timeout < 1)
+ goto out;
+
+ sleep(conf->timeout);
+
+ global_timeout_state = START_TIMEOUT;
+
+out:
+ free(conf);
+ return ((void *)0);
+}
+
+/* isulad: create start timeout thread */
+static int create_start_timeout_thread(struct lxc_conf *conf, unsigned int start_timeout)
+{
+ int ret = 0;
+ pthread_t ptid;
+ pthread_attr_t attr;
+ struct start_timeout_conf *timeout_conf = NULL;
+
+ if (sem_init(&global_timeout_sem, 0, 0)) {
+ ERROR("Failed to init start timeout semaphore");/*lint !e613*/
+ ret = -1;
+ return ret;
+ }
+
+ timeout_conf = malloc(sizeof(struct start_timeout_conf));
+ if (timeout_conf == NULL) {
+ ERROR("Failed to malloc start timeout conf");
+ ret = -1;
+ goto out;
+ }
+
+ memset(timeout_conf, 0, sizeof(struct start_timeout_conf));
+ timeout_conf->errfd = conf->errpipe[1];
+ timeout_conf->timeout = start_timeout;
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ ret = pthread_create(&ptid, &attr, wait_start_timeout, timeout_conf);
+ pthread_attr_destroy(&attr);
+ if (ret != 0) {
+ ERROR("Create start wait timeout thread failed");
+ free(timeout_conf);
+ goto out;
+ }
+
+ sem_wait(&global_timeout_sem);
+out:
+ sem_destroy(&global_timeout_sem);
+ return ret;
+}
+
+// isulad: send '128 + signal' if container is killed by signal.
+#define EXIT_SIGNAL_OFFSET 128
+#endif
+
+
+#ifdef HAVE_ISULAD
+int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops,
+ void *data, const char *lxcpath, bool daemonize, int *error_num,
+ unsigned int start_timeout)
+{
+ int exit_code;
+#else
int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops,
void *data, const char *lxcpath, bool daemonize, int *error_num)
{
+#endif
int ret, status;
const char *name = handler->name;
struct lxc_conf *conf = handler->conf;
@@ -1901,6 +2549,16 @@ int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops,
handler->daemonize = daemonize;
cgroup_ops = handler->cgroup_ops;
+#ifdef HAVE_ISULAD
+ /* isulad: add start timeout limit */
+ if (start_timeout > 0) {
+ ret = create_start_timeout_thread(conf, start_timeout);
+ if (ret) {
+ ERROR("Failed to create start timeout thread for container \"%s\".", name);
+ goto out_abort;
+ }
+ }
+#endif
if (!attach_block_device(handler->conf)) {
ERROR("Failed to attach block device");
ret = -1;
@@ -1959,11 +2617,13 @@ int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops,
goto out_delete_network;
}
+#ifndef HAVE_ISULAD
if (!handler->init_died && handler->pid > 0) {
ERROR("Child process is not killed");
ret = -1;
goto out_delete_network;
}
+#endif
status = lxc_wait_for_pid_status(handler->pid);
if (status < 0)
@@ -1973,6 +2633,21 @@ int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops,
* reboot. This should mean it was an lxc-execute which simply exited.
* In any case, treat it as a 'halt'.
*/
+#ifdef HAVE_ISULAD
+ // isulad: recored log for container init exit
+ if (WIFSIGNALED(status)) {
+ int signal = WTERMSIG(status);
+ signal = WTERMSIG(status);
+ exit_code = EXIT_SIGNAL_OFFSET + signal;
+ ERROR("Container \"%s\" init exited with signal %d", name, signal);
+ } else if (WIFEXITED(status)) {
+ exit_code = WEXITSTATUS(status);
+ ERROR("Container \"%s\" init exited with status %d", name, exit_code);
+ } else {
+ exit_code = -1;
+ ERROR("Container \"%s\" init exited with unknown status", name);
+ }
+#else
if (WIFSIGNALED(status)) {
switch(WTERMSIG(status)) {
case SIGINT: /* halt */
@@ -1990,6 +2665,7 @@ int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops,
break;
}
}
+#endif
ret = lxc_restore_phys_nics_to_netns(handler);
if (ret < 0)
@@ -1997,11 +2673,20 @@ int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops,
close_prot_errno_disarm(handler->pinfd);
+#ifdef HAVE_ISULAD
+ lxc_monitor_send_exit_code(name, exit_code, handler->lxcpath);
+#else
lxc_monitor_send_exit_code(name, status, handler->lxcpath);
+#endif
+
lxc_error_set_and_log(handler->pid, status);
if (error_num)
*error_num = handler->exit_status;
+#ifdef HAVE_ISULAD
+ handler->exit_code = exit_code; /* record exit code */
+#endif
+
/* These are not the droids you are looking for. */
__private_goto1:
lxc_delete_network(handler);
@@ -2032,7 +2717,11 @@ struct start_args {
char *const *argv;
};
+#ifdef HAVE_ISULAD
+static int start(struct lxc_handler *handler, void* data, int fd)
+#else
static int start(struct lxc_handler *handler, void* data)
+#endif
{
struct start_args *arg = data;
@@ -2040,6 +2729,9 @@ static int start(struct lxc_handler *handler, void* data)
execvp(arg->argv[0], arg->argv);
SYSERROR("Failed to exec \"%s\"", arg->argv[0]);
+#ifdef HAVE_ISULAD
+ lxc_write_error_message(fd, "exec: \"%s\": %s.", arg->argv[0], strerror(errno));
+#endif
return 0;
}
@@ -2057,14 +2749,22 @@ static struct lxc_operations start_ops = {
};
int lxc_start(char *const argv[], struct lxc_handler *handler,
+#ifdef HAVE_ISULAD
+ const char *lxcpath, bool daemonize, int *error_num, unsigned int start_timeout)
+#else
const char *lxcpath, bool daemonize, int *error_num)
+#endif
{
struct start_args start_arg = {
.argv = argv,
};
TRACE("Doing lxc_start");
+#ifdef HAVE_ISULAD
+ return __lxc_start(handler, &start_ops, &start_arg, lxcpath, daemonize, error_num, start_timeout);
+#else
return __lxc_start(handler, &start_ops, &start_arg, lxcpath, daemonize, error_num);
+#endif
}
static void lxc_destroy_container_on_signal(struct lxc_handler *handler,
@@ -2136,3 +2836,261 @@ static bool do_destroy_container(struct lxc_handler *handler)
return storage_destroy(handler->conf);
}
+
+#ifdef HAVE_ISULAD
+/*isulad: set env for clean resources */
+static int clean_resource_set_env(struct lxc_handler *handler)
+{
+ const char *name = handler->name;
+ struct lxc_conf *conf = handler->conf;
+ char bufstr[PATH_MAX + 1];
+ int i = 0;
+ int j = 0;
+ int len = 2; //set "LXC_PID" and "LXC_CGNS_AWARE"
+
+ if (conf == NULL || conf->ocihooks == NULL || conf->ocihooks->poststop_len == 0) {
+ return 0;
+ }
+
+ if (name) {
+ len++;
+ }
+ if (conf->rcfile) {
+ len++;
+ }
+ if (conf->rootfs.mount) {
+ len++;
+ }
+ if (conf->rootfs.path) {
+ len++;
+ }
+ if (conf->console.path) {
+ len++;
+ }
+ if (conf->console.log_path) {
+ len++;
+ }
+ if (handler->cgroup_ops->container_cgroup) {
+ len++;
+ }
+
+ for (; i < conf->ocihooks->poststop_len; i++) {
+ size_t cap = conf->ocihooks->poststop[i]->env_len;
+ size_t newcap = cap + len + 1;
+ if (lxc_grow_array((void ***)&(conf->ocihooks->poststop[i]->env), &cap, newcap, 1) != 0) {
+ return -1;
+ }
+ j = conf->ocihooks->poststop[i]->env_len;
+ /* Start of environment variable setup for hooks. */
+ if (name) {
+ snprintf(bufstr, PATH_MAX + 1, "LXC_NAME=%s", name);
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
+ }
+ if (conf->rcfile) {
+ snprintf(bufstr, PATH_MAX + 1, "LXC_CONFIG_FILE=%s", conf->rcfile);
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
+ }
+ if (conf->rootfs.mount) {
+ snprintf(bufstr, PATH_MAX + 1, "LXC_ROOTFS_MOUNT=%s", conf->rootfs.mount);
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
+ }
+ if (conf->rootfs.path) {
+ snprintf(bufstr, PATH_MAX + 1, "LXC_ROOTFS_PATH=%s", conf->rootfs.path);
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
+ }
+ if (conf->console.path) {
+ snprintf(bufstr, PATH_MAX + 1, "LXC_CONSOLE=%s", conf->console.path);
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
+ }
+ if (conf->console.log_path) {
+ snprintf(bufstr, PATH_MAX + 1, "LXC_CONSOLE_LOGPATH=%s", conf->console.log_path);
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
+ }
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup("LXC_CGNS_AWARE=1");
+
+ snprintf(bufstr, PATH_MAX + 1, "LXC_PID=%d", handler->pid);
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
+ if (handler->cgroup_ops->container_cgroup) {
+ snprintf(bufstr, PATH_MAX + 1, "LXC_CGROUP_PATH=%s", handler->cgroup_ops->container_cgroup);
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
+ }
+ conf->ocihooks->poststop[i]->env_len = j;
+ /* End of environment variable setup for hooks. */
+ }
+ return 0;
+}
+
+/*isulad: init handler for clean */
+static struct lxc_handler *lxc_init_clean_handler(char *name, char *lxcpath, struct lxc_conf *conf, pid_t pid)
+{
+ int i;
+ struct lxc_handler *handler;
+
+ handler = malloc(sizeof(*handler));
+ if (handler == NULL)
+ return NULL;
+
+ memset(handler, 0, sizeof(*handler));
+
+ /* Note that am_guest_unpriv() checks the effective uid. We
+ * probably don't care if we are real root only if we are running
+ * as root so this should be fine.
+ */
+ handler->am_root = !am_guest_unpriv();
+ handler->data_sock[0] = handler->data_sock[1] = -1;
+ handler->conf = conf;
+ handler->lxcpath = lxcpath;
+ handler->pinfd = -1;
+ handler->sigfd = -EBADF;
+ handler->pidfd = -EBADF;
+ handler->init_died = false;
+ handler->monitor_status_fd = -EBADF;
+ handler->pid = pid;
+ handler->state_socket_pair[0] = handler->state_socket_pair[1] = -1;
+ if (handler->conf->reboot == REBOOT_NONE)
+ lxc_list_init(&handler->conf->state_clients);
+
+ for (i = 0; i < LXC_NS_MAX; i++)
+ handler->nsfd[i] = -1;
+
+ handler->name = name;
+ handler->exit_code = -1; /* isulad: record exit code of container */
+
+ handler->cgroup_ops = cgroup_init(conf);
+ if (!handler->cgroup_ops) {
+ ERROR("Failed to initialize cgroup driver");
+ goto on_error;
+ }
+
+ INFO("Container \"%s\" 's clean handler is initialized.", name);
+
+ return handler;
+
+on_error:
+ lxc_put_handler(handler);
+
+ return NULL;
+}
+
+/*isulad: init handler for clean */
+static struct lxc_handler *lxc_init_pids_handler(char *name, char *lxcpath, struct lxc_conf *conf)
+{
+ int i;
+ struct lxc_handler *handler;
+
+ handler = malloc(sizeof(*handler));
+ if (handler == NULL)
+ return NULL;
+
+ memset(handler, 0, sizeof(*handler));
+
+ /* Note that am_guest_unpriv() checks the effective uid. We
+ * probably don't care if we are real root only if we are running
+ * as root so this should be fine.
+ */
+ handler->am_root = !am_guest_unpriv();
+ handler->data_sock[0] = handler->data_sock[1] = -1;
+ handler->conf = conf;
+ handler->lxcpath = lxcpath;
+ handler->pinfd = -1;
+ handler->sigfd = -EBADF;
+ handler->init_died = false;
+ handler->state_socket_pair[0] = handler->state_socket_pair[1] = -1;
+ handler->monitor_status_fd = -EBADF;
+ handler->pidfd = -EBADF;
+ if (handler->conf->reboot == REBOOT_NONE)
+ lxc_list_init(&handler->conf->state_clients);
+
+ for (i = 0; i < LXC_NS_MAX; i++)
+ handler->nsfd[i] = -1;
+
+ handler->name = name;
+ handler->exit_code = -1; /* isulad: record exit code of container */
+
+ handler->cgroup_ops = cgroup_init(conf);
+ if (!handler->cgroup_ops) {
+ ERROR("Failed to initialize cgroup driver");
+ goto on_error;
+ }
+
+ INFO("Container \"%s\" 's clean handler is initialized.", name);
+
+ return handler;
+
+on_error:
+ lxc_put_handler(handler);
+
+ return NULL;
+}
+
+/*isulad: do_lxcapi_clean_resource */
+int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, pid_t pid)
+{
+ int ret = 0;
+ struct lxc_handler *handler = NULL;
+ int retry_count = 0;
+ int max_retry = 10;
+
+ handler = lxc_init_clean_handler(name, lxcpath, conf, pid);
+ if (!handler) {
+ ERROR("Failed to init container %s clean handler", name);
+ ret = -1;
+ goto out;
+ }
+
+ if (clean_resource_set_env(handler) != 0) {
+ ERROR("Failed to set env for poststop hooks");
+ ret = -1;
+ goto out;
+ }
+
+ if (run_oci_hooks(handler->name, "oci-poststop", handler->conf, handler->lxcpath)) {
+ ERROR("Failed to run lxc.hook.post-stop for container \"%s\".", handler->name);
+ ret = -1;
+ }
+
+retry:
+ if (!handler->cgroup_ops->payload_destroy(handler->cgroup_ops, handler)) {
+ TRACE("Trying to kill all subprocess");
+ signal_all_processes(handler);
+ TRACE("Finished kill all subprocess");
+ if (retry_count < max_retry) {
+ usleep(100 * 1000); /* 100 millisecond */
+ retry_count++;
+ goto retry;
+ }
+ SYSERROR("Failed to destroy cgroup path for container: \"%s\"", handler->name);
+ ret = -1;
+ }
+
+out:
+ lxc_put_handler(handler);
+ return ret;
+}
+
+/*isulad: do_lxcapi_get_pids */
+int do_lxcapi_get_pids(char *name, char *lxcpath, struct lxc_conf *conf, pid_t **pids,size_t *pids_len)
+{
+ int ret = 0;
+ struct lxc_handler *handler = NULL;
+ struct cgroup_ops *cg_ops = NULL;
+
+ handler = lxc_init_pids_handler(name, lxcpath, conf);
+ if (!handler) {
+ ERROR("Failed to init container %s clean handler", name);
+ ret = -1;
+ goto out;
+ }
+
+ cg_ops = handler->cgroup_ops;
+ ret = get_all_pids(cg_ops, pids, pids_len);
+ if (ret < 0) {
+ WARN("failed to get all pids");
+ }
+
+out:
+ lxc_put_handler(handler);
+ return ret;
+}
+
+#endif
diff --git a/src/lxc/storage/btrfs.c b/src/lxc/storage/btrfs.c
index 92a4a6d..069a9dd 100644
--- a/src/lxc/storage/btrfs.c
+++ b/src/lxc/storage/btrfs.c
@@ -197,16 +197,27 @@ int btrfs_mount(struct lxc_storage *bdev)
const char *src;
int ret;
+#ifdef HAVE_ISULAD
+ unsigned long pflags = 0;
+#endif
+
if (strcmp(bdev->type, "btrfs"))
return -22;
if (!bdev->src || !bdev->dest)
return -22;
+#ifdef HAVE_ISULAD
+ if (parse_mntopts(bdev->mntopts, &mntflags, &pflags, &mntdata) < 0) {
+ free(mntdata);
+ return -22;
+ }
+#else
if (parse_mntopts(bdev->mntopts, &mntflags, &mntdata) < 0) {
free(mntdata);
return -22;
}
+#endif
src = lxc_storage_get_path(bdev->src, "btrfs");
diff --git a/src/lxc/storage/overlay.c b/src/lxc/storage/overlay.c
index 770785c..75a81de 100644
--- a/src/lxc/storage/overlay.c
+++ b/src/lxc/storage/overlay.c
@@ -349,6 +349,9 @@ int ovl_mount(struct lxc_storage *bdev)
char *work, *lastslash;
size_t len, len2;
int ret, ret2;
+#ifdef HAVE_ISULAD
+ unsigned long pflags = 0;
+#endif
if (strcmp(bdev->type, "overlay") && strcmp(bdev->type, "overlayfs"))
return -22;
@@ -414,7 +417,12 @@ int ovl_mount(struct lxc_storage *bdev)
work = must_make_path(upper, LXC_OVERLAY_WORK_DIR, NULL);
upper[lastslash - upper] = '/';
+#ifdef HAVE_ISULAD
+ ret = parse_mntopts(bdev->mntopts, &mntflags, &pflags, &mntdata);
+#else
ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata);
+#endif
+
if (ret < 0) {
ERROR("Failed to parse mount options");
free(mntdata);
diff --git a/src/lxc/sync.h b/src/lxc/sync.h
index ff7a1eb..56c1dfc 100644
--- a/src/lxc/sync.h
+++ b/src/lxc/sync.h
@@ -11,6 +11,10 @@ enum {
LXC_SYNC_POST_CONFIGURE,
LXC_SYNC_CGROUP,
LXC_SYNC_CGROUP_UNSHARE,
+#ifdef HAVE_ISULAD
+ LXC_SYNC_OCI_PRESTART_HOOK,
+ LXC_SYNC_POST_OCI_PRESTART_HOOK,
+#endif
LXC_SYNC_CGROUP_LIMITS,
LXC_SYNC_READY_START,
LXC_SYNC_RESTART,
diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c
index e58db5c..0539eca 100644
--- a/src/lxc/terminal.c
+++ b/src/lxc/terminal.c
@@ -28,6 +28,10 @@
#include "syscall_wrappers.h"
#include "terminal.h"
#include "utils.h"
+#ifdef HAVE_ISULAD
+#include "logger_json_file.h"
+#include "include/strlcpy.h"
+#endif
#if HAVE_PTY_H
#include <pty.h>
@@ -183,6 +187,69 @@ static int lxc_terminal_truncate_log_file(struct lxc_terminal *terminal)
return lxc_unpriv(ftruncate(terminal->log_fd, 0));
}
+#ifdef HAVE_ISULAD
+
+int lxc_set_terminal_winsz(struct lxc_terminal *terminal, unsigned int height, unsigned int width)
+{
+ int ret = 0;
+ struct winsize wsz;
+
+ if (terminal->ptmx < 0) {
+ return 0;
+ }
+
+ ret = ioctl(terminal->ptmx, TIOCGWINSZ, &wsz);
+ if (ret < 0) {
+ WARN("Failed to get window size");
+ return -1;
+ }
+ wsz.ws_col = width;
+ wsz.ws_row = height;
+
+ ret = ioctl(terminal->ptmx, TIOCSWINSZ, &wsz);
+ if (ret < 0)
+ WARN("Failed to set window size");
+ else
+ DEBUG("Set window size to %d columns and %d rows", wsz.ws_col,
+ wsz.ws_row);
+ return ret;
+}
+
+/*
+ * isulad: support mult-logfiles
+ * */
+static int lxc_terminal_rename_old_log_file(struct lxc_terminal *terminal)
+{
+ int ret;
+ unsigned int i;
+ char tmp[PATH_MAX] = {0};
+ char *rename_fname = NULL;
+
+ for (i = terminal->log_rotate - 1; i > 1; i--) {
+ ret = snprintf(tmp, PATH_MAX, "%s.%u", terminal->log_path, i);
+ if (ret < 0 || ret >= PATH_MAX) {
+ free(rename_fname);
+ return -EFBIG;
+ }
+ free(rename_fname);
+ rename_fname = safe_strdup(tmp);
+ ret = snprintf(tmp, PATH_MAX, "%s.%u", terminal->log_path, (i - 1));
+ if (ret < 0 || ret >= PATH_MAX) {
+ free(rename_fname);
+ return -EFBIG;
+ }
+ ret = lxc_unpriv(rename(tmp, rename_fname));
+ if (ret < 0 && errno != ENOENT) {
+ free(rename_fname);
+ return ret;
+ }
+ }
+
+ free(rename_fname);
+ return 0;
+}
+#endif
+
static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal)
{
__do_free char *tmp = NULL;
@@ -196,6 +263,15 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal)
if (terminal->log_fd < 0)
return -EBADF;
+#ifdef HAVE_ISULAD
+ /* isuald: rotate old log file first */
+ ret = lxc_terminal_rename_old_log_file(terminal);
+ if(ret != 0) {
+ ERROR("Rename old log file failed");
+ return ret;
+ }
+#endif
+
len = strlen(terminal->log_path) + sizeof(".1");
tmp = must_realloc(NULL, len);
@@ -212,6 +288,7 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal)
return lxc_terminal_create_log_file(terminal);
}
+#ifndef HAVE_ISULAD
static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf,
int bytes_read)
{
@@ -317,7 +394,465 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf,
bytes_read -= ret;
return bytes_read;
}
+#endif
+
+#ifdef HAVE_ISULAD
+/* get time buffer */
+static bool get_time_buffer(struct timespec *timestamp, char *timebuffer,
+ size_t maxsize)
+{
+ struct tm tm_utc = { 0 };
+ int32_t nanos = 0;
+ time_t seconds;
+ size_t len = 0;
+ int ret = 0;
+
+ if (!timebuffer || !maxsize) {
+ return false;
+ }
+
+ seconds = (time_t)timestamp->tv_sec;
+ gmtime_r(&seconds, &tm_utc);
+ strftime(timebuffer, maxsize, "%Y-%m-%dT%H:%M:%S", &tm_utc);
+
+ nanos = (int32_t)timestamp->tv_nsec;
+ len = strlen(timebuffer);
+ ret = snprintf(timebuffer + len, (maxsize - len), ".%09dZ", nanos);
+ if (ret < 0 || ret >= (maxsize - len)) {
+ return false;
+ }
+
+ return true;
+}
+
+/* get now time buffer */
+static bool get_now_time_buffer(char *timebuffer, size_t maxsize)
+{
+ int err = 0;
+ struct timespec ts;
+
+ err = clock_gettime(CLOCK_REALTIME, &ts);
+ if (err != 0) {
+ ERROR("failed to get time");
+ return false;
+ }
+
+ return get_time_buffer(&ts, timebuffer, maxsize);
+}
+
+static int isulad_lxc_terminal_rotate_write_data(struct lxc_terminal *terminal, const char *buf,
+ int bytes_read)
+{
+ int ret;
+ struct stat st;
+ int64_t space_left = -1;
+
+ if (terminal->log_fd < 0)
+ return 0;
+
+ /* A log size <= 0 means that there's no limit on the size of the log
+ * file at which point we simply ignore whether the log is supposed to
+ * be rotated or not.
+ */
+ if (terminal->log_size <= 0)
+ return lxc_write_nointr(terminal->log_fd, buf, bytes_read);
+
+ /* Get current size of the log file. */
+ ret = fstat(terminal->log_fd, &st);
+ if (ret < 0) {
+ SYSERROR("Failed to stat the terminal log file descriptor");
+ return -1;
+ }
+
+ /* handle non-regular files */
+ if ((st.st_mode & S_IFMT) != S_IFREG) {
+ /* This isn't a regular file. so rotating the file seems a
+ * dangerous thing to do, size limits are also very
+ * questionable. Let's not risk anything and tell the user that
+ * he's requesting us to do weird stuff.
+ */
+ if (terminal->log_rotate > 0 || terminal->log_size > 0)
+ return -EINVAL;
+
+ /* I mean, sure log wherever you want to. */
+ return lxc_write_nointr(terminal->log_fd, buf, bytes_read);
+ }
+
+ space_left = terminal->log_size - st.st_size;
+
+ /* User doesn't want to rotate the log file and there's no more space
+ * left so simply truncate it.
+ */
+ if (space_left <= 0 && terminal->log_rotate <= 0) {
+ ret = lxc_terminal_truncate_log_file(terminal);
+ if (ret < 0)
+ return ret;
+
+ if (bytes_read <= terminal->log_size)
+ return lxc_write_nointr(terminal->log_fd, buf, bytes_read);
+
+ /* Write as much as we can into the buffer and loose the rest. */
+ return lxc_write_nointr(terminal->log_fd, buf, terminal->log_size);
+ }
+
+ /* There's enough space left. */
+ if (bytes_read <= space_left)
+ return lxc_write_nointr(terminal->log_fd, buf, bytes_read);
+
+ /* There'd be more to write but we aren't instructed to rotate the log
+ * file so simply return. There's no error on our side here.
+ */
+ if (terminal->log_rotate > 0)
+ ret = lxc_terminal_rotate_log_file(terminal);
+ else
+ ret = lxc_terminal_truncate_log_file(terminal);
+ if (ret < 0)
+ return ret;
+
+ if (terminal->log_size < bytes_read) {
+ /* Well, this is unfortunate because it means that there is more
+ * to write than the user has granted us space. There are
+ * multiple ways to handle this but let's use the simplest one:
+ * write as much as we can, tell the user that there was more
+ * stuff to write and move on.
+ * Note that this scenario shouldn't actually happen with the
+ * standard pty-based terminal that LXC allocates since it will
+ * be switched into raw mode. In raw mode only 1 byte at a time
+ * should be read and written.
+ */
+ WARN("Size of terminal log file is smaller than the bytes to write");
+ ret = lxc_write_nointr(terminal->log_fd, buf, terminal->log_size);
+ if (ret < 0)
+ return -1;
+ bytes_read -= ret;
+ return bytes_read;
+ }
+
+ /* Yay, we made it. */
+ ret = lxc_write_nointr(terminal->log_fd, buf, bytes_read);
+ if (ret < 0)
+ return -1;
+ bytes_read -= ret;
+ return bytes_read;
+}
+
+static ssize_t isulad_logger_json_write(struct lxc_terminal *terminal, const char *type, const char *buf,
+ int bytes_read)
+{
+ logger_json_file *msg = NULL;
+ ssize_t ret = -1;
+ size_t len;
+ char *json = NULL;
+ char timebuffer[64] = { 0 };
+ parser_error err = NULL;
+ struct parser_context ctx = { GEN_OPTIONS_SIMPLIFY | GEN_OPTIONS_NOT_VALIDATE_UTF8, stderr };
+
+ if (bytes_read < 0 || bytes_read >= INT_MAX) {
+ return -1;
+ }
+ msg = calloc(sizeof(logger_json_file), 1);
+ if (msg == NULL) {
+ return -errno;
+ }
+ msg->log = calloc(bytes_read, 1);
+ if (!msg->log) {
+ goto cleanup;
+ }
+ memcpy(msg->log, buf, bytes_read);
+ msg->log_len = bytes_read;
+ msg->stream = type ? safe_strdup(type) : safe_strdup("stdout");
+
+ get_now_time_buffer(timebuffer, sizeof(timebuffer));
+ msg->time = safe_strdup(timebuffer);
+
+ json = logger_json_file_generate_json(msg, &ctx, &err);
+ if (!json) {
+ ERROR("Failed to generate json: %s", err);
+ goto cleanup;
+ }
+ len = strlen(json);
+ json[len] = '\n';
+ ret = isulad_lxc_terminal_rotate_write_data(terminal, json, len + 1);
+cleanup:
+ free(json);
+ free_logger_json_file(msg);
+ free(err);
+ return ret;
+}
+
+static ssize_t isulad_logger_syslog_write(struct lxc_terminal *terminal, const char *buf)
+{
+ syslog(LOG_INFO, "%s", buf);
+ return 0;
+}
+
+static inline bool is_syslog(const char *driver)
+{
+ if (driver == NULL) {
+ return false;
+ }
+
+ return (strcmp("syslog", driver) == 0);
+}
+
+static inline ssize_t isulad_logger_write(struct lxc_terminal *terminal, const char *type, const char *buf,
+ int bytes_read)
+{
+ if (is_syslog(terminal->log_driver)) {
+ return isulad_logger_syslog_write(terminal, buf);
+ }
+
+ return isulad_logger_json_write(terminal, type, buf, bytes_read);
+}
+
+static int isulad_lxc_terminal_write_log_file(struct lxc_terminal *terminal, const char *type, char *buf,
+ int bytes_read)
+{
+#define __BUF_CACHE_SIZE (16 * LXC_TERMINAL_BUFFER_SIZE)
+ static char cache[__BUF_CACHE_SIZE];
+ static int size = 0;
+ int upto, index;
+ int begin = 0, buf_readed = 0, buf_left = 0;
+ int ret;
+
+ if (buf != NULL && bytes_read > 0) {
+ /* Work out how much more data we are okay with reading this time. */
+ upto = size + bytes_read;
+ if (upto > __BUF_CACHE_SIZE) {
+ upto = __BUF_CACHE_SIZE;
+ }
+
+ if (upto > size) {
+ buf_readed = upto - size;
+ memcpy(cache + size, buf, buf_readed);
+ buf_left = bytes_read - buf_readed;
+ size += buf_readed;
+ }
+ }
+
+ // If we have no data to log, and there's no more coming, we're done.
+ if (size == 0)
+ return 0;
+
+ // Break up the data that we've buffered up into lines, and log each in turn.
+ for (index = 0; index < size; index++) {
+ if (cache[index] == '\n') {
+ ret = isulad_logger_write(terminal, type, cache + begin, index - begin + 1);
+ if (ret < 0) {
+ WARN("Failed to log msg");
+ }
+ begin = index + 1;
+ }
+ }
+ /* If there's no more coming, or the buffer is full but
+ * has no newlines, log whatever we haven't logged yet,
+ * noting that it's a partial log line. */
+ if (buf == NULL || (begin == 0 && size == __BUF_CACHE_SIZE)) {
+ if (begin < size) {
+ ret = isulad_logger_write(terminal, type, cache + begin, size - begin);
+ if (ret < 0) {
+ WARN("Failed to log msg");
+ }
+ begin = 0;
+ size = 0;
+ }
+ if (buf == NULL) {
+ return 0;
+ }
+ }
+ /* Move any unlogged data to the front of the buffer in preparation for another read. */
+ if (begin > 0) {
+ memcpy(cache, cache + begin, size - begin);
+ size -= begin;
+ }
+ /* Move left data to cache buffer */
+ if (buf_left > 0) {
+ memcpy(cache + size, buf + buf_readed, buf_left);
+ size += buf_left;
+ }
+ return 0;
+}
+
+/* isulad: forward data to all fifos */
+static void lxc_forward_data_to_fifo(struct lxc_list *list, bool is_err, const char *buf, int r)
+{
+ struct lxc_list *it = NULL;
+ struct lxc_list *next = NULL;
+ struct lxc_fifos_fd *elem = NULL;
+ ssize_t w = 0;
+
+ lxc_list_for_each_safe(it, list, next) {
+ elem = it->elem;
+ if (is_err) {
+ if (elem->err_fd >= 0) {
+ w = lxc_write_nointr_for_fifo(elem->err_fd, buf, r);
+ if (w != r) {
+ WARN("Failed to write to fifo fd %d with error: %s", elem->err_fd, strerror(errno));
+ }
+ }
+ } else {
+ if (elem->out_fd >= 0) {
+ w = lxc_write_nointr_for_fifo(elem->out_fd, buf, r);
+ if (w != r) {
+ WARN("Failed to write to fifo fd %d with error: %s", elem->out_fd, strerror(errno));
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+/* isulad: judge the fd whether is fifo */
+static bool lxc_terminal_is_fifo(int fd, struct lxc_list *list)
+{
+ struct lxc_list *it = NULL;
+ struct lxc_list *next = NULL;
+ struct lxc_fifos_fd *elem = NULL;
+
+ lxc_list_for_each_safe(it, list, next) {
+ elem = it->elem;
+ if (elem->in_fd == fd)
+ return true;
+ }
+
+ return false;
+}
+
+/* isulad: if fd == -1, means delete all the fifos*/
+int lxc_terminal_delete_fifo(int fd, struct lxc_list *list)
+{
+ struct lxc_list *it = NULL;
+ struct lxc_list *next = NULL;
+ struct lxc_fifos_fd *elem = NULL;
+
+ lxc_list_for_each_safe(it, list, next) {
+ elem = it->elem;
+ if (elem->in_fd == fd || -1 == fd) {
+ INFO("Delete fifo fd %d", fd);
+ lxc_list_del(it);
+ if (elem->in_fifo)
+ free(elem->in_fifo);
+ if (elem->out_fifo)
+ free(elem->out_fifo);
+ if (elem->err_fifo)
+ free(elem->err_fifo);
+ if (elem->in_fd >= 0)
+ close(elem->in_fd);
+ if (elem->out_fd >= 0)
+ close(elem->out_fd);
+ if (elem->err_fd >= 0)
+ close(elem->err_fd);
+ free(elem);
+ }
+ }
+
+ return 0;
+}
+
+int lxc_terminal_io_cb(int fd, uint32_t events, void *data,
+ struct lxc_epoll_descr *descr)
+{
+ struct lxc_terminal *terminal = data;
+ char buf[2 * LXC_TERMINAL_BUFFER_SIZE];
+ int r, w, w_log, w_rbuf;
+
+ w = r = lxc_read_nointr(fd, buf, sizeof(buf));
+ if (r <= 0) {
+ INFO("Terminal client on fd %d has exited", fd);
+ lxc_mainloop_del_handler(descr, fd);
+
+ if (fd == terminal->ptmx) {
+ terminal->ptmx = -EBADF;
+ /* write remained buffer to terminal log */
+ if (terminal->log_fd >= 0) {
+ w_log = isulad_lxc_terminal_write_log_file(terminal, "stdout", NULL, 0);
+ if (w_log < 0)
+ TRACE("Failed to write %d bytes to terminal log", r);
+ }
+ /* notes: do not close the ptmx fd due to if we close the fd, the process may
+ * recive SIGHUP and the exit code will be 129 (128 + 1)
+ */
+ return LXC_MAINLOOP_CLOSE;
+ } else if (fd == terminal->peer) {
+ lxc_terminal_signal_fini(terminal);
+ terminal->peer = -EBADF;
+ close(fd);
+ return LXC_MAINLOOP_CONTINUE; /* isulad: do not close mainloop when peer close*/
+ } else if (lxc_terminal_is_fifo(fd, &terminal->fifos)) {
+ /* isulad: delete fifos when the client close */
+ lxc_terminal_delete_fifo(fd, &terminal->fifos);
+ return LXC_MAINLOOP_CONTINUE;
+ } else if (fd == terminal->pipes[1][0] || fd == terminal->pipes[2][0]) {
+ if (fd == terminal->pipes[1][0]) {
+ if (terminal->log_fd >= 0) {
+ w_log = isulad_lxc_terminal_write_log_file(terminal, "stdout", NULL, 0);
+ }
+ terminal->pipes[1][0] = -EBADF;
+ } else if (fd == terminal->pipes[2][0]) {
+ if (terminal->log_fd >= 0) {
+ w_log = isulad_lxc_terminal_write_log_file(terminal, "stderr", NULL, 0);
+ }
+ terminal->pipes[2][0] = -EBADF;
+ }
+ /* notes: do not close the ptmx fd due to if we close the fd, the process may
+ * recive SIGHUP and the exit code will be 141 (128 + 13)
+ */
+ return LXC_MAINLOOP_CONTINUE;
+ } else if (fd == terminal->pipes[0][1]) {
+ TRACE("closed stdin pipe of container stdin");
+ terminal->pipes[0][1] = -EBADF;
+ return LXC_MAINLOOP_CONTINUE;
+ } else {
+ WARN("Handler received unexpected file descriptor");
+ }
+ close(fd);
+ return LXC_MAINLOOP_CLOSE;
+ }
+
+ if (fd == terminal->peer || lxc_terminal_is_fifo(fd, &terminal->fifos)) {
+ if (terminal->ptmx > 0)
+ w = lxc_write_nointr(terminal->ptmx, buf, r);
+ if (terminal->pipes[0][1] > 0)
+ w = lxc_write_nointr(terminal->pipes[0][1], buf, r);
+ }
+
+ w_rbuf = w_log = 0;
+ if (fd == terminal->ptmx || fd == terminal->pipes[1][0] || fd == terminal->pipes[2][0]) {
+ /* write to peer first */
+ if (terminal->peer >= 0)
+ w = lxc_write_nointr(terminal->peer, buf, r);
+
+ /* isulad: forward data to fifos */
+ lxc_forward_data_to_fifo(&terminal->fifos, fd == terminal->pipes[2][0], buf, r);
+
+ /* write to terminal ringbuffer */
+ if (terminal->buffer_size > 0)
+ w_rbuf = lxc_ringbuf_write(&terminal->ringbuf, buf, r);
+
+ /* write to terminal log */
+ if (terminal->log_fd >= 0) {
+ if (fd == terminal->ptmx || fd == terminal->pipes[1][0])
+ w_log = isulad_lxc_terminal_write_log_file(terminal, "stdout", buf, r);
+ else if (fd == terminal->pipes[2][0])
+ w_log = isulad_lxc_terminal_write_log_file(terminal, "stderr", buf, r);
+ }
+ }
+
+ if (w != r)
+ WARN("Short write on terminal r:%d != w:%d", r, w);
+
+ if (w_rbuf < 0) {
+ errno = -w_rbuf;
+ SYSTRACE("Failed to write %d bytes to terminal ringbuffer", r);
+ }
+
+ if (w_log < 0)
+ TRACE("Failed to write %d bytes to terminal log", r);
+ return LXC_MAINLOOP_CONTINUE;
+}
+#else
int lxc_terminal_io_cb(int fd, uint32_t events, void *data,
struct lxc_epoll_descr *descr)
{
@@ -374,6 +909,7 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data,
return LXC_MAINLOOP_CONTINUE;
}
+#endif
static int lxc_terminal_mainloop_add_peer(struct lxc_terminal *terminal)
{
@@ -401,6 +937,110 @@ static int lxc_terminal_mainloop_add_peer(struct lxc_terminal *terminal)
return 0;
}
+#ifdef HAVE_ISULAD
+/* isulad add pipes to mainloop */
+static int lxc_terminal_mainloop_add_pipes(struct lxc_terminal *terminal)
+{
+ int ret = 0;
+
+ // parent read data from fifo, and send to stdin of container
+ if (terminal->pipes[0][1] > 0) {
+ ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[0][1],
+ lxc_terminal_io_cb, terminal);
+ if (ret) {
+ ERROR("pipe fd %d not added to mainloop", terminal->pipes[0][1]);
+ return -1;
+ }
+ }
+ // parent read data from stdout of container, and send to fifo
+ if (terminal->pipes[1][0] > 0) {
+ ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[1][0],
+ lxc_terminal_io_cb, terminal);
+ if (ret) {
+ ERROR("pipe fd %d not added to mainloop", terminal->pipes[1][0]);
+ return -1;
+ }
+ }
+ // parent read data from stderr of container, and send to fifo
+ if (terminal->pipes[2][0] > 0) {
+ ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[2][0],
+ lxc_terminal_io_cb, terminal);
+ if (ret) {
+ ERROR("pipe fd %d not added to mainloop", terminal->pipes[2][0]);
+ return -1;
+ }
+ }
+ return ret;
+}
+
+/* isulad add fifo to mainloop */
+static int lxc_terminal_mainloop_add_fifo(struct lxc_terminal *terminal)
+{
+ int ret = 0;
+ struct lxc_list *it = NULL;
+ struct lxc_list *next = NULL;
+ struct lxc_fifos_fd *elem = NULL;
+
+ lxc_list_for_each_safe(it, &terminal->fifos, next) {
+ elem = it->elem;
+ if (elem->in_fd >= 0) {
+ ret = lxc_mainloop_add_handler(terminal->descr, elem->in_fd,
+ lxc_terminal_io_cb, terminal);
+ if (ret) {
+ ERROR("console fifo %s not added to mainloop", elem->in_fifo);
+ return -1;
+ }
+ }
+ }
+ return ret;
+}
+
+int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr,
+ struct lxc_terminal *terminal)
+{
+ int ret;
+
+ /* We cache the descr so that we can add an fd to it when someone
+ * does attach to it in lxc_terminal_allocate().
+ */
+ terminal->descr = descr;
+
+ ret = lxc_terminal_mainloop_add_peer(terminal);
+ if (ret < 0) {
+ ERROR("Failed to add handler for terminal peer to mainloop");
+ return -1;
+ }
+
+ /* isulad add pipes to mainloop */
+ ret = lxc_terminal_mainloop_add_pipes(terminal);
+ if (ret < 0) {
+ ERROR("Failed to add handler for terminal fifos to mainloop");
+ return -1;
+ }
+
+ /* isulad add fifo to mainloop */
+ ret = lxc_terminal_mainloop_add_fifo(terminal);
+ if (ret < 0) {
+ ERROR("Failed to add handler for terminal fifos to mainloop");
+ return -1;
+ }
+
+ if (terminal->ptmx < 0) {
+ INFO("Terminal is not initialized");
+ return 0;
+ }
+
+ ret = lxc_mainloop_add_handler(descr, terminal->ptmx,
+ lxc_terminal_io_cb, terminal);
+ if (ret < 0) {
+ ERROR("Failed to add handler for terminal ptmx fd %d to "
+ "mainloop", terminal->ptmx);
+ return -1;
+ }
+
+ return 0;
+}
+#else
int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr,
struct lxc_terminal *terminal)
{
@@ -426,6 +1066,7 @@ int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr,
return lxc_terminal_mainloop_add_peer(terminal);
}
+#endif
int lxc_setup_tios(int fd, struct termios *oldtios)
{
@@ -639,14 +1280,39 @@ void lxc_terminal_free(struct lxc_conf *conf, int fd)
static int lxc_terminal_peer_default(struct lxc_terminal *terminal)
{
+#ifdef HAVE_ISULAD
+ struct lxc_terminal_state *ts = NULL;
+ const char *path = NULL;
+#else
struct lxc_terminal_state *ts;
const char *path;
+#endif
int ret = 0;
if (terminal->path)
path = terminal->path;
+
+#ifdef HAVE_ISULAD
+ /* isulad: if no console was given, try current controlling terminal, there
+ * won't be one if we were started as a daemon (-d)
+ */
+ if (!path && !access("/dev/tty", F_OK)) {
+ int fd;
+ fd = open("/dev/tty", O_RDWR);
+ if (fd >= 0) {
+ close(fd);
+ path = "/dev/tty";
+ }
+ }
+
+ if (!path) {
+ DEBUG("Not have a controlling terminal");
+ return 0;
+ }
+#else
else
path = "/dev/tty";
+#endif
terminal->peer = lxc_unpriv(open(path, O_RDWR | O_CLOEXEC));
if (terminal->peer < 0) {
@@ -760,6 +1426,35 @@ void lxc_terminal_delete(struct lxc_terminal *terminal)
if (terminal->log_fd >= 0)
close(terminal->log_fd);
terminal->log_fd = -1;
+
+#ifdef HAVE_ISULAD
+ if (is_syslog(terminal->log_driver)) {
+ closelog();
+ free(terminal->log_driver);
+ }
+ /* isulad: close all pipes */
+ if (terminal->pipes[0][0] >= 0)
+ close(terminal->pipes[0][0]);
+ terminal->pipes[0][0] = -1;
+ if (terminal->pipes[0][1] >= 0)
+ close(terminal->pipes[0][1]);
+ terminal->pipes[0][1] = -1;
+ if (terminal->pipes[1][0] >= 0)
+ close(terminal->pipes[1][0]);
+ terminal->pipes[1][0] = -1;
+ if (terminal->pipes[1][1] >= 0)
+ close(terminal->pipes[1][1]);
+ terminal->pipes[1][1] = -1;
+ if (terminal->pipes[2][0] >= 0)
+ close(terminal->pipes[2][0]);
+ terminal->pipes[2][0] = -1;
+ if (terminal->pipes[2][1] >= 0)
+ close(terminal->pipes[2][1]);
+ terminal->pipes[2][1] = -1;
+
+ /* isulad: delete all fifos */
+ lxc_terminal_delete_fifo(-1, &terminal->fifos);
+#endif
}
/**
@@ -828,6 +1523,251 @@ int lxc_terminal_create_log_file(struct lxc_terminal *terminal)
return 0;
}
+#ifdef HAVE_ISULAD
+/* isulad: fd_nonblock */
+static int fd_nonblock(int fd)
+{
+ int flags;
+
+ flags = fcntl(fd, F_GETFL);
+
+ return fcntl(fd, F_SETFL, (int)((unsigned int)flags | O_NONBLOCK));
+}
+
+static int terminal_fifo_open(const char *fifo_path, int flags)
+{
+ int fd = -1;
+
+ fd = lxc_open(fifo_path, flags, 0);
+ if (fd < 0) {
+ WARN("Failed to open fifo %s to send message: %s.", fifo_path,
+ strerror(errno));
+ return -1;
+ }
+
+ return fd;
+}
+
+bool fifo_exists(const char *path)
+{
+ struct stat sb;
+ int ret;
+
+ ret = stat(path, &sb);
+ if (ret < 0)
+ // could be something other than eexist, just say no
+ return false;
+ return S_ISFIFO(sb.st_mode);
+}
+
+/* isulad: set terminal fifos */
+static int lxc_terminal_set_fifo(struct lxc_terminal *console, const char *in, const char *out, const char *err, int *input_fd)
+{
+ int fifofd_in = -1, fifofd_out = -1, fifofd_err = -1;
+ struct lxc_fifos_fd *fifo_elem = NULL;
+
+ if ((in && !fifo_exists(in)) || (out && !fifo_exists(out)) || (err && !fifo_exists(err))) {
+ ERROR("File %s or %s or %s does not refer to a FIFO", in, out, err);
+ return -1;
+ }
+
+ if (in) {
+ fifofd_in = terminal_fifo_open(in, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
+ if (fifofd_in < 0) {
+ SYSERROR("Failed to open FIFO: %s", in);
+ return -1;
+ }
+ }
+
+ if (out) {
+ fifofd_out = terminal_fifo_open(out, O_WRONLY | O_NONBLOCK | O_CLOEXEC);
+ if (fifofd_out < 0) {
+ SYSERROR("Failed to open FIFO: %s", out);
+ if (fifofd_in >= 0)
+ close(fifofd_in);
+ return -1;
+ }
+ }
+
+ if (err) {
+ fifofd_err = terminal_fifo_open(err, O_WRONLY | O_NONBLOCK | O_CLOEXEC);
+ if (fifofd_err < 0) {
+ SYSERROR("Failed to open FIFO: %s", err);
+ if (fifofd_in >= 0)
+ close(fifofd_in);
+ if (fifofd_out >= 0)
+ close(fifofd_out);
+ return -1;
+ }
+ }
+
+ fifo_elem = malloc(sizeof(*fifo_elem));
+ if (fifo_elem == NULL) {
+ if (fifofd_in >= 0)
+ close(fifofd_in);
+ if (fifofd_out >= 0)
+ close(fifofd_out);
+ if (fifofd_err >= 0)
+ close(fifofd_err);
+ return -1;
+ }
+ memset(fifo_elem, 0, sizeof(*fifo_elem));
+
+ fifo_elem->in_fifo = safe_strdup(in ? in : "");
+ fifo_elem->out_fifo = safe_strdup(out ? out : "");
+ fifo_elem->err_fifo = safe_strdup(err ? err : "");
+ fifo_elem->in_fd = fifofd_in;
+ fifo_elem->out_fd = fifofd_out;
+ fifo_elem->err_fd = fifofd_err;
+ lxc_list_add_elem(&fifo_elem->node, fifo_elem);
+ lxc_list_add_tail(&console->fifos, &fifo_elem->node);
+
+ if (input_fd)
+ *input_fd = fifofd_in;
+
+ return 0;
+}
+
+/* isulad: add default fifos */
+static int lxc_terminal_fifo_default(struct lxc_terminal *terminal)
+{
+ if (terminal->init_fifo[0] || terminal->init_fifo[1] || terminal->init_fifo[2])
+ return lxc_terminal_set_fifo(terminal, terminal->init_fifo[0], terminal->init_fifo[1], terminal->init_fifo[2], NULL);
+ return 0;
+}
+
+int lxc_terminal_create(struct lxc_terminal *terminal)
+{
+ int ret;
+
+ if (!terminal->disable_pty) {
+ ret = openpty(&terminal->ptmx, &terminal->pts, NULL, NULL, NULL);
+ if (ret < 0) {
+ SYSERROR("Failed to open terminal");
+ return -1;
+ }
+
+ ret = ttyname_r(terminal->pts, terminal->name, sizeof(terminal->name));
+ if (ret < 0) {
+ SYSERROR("Failed to retrieve name of terminal pts");
+ goto err;
+ }
+
+ ret = fd_cloexec(terminal->ptmx, true);
+ if (ret < 0) {
+ SYSERROR("Failed to set FD_CLOEXEC flag on terminal ptmx");
+ goto err;
+ }
+
+ /* isulad: make ptmx NONBLOCK */
+ ret = fd_nonblock(terminal->ptmx);
+ if (ret < 0) {
+ SYSERROR("Failed to set O_NONBLOCK flag on terminal ptmx");
+ goto err;
+ }
+
+ ret = fd_cloexec(terminal->pts, true);
+ if (ret < 0) {
+ SYSERROR("Failed to set FD_CLOEXEC flag on terminal pts");
+ goto err;
+ }
+
+ ret = lxc_terminal_peer_default(terminal);
+ if (ret < 0) {
+ ERROR("Failed to allocate proxy terminal");
+ goto err;
+ }
+ } else {
+ /* isulad: create 3 pipes */
+ /* for stdin */
+ if (pipe2(terminal->pipes[0], O_CLOEXEC)) {
+ ERROR("Failed to create stdin pipe");
+ goto err;
+ }
+
+ /* for stdout */
+ if (pipe2(terminal->pipes[1], O_CLOEXEC)) {
+ ERROR("Failed to create stdout pipe");
+ goto err;
+ }
+ /* for stderr */
+ if (pipe2(terminal->pipes[2], O_CLOEXEC)) {
+ ERROR("Failed to create stderr pipe");
+ goto err;
+ }
+ }
+
+ /* isulad: open fifos */
+ ret = lxc_terminal_fifo_default(terminal);
+ if (ret < 0) {
+ ERROR("Failed to allocate fifo terminal");
+ goto err;
+ }
+
+ return 0;
+
+err:
+ lxc_terminal_delete(terminal);
+ return -ENODEV;
+}
+
+/* isulad: add fifos dynamic*/
+int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames)
+{
+ int ret = 0;
+ struct lxc_terminal *terminal = &conf->console;
+ int fifofd_in = -1;
+ char *tmp = NULL, *saveptr = NULL, *in = NULL, *out = NULL, *err = NULL;
+ const char *none_fifo_name = "none";
+
+ tmp = safe_strdup(fifonames);
+
+ in = strtok_r(tmp, "&&&&", &saveptr);
+ if (!in) {
+ ret = -1;
+ goto free_out;
+ }
+ if (strcmp(in, none_fifo_name) == 0)
+ in = NULL;
+
+ out = strtok_r(NULL, "&&&&", &saveptr);
+ if (!out) {
+ ret = -1;
+ goto free_out;
+ }
+ if (strcmp(out, none_fifo_name) == 0)
+ out = NULL;
+
+ err = strtok_r(NULL, "&&&&", &saveptr);
+ if (!err) {
+ ret = -1;
+ goto free_out;
+ }
+ if (strcmp(err, none_fifo_name) == 0)
+ err = NULL;
+
+ ret = lxc_terminal_set_fifo(terminal, in, out, err, &fifofd_in);
+ if (ret < 0) {
+ ERROR("Faild to set fifos to console config");
+ ret = -1;
+ goto free_out;
+ }
+
+ if (lxc_mainloop_add_handler(terminal->descr, fifofd_in,
+ lxc_terminal_io_cb, terminal)) {
+ ERROR("console fifo not added to mainloop");
+ lxc_terminal_delete_fifo(fifofd_in, &terminal->fifos);
+ ret = -1;
+ goto free_out;
+ }
+
+free_out:
+ if (tmp)
+ free(tmp);
+ return ret;
+}
+
+#else
int lxc_terminal_create(struct lxc_terminal *terminal)
{
int ret;
@@ -868,6 +1808,7 @@ err:
lxc_terminal_delete(terminal);
return -ENODEV;
}
+#endif
int lxc_terminal_setup(struct lxc_conf *conf)
{
@@ -883,6 +1824,18 @@ int lxc_terminal_setup(struct lxc_conf *conf)
if (ret < 0)
return -1;
+#ifdef HAVE_ISULAD
+ if (is_syslog(terminal->log_driver)) {
+ if (terminal->log_syslog_tag == NULL) {
+ terminal->log_syslog_tag = malloc(16 * sizeof(char));
+ (void)strlcpy(terminal->log_syslog_tag, conf->name, 16);
+ }
+ if (terminal->log_syslog_facility <= 0) {
+ terminal->log_syslog_facility = LOG_DAEMON;
+ }
+ openlog(terminal->log_syslog_tag, LOG_PID, terminal->log_syslog_facility);
+ }
+#endif
ret = lxc_terminal_create_log_file(terminal);
if (ret < 0)
goto err;
@@ -1120,9 +2073,15 @@ int lxc_terminal_prepare_login(int fd)
if (ret < 0)
return -1;
+#ifdef HAVE_ISULAD
+ ret = set_stdfds(fd);
+ if (ret < 0)
+ return -1;
+#else
ret = lxc_terminal_set_stdfds(fd);
if (ret < 0)
return -1;
+#endif
if (fd > STDERR_FILENO)
close(fd);
@@ -1146,6 +2105,18 @@ void lxc_terminal_init(struct lxc_terminal *terminal)
terminal->peer = -EBADF;
terminal->log_fd = -EBADF;
lxc_terminal_info_init(&terminal->proxy);
+#ifdef HAVE_ISULAD
+ terminal->init_fifo[0] = NULL;
+ terminal->init_fifo[1] = NULL;
+ terminal->init_fifo[2] = NULL;
+ terminal->pipes[0][0] = -1;
+ terminal->pipes[0][1] = -1;
+ terminal->pipes[1][0] = -1;
+ terminal->pipes[1][1] = -1;
+ terminal->pipes[2][0] = -1;
+ terminal->pipes[2][1] = -1;
+ lxc_list_init(&terminal->fifos);
+#endif
}
void lxc_terminal_conf_free(struct lxc_terminal *terminal)
@@ -1155,6 +2126,15 @@ void lxc_terminal_conf_free(struct lxc_terminal *terminal)
if (terminal->buffer_size > 0 && terminal->ringbuf.addr)
lxc_ringbuf_release(&terminal->ringbuf);
lxc_terminal_signal_fini(terminal);
+#ifdef HAVE_ISULAD
+ /*isulad: free console fifos */
+ free(terminal->init_fifo[0]);
+ free(terminal->init_fifo[1]);
+ free(terminal->init_fifo[2]);
+ lxc_terminal_delete_fifo(-1, &terminal->fifos);
+ free(terminal->log_driver);
+ free(terminal->log_syslog_tag);
+#endif
}
int lxc_terminal_map_ids(struct lxc_conf *c, struct lxc_terminal *terminal)
@@ -1167,6 +2147,15 @@ int lxc_terminal_map_ids(struct lxc_conf *c, struct lxc_terminal *terminal)
if (strcmp(terminal->name, "") == 0)
return 0;
+#ifdef HAVE_ISULAD
+ ret = chown_mapped_root(terminal->name, c);
+ if (ret < 0) {
+ ERROR("Failed to chown terminal \"%s\"", terminal->name);
+ return -1;
+ }
+
+ TRACE("Chowned terminal \"%s\"", terminal->name);
+#else
ret = userns_exec_mapped_root(terminal->name, terminal->pts, c);
if (ret < 0) {
return log_error(-1, "Failed to chown terminal %d(%s)",
@@ -1174,6 +2163,7 @@ int lxc_terminal_map_ids(struct lxc_conf *c, struct lxc_terminal *terminal)
}
TRACE("Chowned terminal %d(%s)", terminal->pts, terminal->name);
+#endif
return 0;
}
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index 11bba26..03bf439 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -58,6 +58,10 @@ AM_CFLAGS=-DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \
-I $(top_srcdir)/src/lxc/tools \
-pthread
+if HAVE_ISULAD
+AM_CFLAGS += -I $(top_srcdir)/src/lxc/json
+endif
+
if ENABLE_APPARMOR
AM_CFLAGS += -DHAVE_APPARMOR
endif
diff --git a/src/tests/attach.c b/src/tests/attach.c
index 07e641d..f36caac 100644
--- a/src/tests/attach.c
+++ b/src/tests/attach.c
@@ -29,6 +29,9 @@
#include "lxctest.h"
#include "utils.h"
#include "lsm/lsm.h"
+#ifdef HAVE_ISULAD
+#include "config.h"
+#endif
#include <lxc/lxccontainer.h>
@@ -76,7 +79,11 @@ static void test_attach_lsm_set_config(struct lxc_container *ct)
ct->save_config(ct, NULL);
}
+#ifdef HAVE_ISULAD
+static int test_attach_lsm_func_func(void* payload, int fd)
+#else
static int test_attach_lsm_func_func(void* payload)
+#endif
{
TSTOUT("%s", lsm_process_label_get(syscall(SYS_getpid)));
return 0;
@@ -187,7 +194,11 @@ static int test_attach_lsm_func(struct lxc_container *ct) { return 0; }
static int test_attach_lsm_cmd(struct lxc_container *ct) { return 0; }
#endif /* HAVE_APPARMOR || HAVE_SELINUX */
+#ifdef HAVE_ISULAD
+static int test_attach_func_func(void* payload, int fd)
+#else
static int test_attach_func_func(void* payload)
+#endif
{
TSTOUT("%d", (int)syscall(SYS_getpid));
return 0;
--
2.25.1
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/hanshuang123456/lxc.git
git@gitee.com:hanshuang123456/lxc.git
hanshuang123456
lxc
lxc
master

搜索帮助