diff mbox series

[V2] handler: rawcopy: fixes and run on scope if set

Message ID 20220401211907.1996224-1-sbabic@denx.de
State Accepted
Headers show
Series [V2] handler: rawcopy: fixes and run on scope if set | expand

Commit Message

Stefano Babic April 1, 2022, 9:19 p.m. UTC
The script type (pre or postinstall) was ignored. Evaluate it and skip
the handler if the scope does not match.

Fix retrieving the size in case the source is not a block device, and
add a couple of debug information.

Signed-off-by: Stefano Babic <sbabic@denx.de>
---

Changes since V1:

	- switch to new structure for data pointer

 doc/source/handlers.rst | 13 ++++++++-----
 handlers/raw_handler.c  | 41 +++++++++++++++++++++++++++++++++++++----
 2 files changed, 45 insertions(+), 9 deletions(-)
diff mbox series

Patch

diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst
index 81945e6..8d2aeea 100644
--- a/doc/source/handlers.rst
+++ b/doc/source/handlers.rst
@@ -780,11 +780,12 @@  Properties ``size`` and ``offset`` are optional, all the other properties are ma
 Rawcopy handler
 ---------------
 
-The rawcopy handler copies one source to a destination. It can be used to copy configuration data,
-or parts that should be taken by the current installation. It requires just one property (`copyfrom`), while
-device contains the destination path. The handler performs a byte copy, and it does not matter which is
-the source - it can be a file or a partition.
-
+The rawcopy handler copies one source to a destination. It is a script handler, and no artifact in the SWU is associated
+with the handler.  It can be used to copy configuration data, or parts that should be taken by the current installation.
+It requires the mandatory  property (`copyfrom`), while device contains the destination path. 
+The handler performs a byte copy, and it does not matter which is the source - it can be a file or a partition.
+An optional `type` field can set if the handler is active as pre or postinstall script. If not set, the handler
+is called twice.
 
 ::
 
@@ -794,9 +795,11 @@  the source - it can be a file or a partition.
                 type = "rawcopy";
                 properties : {
                         copyfrom = "/dev/mmcblk2p2";
+                        type = "postinstall";
                 }
         }
 
+
 Archive handler
 ---------------
 
diff --git a/handlers/raw_handler.c b/handlers/raw_handler.c
index 2dba412..9c2cf5a 100644
--- a/handlers/raw_handler.c
+++ b/handlers/raw_handler.c
@@ -9,6 +9,7 @@ 
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <unistd.h>
 #include <sys/ioctl.h>
 #ifdef __FreeBSD__
 #include <sys/disk.h>
@@ -149,8 +150,7 @@  static int install_raw_image(struct img_type *img,
 	return ret;
 }
 
-static int copy_raw_image(struct img_type *img,
-	void __attribute__ ((__unused__)) *data)
+static int copy_raw_image(struct img_type *img, void *data)
 {
 	int ret;
 	int fdout, fdin;
@@ -159,6 +159,30 @@  static int copy_raw_image(struct img_type *img,
 	uint32_t checksum;
 	unsigned long offset = 0;
 	size_t size;
+	struct stat statbuf;
+	struct script_handler_data *script_data;
+
+	if (!data)
+		return -1;
+
+	script_data = data;
+
+	proplist = dict_get_list(&img->properties, "type");
+	if (proplist) {
+		entry = LIST_FIRST(proplist);
+		/* check if this should just run as pre or post install */
+		if (entry) {
+			if (strcmp(entry->value, "preinstall") && strcmp(entry->value, "postinstall")) {
+				ERROR("Type can be just preinstall or postinstall");
+				return -EINVAL;
+			}
+			script_fn type = !strcmp(entry->value, "preinstall") ? PREINSTALL : POSTINSTALL;
+			if (type != script_data->scriptfn) {
+				TRACE("Script set to %s, skipping", entry->value);
+				return 0;
+			}
+		}
+	}
 
 	proplist = dict_get_list(&img->properties, "copyfrom");
 
@@ -168,13 +192,21 @@  static int copy_raw_image(struct img_type *img,
 	}
 	fdin = open(entry->value, O_RDONLY);
 	if (fdin < 0) {
-		TRACE("Device %s cannot be opened: %s",
+		ERROR("Device %s cannot be opened: %s",
 			entry->value, strerror(errno));
 		return -ENODEV;
 	}
 
-	if (ioctl(fdin, BLKGETSIZE64, &size) < 0) {
+	ret = fstat(fdin, &statbuf);
+	if (ret < 0) {
+		ERROR("Cannot be retrieved information on %s", entry->value);
+		return -ENODEV;
+	}
+	if ((statbuf.st_mode & S_IFMT) == S_IFREG)
+		size = statbuf.st_size;
+	else if (ioctl(fdin, BLKGETSIZE64, &size) < 0) {
 		ERROR("Cannot get size of %s", entry->value);
+		return -ENODEV;
 	}
 
 	fdout = open(img->device, O_RDWR);
@@ -185,6 +217,7 @@  static int copy_raw_image(struct img_type *img,
 		return -ENODEV;
 	}
 
+	TRACE("Copying %s to %s", entry->value, img->device);
 	ret = copyfile(fdin,
 			&fdout,
 			size,