0106-procd-add-universal-staged-sysupgrade-patches.patch 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116
  1. From: Matthias Schiffer <mschiffer@universe-factory.net>
  2. Date: Thu, 1 Jun 2017 22:42:04 +0200
  3. Subject: procd: add universal staged sysupgrade patches
  4. diff --git a/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch b/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch
  5. deleted file mode 100644
  6. index bc2434200364b46f1db4c2eec22c4e8b973844d5..0000000000000000000000000000000000000000
  7. --- a/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch
  8. +++ /dev/null
  9. @@ -1,97 +0,0 @@
  10. -From 03a2bc70e4260ec9f669391c47b9a7a9ecd0b75d Mon Sep 17 00:00:00 2001
  11. -Message-Id: <03a2bc70e4260ec9f669391c47b9a7a9ecd0b75d.1407329621.git.mschiffer@universe-factory.net>
  12. -From: Matthias Schiffer <mschiffer@universe-factory.net>
  13. -Date: Wed, 6 Aug 2014 14:51:49 +0200
  14. -Subject: [PATCH] Add support for alternative rc.d directories
  15. -
  16. ----
  17. - initd/preinit.c | 38 ++++++++++++++++++++++++++++++++++++++
  18. - rcS.c | 2 +-
  19. - 2 files changed, 39 insertions(+), 1 deletion(-)
  20. -
  21. -diff --git a/initd/preinit.c b/initd/preinit.c
  22. -index fb94527..8b832a7 100644
  23. ---- a/initd/preinit.c
  24. -+++ b/initd/preinit.c
  25. -@@ -12,6 +12,8 @@
  26. - * GNU General Public License for more details.
  27. - */
  28. -
  29. -+#define _GNU_SOURCE
  30. -+
  31. - #include <sys/stat.h>
  32. - #include <sys/types.h>
  33. - #include <sys/mount.h>
  34. -@@ -46,6 +48,35 @@ check_dbglvl(void)
  35. - debug = lvl;
  36. - }
  37. -
  38. -+static char*
  39. -+get_rc_d(void)
  40. -+{
  41. -+ size_t n = 0;
  42. -+ ssize_t len;
  43. -+ char *ret = NULL;
  44. -+
  45. -+ FILE *fp = fopen("/tmp/rc_d_path", "r");
  46. -+
  47. -+ if (!fp)
  48. -+ return NULL;
  49. -+
  50. -+ len = getline(&ret, &n, fp);
  51. -+
  52. -+ fclose(fp);
  53. -+
  54. -+ unlink("/tmp/rc_d_path");
  55. -+
  56. -+ if (len <= 0) {
  57. -+ free(ret);
  58. -+ return NULL;
  59. -+ }
  60. -+
  61. -+ if (ret[len-1] == '\n')
  62. -+ ret[len-1] = 0;
  63. -+
  64. -+ return ret;
  65. -+}
  66. -+
  67. - static void
  68. - spawn_procd(struct uloop_process *proc, int ret)
  69. - {
  70. -@@ -53,6 +84,7 @@ spawn_procd(struct uloop_process *proc, int ret)
  71. - char *argv[] = { "/sbin/procd", NULL};
  72. - struct stat s;
  73. - char dbg[2];
  74. -+ char *rc_d_path;
  75. -
  76. - if (plugd_proc.pid > 0)
  77. - kill(plugd_proc.pid, SIGKILL);
  78. -@@ -72,6 +104,12 @@ spawn_procd(struct uloop_process *proc, int ret)
  79. - setenv("DBGLVL", dbg, 1);
  80. - }
  81. -
  82. -+ rc_d_path = get_rc_d();
  83. -+ if (rc_d_path) {
  84. -+ setenv("RC_D_PATH", rc_d_path, 1);
  85. -+ free(rc_d_path);
  86. -+ }
  87. -+
  88. - execvp(argv[0], argv);
  89. - }
  90. -
  91. -diff --git a/rcS.c b/rcS.c
  92. -index 0e1b0ba..1b00831 100644
  93. ---- a/rcS.c
  94. -+++ b/rcS.c
  95. -@@ -150,7 +150,7 @@ int rcS(char *pattern, char *param, void (*q_empty)(struct runqueue *))
  96. - q.empty_cb = q_empty;
  97. - q.max_running_tasks = 1;
  98. -
  99. -- return _rc(&q, "/etc/rc.d", pattern, "*", param);
  100. -+ return _rc(&q, getenv("RC_D_PATH") ?: "/etc/rc.d", pattern, "*", param);
  101. - }
  102. -
  103. - int rc(const char *file, char *param)
  104. ---
  105. -2.0.4
  106. -
  107. diff --git a/package/system/procd/patches/1001-Add-support-for-alternative-rc.d-directories.patch b/package/system/procd/patches/1001-Add-support-for-alternative-rc.d-directories.patch
  108. new file mode 100644
  109. index 0000000000000000000000000000000000000000..2d3c24181cef32ae9e15401ff2e4772805ea9551
  110. --- /dev/null
  111. +++ b/package/system/procd/patches/1001-Add-support-for-alternative-rc.d-directories.patch
  112. @@ -0,0 +1,97 @@
  113. +From 36673c2a0e409d9c8ea9e1c15363e73bb21ae65b Mon Sep 17 00:00:00 2001
  114. +Message-Id: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net>
  115. +From: Matthias Schiffer <mschiffer@universe-factory.net>
  116. +Date: Wed, 6 Aug 2014 14:51:49 +0200
  117. +Subject: [PATCH 1001/1007] Add support for alternative rc.d directories
  118. +
  119. +---
  120. + initd/preinit.c | 38 ++++++++++++++++++++++++++++++++++++++
  121. + rcS.c | 2 +-
  122. + 2 files changed, 39 insertions(+), 1 deletion(-)
  123. +
  124. +diff --git a/initd/preinit.c b/initd/preinit.c
  125. +index f38d8ef..acc64e7 100644
  126. +--- a/initd/preinit.c
  127. ++++ b/initd/preinit.c
  128. +@@ -12,6 +12,8 @@
  129. + * GNU General Public License for more details.
  130. + */
  131. +
  132. ++#define _GNU_SOURCE
  133. ++
  134. + #include <sys/stat.h>
  135. + #include <sys/types.h>
  136. + #include <sys/mount.h>
  137. +@@ -47,6 +49,35 @@ check_dbglvl(void)
  138. + debug = lvl;
  139. + }
  140. +
  141. ++static char*
  142. ++get_rc_d(void)
  143. ++{
  144. ++ size_t n = 0;
  145. ++ ssize_t len;
  146. ++ char *ret = NULL;
  147. ++
  148. ++ FILE *fp = fopen("/tmp/rc_d_path", "r");
  149. ++
  150. ++ if (!fp)
  151. ++ return NULL;
  152. ++
  153. ++ len = getline(&ret, &n, fp);
  154. ++
  155. ++ fclose(fp);
  156. ++
  157. ++ unlink("/tmp/rc_d_path");
  158. ++
  159. ++ if (len <= 0) {
  160. ++ free(ret);
  161. ++ return NULL;
  162. ++ }
  163. ++
  164. ++ if (ret[len-1] == '\n')
  165. ++ ret[len-1] = 0;
  166. ++
  167. ++ return ret;
  168. ++}
  169. ++
  170. + static void
  171. + spawn_procd(struct uloop_process *proc, int ret)
  172. + {
  173. +@@ -54,6 +85,7 @@ spawn_procd(struct uloop_process *proc, int ret)
  174. + char *argv[] = { "/sbin/procd", NULL};
  175. + struct stat s;
  176. + char dbg[2];
  177. ++ char *rc_d_path;
  178. +
  179. + if (plugd_proc.pid > 0)
  180. + kill(plugd_proc.pid, SIGKILL);
  181. +@@ -73,6 +105,12 @@ spawn_procd(struct uloop_process *proc, int ret)
  182. + setenv("DBGLVL", dbg, 1);
  183. + }
  184. +
  185. ++ rc_d_path = get_rc_d();
  186. ++ if (rc_d_path) {
  187. ++ setenv("RC_D_PATH", rc_d_path, 1);
  188. ++ free(rc_d_path);
  189. ++ }
  190. ++
  191. + execvp(argv[0], argv);
  192. + }
  193. +
  194. +diff --git a/rcS.c b/rcS.c
  195. +index b3e3c22..e231d71 100644
  196. +--- a/rcS.c
  197. ++++ b/rcS.c
  198. +@@ -162,7 +162,7 @@ int rcS(char *pattern, char *param, void (*q_empty)(struct runqueue *))
  199. + q.empty_cb = q_empty;
  200. + q.max_running_tasks = 1;
  201. +
  202. +- return _rc(&q, "/etc/rc.d", pattern, "*", param);
  203. ++ return _rc(&q, getenv("RC_D_PATH") ?: "/etc/rc.d", pattern, "*", param);
  204. + }
  205. +
  206. + int rc(const char *file, char *param)
  207. +--
  208. +2.13.0
  209. +
  210. diff --git a/package/system/procd/patches/1002-system-always-support-staged-sysupgrade.patch b/package/system/procd/patches/1002-system-always-support-staged-sysupgrade.patch
  211. new file mode 100644
  212. index 0000000000000000000000000000000000000000..f19a21aed1a5931d609684ff70784fe40b0d1406
  213. --- /dev/null
  214. +++ b/package/system/procd/patches/1002-system-always-support-staged-sysupgrade.patch
  215. @@ -0,0 +1,114 @@
  216. +From 7d2c86de79b6bd976f0e37f7c3cbc61a3b3c3bb7 Mon Sep 17 00:00:00 2001
  217. +Message-Id: <7d2c86de79b6bd976f0e37f7c3cbc61a3b3c3bb7.1496349467.git.mschiffer@universe-factory.net>
  218. +In-Reply-To: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net>
  219. +References: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net>
  220. +From: Matthias Schiffer <mschiffer@universe-factory.net>
  221. +Date: Fri, 21 Apr 2017 20:06:59 +0200
  222. +Subject: [PATCH 1002/1007] system: always support staged sysupgrade
  223. +
  224. +In preparation for switching all targets to the staged sysupgrade
  225. +mechanism, upgraded is always built, and the "nandupgrade" ubus method is
  226. +renamed to "sysupgrade".
  227. +
  228. +To make the migration easier, support for the old name "nandupgrade" and
  229. +the "upgrade" method that will become unused with the staged sysupgrade is
  230. +retained for now.
  231. +
  232. +Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
  233. +---
  234. + CMakeLists.txt | 4 +---
  235. + system.c | 31 +++++++++++++------------------
  236. + 2 files changed, 14 insertions(+), 21 deletions(-)
  237. +
  238. +diff --git a/CMakeLists.txt b/CMakeLists.txt
  239. +index cc1e4a5..9e378ae 100644
  240. +--- a/CMakeLists.txt
  241. ++++ b/CMakeLists.txt
  242. +@@ -32,9 +32,7 @@ IF(ZRAM_TMPFS)
  243. + SET(SOURCES_ZRAM initd/zram.c)
  244. + ENDIF()
  245. +
  246. +-IF(BUILD_UPGRADED)
  247. +- add_subdirectory(upgraded)
  248. +-ENDIF()
  249. ++add_subdirectory(upgraded)
  250. +
  251. + ADD_EXECUTABLE(procd ${SOURCES})
  252. + TARGET_LINK_LIBRARIES(procd ${LIBS})
  253. +diff --git a/system.c b/system.c
  254. +index fb7fbe4..701ff35 100644
  255. +--- a/system.c
  256. ++++ b/system.c
  257. +@@ -328,12 +328,12 @@ static int proc_signal(struct ubus_context *ctx, struct ubus_object *obj,
  258. + }
  259. +
  260. + enum {
  261. +- NAND_PATH,
  262. +- __NAND_MAX
  263. ++ SYSUPGRADE_PATH,
  264. ++ __SYSUPGRADE_MAX
  265. + };
  266. +
  267. +-static const struct blobmsg_policy nand_policy[__NAND_MAX] = {
  268. +- [NAND_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
  269. ++static const struct blobmsg_policy sysupgrade_policy[__SYSUPGRADE_MAX] = {
  270. ++ [SYSUPGRADE_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
  271. + };
  272. +
  273. + static void
  274. +@@ -352,20 +352,20 @@ procd_spawn_upgraded(char *path)
  275. + execvp(argv[0], argv);
  276. + }
  277. +
  278. +-static int nand_set(struct ubus_context *ctx, struct ubus_object *obj,
  279. +- struct ubus_request_data *req, const char *method,
  280. +- struct blob_attr *msg)
  281. ++static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj,
  282. ++ struct ubus_request_data *req, const char *method,
  283. ++ struct blob_attr *msg)
  284. + {
  285. +- struct blob_attr *tb[__NAND_MAX];
  286. ++ struct blob_attr *tb[__SYSUPGRADE_MAX];
  287. +
  288. + if (!msg)
  289. + return UBUS_STATUS_INVALID_ARGUMENT;
  290. +
  291. +- blobmsg_parse(nand_policy, __NAND_MAX, tb, blob_data(msg), blob_len(msg));
  292. +- if (!tb[NAND_PATH])
  293. ++ blobmsg_parse(sysupgrade_policy, __SYSUPGRADE_MAX, tb, blob_data(msg), blob_len(msg));
  294. ++ if (!tb[SYSUPGRADE_PATH])
  295. + return UBUS_STATUS_INVALID_ARGUMENT;
  296. +
  297. +- procd_spawn_upgraded(blobmsg_get_string(tb[NAND_PATH]));
  298. ++ procd_spawn_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PATH]));
  299. + fprintf(stderr, "Yikees, something went wrong. no /sbin/upgraded ?\n");
  300. + return 0;
  301. + }
  302. +@@ -383,9 +383,8 @@ static const struct ubus_method system_methods[] = {
  303. + UBUS_METHOD_NOARG("upgrade", system_upgrade),
  304. + UBUS_METHOD("watchdog", watchdog_set, watchdog_policy),
  305. + UBUS_METHOD("signal", proc_signal, signal_policy),
  306. +-
  307. +- /* must remain at the end as it ia not always loaded */
  308. +- UBUS_METHOD("nandupgrade", nand_set, nand_policy),
  309. ++ UBUS_METHOD("nandupgrade", sysupgrade, sysupgrade_policy),
  310. ++ UBUS_METHOD("sysupgrade", sysupgrade, sysupgrade_policy),
  311. + };
  312. +
  313. + static struct ubus_object_type system_object_type =
  314. +@@ -414,12 +413,8 @@ procd_bcast_event(char *event, struct blob_attr *msg)
  315. +
  316. + void ubus_init_system(struct ubus_context *ctx)
  317. + {
  318. +- struct stat s;
  319. + int ret;
  320. +
  321. +- if (stat("/sbin/upgraded", &s))
  322. +- system_object.n_methods -= 1;
  323. +-
  324. + _ctx = ctx;
  325. + ret = ubus_add_object(ctx, &system_object);
  326. + if (ret)
  327. +--
  328. +2.13.0
  329. +
  330. diff --git a/package/system/procd/patches/1003-upgraded-link-dynamically-chroot-during-exec.patch b/package/system/procd/patches/1003-upgraded-link-dynamically-chroot-during-exec.patch
  331. new file mode 100644
  332. index 0000000000000000000000000000000000000000..d57cb02fba42894e5d279d4aa4ab00e0619f66f4
  333. --- /dev/null
  334. +++ b/package/system/procd/patches/1003-upgraded-link-dynamically-chroot-during-exec.patch
  335. @@ -0,0 +1,222 @@
  336. +From a6f07873f2189dd7b6742c04064c7bbee2c9d28b Mon Sep 17 00:00:00 2001
  337. +Message-Id: <a6f07873f2189dd7b6742c04064c7bbee2c9d28b.1496349467.git.mschiffer@universe-factory.net>
  338. +In-Reply-To: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net>
  339. +References: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net>
  340. +From: Matthias Schiffer <mschiffer@universe-factory.net>
  341. +Date: Sun, 23 Apr 2017 02:28:13 +0200
  342. +Subject: [PATCH 1003/1007] upgraded: link dynamically, chroot during exec
  343. +
  344. +The chroot ensures we don't reference anything on the rootfs and is
  345. +reverted after the upgraded exec. While we're at it, also improve error
  346. +handling a bit.
  347. +
  348. +This change also required changes to sysupgrade, as the dynamically linked
  349. +version is expected at a different location, and libraries need to be made
  350. +available.
  351. +
  352. +Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
  353. +---
  354. + system.c | 25 +++++++++++++++++++------
  355. + upgraded/CMakeLists.txt | 10 +---------
  356. + upgraded/upgraded.c | 26 +++++++++++++++++++++-----
  357. + watchdog.c | 9 +++++++--
  358. + watchdog.h | 2 +-
  359. + 5 files changed, 49 insertions(+), 23 deletions(-)
  360. +
  361. +diff --git a/system.c b/system.c
  362. +index 701ff35..ad71956 100644
  363. +--- a/system.c
  364. ++++ b/system.c
  365. +@@ -329,27 +329,40 @@ static int proc_signal(struct ubus_context *ctx, struct ubus_object *obj,
  366. +
  367. + enum {
  368. + SYSUPGRADE_PATH,
  369. ++ SYSUPGRADE_PREFIX,
  370. + __SYSUPGRADE_MAX
  371. + };
  372. +
  373. + static const struct blobmsg_policy sysupgrade_policy[__SYSUPGRADE_MAX] = {
  374. + [SYSUPGRADE_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
  375. ++ [SYSUPGRADE_PREFIX] = { .name = "prefix", .type = BLOBMSG_TYPE_STRING },
  376. + };
  377. +
  378. + static void
  379. +-procd_spawn_upgraded(char *path)
  380. ++procd_exec_upgraded(const char *prefix, char *path)
  381. + {
  382. + char *wdt_fd = watchdog_fd();
  383. +- char *argv[] = { "/tmp/upgraded", NULL, NULL};
  384. ++ char *argv[] = { "/sbin/upgraded", NULL, NULL};
  385. ++
  386. ++ if (chroot(prefix)) {
  387. ++ fprintf(stderr, "Failed to chroot for upgraded exec.\n");
  388. ++ return;
  389. ++ }
  390. +
  391. + argv[1] = path;
  392. +
  393. + DEBUG(2, "Exec to upgraded now\n");
  394. + if (wdt_fd) {
  395. +- watchdog_no_cloexec();
  396. ++ watchdog_set_cloexec(false);
  397. + setenv("WDTFD", wdt_fd, 1);
  398. + }
  399. + execvp(argv[0], argv);
  400. ++
  401. ++ /* Cleanup on failure */
  402. ++ fprintf(stderr, "Failed to exec upgraded.\n");
  403. ++ unsetenv("WDTFD");
  404. ++ watchdog_set_cloexec(true);
  405. ++ chroot(".");
  406. + }
  407. +
  408. + static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj,
  409. +@@ -362,11 +375,11 @@ static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj,
  410. + return UBUS_STATUS_INVALID_ARGUMENT;
  411. +
  412. + blobmsg_parse(sysupgrade_policy, __SYSUPGRADE_MAX, tb, blob_data(msg), blob_len(msg));
  413. +- if (!tb[SYSUPGRADE_PATH])
  414. ++ if (!tb[SYSUPGRADE_PATH] || !tb[SYSUPGRADE_PREFIX])
  415. + return UBUS_STATUS_INVALID_ARGUMENT;
  416. +
  417. +- procd_spawn_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PATH]));
  418. +- fprintf(stderr, "Yikees, something went wrong. no /sbin/upgraded ?\n");
  419. ++ procd_exec_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PREFIX]),
  420. ++ blobmsg_get_string(tb[SYSUPGRADE_PATH]));
  421. + return 0;
  422. + }
  423. +
  424. +diff --git a/upgraded/CMakeLists.txt b/upgraded/CMakeLists.txt
  425. +index 093dba2..00d8ce5 100644
  426. +--- a/upgraded/CMakeLists.txt
  427. ++++ b/upgraded/CMakeLists.txt
  428. +@@ -2,16 +2,8 @@ cmake_minimum_required(VERSION 2.6)
  429. +
  430. + PROJECT(upgraded C)
  431. + ADD_DEFINITIONS(-Os -ggdb -Wall -Werror --std=gnu99 -Wmissing-declarations)
  432. +-set(CMAKE_EXE_LINKER_FLAGS "-static -fPIC")
  433. +-set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
  434. +-set(CMAKE_EXE_LINK_DYNAMIC_C_FLAGS)
  435. +-set(CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS)
  436. +-set(CMAKE_SHARED_LIBRARY_C_FLAGS)
  437. +-set(CMAKE_SHARED_LIBRARY_CXX_FLAGS)
  438. +-set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS)
  439. +-set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
  440. + ADD_EXECUTABLE(upgraded upgraded.c ../watchdog.c)
  441. +-TARGET_LINK_LIBRARIES(upgraded ubox rt -lc -lgcc_pic)
  442. ++TARGET_LINK_LIBRARIES(upgraded ubox)
  443. + INSTALL(TARGETS upgraded
  444. + RUNTIME DESTINATION sbin
  445. + )
  446. +diff --git a/upgraded/upgraded.c b/upgraded/upgraded.c
  447. +index d7433e7..aa0b4ff 100644
  448. +--- a/upgraded/upgraded.c
  449. ++++ b/upgraded/upgraded.c
  450. +@@ -14,6 +14,7 @@
  451. +
  452. + #include <sys/reboot.h>
  453. +
  454. ++#include <fcntl.h>
  455. + #include <stdio.h>
  456. + #include <stdlib.h>
  457. + #include <string.h>
  458. +@@ -24,6 +25,10 @@
  459. +
  460. + #include "../watchdog.h"
  461. +
  462. ++#ifndef O_PATH
  463. ++#define O_PATH 010000000
  464. ++#endif
  465. ++
  466. + static struct uloop_process upgrade_proc;
  467. + unsigned int debug = 2;
  468. +
  469. +@@ -34,7 +39,7 @@ static void upgrade_proc_cb(struct uloop_process *proc, int ret)
  470. + uloop_end();
  471. + }
  472. +
  473. +-static void sysupgarde(char *folder)
  474. ++static void sysupgrade(char *folder)
  475. + {
  476. + char *args[] = { "/sbin/sysupgrade", "nand", NULL, NULL };
  477. +
  478. +@@ -47,7 +52,7 @@ static void sysupgarde(char *folder)
  479. + exit(-1);
  480. + }
  481. + if (upgrade_proc.pid <= 0) {
  482. +- fprintf(stderr, "Failed to start sysupgarde\n");
  483. ++ fprintf(stderr, "Failed to start sysupgrade\n");
  484. + uloop_end();
  485. + }
  486. + }
  487. +@@ -60,10 +65,21 @@ int main(int argc, char **argv)
  488. + fprintf(stderr, "this tool needs to run as pid 1\n");
  489. + return -1;
  490. + }
  491. +- if (chdir("/tmp") == -1) {
  492. +- fprintf(stderr, "failed to chdir to /tmp: %s\n", strerror(errno));
  493. ++
  494. ++ int fd = open("/", O_DIRECTORY|O_PATH);
  495. ++ if (fd < 0) {
  496. ++ fprintf(stderr, "unable to open prefix directory: %s\n", strerror(errno));
  497. + return -1;
  498. + }
  499. ++
  500. ++ chroot(".");
  501. ++
  502. ++ if (fchdir(fd) == -1) {
  503. ++ fprintf(stderr, "failed to chdir to prefix directory: %s\n", strerror(errno));
  504. ++ return -1;
  505. ++ }
  506. ++ close(fd);
  507. ++
  508. + if (argc != 2) {
  509. + fprintf(stderr, "sysupgrade stage 2 failed, no folder specified\n");
  510. + return -1;
  511. +@@ -71,7 +87,7 @@ int main(int argc, char **argv)
  512. +
  513. + uloop_init();
  514. + watchdog_init(0);
  515. +- sysupgarde(argv[1]);
  516. ++ sysupgrade(argv[1]);
  517. + uloop_run();
  518. +
  519. + reboot(RB_AUTOBOOT);
  520. +diff --git a/watchdog.c b/watchdog.c
  521. +index 592ae7e..780b321 100644
  522. +--- a/watchdog.c
  523. ++++ b/watchdog.c
  524. +@@ -126,10 +126,15 @@ void watchdog_init(int preinit)
  525. + }
  526. +
  527. +
  528. +-void watchdog_no_cloexec(void)
  529. ++void watchdog_set_cloexec(bool val)
  530. + {
  531. + if (wdt_fd < 0)
  532. + return;
  533. +
  534. +- fcntl(wdt_fd, F_SETFD, fcntl(wdt_fd, F_GETFD) & ~FD_CLOEXEC);
  535. ++ int flags = fcntl(wdt_fd, F_GETFD);
  536. ++ if (val)
  537. ++ flags |= FD_CLOEXEC;
  538. ++ else
  539. ++ flags &= ~FD_CLOEXEC;
  540. ++ fcntl(wdt_fd, F_SETFD, flags);
  541. + }
  542. +diff --git a/watchdog.h b/watchdog.h
  543. +index 015fa93..e857010 100644
  544. +--- a/watchdog.h
  545. ++++ b/watchdog.h
  546. +@@ -21,7 +21,7 @@ int watchdog_timeout(int timeout);
  547. + int watchdog_frequency(int frequency);
  548. + void watchdog_set_stopped(bool val);
  549. + bool watchdog_get_stopped(void);
  550. +-void watchdog_no_cloexec(void);
  551. ++void watchdog_set_cloexec(bool val);
  552. + void watchdog_ping(void);
  553. +
  554. + #endif
  555. +--
  556. +2.13.0
  557. +
  558. diff --git a/package/system/procd/patches/1004-upgraded-add-support-for-passing-a-command-argument-.patch b/package/system/procd/patches/1004-upgraded-add-support-for-passing-a-command-argument-.patch
  559. new file mode 100644
  560. index 0000000000000000000000000000000000000000..ac8c3fe6ee15e773c973c9d340fbe52ce428d6ee
  561. --- /dev/null
  562. +++ b/package/system/procd/patches/1004-upgraded-add-support-for-passing-a-command-argument-.patch
  563. @@ -0,0 +1,104 @@
  564. +From af1e6d9839a9a8f2c579202597630df9b8f842e6 Mon Sep 17 00:00:00 2001
  565. +Message-Id: <af1e6d9839a9a8f2c579202597630df9b8f842e6.1496349467.git.mschiffer@universe-factory.net>
  566. +In-Reply-To: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net>
  567. +References: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net>
  568. +From: Matthias Schiffer <mschiffer@universe-factory.net>
  569. +Date: Sun, 23 Apr 2017 19:04:25 +0200
  570. +Subject: [PATCH 1004/1007] upgraded: add support for passing a "command"
  571. + argument to stage2
  572. +
  573. +This allows us to make use of upgraded in "snapshot convert" as well.
  574. +
  575. +Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
  576. +---
  577. + system.c | 10 +++++++---
  578. + upgraded/upgraded.c | 13 +++++++------
  579. + 2 files changed, 14 insertions(+), 9 deletions(-)
  580. +
  581. +diff --git a/system.c b/system.c
  582. +index ad71956..1e8a06d 100644
  583. +--- a/system.c
  584. ++++ b/system.c
  585. +@@ -330,19 +330,21 @@ static int proc_signal(struct ubus_context *ctx, struct ubus_object *obj,
  586. + enum {
  587. + SYSUPGRADE_PATH,
  588. + SYSUPGRADE_PREFIX,
  589. ++ SYSUPGRADE_COMMAND,
  590. + __SYSUPGRADE_MAX
  591. + };
  592. +
  593. + static const struct blobmsg_policy sysupgrade_policy[__SYSUPGRADE_MAX] = {
  594. + [SYSUPGRADE_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
  595. + [SYSUPGRADE_PREFIX] = { .name = "prefix", .type = BLOBMSG_TYPE_STRING },
  596. ++ [SYSUPGRADE_COMMAND] = { .name = "command", .type = BLOBMSG_TYPE_STRING },
  597. + };
  598. +
  599. + static void
  600. +-procd_exec_upgraded(const char *prefix, char *path)
  601. ++procd_exec_upgraded(const char *prefix, char *path, char *command)
  602. + {
  603. + char *wdt_fd = watchdog_fd();
  604. +- char *argv[] = { "/sbin/upgraded", NULL, NULL};
  605. ++ char *argv[] = { "/sbin/upgraded", NULL, NULL, NULL};
  606. +
  607. + if (chroot(prefix)) {
  608. + fprintf(stderr, "Failed to chroot for upgraded exec.\n");
  609. +@@ -350,6 +352,7 @@ procd_exec_upgraded(const char *prefix, char *path)
  610. + }
  611. +
  612. + argv[1] = path;
  613. ++ argv[2] = command;
  614. +
  615. + DEBUG(2, "Exec to upgraded now\n");
  616. + if (wdt_fd) {
  617. +@@ -379,7 +382,8 @@ static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj,
  618. + return UBUS_STATUS_INVALID_ARGUMENT;
  619. +
  620. + procd_exec_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PREFIX]),
  621. +- blobmsg_get_string(tb[SYSUPGRADE_PATH]));
  622. ++ blobmsg_get_string(tb[SYSUPGRADE_PATH]),
  623. ++ tb[SYSUPGRADE_COMMAND] ? blobmsg_get_string(tb[SYSUPGRADE_COMMAND]) : NULL);
  624. + return 0;
  625. + }
  626. +
  627. +diff --git a/upgraded/upgraded.c b/upgraded/upgraded.c
  628. +index aa0b4ff..303edb7 100644
  629. +--- a/upgraded/upgraded.c
  630. ++++ b/upgraded/upgraded.c
  631. +@@ -39,11 +39,12 @@ static void upgrade_proc_cb(struct uloop_process *proc, int ret)
  632. + uloop_end();
  633. + }
  634. +
  635. +-static void sysupgrade(char *folder)
  636. ++static void sysupgrade(char *path, char *command)
  637. + {
  638. +- char *args[] = { "/sbin/sysupgrade", "nand", NULL, NULL };
  639. ++ char *args[] = { "/sbin/sysupgrade", "nand", NULL, NULL, NULL };
  640. +
  641. +- args[2] = folder;
  642. ++ args[2] = path;
  643. ++ args[3] = command;
  644. + upgrade_proc.cb = upgrade_proc_cb;
  645. + upgrade_proc.pid = fork();
  646. + if (!upgrade_proc.pid) {
  647. +@@ -80,14 +81,14 @@ int main(int argc, char **argv)
  648. + }
  649. + close(fd);
  650. +
  651. +- if (argc != 2) {
  652. +- fprintf(stderr, "sysupgrade stage 2 failed, no folder specified\n");
  653. ++ if (argc != 2 && argc != 3) {
  654. ++ fprintf(stderr, "sysupgrade stage 2 failed, invalid command line\n");
  655. + return -1;
  656. + }
  657. +
  658. + uloop_init();
  659. + watchdog_init(0);
  660. +- sysupgrade(argv[1]);
  661. ++ sysupgrade(argv[1], (argc == 3) ? argv[2] : NULL);
  662. + uloop_run();
  663. +
  664. + reboot(RB_AUTOBOOT);
  665. +--
  666. +2.13.0
  667. +
  668. diff --git a/package/system/procd/patches/1005-Remove-code-that-has-become-unnecessary-after-sysupg.patch b/package/system/procd/patches/1005-Remove-code-that-has-become-unnecessary-after-sysupg.patch
  669. new file mode 100644
  670. index 0000000000000000000000000000000000000000..0be544bce113b920556bc6a9889041227fc42e07
  671. --- /dev/null
  672. +++ b/package/system/procd/patches/1005-Remove-code-that-has-become-unnecessary-after-sysupg.patch
  673. @@ -0,0 +1,119 @@
  674. +From 45bd440ec30f777b3619dcd0e7db330cc29a7850 Mon Sep 17 00:00:00 2001
  675. +Message-Id: <45bd440ec30f777b3619dcd0e7db330cc29a7850.1496349467.git.mschiffer@universe-factory.net>
  676. +In-Reply-To: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net>
  677. +References: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net>
  678. +From: Matthias Schiffer <mschiffer@universe-factory.net>
  679. +Date: Sun, 23 Apr 2017 19:06:12 +0200
  680. +Subject: [PATCH 1005/1007] Remove code that has become unnecessary after
  681. + sysupgrade changes
  682. +
  683. +Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
  684. +---
  685. + procd.h | 1 -
  686. + service/instance.c | 2 --
  687. + system.c | 12 ------------
  688. + upgraded/upgraded.c | 10 +++++-----
  689. + 4 files changed, 5 insertions(+), 20 deletions(-)
  690. +
  691. +diff --git a/procd.h b/procd.h
  692. +index 66d183c..796e524 100644
  693. +--- a/procd.h
  694. ++++ b/procd.h
  695. +@@ -27,7 +27,6 @@
  696. + #define __init __attribute__((constructor))
  697. +
  698. + extern char *ubus_socket;
  699. +-extern int upgrade_running;
  700. +
  701. + void procd_connect_ubus(void);
  702. + void procd_reconnect_ubus(int reconnect);
  703. +diff --git a/service/instance.c b/service/instance.c
  704. +index 40ff021..f33eae9 100644
  705. +--- a/service/instance.c
  706. ++++ b/service/instance.c
  707. +@@ -453,8 +453,6 @@ instance_exit(struct uloop_process *p, int ret)
  708. + runtime = tp.tv_sec - in->start.tv_sec;
  709. +
  710. + DEBUG(2, "Instance %s::%s exit with error code %d after %ld seconds\n", in->srv->name, in->name, ret, runtime);
  711. +- if (upgrade_running)
  712. +- return;
  713. +
  714. + uloop_timeout_cancel(&in->timeout);
  715. + if (in->halt) {
  716. +diff --git a/system.c b/system.c
  717. +index 1e8a06d..80205da 100644
  718. +--- a/system.c
  719. ++++ b/system.c
  720. +@@ -31,8 +31,6 @@ static struct blob_buf b;
  721. + static int notify;
  722. + static struct ubus_context *_ctx;
  723. +
  724. +-int upgrade_running = 0;
  725. +-
  726. + static int system_board(struct ubus_context *ctx, struct ubus_object *obj,
  727. + struct ubus_request_data *req, const char *method,
  728. + struct blob_attr *msg)
  729. +@@ -227,14 +225,6 @@ static int system_info(struct ubus_context *ctx, struct ubus_object *obj,
  730. + return UBUS_STATUS_OK;
  731. + }
  732. +
  733. +-static int system_upgrade(struct ubus_context *ctx, struct ubus_object *obj,
  734. +- struct ubus_request_data *req, const char *method,
  735. +- struct blob_attr *msg)
  736. +-{
  737. +- upgrade_running = 1;
  738. +- return 0;
  739. +-}
  740. +-
  741. + enum {
  742. + WDT_FREQUENCY,
  743. + WDT_TIMEOUT,
  744. +@@ -397,10 +387,8 @@ procd_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj)
  745. + static const struct ubus_method system_methods[] = {
  746. + UBUS_METHOD_NOARG("board", system_board),
  747. + UBUS_METHOD_NOARG("info", system_info),
  748. +- UBUS_METHOD_NOARG("upgrade", system_upgrade),
  749. + UBUS_METHOD("watchdog", watchdog_set, watchdog_policy),
  750. + UBUS_METHOD("signal", proc_signal, signal_policy),
  751. +- UBUS_METHOD("nandupgrade", sysupgrade, sysupgrade_policy),
  752. + UBUS_METHOD("sysupgrade", sysupgrade, sysupgrade_policy),
  753. + };
  754. +
  755. +diff --git a/upgraded/upgraded.c b/upgraded/upgraded.c
  756. +index 303edb7..79ebd37 100644
  757. +--- a/upgraded/upgraded.c
  758. ++++ b/upgraded/upgraded.c
  759. +@@ -41,10 +41,10 @@ static void upgrade_proc_cb(struct uloop_process *proc, int ret)
  760. +
  761. + static void sysupgrade(char *path, char *command)
  762. + {
  763. +- char *args[] = { "/sbin/sysupgrade", "nand", NULL, NULL, NULL };
  764. ++ char *args[] = { "/lib/upgrade/stage2", NULL, NULL, NULL };
  765. +
  766. +- args[2] = path;
  767. +- args[3] = command;
  768. ++ args[1] = path;
  769. ++ args[2] = command;
  770. + upgrade_proc.cb = upgrade_proc_cb;
  771. + upgrade_proc.pid = fork();
  772. + if (!upgrade_proc.pid) {
  773. +@@ -81,14 +81,14 @@ int main(int argc, char **argv)
  774. + }
  775. + close(fd);
  776. +
  777. +- if (argc != 2 && argc != 3) {
  778. ++ if (argc != 3) {
  779. + fprintf(stderr, "sysupgrade stage 2 failed, invalid command line\n");
  780. + return -1;
  781. + }
  782. +
  783. + uloop_init();
  784. + watchdog_init(0);
  785. +- sysupgrade(argv[1], (argc == 3) ? argv[2] : NULL);
  786. ++ sysupgrade(argv[1], argv[2]);
  787. + uloop_run();
  788. +
  789. + reboot(RB_AUTOBOOT);
  790. +--
  791. +2.13.0
  792. +
  793. diff --git a/package/system/procd/patches/1006-init-add-support-for-sysupgrades-triggered-from-prei.patch b/package/system/procd/patches/1006-init-add-support-for-sysupgrades-triggered-from-prei.patch
  794. new file mode 100644
  795. index 0000000000000000000000000000000000000000..872846be3e3984f6177512a7adbf0886b78d2677
  796. --- /dev/null
  797. +++ b/package/system/procd/patches/1006-init-add-support-for-sysupgrades-triggered-from-prei.patch
  798. @@ -0,0 +1,280 @@
  799. +From f4e6df8848e54d83bac0ab7451312a9db5b59143 Mon Sep 17 00:00:00 2001
  800. +Message-Id: <f4e6df8848e54d83bac0ab7451312a9db5b59143.1496349467.git.mschiffer@universe-factory.net>
  801. +In-Reply-To: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net>
  802. +References: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net>
  803. +From: Matthias Schiffer <mschiffer@universe-factory.net>
  804. +Date: Mon, 24 Apr 2017 00:40:27 +0200
  805. +Subject: [PATCH 1006/1007] init: add support for sysupgrades triggered from
  806. + preinit
  807. +
  808. +This will allow to add support for sysupgrades via upgraded from failsafe
  809. +mode.
  810. +
  811. +Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
  812. +---
  813. + CMakeLists.txt | 4 ++--
  814. + initd/preinit.c | 46 +++++++++++++++++++++++++++++++++++++++++-----
  815. + system.c | 35 ++++-------------------------------
  816. + sysupgrade.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
  817. + sysupgrade.h | 21 +++++++++++++++++++++
  818. + watchdog.h | 2 ++
  819. + 6 files changed, 119 insertions(+), 38 deletions(-)
  820. + create mode 100644 sysupgrade.c
  821. + create mode 100644 sysupgrade.h
  822. +
  823. +diff --git a/CMakeLists.txt b/CMakeLists.txt
  824. +index 9e378ae..441216b 100644
  825. +--- a/CMakeLists.txt
  826. ++++ b/CMakeLists.txt
  827. +@@ -17,7 +17,7 @@ INSTALL(TARGETS setlbf
  828. + )
  829. +
  830. +
  831. +-SET(SOURCES procd.c signal.c watchdog.c state.c inittab.c rcS.c ubus.c system.c
  832. ++SET(SOURCES procd.c signal.c watchdog.c state.c inittab.c rcS.c ubus.c system.c sysupgrade.c
  833. + service/service.c service/instance.c service/validate.c service/trigger.c service/watch.c
  834. + plug/coldplug.c plug/hotplug.c utils/utils.c)
  835. +
  836. +@@ -41,7 +41,7 @@ INSTALL(TARGETS procd
  837. + )
  838. +
  839. +
  840. +-ADD_EXECUTABLE(init initd/init.c initd/early.c initd/preinit.c initd/mkdev.c watchdog.c
  841. ++ADD_EXECUTABLE(init initd/init.c initd/early.c initd/preinit.c initd/mkdev.c sysupgrade.c watchdog.c
  842. + utils/utils.c ${SOURCES_ZRAM})
  843. + TARGET_LINK_LIBRARIES(init ${LIBS})
  844. + INSTALL(TARGETS init
  845. +diff --git a/initd/preinit.c b/initd/preinit.c
  846. +index acc64e7..3a606e4 100644
  847. +--- a/initd/preinit.c
  848. ++++ b/initd/preinit.c
  849. +@@ -28,6 +28,7 @@
  850. +
  851. + #include "init.h"
  852. + #include "../watchdog.h"
  853. ++#include "../sysupgrade.h"
  854. +
  855. + static struct uloop_process preinit_proc;
  856. + static struct uloop_process plugd_proc;
  857. +@@ -79,23 +80,58 @@ get_rc_d(void)
  858. + }
  859. +
  860. + static void
  861. ++check_sysupgrade(void)
  862. ++{
  863. ++ char *prefix = NULL, *path = NULL, *command = NULL;
  864. ++ size_t n;
  865. ++
  866. ++ if (chdir("/"))
  867. ++ return;
  868. ++
  869. ++ FILE *sysupgrade = fopen("/tmp/sysupgrade", "r");
  870. ++ if (!sysupgrade)
  871. ++ return;
  872. ++
  873. ++ n = 0;
  874. ++ if (getdelim(&prefix, &n, 0, sysupgrade) < 0)
  875. ++ goto fail;
  876. ++ n = 0;
  877. ++ if (getdelim(&path, &n, 0, sysupgrade) < 0)
  878. ++ goto fail;
  879. ++ n = 0;
  880. ++ if (getdelim(&command, &n, 0, sysupgrade) < 0)
  881. ++ goto fail;
  882. ++
  883. ++ fclose(sysupgrade);
  884. ++
  885. ++ sysupgrade_exec_upgraded(prefix, path, command);
  886. ++
  887. ++ while (true)
  888. ++ sleep(1);
  889. ++
  890. ++fail:
  891. ++ fclose(sysupgrade);
  892. ++ free(prefix);
  893. ++ free(path);
  894. ++ free(command);
  895. ++}
  896. ++
  897. ++static void
  898. + spawn_procd(struct uloop_process *proc, int ret)
  899. + {
  900. + char *wdt_fd = watchdog_fd();
  901. + char *argv[] = { "/sbin/procd", NULL};
  902. +- struct stat s;
  903. + char dbg[2];
  904. + char *rc_d_path;
  905. +
  906. + if (plugd_proc.pid > 0)
  907. + kill(plugd_proc.pid, SIGKILL);
  908. +
  909. +- if (!stat("/tmp/sysupgrade", &s))
  910. +- while (true)
  911. +- sleep(1);
  912. +-
  913. + unsetenv("INITRAMFS");
  914. + unsetenv("PREINIT");
  915. ++
  916. ++ check_sysupgrade();
  917. ++
  918. + DEBUG(2, "Exec to real procd now\n");
  919. + if (wdt_fd)
  920. + setenv("WDTFD", wdt_fd, 1);
  921. +diff --git a/system.c b/system.c
  922. +index 80205da..700530d 100644
  923. +--- a/system.c
  924. ++++ b/system.c
  925. +@@ -25,6 +25,7 @@
  926. + #include <libubox/uloop.h>
  927. +
  928. + #include "procd.h"
  929. ++#include "sysupgrade.h"
  930. + #include "watchdog.h"
  931. +
  932. + static struct blob_buf b;
  933. +@@ -330,34 +331,6 @@ static const struct blobmsg_policy sysupgrade_policy[__SYSUPGRADE_MAX] = {
  934. + [SYSUPGRADE_COMMAND] = { .name = "command", .type = BLOBMSG_TYPE_STRING },
  935. + };
  936. +
  937. +-static void
  938. +-procd_exec_upgraded(const char *prefix, char *path, char *command)
  939. +-{
  940. +- char *wdt_fd = watchdog_fd();
  941. +- char *argv[] = { "/sbin/upgraded", NULL, NULL, NULL};
  942. +-
  943. +- if (chroot(prefix)) {
  944. +- fprintf(stderr, "Failed to chroot for upgraded exec.\n");
  945. +- return;
  946. +- }
  947. +-
  948. +- argv[1] = path;
  949. +- argv[2] = command;
  950. +-
  951. +- DEBUG(2, "Exec to upgraded now\n");
  952. +- if (wdt_fd) {
  953. +- watchdog_set_cloexec(false);
  954. +- setenv("WDTFD", wdt_fd, 1);
  955. +- }
  956. +- execvp(argv[0], argv);
  957. +-
  958. +- /* Cleanup on failure */
  959. +- fprintf(stderr, "Failed to exec upgraded.\n");
  960. +- unsetenv("WDTFD");
  961. +- watchdog_set_cloexec(true);
  962. +- chroot(".");
  963. +-}
  964. +-
  965. + static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj,
  966. + struct ubus_request_data *req, const char *method,
  967. + struct blob_attr *msg)
  968. +@@ -371,9 +344,9 @@ static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj,
  969. + if (!tb[SYSUPGRADE_PATH] || !tb[SYSUPGRADE_PREFIX])
  970. + return UBUS_STATUS_INVALID_ARGUMENT;
  971. +
  972. +- procd_exec_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PREFIX]),
  973. +- blobmsg_get_string(tb[SYSUPGRADE_PATH]),
  974. +- tb[SYSUPGRADE_COMMAND] ? blobmsg_get_string(tb[SYSUPGRADE_COMMAND]) : NULL);
  975. ++ sysupgrade_exec_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PREFIX]),
  976. ++ blobmsg_get_string(tb[SYSUPGRADE_PATH]),
  977. ++ tb[SYSUPGRADE_COMMAND] ? blobmsg_get_string(tb[SYSUPGRADE_COMMAND]) : NULL);
  978. + return 0;
  979. + }
  980. +
  981. +diff --git a/sysupgrade.c b/sysupgrade.c
  982. +new file mode 100644
  983. +index 0000000..30f1836
  984. +--- /dev/null
  985. ++++ b/sysupgrade.c
  986. +@@ -0,0 +1,49 @@
  987. ++/*
  988. ++ * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
  989. ++ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
  990. ++ * Copyright (C) 2017 Matthias Schiffer <mschiffer@universe-factory.net>
  991. ++ *
  992. ++ * This program is free software; you can redistribute it and/or modify
  993. ++ * it under the terms of the GNU Lesser General Public License version 2.1
  994. ++ * as published by the Free Software Foundation
  995. ++ *
  996. ++ * This program is distributed in the hope that it will be useful,
  997. ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
  998. ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  999. ++ * GNU General Public License for more details.
  1000. ++ */
  1001. ++
  1002. ++
  1003. ++#include "watchdog.h"
  1004. ++#include "sysupgrade.h"
  1005. ++
  1006. ++#include <stdio.h>
  1007. ++#include <stdlib.h>
  1008. ++#include <unistd.h>
  1009. ++
  1010. ++
  1011. ++void sysupgrade_exec_upgraded(const char *prefix, char *path, char *command)
  1012. ++{
  1013. ++ char *wdt_fd = watchdog_fd();
  1014. ++ char *argv[] = { "/sbin/upgraded", NULL, NULL, NULL};
  1015. ++
  1016. ++ if (chroot(prefix)) {
  1017. ++ fprintf(stderr, "Failed to chroot for upgraded exec.\n");
  1018. ++ return;
  1019. ++ }
  1020. ++
  1021. ++ argv[1] = path;
  1022. ++ argv[2] = command;
  1023. ++
  1024. ++ if (wdt_fd) {
  1025. ++ watchdog_set_cloexec(false);
  1026. ++ setenv("WDTFD", wdt_fd, 1);
  1027. ++ }
  1028. ++ execvp(argv[0], argv);
  1029. ++
  1030. ++ /* Cleanup on failure */
  1031. ++ fprintf(stderr, "Failed to exec upgraded.\n");
  1032. ++ unsetenv("WDTFD");
  1033. ++ watchdog_set_cloexec(true);
  1034. ++ chroot(".");
  1035. ++}
  1036. +diff --git a/sysupgrade.h b/sysupgrade.h
  1037. +new file mode 100644
  1038. +index 0000000..8c09fc9
  1039. +--- /dev/null
  1040. ++++ b/sysupgrade.h
  1041. +@@ -0,0 +1,21 @@
  1042. ++/*
  1043. ++ * Copyright (C) 2017 Matthias Schiffer <mschiffer@universe-factory.net>
  1044. ++ *
  1045. ++ * This program is free software; you can redistribute it and/or modify
  1046. ++ * it under the terms of the GNU Lesser General Public License version 2.1
  1047. ++ * as published by the Free Software Foundation
  1048. ++ *
  1049. ++ * This program is distributed in the hope that it will be useful,
  1050. ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1051. ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1052. ++ * GNU General Public License for more details.
  1053. ++ */
  1054. ++
  1055. ++#ifndef __PROCD_SYSUPGRADE_H
  1056. ++#define __PROCD_SYSUPGRADE_H
  1057. ++
  1058. ++
  1059. ++void sysupgrade_exec_upgraded(const char *prefix, char *path, char *command);
  1060. ++
  1061. ++
  1062. ++#endif
  1063. +diff --git a/watchdog.h b/watchdog.h
  1064. +index e857010..06ce5e5 100644
  1065. +--- a/watchdog.h
  1066. ++++ b/watchdog.h
  1067. +@@ -15,6 +15,8 @@
  1068. + #ifndef __PROCD_WATCHDOG_H
  1069. + #define __PROCD_WATCHDOG_H
  1070. +
  1071. ++#include <stdbool.h>
  1072. ++
  1073. + void watchdog_init(int preinit);
  1074. + char* watchdog_fd(void);
  1075. + int watchdog_timeout(int timeout);
  1076. +--
  1077. +2.13.0
  1078. +
  1079. diff --git a/package/system/procd/patches/1007-upgraded-define-__GNU_SOURCE.patch b/package/system/procd/patches/1007-upgraded-define-__GNU_SOURCE.patch
  1080. new file mode 100644
  1081. index 0000000000000000000000000000000000000000..c98cb9baa4371b64d6b1297fc0a9921d580947be
  1082. --- /dev/null
  1083. +++ b/package/system/procd/patches/1007-upgraded-define-__GNU_SOURCE.patch
  1084. @@ -0,0 +1,31 @@
  1085. +From 8137d283c7f858ca658fa556b95eb62e35ae980d Mon Sep 17 00:00:00 2001
  1086. +Message-Id: <8137d283c7f858ca658fa556b95eb62e35ae980d.1496349467.git.mschiffer@universe-factory.net>
  1087. +In-Reply-To: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net>
  1088. +References: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net>
  1089. +From: Matthias Schiffer <mschiffer@universe-factory.net>
  1090. +Date: Tue, 30 May 2017 07:23:57 +0200
  1091. +Subject: [PATCH 1007/1007] upgraded: define __GNU_SOURCE
  1092. +
  1093. +It is required on non-musl libcs for O_DIRECTORY.
  1094. +
  1095. +Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
  1096. +---
  1097. + upgraded/upgraded.c | 2 ++
  1098. + 1 file changed, 2 insertions(+)
  1099. +
  1100. +diff --git a/upgraded/upgraded.c b/upgraded/upgraded.c
  1101. +index 79ebd37..e70f92d 100644
  1102. +--- a/upgraded/upgraded.c
  1103. ++++ b/upgraded/upgraded.c
  1104. +@@ -12,6 +12,8 @@
  1105. + * GNU General Public License for more details.
  1106. + */
  1107. +
  1108. ++#define _GNU_SOURCE
  1109. ++
  1110. + #include <sys/reboot.h>
  1111. +
  1112. + #include <fcntl.h>
  1113. +--
  1114. +2.13.0
  1115. +