From: Karol Lewandowski Date: Tue, 12 Apr 2022 15:26:17 +0000 (+0200) Subject: block: properly detect internal/external storage when tizen is run from loop-mounted... X-Git-Tag: submit/tizen_6.5/20220414.114351^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2cdbae66ad4eb2e4f19bbe3a810d84cf0678b4e5;p=platform%2Fcore%2Fsystem%2Fstoraged.git block: properly detect internal/external storage when tizen is run from loop-mounted image For loop-mounted devices we have to check on which device the image file resides, and to treat this device as internal storage. Change-Id: I0c3e1b51e948963b2fdf0fc711539d11631f0110 (cherry picked from commit ad665e3acc10e3707309be2988a8ff14ac0bb2dd) --- diff --git a/packaging/storaged.spec b/packaging/storaged.spec index 2d3ad40..0b2a5c8 100644 --- a/packaging/storaged.spec +++ b/packaging/storaged.spec @@ -4,7 +4,7 @@ Name: storaged Summary: Storaged -Version: 1.0.0 +Version: 1.0.1 Release: 1 Group: System/Management License: Apache-2.0 diff --git a/src/block/block.c b/src/block/block.c index 9456604..5e51bab 100644 --- a/src/block/block.c +++ b/src/block/block.c @@ -61,6 +61,7 @@ #include "apps.h" #include "storaged_common.h" +#define LOOP_PATH "/dev/loop[0-9]*" #define MMC_PATH "*/mmcblk[0-9]*" #define MMC_PARTITION_PATH "mmcblk[0-9]p[0-9]*" /* Emulator send devlink for sdcard as \*\/sdcard\/\* */ @@ -2468,6 +2469,61 @@ out: dm_task_destroy(dmt); } +static char *loopdev_get_backing_file(int loop_id) +{ + char sysfile[96] = ""; + (void)snprintf(sysfile, sizeof(sysfile), "/sys/class/block/loop%d/loop/backing_file", loop_id); + + int fd = open(sysfile, O_RDONLY); + if (fd < 0) { + _W("Unable to read information about backing file for loop device %d: %m", loop_id); + return NULL; + } + + char line[PATH_MAX]; + int r = read(fd, line, sizeof line); + if (r < 0) { + _W("Unable to read from %s: %m", sysfile); + close(fd); + return NULL; + } + close(fd); // theoretically we could have one close after read (and not in if), but it would overwrite 'errno' + + char *p = malloc(r + 1); + if (!p) + return NULL; + + memcpy(p, line, r); + p[r] = '\0'; + + _D("Got backing file for loop device %d: %s", loop_id, p); + + return p; +} + +static char* trunc_one_pathlevel(char *path) +{ + int len = strlen(path); + if (len == 1) { + path[0] = '\0'; + return NULL; + } + + for (char *p = path; len > 0; len--) { + if (p[len] != '/') + continue; + p[len] = '\0'; + return path; + } + + if (strlen(path) > 0) { + path[1] = '\0'; + return path; + } + + return NULL; +} + static int get_internal_storage_number(void) { struct libmnt_table *t = NULL; @@ -2490,7 +2546,6 @@ static int get_internal_storage_number(void) for ( dev_i = 0; dev_i < DEV_INTERNAL_COUNT; dev_i++) { fs = mnt_table_find_target(t, dev_internal_list[dev_i], MNT_ITER_BACKWARD); - if (!fs) { mnt_free_table(t); return -EPERM; @@ -2502,6 +2557,31 @@ static int get_internal_storage_number(void) return -EPERM; } + /* Any of filesystems we look for could be on loop device. We have to check this case first + * as the loop file can be on any of the storage we check for below. + */ + if (!fnmatch(LOOP_PATH, temp, 0)) { + int num = atoi(temp + sizeof("/dev/loop") - 1 /* -1 for extra zero in string literal */); + _D("Found %s on loop device %s (loop id %d)", dev_internal_list[dev_i], temp, num); + + char *backingfile_path = loopdev_get_backing_file(num); + /* We have path to file from which image was mounted, but to find from which device it originates + * we have assume it might be mounted in any of directories the path points to, ie. + * with backing file in /var/images/tizen/foo.img, we have to check if /var/images/tizen, /var/images, /var, / + * are the mountpoints which contain the image. + */ + for (char *p = NULL; (p = trunc_one_pathlevel(backingfile_path)) != NULL;) { + fs = mnt_table_find_target(t, p, MNT_ITER_BACKWARD); + if (!fs) + continue; + const char *origtemp = temp; + temp = mnt_fs_get_srcpath(fs); + _I("%s is found under mountpoint %s on device %s (internal storage candidate)\n", origtemp, p, temp); + break; + } + free(backingfile_path); + } + name = strrchr(temp, '/'); if (!name) { mnt_free_table(t);