Recognize partition device name by blkid label 81/188081/5 accepted/tizen/unified/20180918.152300 submit/devel/20180917.094703 submit/tizen/20180917.095112
authorDongwoo Lee <dwoo08.lee@samsung.com>
Fri, 25 May 2018 00:15:30 +0000 (09:15 +0900)
committerDongwoo Lee <dwoo08.lee@samsung.com>
Wed, 12 Sep 2018 04:03:02 +0000 (13:03 +0900)
In certain case, target board can have different device name for
storage. So, static device name cannot be applicable for all cases.
This patch gets device name from blkid information within target
storage instead of static information in partition table.

Change-Id: I171fa8d5da79ea815b1acdef438908849a37861b
Signed-off-by: Dongwoo Lee <dwoo08.lee@samsung.com>
CMakeLists.txt
packaging/initrd-flash.spec
partition.info
src/dfu.c
src/dfu.h

index 8688aa1e8f40981414ec3968086d83893e0a8ae3..05e7c74fb92ca9df5dd4dd9c1cf2f17281acc55a 100644 (file)
@@ -8,7 +8,7 @@ ADD_EXECUTABLE(${PROJECT_NAME} src/main.c src/thor.c src/dfu.c src/net.c)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src)
 
 IF(CMAKE_THREAD_LIBS_INIT)
-       TARGET_LINK_LIBRARIES(flash-manager "${CMAKE_THREAD_LIBS_INIT}")
+       TARGET_LINK_LIBRARIES(flash-manager "${CMAKE_THREAD_LIBS_INIT}" blkid)
 ENDIF()
 
 ADD_DEFINITIONS(-Wall -g -O2)
index 79f61f197de0f436088e47382caaff96fb86042a..d36b5ceb68a4a75fe2ebdcf9874653aa5f66e137 100644 (file)
@@ -7,6 +7,7 @@ License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
 ExclusiveArch: %{arm}
 BuildRequires: cmake
+BuildRequires: libblkid-devel
 
 Requires: util-linux
 Requires: bash
index e97c17717abb75cce85e96679801cd5e437d519a..833f9c2e928298f2fcc5d869556ad337015afda9 100644 (file)
@@ -1,8 +1,8 @@
-p:boot.img:/dev/mmcblk0p1:x
-p:rootfs.img:/dev/mmcblk0p2:x
-p:system-data.img:/dev/mmcblk0p3:x
-p:user.img:/dev/mmcblk0p5:x
-p:modules.img:/dev/mmcblk0p6:x
-p:ramdisk.img:/dev/mmcblk0p7:x
-p:ramdisk-recovery.img:/dev/mmcblk0p8:x
-f:Image:/dev/mmcblk0p1:/
+p:BOOT:boot.img:x
+p:rootfs:rootfs.img:x
+p:system-data:system-data.img:x
+p:user:user.img:x
+p:modules:modules.img:x
+p:ramdisk:ramdisk.img:x
+p:ramdisk-recovery:ramdisk-recovery.img:x
+f:BOOT:Image:/
index 77e47a70fdd068a1d1086d91059f43c261763616..9beaf95d1888a1cf18fb18ab06fc1ef828b92d30 100644 (file)
--- a/src/dfu.c
+++ b/src/dfu.c
@@ -26,6 +26,7 @@
 #include <sys/fcntl.h>
 #include <sys/mount.h>
 #include <pthread.h>
+#include <blkid/blkid.h>
 
 #include "dfu.h"
 #include "thor-proto.h"
@@ -96,13 +97,13 @@ int dfu_request_io(struct tfm_context *ctx, unsigned long len)
        return 0;
 }
 
