Under some circumstances these folders may get removed after
startup, for example if /tmp has a mountpoint change after
swupdate is started.
In order to make swupdate better able to handle these sort of
race conditions we can create/destroy these folders for each
update installation.
Fixes:
[ERROR] : SWUPDATE failed [0] ERROR : I cannot open /tmp/scripts/format.lua 2
[ERROR] : SWUPDATE failed [0] ERROR : extracting script to /tmp/scripts/ failed
[ERROR] : SWUPDATE failed [1] Installation failed !
Signed-off-by: James Hilliard <
james.h...@gmail.com>
---
Changes v1 -> v2:
- just create/destroy datadst once for each install
---
core/installer.c | 71 ++++++++++++++++++++++++++++++++++++++++++------
core/swupdate.c | 57 --------------------------------------
2 files changed, 62 insertions(+), 66 deletions(-)
diff --git a/core/installer.c b/core/installer.c
index 5e4cbe5..fbb5e5a 100644
--- a/core/installer.c
+++ b/core/installer.c
@@ -18,6 +18,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
+#include <ftw.h>
#include <sys/stat.h>
#include <sys/mount.h>
@@ -209,6 +210,45 @@ static int run_prepost_scripts(struct imglist *list, script_fn type)
return 0;
}
+static void create_directory(const char* path) {
+ char* dpath;
+ if (asprintf(&dpath, "%s%s", get_tmpdir(), path) ==
+ ENOMEM_ASPRINTF) {
+ ERROR("OOM: Directory %s not created", path);
+ return;
+ }
+ if (mkdir(dpath, 0777)) {
+ WARN("Directory %s cannot be created due to : %s",
+ path, strerror(errno));
+ }
+ free(dpath);
+}
+
+#ifndef CONFIG_NOCLEANUP
+static int _remove_directory_cb(const char *fpath, const struct stat *sb,
+ int typeflag, struct FTW *ftwbuf)
+{
+ (void)sb;
+ (void)typeflag;
+ (void)ftwbuf;
+ return remove(fpath);
+}
+
+static int remove_directory(const char* path)
+{
+ char* dpath;
+ int ret;
+ if (asprintf(&dpath, "%s%s", get_tmpdir(), path) ==
+ ENOMEM_ASPRINTF) {
+ ERROR("OOM: Directory %s not removed", path);
+ return -ENOMEM;
+ }
+ ret = nftw(dpath, _remove_directory_cb, 64, FTW_DEPTH | FTW_PHYS);
+ free(dpath);
+ return ret;
+}
+#endif
+
int install_single_image(struct img_type *img, bool dry_run)
{
struct installer_handler *hnd;
@@ -258,13 +298,17 @@ int install_images(struct swupdate_cfg *sw)
bool dry_run = sw->parms.dry_run;
bool dropimg;
+ /* Create directories for scripts/datadst */
+ create_directory(SCRIPTS_DIR_SUFFIX);
+ create_directory(DATADST_DIR_SUFFIX);
+
/* Extract all scripts, preinstall scripts must be run now */
const char* tmpdir_scripts = get_tmpdirscripts();
ret = extract_scripts(&sw->scripts);
ret |= extract_scripts(&sw->bootscripts);
if (ret) {
ERROR("extracting script to %s failed", tmpdir_scripts);
- return ret;
+ goto out;
}
/* Scripts must be run before installing images */
@@ -272,7 +316,7 @@ int install_images(struct swupdate_cfg *sw)
ret = run_prepost_scripts(&sw->scripts, PREINSTALL);
if (ret) {
ERROR("execute preinstall scripts failed");
- return ret;
+ goto out;
}
}
@@ -293,14 +337,16 @@ int install_images(struct swupdate_cfg *sw)
if (asprintf(&filename, "%s%s", TMPDIR, img->fname) ==
ENOMEM_ASPRINTF) {
ERROR("Path too long: %s%s", TMPDIR, img->fname);
- return -1;
+ ret = -1;
+ goto out;
}
ret = stat(filename, &buf);
if (ret) {
TRACE("%s not found or wrong", filename);
free(filename);
- return -1;
+ ret = -1;
+ goto out;
}
img->size = buf.st_size;
img->fdin = open(filename, O_RDONLY);
@@ -308,7 +354,8 @@ int install_images(struct swupdate_cfg *sw)
if (img->fdin < 0) {
ERROR("Image %s cannot be opened",
img->fname);
- return -1;
+ ret = -1;
+ goto out;
}
if ((strlen(img->path) > 0) &&
@@ -337,20 +384,20 @@ int install_images(struct swupdate_cfg *sw)
free_image(img);
if (ret)
- return ret;
+ goto out;
}
/*
* Skip scripts in dry-run mode
*/
if (dry_run) {
- return ret;
+ goto out;
}
ret = run_prepost_scripts(&sw->scripts, POSTINSTALL);
if (ret) {
ERROR("execute postinstall scripts failed");
- return ret;
+ goto out;
}
if (!LIST_EMPTY(&sw->bootloader)) {
@@ -358,12 +405,18 @@ int install_images(struct swupdate_cfg *sw)
sprintf(bootscript, "%s%s", TMPDIR, BOOT_SCRIPT_SUFFIX);
ret = update_bootloader_env(sw, bootscript);
if (ret) {
- return ret;
+ goto out;
}
}
ret |= run_prepost_scripts(&sw->bootscripts, POSTINSTALL);
+out:
+#ifndef CONFIG_NOCLEANUP
+ remove_directory(SCRIPTS_DIR_SUFFIX);
+ remove_directory(DATADST_DIR_SUFFIX);
+#endif
+
return ret;
}
diff --git a/core/swupdate.c b/core/swupdate.c
index 949a647..a31aeb1 100644
--- a/core/swupdate.c
+++ b/core/swupdate.c
@@ -23,7 +23,6 @@
#include <pthread.h>
#include <signal.h>
#include <sys/wait.h>
-#include <ftw.h>
#include "bsdqueue.h"
#include "cpiohdr.h"
@@ -244,53 +243,6 @@ static int parse_image_selector(const char *selector, struct swupdate_cfg *sw)
return 0;
}
-static void create_directory(const char* path) {
- char* dpath;
- if (asprintf(&dpath, "%s%s", get_tmpdir(), path) ==
- ENOMEM_ASPRINTF) {
- ERROR("OOM: Directory %s not created", path);
- return;
- }
- if (mkdir(dpath, 0777)) {
- WARN("Directory %s cannot be created due to : %s",
- path, strerror(errno));
- }
- free(dpath);
-}
-
-#ifndef CONFIG_NOCLEANUP
-static int _remove_directory_cb(const char *fpath, const struct stat *sb,
- int typeflag, struct FTW *ftwbuf)
-{
- (void)sb;
- (void)typeflag;
- (void)ftwbuf;
- return remove(fpath);
-}
-
-static int remove_directory(const char* path)
-{
- char* dpath;
- int ret;
- if (asprintf(&dpath, "%s%s", get_tmpdir(), path) ==
- ENOMEM_ASPRINTF) {
- ERROR("OOM: Directory %s not removed", path);
- return -ENOMEM;
- }
- ret = nftw(dpath, _remove_directory_cb, 64, FTW_DEPTH | FTW_PHYS);
- free(dpath);
- return ret;
-}
-#endif
-
-static void swupdate_cleanup(void)
-{
-#ifndef CONFIG_NOCLEANUP
- remove_directory(SCRIPTS_DIR_SUFFIX);
- remove_directory(DATADST_DIR_SUFFIX);
-#endif
-}
-
static void swupdate_init(struct swupdate_cfg *sw)
{
/* Initialize internal tree to store configuration */
@@ -303,15 +255,6 @@ static void swupdate_init(struct swupdate_cfg *sw)
LIST_INIT(&sw->extprocs);
sw->cert_purpose = SSL_PURPOSE_DEFAULT;
-
- /* Create directories for scripts */
- create_directory(SCRIPTS_DIR_SUFFIX);
- create_directory(DATADST_DIR_SUFFIX);
-
- if (atexit(swupdate_cleanup) != 0) {
- TRACE("Cannot setup SWUpdate cleanup on exit");
- }
-
#ifdef CONFIG_MTD
mtd_init();
ubi_init();
--
2.32.0