#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\/\* */
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;
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;
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);