-static void mount_dev(const char *dev)
+static void mount_dev(const char *dev, const char *fstype)
 {
        int ret;
 
        mkdir(DFU_MOUNT_PATH,  0600);
 
-       ret = mount(dev, DFU_MOUNT_PATH, "ext4", 0, NULL);
+       ret = mount(dev, DFU_MOUNT_PATH, fstype, 0, NULL);
        if (ret < 0) {
                fprintf(stderr, "Failed to mount target partition\n");
                rmdir(DFU_MOUNT_PATH);
@@ -153,6 +154,85 @@ void dfu_sync(struct tfm_context *ctx)
        fprintf(stdout, "finished\n");
 }
 
+static char *get_partition_devname(const char *label)
+{
+       blkid_dev_iterate dev_iter;
+       blkid_tag_iterate tag_iter;
+       blkid_dev dev;
+       blkid_cache cache = NULL;
+       const char *type, *value;
+       int ret;
+
+       ret = blkid_get_cache(&cache, NULL);
+       if (ret < 0)
+               return NULL;
+
+       blkid_probe_all(cache);
+
+       dev_iter = blkid_dev_iterate_begin(cache);
+       blkid_dev_set_search(dev_iter, NULL, NULL);
+       while (blkid_dev_next(dev_iter, &dev) == 0) {
+               dev = blkid_verify(cache, dev);
+               if (!dev)
+                       continue;
+
+               tag_iter = blkid_tag_iterate_begin(dev);
+               while (blkid_tag_next(tag_iter, &type, &value) == 0) {
+                       if (!strncmp(type, "LABEL", 5) && !strncmp(value, label, strlen(label))) {
+                               char *devname = strdup(blkid_dev_devname(dev));
+
+                               blkid_tag_iterate_end(tag_iter);
+                               blkid_dev_iterate_end(dev_iter);
+                               blkid_put_cache(cache);
+                               return devname;
+                       }
+               }
+               blkid_tag_iterate_end(tag_iter);
+       }
+       blkid_dev_iterate_end(dev_iter);
+       blkid_put_cache(cache);
+
+       return NULL;
+}
+
+static char *get_partition_fstype(const char *devname)
+{
+       blkid_tag_iterate tag_iter;
+       blkid_dev dev;
+       blkid_cache cache = NULL;
+       const char *type, *value;
+       int ret;
+
+       ret = blkid_get_cache(&cache, NULL);
+       if (ret < 0)
+               return NULL;
+
+       blkid_probe_all(cache);
+
+       dev = blkid_get_dev(cache, devname, 0);
+       if (!dev)
+               return NULL;
+
+       dev = blkid_verify(cache, dev);
+       if (!dev)
+               return NULL;
+
+       tag_iter = blkid_tag_iterate_begin(dev);
+       while (blkid_tag_next(tag_iter, &type, &value) == 0) {
+               if (!strncmp(type, "TYPE", 4)) {
+                       char *fstype = strdup(value);
+
+                       blkid_tag_iterate_end(tag_iter);
+                       blkid_put_cache(cache);
+                       return fstype;
+               }
+       }
+       blkid_tag_iterate_end(tag_iter);
+       blkid_put_cache(cache);
+
+       return NULL;
+}
+
 static int dfu_start_entity(struct tfm_context *ctx, int idx, unsigned long size)
 {
        char **info = dfu_info[idx];
@@ -161,12 +241,44 @@ static int dfu_start_entity(struct tfm_context *ctx, int idx, unsigned long size
 
        switch (*info[DFU_INFO_MODE]) {
        case 'p':
-               file = info[DFU_INFO_DEV];
+               file = get_partition_devname(info[DFU_INFO_LABEL]);
+               if (!file) {
+                       fprintf(stderr, "failed to get partition devname: %s", info[DFU_INFO_LABEL]);
+                       return -EINVAL;
+               }
                break;
        case 'f':
-               mount_dev(info[DFU_INFO_DEV]);
-               file = info[DFU_INFO_PATH];
+       {
+               int path_prefix = strlen(DFU_MOUNT_PATH);
+               int path_suffix = strlen(info[DFU_INFO_PATH]);
+               int path_name = strlen(info[DFU_INFO_NAME]);
+               char *devname, *fstype;
+
+               devname = get_partition_devname(info[DFU_INFO_LABEL]);
+               if (!devname) {
+                       fprintf(stderr, "failed to get partition devname: %s", info[DFU_INFO_LABEL]);
+                       return -EINVAL;
+               }
+
+               fstype = get_partition_fstype(devname);
+               if (!fstype) {
+                       fprintf(stderr, "failed to get partition filesystem type: %s", devname);
+                       return -EINVAL;
+               }
+
+               mount_dev(devname, fstype);
+               free(devname);
+               free(fstype);
+
+               file = malloc(path_prefix + path_suffix + path_name + 1);
+               if (!file)
+                       return -ENOMEM;
+
+               strncpy(file, DFU_MOUNT_PATH, path_prefix + 1);
+               strncat(file, info[DFU_INFO_PATH], path_suffix);
+               strncat(file, info[DFU_INFO_NAME], path_name);
                break;
+       }
        default:
                fprintf(stderr, "flash entry '%s' has wrong mode\n", info[DFU_INFO_NAME]);
                return -EINVAL;
@@ -175,6 +287,7 @@ static int dfu_start_entity(struct tfm_context *ctx, int idx, unsigned long size
        fd = open(file, O_WRONLY);
        if (fd < 0) {
                fprintf(stderr, "cannot open target: %s\n", info[DFU_INFO_NAME]);
+               free(file);
                return -EIO;
        }
 
@@ -183,6 +296,8 @@ static int dfu_start_entity(struct tfm_context *ctx, int idx, unsigned long size
        ctx->dfu_info = info;
        ctx->transfer_done = 0;
 
+       free(file);
+
        return 0;
 }
 
index 7f86a51302080efb2f3373be886b57ce79f7c777..4138acf507b0a2f63db16d8a398b1e00aec526c2 100644 (file)
--- a/src/dfu.h
+++ b/src/dfu.h
@@ -26,8 +26,8 @@
 
 enum dfu_info_entry {
        DFU_INFO_MODE = 0,
+       DFU_INFO_LABEL,
        DFU_INFO_NAME,
-       DFU_INFO_DEV,
        DFU_INFO_PATH,
        DFU_INFO_MAX,
 };