diff mbox series

raw handler: Unmount target device when installing a file fails

Message ID PAWP192MB2128FB78B7ADECCAC19182EDC3489@PAWP192MB2128.EURP192.PROD.OUTLOOK.COM
State Accepted
Headers show
Series raw handler: Unmount target device when installing a file fails | expand

Commit Message

Sava Jakovljev May 31, 2023, 9:44 p.m. UTC
From: Sava Jakovljev <savaj@meyersound.com>

* Make sure to call 'swupdate_umount' in every scenario in
  'install_raw_file' function - this patch thus solves
  problems when an update fails on installing a file, and next update
  cannot be done because 'swupdate_mount' function fails with message
  "already mounted" because the  mount is still there from the previous
  attempt.
---
 handlers/raw_handler.c | 45 +++++++++++++++++++++++++++---------------
 1 file changed, 29 insertions(+), 16 deletions(-)

Comments

Fabio Estevam May 31, 2023, 10:47 p.m. UTC | #1
Hi Sava,

On Wed, May 31, 2023 at 6:44 PM Sava Jakovljev <sjakovljev@outlook.com> wrote:
>
> From: Sava Jakovljev <savaj@meyersound.com>
>
> * Make sure to call 'swupdate_umount' in every scenario in
>   'install_raw_file' function - this patch thus solves
>   problems when an update fails on installing a file, and next update
>   cannot be done because 'swupdate_mount' function fails with message
>   "already mounted" because the  mount is still there from the previous
>   attempt.

Please add your Signed-off-by tag, thanks.
diff mbox series

Patch

diff --git a/handlers/raw_handler.c b/handlers/raw_handler.c
index 45f038a..02de03e 100644
--- a/handlers/raw_handler.c
+++ b/handlers/raw_handler.c
@@ -153,7 +153,7 @@  static int install_raw_file(struct img_type *img,
 	char path[255];
 	char tmp_path[255];
 	int fdout;
-	int ret = 0;
+	int ret = -1;
 	int use_mount = (strlen(img->device) && strlen(img->filesystem)) ? 1 : 0;
 	char* DATADST_DIR = alloca(strlen(get_tmpdir())+strlen(DATADST_DIR_SUFFIX)+1);
 	sprintf(DATADST_DIR, "%s%s", get_tmpdir(), DATADST_DIR_SUFFIX);
@@ -174,7 +174,7 @@  static int install_raw_file(struct img_type *img,
 		if (snprintf(path, sizeof(path), "%s%s",
 					 DATADST_DIR, img->path) >= (int)sizeof(path)) {
 			ERROR("Path too long: %s%s", DATADST_DIR, img->path);
-			return -1;
+			goto cleanup;
 		}
 	} else {
 		if (snprintf(path, sizeof(path), "%s", img->path) >= (int)sizeof(path)) {
@@ -186,7 +186,8 @@  static int install_raw_file(struct img_type *img,
 	if (strtobool(dict_get_value(&img->properties, "atomic-install"))) {
 		if (snprintf(tmp_path, sizeof(tmp_path), "%s.tmp", path) >= (int)sizeof(tmp_path)) {
 			ERROR("Temp path too long: %s.tmp", img->path);
-			return -1;
+			ret = -1;
+			goto cleanup;
 		}
 	}
 	else {
@@ -196,43 +197,55 @@  static int install_raw_file(struct img_type *img,
 
 	if (strtobool(dict_get_value(&img->properties, "create-destination"))) {
 		TRACE("Creating path %s", path);
-		fdout = mkpath(dirname(strdupa(path)), 0755);
-		if (fdout < 0) {
+		ret = mkpath(dirname(strdupa(path)), 0755);
+		if (ret < 0) {
 			ERROR("I cannot create path %s: %s", path, strerror(errno));
-			return -1;
+			goto cleanup;
 		}
 	}
 
 	fdout = openfileoutput(tmp_path);
-	if (fdout < 0)
-		return fdout;
+	if (fdout < 0) {
+		ret = -1;
+		goto cleanup;
+	}
 	if (!img_check_free_space(img, fdout)) {
-		return -ENOSPC;
+		ret = -ENOSPC;
+		goto cleanup;
 	}
 
 	ret = copyimage(&fdout, img, NULL);
-	if (ret< 0) {
+	if (ret < 0) {
 		ERROR("Error copying extracted file");
+		goto cleanup;
 	}
 
-	if(fsync(fdout)) {
+	if (fsync(fdout)) {
 		ERROR("Error writing %s to disk: %s", tmp_path, strerror(errno));
-		return -1;
+		ret = -1;
+		goto cleanup;
 	}
 
 	close(fdout);
+	fdout = 0;
 
 	if (strtobool(dict_get_value(&img->properties, "atomic-install"))) {
 		TRACE("Renaming file %s to %s", tmp_path, path);
-		if(rename(tmp_path, path)) {
+		if (rename(tmp_path, path)) {
 			ERROR("Error renaming %s to %s: %s", tmp_path, path, strerror(errno));
-			return -1;
+			ret = -1;
+			goto cleanup;
 		}
 	}
 
-	if (use_mount) {
+	ret = 0;
+
+cleanup:
+	if (fdout > 0)
+		close(fdout);
+
+	if (use_mount)
 		swupdate_umount(DATADST_DIR);
-	}
 
 	return ret;
 }