instance.c 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429
  1. /*
  2. * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
  3. * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License version 2.1
  7. * as published by the Free Software Foundation
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #define _GNU_SOURCE
  15. #include <sys/resource.h>
  16. #include <sys/types.h>
  17. #include <sys/socket.h>
  18. #include <sys/stat.h>
  19. #include <grp.h>
  20. #include <net/if.h>
  21. #include <unistd.h>
  22. #include <stdint.h>
  23. #include <stdio.h>
  24. #include <fcntl.h>
  25. #include <pwd.h>
  26. #include <libgen.h>
  27. #include <unistd.h>
  28. #define SYSLOG_NAMES
  29. #include <syslog.h>
  30. #include <libubox/md5.h>
  31. #include "../procd.h"
  32. #include "service.h"
  33. #include "instance.h"
  34. #define UJAIL_BIN_PATH "/sbin/ujail"
  35. enum {
  36. INSTANCE_ATTR_COMMAND,
  37. INSTANCE_ATTR_ENV,
  38. INSTANCE_ATTR_DATA,
  39. INSTANCE_ATTR_NETDEV,
  40. INSTANCE_ATTR_FILE,
  41. INSTANCE_ATTR_TRIGGER,
  42. INSTANCE_ATTR_RESPAWN,
  43. INSTANCE_ATTR_NICE,
  44. INSTANCE_ATTR_LIMITS,
  45. INSTANCE_ATTR_WATCH,
  46. INSTANCE_ATTR_ERROR,
  47. INSTANCE_ATTR_USER,
  48. INSTANCE_ATTR_GROUP,
  49. INSTANCE_ATTR_STDOUT,
  50. INSTANCE_ATTR_STDERR,
  51. INSTANCE_ATTR_NO_NEW_PRIVS,
  52. INSTANCE_ATTR_JAIL,
  53. INSTANCE_ATTR_TRACE,
  54. INSTANCE_ATTR_SECCOMP,
  55. INSTANCE_ATTR_PIDFILE,
  56. INSTANCE_ATTR_RELOADSIG,
  57. INSTANCE_ATTR_TERMTIMEOUT,
  58. INSTANCE_ATTR_FACILITY,
  59. INSTANCE_ATTR_EXTROOT,
  60. INSTANCE_ATTR_OVERLAYDIR,
  61. INSTANCE_ATTR_TMPOVERLAYSIZE,
  62. __INSTANCE_ATTR_MAX
  63. };
  64. static const struct blobmsg_policy instance_attr[__INSTANCE_ATTR_MAX] = {
  65. [INSTANCE_ATTR_COMMAND] = { "command", BLOBMSG_TYPE_ARRAY },
  66. [INSTANCE_ATTR_ENV] = { "env", BLOBMSG_TYPE_TABLE },
  67. [INSTANCE_ATTR_DATA] = { "data", BLOBMSG_TYPE_TABLE },
  68. [INSTANCE_ATTR_NETDEV] = { "netdev", BLOBMSG_TYPE_ARRAY },
  69. [INSTANCE_ATTR_FILE] = { "file", BLOBMSG_TYPE_ARRAY },
  70. [INSTANCE_ATTR_TRIGGER] = { "triggers", BLOBMSG_TYPE_ARRAY },
  71. [INSTANCE_ATTR_RESPAWN] = { "respawn", BLOBMSG_TYPE_ARRAY },
  72. [INSTANCE_ATTR_NICE] = { "nice", BLOBMSG_TYPE_INT32 },
  73. [INSTANCE_ATTR_LIMITS] = { "limits", BLOBMSG_TYPE_TABLE },
  74. [INSTANCE_ATTR_WATCH] = { "watch", BLOBMSG_TYPE_ARRAY },
  75. [INSTANCE_ATTR_ERROR] = { "error", BLOBMSG_TYPE_ARRAY },
  76. [INSTANCE_ATTR_USER] = { "user", BLOBMSG_TYPE_STRING },
  77. [INSTANCE_ATTR_GROUP] = { "group", BLOBMSG_TYPE_STRING },
  78. [INSTANCE_ATTR_STDOUT] = { "stdout", BLOBMSG_TYPE_BOOL },
  79. [INSTANCE_ATTR_STDERR] = { "stderr", BLOBMSG_TYPE_BOOL },
  80. [INSTANCE_ATTR_NO_NEW_PRIVS] = { "no_new_privs", BLOBMSG_TYPE_BOOL },
  81. [INSTANCE_ATTR_JAIL] = { "jail", BLOBMSG_TYPE_TABLE },
  82. [INSTANCE_ATTR_TRACE] = { "trace", BLOBMSG_TYPE_BOOL },
  83. [INSTANCE_ATTR_SECCOMP] = { "seccomp", BLOBMSG_TYPE_STRING },
  84. [INSTANCE_ATTR_PIDFILE] = { "pidfile", BLOBMSG_TYPE_STRING },
  85. [INSTANCE_ATTR_RELOADSIG] = { "reload_signal", BLOBMSG_TYPE_INT32 },
  86. [INSTANCE_ATTR_TERMTIMEOUT] = { "term_timeout", BLOBMSG_TYPE_INT32 },
  87. [INSTANCE_ATTR_FACILITY] = { "facility", BLOBMSG_TYPE_STRING },
  88. [INSTANCE_ATTR_EXTROOT] = { "extroot", BLOBMSG_TYPE_STRING },
  89. [INSTANCE_ATTR_OVERLAYDIR] = { "overlaydir", BLOBMSG_TYPE_STRING },
  90. [INSTANCE_ATTR_TMPOVERLAYSIZE] = { "tmpoverlaysize", BLOBMSG_TYPE_STRING },
  91. };
  92. enum {
  93. JAIL_ATTR_NAME,
  94. JAIL_ATTR_HOSTNAME,
  95. JAIL_ATTR_PROCFS,
  96. JAIL_ATTR_SYSFS,
  97. JAIL_ATTR_UBUS,
  98. JAIL_ATTR_LOG,
  99. JAIL_ATTR_RONLY,
  100. JAIL_ATTR_MOUNT,
  101. JAIL_ATTR_NETNS,
  102. JAIL_ATTR_USERNS,
  103. JAIL_ATTR_CGROUPSNS,
  104. JAIL_ATTR_CONSOLE,
  105. JAIL_ATTR_REQUIREJAIL,
  106. __JAIL_ATTR_MAX,
  107. };
  108. static const struct blobmsg_policy jail_attr[__JAIL_ATTR_MAX] = {
  109. [JAIL_ATTR_NAME] = { "name", BLOBMSG_TYPE_STRING },
  110. [JAIL_ATTR_HOSTNAME] = { "hostname", BLOBMSG_TYPE_STRING },
  111. [JAIL_ATTR_PROCFS] = { "procfs", BLOBMSG_TYPE_BOOL },
  112. [JAIL_ATTR_SYSFS] = { "sysfs", BLOBMSG_TYPE_BOOL },
  113. [JAIL_ATTR_UBUS] = { "ubus", BLOBMSG_TYPE_BOOL },
  114. [JAIL_ATTR_LOG] = { "log", BLOBMSG_TYPE_BOOL },
  115. [JAIL_ATTR_RONLY] = { "ronly", BLOBMSG_TYPE_BOOL },
  116. [JAIL_ATTR_MOUNT] = { "mount", BLOBMSG_TYPE_TABLE },
  117. [JAIL_ATTR_NETNS] = { "netns", BLOBMSG_TYPE_BOOL },
  118. [JAIL_ATTR_USERNS] = { "userns", BLOBMSG_TYPE_BOOL },
  119. [JAIL_ATTR_CGROUPSNS] = { "cgroupsns", BLOBMSG_TYPE_BOOL },
  120. [JAIL_ATTR_CONSOLE] = { "console", BLOBMSG_TYPE_BOOL },
  121. [JAIL_ATTR_REQUIREJAIL] = { "requirejail", BLOBMSG_TYPE_BOOL },
  122. };
  123. struct instance_netdev {
  124. struct blobmsg_list_node node;
  125. int ifindex;
  126. };
  127. struct instance_file {
  128. struct blobmsg_list_node node;
  129. uint32_t md5[4];
  130. };
  131. struct rlimit_name {
  132. const char *name;
  133. int resource;
  134. };
  135. static const struct rlimit_name rlimit_names[] = {
  136. { "as", RLIMIT_AS },
  137. { "core", RLIMIT_CORE },
  138. { "cpu", RLIMIT_CPU },
  139. { "data", RLIMIT_DATA },
  140. { "fsize", RLIMIT_FSIZE },
  141. { "memlock", RLIMIT_MEMLOCK },
  142. { "nofile", RLIMIT_NOFILE },
  143. { "nproc", RLIMIT_NPROC },
  144. { "rss", RLIMIT_RSS },
  145. { "stack", RLIMIT_STACK },
  146. #ifdef linux
  147. { "nice", RLIMIT_NICE },
  148. { "rtprio", RLIMIT_RTPRIO },
  149. { "msgqueue", RLIMIT_MSGQUEUE },
  150. { "sigpending", RLIMIT_SIGPENDING },
  151. #endif
  152. { NULL, 0 }
  153. };
  154. static void closefd(int fd)
  155. {
  156. if (fd > STDERR_FILENO)
  157. close(fd);
  158. }
  159. /* convert a string into numeric syslog facility or return -1 if no match found */
  160. static int
  161. syslog_facility_str_to_int(const char *facility)
  162. {
  163. CODE *p = facilitynames;
  164. while (p->c_name && strcasecmp(p->c_name, facility))
  165. p++;
  166. return p->c_val;
  167. }
  168. static void
  169. instance_limits(const char *limit, const char *value)
  170. {
  171. int i;
  172. struct rlimit rlim;
  173. unsigned long cur, max;
  174. for (i = 0; rlimit_names[i].name != NULL; i++) {
  175. if (strcmp(rlimit_names[i].name, limit))
  176. continue;
  177. if (!strcmp(value, "unlimited")) {
  178. rlim.rlim_cur = RLIM_INFINITY;
  179. rlim.rlim_max = RLIM_INFINITY;
  180. } else {
  181. if (getrlimit(rlimit_names[i].resource, &rlim))
  182. return;
  183. cur = rlim.rlim_cur;
  184. max = rlim.rlim_max;
  185. if (sscanf(value, "%lu %lu", &cur, &max) < 1)
  186. return;
  187. rlim.rlim_cur = cur;
  188. rlim.rlim_max = max;
  189. }
  190. setrlimit(rlimit_names[i].resource, &rlim);
  191. return;
  192. }
  193. }
  194. static inline int
  195. jail_run(struct service_instance *in, char **argv)
  196. {
  197. struct blobmsg_list_node *var;
  198. struct jail *jail = &in->jail;
  199. int argc = 0;
  200. argv[argc++] = UJAIL_BIN_PATH;
  201. if (jail->name) {
  202. argv[argc++] = "-n";
  203. argv[argc++] = jail->name;
  204. }
  205. if (jail->hostname) {
  206. argv[argc++] = "-h";
  207. argv[argc++] = jail->hostname;
  208. }
  209. if (in->seccomp) {
  210. argv[argc++] = "-S";
  211. argv[argc++] = in->seccomp;
  212. }
  213. if (in->user) {
  214. argv[argc++] = "-U";
  215. argv[argc++] = in->user;
  216. }
  217. if (in->group) {
  218. argv[argc++] = "-G";
  219. argv[argc++] = in->group;
  220. }
  221. if (in->no_new_privs)
  222. argv[argc++] = "-c";
  223. if (jail->procfs)
  224. argv[argc++] = "-p";
  225. if (jail->sysfs)
  226. argv[argc++] = "-s";
  227. if (jail->ubus)
  228. argv[argc++] = "-u";
  229. if (jail->log)
  230. argv[argc++] = "-l";
  231. if (jail->ronly)
  232. argv[argc++] = "-o";
  233. if (jail->netns)
  234. argv[argc++] = "-N";
  235. if (jail->userns)
  236. argv[argc++] = "-f";
  237. if (jail->cgroupsns)
  238. argv[argc++] = "-F";
  239. if (jail->console)
  240. argv[argc++] = "-y";
  241. if (in->extroot) {
  242. argv[argc++] = "-R";
  243. argv[argc++] = in->extroot;
  244. }
  245. if (in->overlaydir) {
  246. argv[argc++] = "-O";
  247. argv[argc++] = in->overlaydir;
  248. }
  249. if (in->tmpoverlaysize) {
  250. argv[argc++] = "-T";
  251. argv[argc++] = in->tmpoverlaysize;
  252. }
  253. if (in->require_jail)
  254. argv[argc++] = "-E";
  255. blobmsg_list_for_each(&jail->mount, var) {
  256. const char *type = blobmsg_data(var->data);
  257. if (*type == '1')
  258. argv[argc++] = "-w";
  259. else
  260. argv[argc++] = "-r";
  261. argv[argc++] = (char *) blobmsg_name(var->data);
  262. }
  263. argv[argc++] = "--";
  264. return argc;
  265. }
  266. static int
  267. instance_removepid(struct service_instance *in) {
  268. if (!in->pidfile)
  269. return 0;
  270. if (unlink(in->pidfile)) {
  271. ERROR("Failed to remove pidfile: %s: %m\n", in->pidfile);
  272. return 1;
  273. }
  274. return 0;
  275. }
  276. static int
  277. instance_writepid(struct service_instance *in)
  278. {
  279. FILE *_pidfile;
  280. if (!in->pidfile) {
  281. return 0;
  282. }
  283. _pidfile = fopen(in->pidfile, "w");
  284. if (_pidfile == NULL) {
  285. ERROR("failed to open pidfile for writing: %s: %m", in->pidfile);
  286. return 1;
  287. }
  288. if (fprintf(_pidfile, "%d\n", in->proc.pid) < 0) {
  289. ERROR("failed to write pidfile: %s: %m", in->pidfile);
  290. fclose(_pidfile);
  291. return 2;
  292. }
  293. if (fclose(_pidfile)) {
  294. ERROR("failed to close pidfile: %s: %m", in->pidfile);
  295. return 3;
  296. }
  297. return 0;
  298. }
  299. static void
  300. instance_run(struct service_instance *in, int _stdout, int _stderr)
  301. {
  302. struct blobmsg_list_node *var;
  303. struct blob_attr *cur;
  304. char **argv;
  305. int argc = 1; /* NULL terminated */
  306. int rem, _stdin;
  307. bool seccomp = !in->trace && !in->has_jail && in->seccomp;
  308. bool setlbf = _stdout >= 0;
  309. if (in->nice)
  310. setpriority(PRIO_PROCESS, 0, in->nice);
  311. blobmsg_for_each_attr(cur, in->command, rem)
  312. argc++;
  313. blobmsg_list_for_each(&in->env, var)
  314. setenv(blobmsg_name(var->data), blobmsg_data(var->data), 1);
  315. if (seccomp)
  316. setenv("SECCOMP_FILE", in->seccomp, 1);
  317. if (setlbf)
  318. setenv("LD_PRELOAD", "/lib/libsetlbf.so", 1);
  319. blobmsg_list_for_each(&in->limits, var)
  320. instance_limits(blobmsg_name(var->data), blobmsg_data(var->data));
  321. if (in->trace || seccomp)
  322. argc += 1;
  323. argv = alloca(sizeof(char *) * (argc + in->jail.argc));
  324. argc = 0;
  325. #ifdef SECCOMP_SUPPORT
  326. if (in->trace)
  327. argv[argc++] = "/sbin/utrace";
  328. else if (seccomp)
  329. argv[argc++] = "/sbin/seccomp-trace";
  330. #else
  331. if (in->trace || seccomp)
  332. ULOG_WARN("Seccomp support for %s::%s not available\n", in->srv->name, in->name);
  333. #endif
  334. if (in->has_jail) {
  335. argc = jail_run(in, argv);
  336. if (argc != in->jail.argc)
  337. ULOG_WARN("expected %i jail params, used %i for %s::%s\n",
  338. in->jail.argc, argc, in->srv->name, in->name);
  339. }
  340. blobmsg_for_each_attr(cur, in->command, rem)
  341. argv[argc++] = blobmsg_data(cur);
  342. argv[argc] = NULL;
  343. _stdin = open("/dev/null", O_RDONLY);
  344. if (_stdout == -1)
  345. _stdout = open("/dev/null", O_WRONLY);
  346. if (_stderr == -1)
  347. _stderr = open("/dev/null", O_WRONLY);
  348. if (_stdin > -1) {
  349. dup2(_stdin, STDIN_FILENO);
  350. closefd(_stdin);
  351. }
  352. if (_stdout > -1) {
  353. dup2(_stdout, STDOUT_FILENO);
  354. closefd(_stdout);
  355. }
  356. if (_stderr > -1) {
  357. dup2(_stderr, STDERR_FILENO);
  358. closefd(_stderr);
  359. }
  360. if (!in->has_jail && in->user && in->pw_gid && initgroups(in->user, in->pw_gid)) {
  361. ERROR("failed to initgroups() for user %s: %m\n", in->user);
  362. exit(127);
  363. }
  364. if (!in->has_jail && in->gr_gid && setgid(in->gr_gid)) {
  365. ERROR("failed to set group id %d: %m\n", in->gr_gid);
  366. exit(127);
  367. }
  368. if (!in->has_jail && in->uid && setuid(in->uid)) {
  369. ERROR("failed to set user id %d: %m\n", in->uid);
  370. exit(127);
  371. }
  372. execvp(argv[0], argv);
  373. exit(127);
  374. }
  375. static void
  376. instance_free_stdio(struct service_instance *in)
  377. {
  378. if (in->_stdout.fd.fd > -1) {
  379. ustream_free(&in->_stdout.stream);
  380. close(in->_stdout.fd.fd);
  381. in->_stdout.fd.fd = -1;
  382. }
  383. if (in->_stderr.fd.fd > -1) {
  384. ustream_free(&in->_stderr.stream);
  385. close(in->_stderr.fd.fd);
  386. in->_stderr.fd.fd = -1;
  387. }
  388. if (in->console.fd.fd > -1) {
  389. ustream_free(&in->console.stream);
  390. close(in->console.fd.fd);
  391. in->console.fd.fd = -1;
  392. }
  393. if (in->console_client.fd.fd > -1) {
  394. ustream_free(&in->console_client.stream);
  395. close(in->console_client.fd.fd);
  396. in->console_client.fd.fd = -1;
  397. }
  398. }
  399. void
  400. instance_start(struct service_instance *in)
  401. {
  402. int pid;
  403. int opipe[2] = { -1, -1 };
  404. int epipe[2] = { -1, -1 };
  405. if (!avl_is_empty(&in->errors.avl)) {
  406. LOG("Not starting instance %s::%s, an error was indicated\n", in->srv->name, in->name);
  407. return;
  408. }
  409. if (!in->command) {
  410. LOG("Not starting instance %s::%s, command not set\n", in->srv->name, in->name);
  411. return;
  412. }
  413. if (in->proc.pending) {
  414. if (in->halt)
  415. in->restart = true;
  416. return;
  417. }
  418. instance_free_stdio(in);
  419. if (in->_stdout.fd.fd > -2) {
  420. if (pipe(opipe)) {
  421. ULOG_WARN("pipe() failed: %m\n");
  422. opipe[0] = opipe[1] = -1;
  423. }
  424. }
  425. if (in->_stderr.fd.fd > -2) {
  426. if (pipe(epipe)) {
  427. ULOG_WARN("pipe() failed: %m\n");
  428. epipe[0] = epipe[1] = -1;
  429. }
  430. }
  431. in->restart = false;
  432. in->halt = false;
  433. if (!in->valid)
  434. return;
  435. pid = fork();
  436. if (pid < 0)
  437. return;
  438. if (!pid) {
  439. uloop_done();
  440. closefd(opipe[0]);
  441. closefd(epipe[0]);
  442. instance_run(in, opipe[1], epipe[1]);
  443. return;
  444. }
  445. DEBUG(2, "Started instance %s::%s[%d]\n", in->srv->name, in->name, pid);
  446. in->proc.pid = pid;
  447. instance_writepid(in);
  448. clock_gettime(CLOCK_MONOTONIC, &in->start);
  449. uloop_process_add(&in->proc);
  450. if (opipe[0] > -1) {
  451. ustream_fd_init(&in->_stdout, opipe[0]);
  452. closefd(opipe[1]);
  453. fcntl(opipe[0], F_SETFD, FD_CLOEXEC);
  454. }
  455. if (epipe[0] > -1) {
  456. ustream_fd_init(&in->_stderr, epipe[0]);
  457. closefd(epipe[1]);
  458. fcntl(epipe[0], F_SETFD, FD_CLOEXEC);
  459. }
  460. service_event("instance.start", in->srv->name, in->name);
  461. }
  462. static void
  463. instance_stdio(struct ustream *s, int prio, struct service_instance *in)
  464. {
  465. char *newline, *str, *arg0, ident[32];
  466. int len;
  467. arg0 = basename(blobmsg_data(blobmsg_data(in->command)));
  468. snprintf(ident, sizeof(ident), "%s[%d]", arg0, in->proc.pid);
  469. ulog_open(ULOG_SYSLOG, in->syslog_facility, ident);
  470. do {
  471. str = ustream_get_read_buf(s, &len);
  472. if (!str)
  473. break;
  474. newline = memchr(str, '\n', len);
  475. if (!newline && (s->r.buffer_len != len))
  476. break;
  477. if (newline) {
  478. *newline = 0;
  479. len = newline + 1 - str;
  480. }
  481. ulog(prio, "%s\n", str);
  482. ustream_consume(s, len);
  483. } while (1);
  484. ulog_open(ULOG_SYSLOG, LOG_DAEMON, "procd");
  485. }
  486. static void
  487. instance_stdout(struct ustream *s, int bytes)
  488. {
  489. instance_stdio(s, LOG_INFO,
  490. container_of(s, struct service_instance, _stdout.stream));
  491. }
  492. static void
  493. instance_console(struct ustream *s, int bytes)
  494. {
  495. struct service_instance *in = container_of(s, struct service_instance, console.stream);
  496. char *buf;
  497. int len;
  498. do {
  499. buf = ustream_get_read_buf(s, &len);
  500. if (!buf)
  501. break;
  502. ulog(LOG_INFO, "out: %s\n", buf);
  503. /* test if console client is attached */
  504. if (in->console_client.fd.fd > -1)
  505. ustream_write(&in->console_client.stream, buf, len, false);
  506. ustream_consume(s, len);
  507. } while (1);
  508. }
  509. static void
  510. instance_console_client(struct ustream *s, int bytes)
  511. {
  512. struct service_instance *in = container_of(s, struct service_instance, console_client.stream);
  513. char *buf;
  514. int len;
  515. do {
  516. buf = ustream_get_read_buf(s, &len);
  517. if (!buf)
  518. break;
  519. ulog(LOG_INFO, "in: %s\n", buf);
  520. ustream_write(&in->console.stream, buf, len, false);
  521. ustream_consume(s, len);
  522. } while (1);
  523. }
  524. static void
  525. instance_stderr(struct ustream *s, int bytes)
  526. {
  527. instance_stdio(s, LOG_ERR,
  528. container_of(s, struct service_instance, _stderr.stream));
  529. }
  530. static void
  531. instance_timeout(struct uloop_timeout *t)
  532. {
  533. struct service_instance *in;
  534. in = container_of(t, struct service_instance, timeout);
  535. if (in->halt) {
  536. LOG("Instance %s::%s pid %d not stopped on SIGTERM, sending SIGKILL instead\n",
  537. in->srv->name, in->name, in->proc.pid);
  538. kill(in->proc.pid, SIGKILL);
  539. } else if (in->restart || in->respawn)
  540. instance_start(in);
  541. }
  542. static void
  543. instance_delete(struct service_instance *in)
  544. {
  545. struct service *s = in->srv;
  546. avl_delete(&s->instances.avl, &in->node.avl);
  547. instance_free(in);
  548. service_stopped(s);
  549. }
  550. static int
  551. instance_exit_code(int ret)
  552. {
  553. if (WIFEXITED(ret)) {
  554. return WEXITSTATUS(ret);
  555. }
  556. if (WIFSIGNALED(ret)) {
  557. return SIGNALLED_OFFSET + WTERMSIG(ret);
  558. }
  559. if (WIFSTOPPED(ret)) {
  560. return WSTOPSIG(ret);
  561. }
  562. return 1;
  563. }
  564. static void
  565. instance_exit(struct uloop_process *p, int ret)
  566. {
  567. struct service_instance *in;
  568. struct timespec tp;
  569. long runtime;
  570. in = container_of(p, struct service_instance, proc);
  571. clock_gettime(CLOCK_MONOTONIC, &tp);
  572. runtime = tp.tv_sec - in->start.tv_sec;
  573. DEBUG(2, "Instance %s::%s exit with error code %d after %ld seconds\n", in->srv->name, in->name, ret, runtime);
  574. in->exit_code = instance_exit_code(ret);
  575. uloop_timeout_cancel(&in->timeout);
  576. service_event("instance.stop", in->srv->name, in->name);
  577. if (in->halt) {
  578. instance_removepid(in);
  579. if (in->restart)
  580. instance_start(in);
  581. else
  582. instance_delete(in);
  583. } else if (in->restart) {
  584. instance_start(in);
  585. } else if (in->respawn) {
  586. if (runtime < in->respawn_threshold)
  587. in->respawn_count++;
  588. else
  589. in->respawn_count = 0;
  590. if (in->respawn_count > in->respawn_retry && in->respawn_retry > 0 ) {
  591. LOG("Instance %s::%s s in a crash loop %d crashes, %ld seconds since last crash\n",
  592. in->srv->name, in->name, in->respawn_count, runtime);
  593. in->restart = in->respawn = 0;
  594. in->halt = 1;
  595. service_event("instance.fail", in->srv->name, in->name);
  596. } else {
  597. service_event("instance.respawn", in->srv->name, in->name);
  598. uloop_timeout_set(&in->timeout, in->respawn_timeout * 1000);
  599. }
  600. }
  601. }
  602. void
  603. instance_stop(struct service_instance *in, bool halt)
  604. {
  605. if (!in->proc.pending) {
  606. if (halt)
  607. instance_delete(in);
  608. return;
  609. }
  610. in->halt = halt;
  611. in->restart = in->respawn = false;
  612. kill(in->proc.pid, SIGTERM);
  613. uloop_timeout_set(&in->timeout, in->term_timeout * 1000);
  614. }
  615. static void
  616. instance_restart(struct service_instance *in)
  617. {
  618. if (!in->proc.pending)
  619. return;
  620. if (in->reload_signal) {
  621. kill(in->proc.pid, in->reload_signal);
  622. return;
  623. }
  624. in->halt = true;
  625. in->restart = true;
  626. kill(in->proc.pid, SIGTERM);
  627. uloop_timeout_set(&in->timeout, in->term_timeout * 1000);
  628. }
  629. static bool string_changed(const char *a, const char *b)
  630. {
  631. return !((!a && !b) || (a && b && !strcmp(a, b)));
  632. }
  633. static bool
  634. instance_config_changed(struct service_instance *in, struct service_instance *in_new)
  635. {
  636. if (!in->valid)
  637. return true;
  638. if (!blob_attr_equal(in->command, in_new->command))
  639. return true;
  640. if (!blobmsg_list_equal(&in->env, &in_new->env))
  641. return true;
  642. if (!blobmsg_list_equal(&in->netdev, &in_new->netdev))
  643. return true;
  644. if (!blobmsg_list_equal(&in->file, &in_new->file))
  645. return true;
  646. if (in->nice != in_new->nice)
  647. return true;
  648. if (in->syslog_facility != in_new->syslog_facility)
  649. return true;
  650. if (string_changed(in->user, in_new->user))
  651. return true;
  652. if (string_changed(in->group, in_new->group))
  653. return true;
  654. if (in->uid != in_new->uid)
  655. return true;
  656. if (in->pw_gid != in_new->pw_gid)
  657. return true;
  658. if (string_changed(in->pidfile, in_new->pidfile))
  659. return true;
  660. if (in->respawn_retry != in_new->respawn_retry)
  661. return true;
  662. if (in->respawn_threshold != in_new->respawn_threshold)
  663. return true;
  664. if (in->respawn_timeout != in_new->respawn_timeout)
  665. return true;
  666. if ((!in->seccomp && in_new->seccomp) ||
  667. (in->seccomp && !in_new->seccomp) ||
  668. (in->seccomp && in_new->seccomp && strcmp(in->seccomp, in_new->seccomp)))
  669. return true;
  670. if (!blobmsg_list_equal(&in->limits, &in_new->limits))
  671. return true;
  672. if (!blobmsg_list_equal(&in->jail.mount, &in_new->jail.mount))
  673. return true;
  674. if (!blobmsg_list_equal(&in->errors, &in_new->errors))
  675. return true;
  676. return false;
  677. }
  678. static bool
  679. instance_netdev_cmp(struct blobmsg_list_node *l1, struct blobmsg_list_node *l2)
  680. {
  681. struct instance_netdev *n1 = container_of(l1, struct instance_netdev, node);
  682. struct instance_netdev *n2 = container_of(l2, struct instance_netdev, node);
  683. return n1->ifindex == n2->ifindex;
  684. }
  685. static void
  686. instance_netdev_update(struct blobmsg_list_node *l)
  687. {
  688. struct instance_netdev *n = container_of(l, struct instance_netdev, node);
  689. n->ifindex = if_nametoindex(n->node.avl.key);
  690. }
  691. static bool
  692. instance_file_cmp(struct blobmsg_list_node *l1, struct blobmsg_list_node *l2)
  693. {
  694. struct instance_file *f1 = container_of(l1, struct instance_file, node);
  695. struct instance_file *f2 = container_of(l2, struct instance_file, node);
  696. return !memcmp(f1->md5, f2->md5, sizeof(f1->md5));
  697. }
  698. static void
  699. instance_file_update(struct blobmsg_list_node *l)
  700. {
  701. struct instance_file *f = container_of(l, struct instance_file, node);
  702. md5_ctx_t md5;
  703. char buf[256];
  704. int len, fd;
  705. memset(f->md5, 0, sizeof(f->md5));
  706. fd = open(l->avl.key, O_RDONLY);
  707. if (fd < 0)
  708. return;
  709. md5_begin(&md5);
  710. do {
  711. len = read(fd, buf, sizeof(buf));
  712. if (len < 0) {
  713. if (errno == EINTR)
  714. continue;
  715. break;
  716. }
  717. if (!len)
  718. break;
  719. md5_hash(buf, len, &md5);
  720. } while(1);
  721. md5_end(f->md5, &md5);
  722. close(fd);
  723. }
  724. static void
  725. instance_fill_any(struct blobmsg_list *l, struct blob_attr *cur)
  726. {
  727. if (!cur)
  728. return;
  729. blobmsg_list_fill(l, blobmsg_data(cur), blobmsg_data_len(cur), false);
  730. }
  731. static bool
  732. instance_fill_array(struct blobmsg_list *l, struct blob_attr *cur, blobmsg_update_cb cb, bool array)
  733. {
  734. struct blobmsg_list_node *node;
  735. if (!cur)
  736. return true;
  737. if (!blobmsg_check_attr_list(cur, BLOBMSG_TYPE_STRING))
  738. return false;
  739. blobmsg_list_fill(l, blobmsg_data(cur), blobmsg_data_len(cur), array);
  740. if (cb) {
  741. blobmsg_list_for_each(l, node)
  742. cb(node);
  743. }
  744. return true;
  745. }
  746. static int
  747. instance_jail_parse(struct service_instance *in, struct blob_attr *attr)
  748. {
  749. struct blob_attr *tb[__JAIL_ATTR_MAX];
  750. struct jail *jail = &in->jail;
  751. blobmsg_parse(jail_attr, __JAIL_ATTR_MAX, tb,
  752. blobmsg_data(attr), blobmsg_data_len(attr));
  753. jail->argc = 2;
  754. if (tb[JAIL_ATTR_REQUIREJAIL]) {
  755. in->require_jail = true;
  756. jail->argc++;
  757. }
  758. if (tb[JAIL_ATTR_NAME]) {
  759. jail->name = strdup(blobmsg_get_string(tb[JAIL_ATTR_NAME]));
  760. jail->argc += 2;
  761. }
  762. if (tb[JAIL_ATTR_HOSTNAME]) {
  763. jail->hostname = strdup(blobmsg_get_string(tb[JAIL_ATTR_HOSTNAME]));
  764. jail->argc += 2;
  765. }
  766. if (tb[JAIL_ATTR_PROCFS]) {
  767. jail->procfs = blobmsg_get_bool(tb[JAIL_ATTR_PROCFS]);
  768. jail->argc++;
  769. }
  770. if (tb[JAIL_ATTR_SYSFS]) {
  771. jail->sysfs = blobmsg_get_bool(tb[JAIL_ATTR_SYSFS]);
  772. jail->argc++;
  773. }
  774. if (tb[JAIL_ATTR_UBUS]) {
  775. jail->ubus = blobmsg_get_bool(tb[JAIL_ATTR_UBUS]);
  776. jail->argc++;
  777. }
  778. if (tb[JAIL_ATTR_LOG]) {
  779. jail->log = blobmsg_get_bool(tb[JAIL_ATTR_LOG]);
  780. jail->argc++;
  781. }
  782. if (tb[JAIL_ATTR_RONLY]) {
  783. jail->ronly = blobmsg_get_bool(tb[JAIL_ATTR_RONLY]);
  784. jail->argc++;
  785. }
  786. if (tb[JAIL_ATTR_NETNS]) {
  787. jail->netns = blobmsg_get_bool(tb[JAIL_ATTR_NETNS]);
  788. jail->argc++;
  789. }
  790. if (tb[JAIL_ATTR_USERNS]) {
  791. jail->userns = blobmsg_get_bool(tb[JAIL_ATTR_USERNS]);
  792. jail->argc++;
  793. }
  794. if (tb[JAIL_ATTR_CGROUPSNS]) {
  795. jail->cgroupsns = blobmsg_get_bool(tb[JAIL_ATTR_CGROUPSNS]);
  796. jail->argc++;
  797. }
  798. if (tb[JAIL_ATTR_CONSOLE]) {
  799. jail->console = blobmsg_get_bool(tb[JAIL_ATTR_CONSOLE]);
  800. jail->argc++;
  801. }
  802. if (tb[JAIL_ATTR_MOUNT]) {
  803. struct blob_attr *cur;
  804. int rem;
  805. blobmsg_for_each_attr(cur, tb[JAIL_ATTR_MOUNT], rem)
  806. jail->argc += 2;
  807. instance_fill_array(&jail->mount, tb[JAIL_ATTR_MOUNT], NULL, false);
  808. }
  809. if (in->seccomp)
  810. jail->argc += 2;
  811. if (in->user)
  812. jail->argc += 2;
  813. if (in->group)
  814. jail->argc += 2;
  815. if (in->extroot)
  816. jail->argc += 2;
  817. if (in->overlaydir)
  818. jail->argc += 2;
  819. if (in->tmpoverlaysize)
  820. jail->argc += 2;
  821. if (in->no_new_privs)
  822. jail->argc++;
  823. return true;
  824. }
  825. static bool
  826. instance_config_parse_command(struct service_instance *in, struct blob_attr **tb)
  827. {
  828. struct blob_attr *cur, *cur2;
  829. bool ret = false;
  830. int rem;
  831. cur = tb[INSTANCE_ATTR_COMMAND];
  832. if (!cur) {
  833. in->command = NULL;
  834. return true;
  835. }
  836. if (!blobmsg_check_attr_list(cur, BLOBMSG_TYPE_STRING))
  837. return false;
  838. blobmsg_for_each_attr(cur2, cur, rem) {
  839. ret = true;
  840. break;
  841. }
  842. in->command = cur;
  843. return ret;
  844. }
  845. static bool
  846. instance_config_parse(struct service_instance *in)
  847. {
  848. struct blob_attr *tb[__INSTANCE_ATTR_MAX];
  849. struct blob_attr *cur, *cur2;
  850. struct stat s;
  851. int rem, r;
  852. blobmsg_parse(instance_attr, __INSTANCE_ATTR_MAX, tb,
  853. blobmsg_data(in->config), blobmsg_data_len(in->config));
  854. if (!instance_config_parse_command(in, tb))
  855. return false;
  856. if (tb[INSTANCE_ATTR_TERMTIMEOUT])
  857. in->term_timeout = blobmsg_get_u32(tb[INSTANCE_ATTR_TERMTIMEOUT]);
  858. if (tb[INSTANCE_ATTR_RESPAWN]) {
  859. int i = 0;
  860. uint32_t vals[3] = { 3600, 5, 5};
  861. blobmsg_for_each_attr(cur2, tb[INSTANCE_ATTR_RESPAWN], rem) {
  862. if ((i >= 3) && (blobmsg_type(cur2) == BLOBMSG_TYPE_STRING))
  863. continue;
  864. vals[i] = atoi(blobmsg_get_string(cur2));
  865. i++;
  866. }
  867. in->respawn = true;
  868. in->respawn_count = 0;
  869. in->respawn_threshold = vals[0];
  870. in->respawn_timeout = vals[1];
  871. in->respawn_retry = vals[2];
  872. }
  873. if (tb[INSTANCE_ATTR_TRIGGER]) {
  874. in->trigger = tb[INSTANCE_ATTR_TRIGGER];
  875. trigger_add(in->trigger, in);
  876. }
  877. if (tb[INSTANCE_ATTR_WATCH]) {
  878. blobmsg_for_each_attr(cur2, tb[INSTANCE_ATTR_WATCH], rem) {
  879. if (blobmsg_type(cur2) != BLOBMSG_TYPE_STRING)
  880. continue;
  881. DEBUG(3, "watch for %s\n", blobmsg_get_string(cur2));
  882. watch_add(blobmsg_get_string(cur2), in);
  883. }
  884. }
  885. if ((cur = tb[INSTANCE_ATTR_NICE])) {
  886. in->nice = (int8_t) blobmsg_get_u32(cur);
  887. if (in->nice < -20 || in->nice > 20)
  888. return false;
  889. }
  890. if (tb[INSTANCE_ATTR_USER]) {
  891. const char *user = blobmsg_get_string(tb[INSTANCE_ATTR_USER]);
  892. struct passwd *p = getpwnam(user);
  893. if (p) {
  894. in->user = strdup(user);
  895. in->uid = p->pw_uid;
  896. in->gr_gid = in->pw_gid = p->pw_gid;
  897. }
  898. }
  899. if (tb[INSTANCE_ATTR_GROUP]) {
  900. const char *group = blobmsg_get_string(tb[INSTANCE_ATTR_GROUP]);
  901. struct group *p = getgrnam(group);
  902. if (p) {
  903. in->group = strdup(group);
  904. in->gr_gid = p->gr_gid;
  905. }
  906. }
  907. if (tb[INSTANCE_ATTR_TRACE])
  908. in->trace = blobmsg_get_bool(tb[INSTANCE_ATTR_TRACE]);
  909. if (tb[INSTANCE_ATTR_NO_NEW_PRIVS])
  910. in->no_new_privs = blobmsg_get_bool(tb[INSTANCE_ATTR_NO_NEW_PRIVS]);
  911. if (!in->trace && tb[INSTANCE_ATTR_SECCOMP])
  912. in->seccomp = strdup(blobmsg_get_string(tb[INSTANCE_ATTR_SECCOMP]));
  913. if (tb[INSTANCE_ATTR_EXTROOT])
  914. in->extroot = strdup(blobmsg_get_string(tb[INSTANCE_ATTR_EXTROOT]));
  915. if (tb[INSTANCE_ATTR_OVERLAYDIR])
  916. in->overlaydir = strdup(blobmsg_get_string(tb[INSTANCE_ATTR_OVERLAYDIR]));
  917. if (tb[INSTANCE_ATTR_TMPOVERLAYSIZE])
  918. in->tmpoverlaysize = strdup(blobmsg_get_string(tb[INSTANCE_ATTR_TMPOVERLAYSIZE]));
  919. if (tb[INSTANCE_ATTR_PIDFILE]) {
  920. char *pidfile = blobmsg_get_string(tb[INSTANCE_ATTR_PIDFILE]);
  921. if (pidfile)
  922. in->pidfile = strdup(pidfile);
  923. }
  924. if (tb[INSTANCE_ATTR_RELOADSIG])
  925. in->reload_signal = blobmsg_get_u32(tb[INSTANCE_ATTR_RELOADSIG]);
  926. if (!in->trace && tb[INSTANCE_ATTR_JAIL])
  927. in->has_jail = instance_jail_parse(in, tb[INSTANCE_ATTR_JAIL]);
  928. if (in->has_jail) {
  929. r = stat(UJAIL_BIN_PATH, &s);
  930. if (r < 0) {
  931. if (in->require_jail) {
  932. ERROR("Cannot jail service %s::%s. %s: %m (%d)\n",
  933. in->srv->name, in->name, UJAIL_BIN_PATH, r);
  934. return false;
  935. }
  936. DEBUG(2, "unable to find %s: %m (%d)\n", UJAIL_BIN_PATH, r);
  937. in->has_jail = false;
  938. }
  939. }
  940. if (tb[INSTANCE_ATTR_STDOUT] && blobmsg_get_bool(tb[INSTANCE_ATTR_STDOUT]))
  941. in->_stdout.fd.fd = -1;
  942. if (tb[INSTANCE_ATTR_STDERR] && blobmsg_get_bool(tb[INSTANCE_ATTR_STDERR]))
  943. in->_stderr.fd.fd = -1;
  944. instance_fill_any(&in->data, tb[INSTANCE_ATTR_DATA]);
  945. if (!instance_fill_array(&in->env, tb[INSTANCE_ATTR_ENV], NULL, false))
  946. return false;
  947. if (!instance_fill_array(&in->netdev, tb[INSTANCE_ATTR_NETDEV], instance_netdev_update, true))
  948. return false;
  949. if (!instance_fill_array(&in->file, tb[INSTANCE_ATTR_FILE], instance_file_update, true))
  950. return false;
  951. if (!instance_fill_array(&in->limits, tb[INSTANCE_ATTR_LIMITS], NULL, false))
  952. return false;
  953. if (!instance_fill_array(&in->errors, tb[INSTANCE_ATTR_ERROR], NULL, true))
  954. return false;
  955. if (tb[INSTANCE_ATTR_FACILITY]) {
  956. int facility = syslog_facility_str_to_int(blobmsg_get_string(tb[INSTANCE_ATTR_FACILITY]));
  957. if (facility != -1) {
  958. in->syslog_facility = facility;
  959. DEBUG(3, "setting facility '%s'\n", blobmsg_get_string(tb[INSTANCE_ATTR_FACILITY]));
  960. } else
  961. DEBUG(3, "unknown syslog facility '%s' given, using default (LOG_DAEMON)\n", blobmsg_get_string(tb[INSTANCE_ATTR_FACILITY]));
  962. }
  963. return true;
  964. }
  965. static void
  966. instance_config_cleanup(struct service_instance *in)
  967. {
  968. blobmsg_list_free(&in->env);
  969. blobmsg_list_free(&in->data);
  970. blobmsg_list_free(&in->netdev);
  971. blobmsg_list_free(&in->file);
  972. blobmsg_list_free(&in->limits);
  973. blobmsg_list_free(&in->errors);
  974. blobmsg_list_free(&in->jail.mount);
  975. }
  976. static void
  977. instance_config_move_strdup(char **dst, char *src)
  978. {
  979. if (*dst) {
  980. free(*dst);
  981. *dst = NULL;
  982. }
  983. if (!src)
  984. return;
  985. *dst = strdup(src);
  986. }
  987. static void
  988. instance_config_move(struct service_instance *in, struct service_instance *in_src)
  989. {
  990. instance_config_cleanup(in);
  991. blobmsg_list_move(&in->env, &in_src->env);
  992. blobmsg_list_move(&in->data, &in_src->data);
  993. blobmsg_list_move(&in->netdev, &in_src->netdev);
  994. blobmsg_list_move(&in->file, &in_src->file);
  995. blobmsg_list_move(&in->limits, &in_src->limits);
  996. blobmsg_list_move(&in->errors, &in_src->errors);
  997. blobmsg_list_move(&in->jail.mount, &in_src->jail.mount);
  998. in->trigger = in_src->trigger;
  999. in->command = in_src->command;
  1000. in->respawn = in_src->respawn;
  1001. in->respawn_retry = in_src->respawn_retry;
  1002. in->respawn_threshold = in_src->respawn_threshold;
  1003. in->respawn_timeout = in_src->respawn_timeout;
  1004. in->name = in_src->name;
  1005. in->trace = in_src->trace;
  1006. in->node.avl.key = in_src->node.avl.key;
  1007. in->syslog_facility = in_src->syslog_facility;
  1008. instance_config_move_strdup(&in->pidfile, in_src->pidfile);
  1009. instance_config_move_strdup(&in->seccomp, in_src->seccomp);
  1010. instance_config_move_strdup(&in->jail.name, in_src->jail.name);
  1011. instance_config_move_strdup(&in->jail.hostname, in_src->jail.hostname);
  1012. free(in->config);
  1013. in->config = in_src->config;
  1014. in_src->config = NULL;
  1015. }
  1016. void
  1017. instance_update(struct service_instance *in, struct service_instance *in_new)
  1018. {
  1019. bool changed = instance_config_changed(in, in_new);
  1020. bool running = in->proc.pending;
  1021. bool stopping = in->halt;
  1022. if (!running || stopping) {
  1023. instance_config_move(in, in_new);
  1024. instance_start(in);
  1025. } else {
  1026. if (changed)
  1027. instance_restart(in);
  1028. instance_config_move(in, in_new);
  1029. /* restart happens in the child callback handler */
  1030. }
  1031. }
  1032. void
  1033. instance_free(struct service_instance *in)
  1034. {
  1035. instance_free_stdio(in);
  1036. uloop_process_delete(&in->proc);
  1037. uloop_timeout_cancel(&in->timeout);
  1038. trigger_del(in);
  1039. watch_del(in);
  1040. instance_config_cleanup(in);
  1041. free(in->config);
  1042. free(in->user);
  1043. free(in->group);
  1044. free(in->extroot);
  1045. free(in->overlaydir);
  1046. free(in->tmpoverlaysize);
  1047. free(in->jail.name);
  1048. free(in->jail.hostname);
  1049. free(in->seccomp);
  1050. free(in->pidfile);
  1051. free(in);
  1052. }
  1053. void
  1054. instance_init(struct service_instance *in, struct service *s, struct blob_attr *config)
  1055. {
  1056. config = blob_memdup(config);
  1057. in->srv = s;
  1058. in->name = blobmsg_name(config);
  1059. in->config = config;
  1060. in->timeout.cb = instance_timeout;
  1061. in->proc.cb = instance_exit;
  1062. in->term_timeout = 5;
  1063. in->syslog_facility = LOG_DAEMON;
  1064. in->exit_code = 0;
  1065. in->require_jail = false;
  1066. in->_stdout.fd.fd = -2;
  1067. in->_stdout.stream.string_data = true;
  1068. in->_stdout.stream.notify_read = instance_stdout;
  1069. in->_stderr.fd.fd = -2;
  1070. in->_stderr.stream.string_data = true;
  1071. in->_stderr.stream.notify_read = instance_stderr;
  1072. in->console.fd.fd = -2;
  1073. in->console.stream.string_data = true;
  1074. in->console.stream.notify_read = instance_console;
  1075. in->console_client.fd.fd = -2;
  1076. in->console_client.stream.string_data = true;
  1077. in->console_client.stream.notify_read = instance_console_client;
  1078. blobmsg_list_init(&in->netdev, struct instance_netdev, node, instance_netdev_cmp);
  1079. blobmsg_list_init(&in->file, struct instance_file, node, instance_file_cmp);
  1080. blobmsg_list_simple_init(&in->env);
  1081. blobmsg_list_simple_init(&in->data);
  1082. blobmsg_list_simple_init(&in->limits);
  1083. blobmsg_list_simple_init(&in->errors);
  1084. blobmsg_list_simple_init(&in->jail.mount);
  1085. in->valid = instance_config_parse(in);
  1086. }
  1087. void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose)
  1088. {
  1089. void *i;
  1090. if (!in->valid)
  1091. return;
  1092. i = blobmsg_open_table(b, in->name);
  1093. blobmsg_add_u8(b, "running", in->proc.pending);
  1094. if (in->proc.pending)
  1095. blobmsg_add_u32(b, "pid", in->proc.pid);
  1096. if (in->command)
  1097. blobmsg_add_blob(b, in->command);
  1098. blobmsg_add_u32(b, "term_timeout", in->term_timeout);
  1099. if (!in->proc.pending)
  1100. blobmsg_add_u32(b, "exit_code", in->exit_code);
  1101. if (!avl_is_empty(&in->errors.avl)) {
  1102. struct blobmsg_list_node *var;
  1103. void *e = blobmsg_open_array(b, "errors");
  1104. blobmsg_list_for_each(&in->errors, var)
  1105. blobmsg_add_string(b, NULL, blobmsg_data(var->data));
  1106. blobmsg_close_table(b, e);
  1107. }
  1108. if (!avl_is_empty(&in->env.avl)) {
  1109. struct blobmsg_list_node *var;
  1110. void *e = blobmsg_open_table(b, "env");
  1111. blobmsg_list_for_each(&in->env, var)
  1112. blobmsg_add_string(b, blobmsg_name(var->data), blobmsg_data(var->data));
  1113. blobmsg_close_table(b, e);
  1114. }
  1115. if (!avl_is_empty(&in->data.avl)) {
  1116. struct blobmsg_list_node *var;
  1117. void *e = blobmsg_open_table(b, "data");
  1118. blobmsg_list_for_each(&in->data, var)
  1119. blobmsg_add_blob(b, var->data);
  1120. blobmsg_close_table(b, e);
  1121. }
  1122. if (!avl_is_empty(&in->limits.avl)) {
  1123. struct blobmsg_list_node *var;
  1124. void *e = blobmsg_open_table(b, "limits");
  1125. blobmsg_list_for_each(&in->limits, var)
  1126. blobmsg_add_string(b, blobmsg_name(var->data), blobmsg_data(var->data));
  1127. blobmsg_close_table(b, e);
  1128. }
  1129. if (in->reload_signal)
  1130. blobmsg_add_u32(b, "reload_signal", in->reload_signal);
  1131. if (in->respawn) {
  1132. void *r = blobmsg_open_table(b, "respawn");
  1133. blobmsg_add_u32(b, "threshold", in->respawn_threshold);
  1134. blobmsg_add_u32(b, "timeout", in->respawn_timeout);
  1135. blobmsg_add_u32(b, "retry", in->respawn_retry);
  1136. blobmsg_close_table(b, r);
  1137. }
  1138. if (in->trace)
  1139. blobmsg_add_u8(b, "trace", true);
  1140. if (in->no_new_privs)
  1141. blobmsg_add_u8(b, "no_new_privs", true);
  1142. if (in->seccomp)
  1143. blobmsg_add_string(b, "seccomp", in->seccomp);
  1144. if (in->pidfile)
  1145. blobmsg_add_string(b, "pidfile", in->pidfile);
  1146. if (in->user)
  1147. blobmsg_add_string(b, "user", in->user);
  1148. if (in->group)
  1149. blobmsg_add_string(b, "group", in->group);
  1150. if (in->has_jail) {
  1151. void *r = blobmsg_open_table(b, "jail");
  1152. if (in->jail.name)
  1153. blobmsg_add_string(b, "name", in->jail.name);
  1154. if (in->jail.hostname)
  1155. blobmsg_add_string(b, "hostname", in->jail.hostname);
  1156. blobmsg_add_u8(b, "procfs", in->jail.procfs);
  1157. blobmsg_add_u8(b, "sysfs", in->jail.sysfs);
  1158. blobmsg_add_u8(b, "ubus", in->jail.ubus);
  1159. blobmsg_add_u8(b, "log", in->jail.log);
  1160. blobmsg_add_u8(b, "ronly", in->jail.ronly);
  1161. blobmsg_add_u8(b, "netns", in->jail.netns);
  1162. blobmsg_add_u8(b, "userns", in->jail.userns);
  1163. blobmsg_add_u8(b, "cgroupsns", in->jail.cgroupsns);
  1164. blobmsg_add_u8(b, "console", (in->console.fd.fd > -1));
  1165. blobmsg_close_table(b, r);
  1166. if (!avl_is_empty(&in->jail.mount.avl)) {
  1167. struct blobmsg_list_node *var;
  1168. void *e = blobmsg_open_table(b, "mount");
  1169. blobmsg_list_for_each(&in->jail.mount, var)
  1170. blobmsg_add_string(b, blobmsg_name(var->data), blobmsg_data(var->data));
  1171. blobmsg_close_table(b, e);
  1172. }
  1173. }
  1174. if (in->extroot)
  1175. blobmsg_add_string(b, "extroot", in->extroot);
  1176. if (in->overlaydir)
  1177. blobmsg_add_string(b, "overlaydir", in->overlaydir);
  1178. if (in->tmpoverlaysize)
  1179. blobmsg_add_string(b, "tmpoverlaysize", in->tmpoverlaysize);
  1180. if (verbose && in->trigger)
  1181. blobmsg_add_blob(b, in->trigger);
  1182. blobmsg_close_table(b, i);
  1183. }