handler: add a copy handler
diff mbox series

Message ID 20191014081044.12972-1-sbabic@denx.de
State Accepted
Headers show
Series
  • handler: add a copy handler
Related show

Commit Message

Stefano Babic Oct. 14, 2019, 8:10 a.m. UTC
This can be used for incrementing update. It performs a copy from
something (a device) before applying some other image.

Signed-off-by: Stefano Babic <sbabic@denx.de>
---
 handlers/raw_handler.c | 63 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

Patch
diff mbox series

diff --git a/handlers/raw_handler.c b/handlers/raw_handler.c
index 410ef94..ba87191 100644
--- a/handlers/raw_handler.c
+++ b/handlers/raw_handler.c
@@ -9,6 +9,9 @@ 
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+
 
 #include <unistd.h>
 #include <fcntl.h>
@@ -22,6 +25,7 @@ 
 
 void raw_image_handler(void);
 void raw_file_handler(void);
+void raw_copyimage_handler(void);
 
 static int install_raw_image(struct img_type *img,
 	void __attribute__ ((__unused__)) *data)
@@ -45,6 +49,58 @@  static int install_raw_image(struct img_type *img,
 	return ret;
 }
 
+static int copy_raw_image(struct img_type *img,
+	void __attribute__ ((__unused__)) *data)
+{
+	int ret;
+	int fdout, fdin;
+	struct dict_list *proplist;
+	struct dict_list_elem *entry;
+	uint32_t checksum;
+	unsigned long offset = 0;
+	size_t size;
+
+	proplist = dict_get_list(&img->properties, "copyfrom");
+
+	if (!proplist || !(entry = LIST_FIRST(proplist))) {
+		ERROR("MIssing source device, no copyfrom property");
+		return -EINVAL;
+	}
+	fdin = open(entry->value, O_RDONLY);
+	if (fdin < 0) {
+		TRACE("Device %s cannot be opened: %s",
+			entry->value, strerror(errno));
+		return -ENODEV;
+	}
+
+	if (ioctl(fdin, BLKGETSIZE64, &size) < 0) {
+		ERROR("Cannot get size of %s", entry->value);
+	}
+
+	fdout = open(img->device, O_RDWR);
+	if (fdout < 0) {
+		TRACE("Device %s cannot be opened: %s",
+			img->device, strerror(errno));
+		close(fdin);
+		return -ENODEV;
+	}
+
+	ret = copyfile(fdin,
+			&fdout,
+			size,
+			&offset,
+			0,
+			0, /* no skip */
+			0, /* no compressed */
+			&checksum,
+			0, /* no sha256 */
+			0, /* no encrypted */
+			NULL);
+
+	close(fdout);
+	return ret;
+}
+
 static int install_raw_file(struct img_type *img,
 	void __attribute__ ((__unused__)) *data)
 {
@@ -122,3 +178,10 @@  void raw_file_handler(void)
 	register_handler("rawfile", install_raw_file,
 				FILE_HANDLER, NULL);
 }
+
+__attribute__((constructor))
+void raw_copyimage_handler(void)
+{
+	register_handler("rawcopy", copy_raw_image,
+				IMAGE_HANDLER | NO_DATA_HANDLER, NULL);
+}