From 17dd99f36885543b6ca68824eaba59b824e66b57 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Fri, 20 Sep 2013 18:12:28 +0200 Subject: local: Fix searching for MyDocs mmc device Device name in /sys/block/ could not be same as in /dev/ if udev renaming it. And this is real problem on Maemo without special kernel patch when device booting with inserted SD card. So read major and minor numbers from /sys/ and find coresponding device in /dev/. These two numbers will be same after renaming device too. --- src/local.c | 82 ++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 22 deletions(-) (limited to 'src/local.c') diff --git a/src/local.c b/src/local.c index 18534fc..290fba5 100644 --- a/src/local.c +++ b/src/local.c @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -290,10 +291,11 @@ int local_dump_image(enum image_type image, const char * file) { int align; DIR * dir; DIR * dir2; + FILE * f; struct dirent * dirent; struct dirent * dirent2; - char * ptr; - int i; + struct stat st; + int maj, min; char buf[1024]; char blk[1024]; @@ -301,16 +303,17 @@ int local_dump_image(enum image_type image, const char * file) { if ( image == IMAGE_MMC ) { + maj = -1; + min = -1; + /* Find block device in /dev/ for MyDocs (mmc device, partition 1) */ dir = opendir("/sys/class/mmc_host/"); if ( ! dir ) { - ERROR("Cannot find MyDocs mmc device"); + ERROR("Cannot find MyDocs mmc device: Opening '/sys/class/mmc_host/' failed"); goto clean; } - blk[0] = 0; - while ( ( dirent = readdir(dir) ) ) { snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/slot_name", dirent->d_name); @@ -327,7 +330,7 @@ int local_dump_image(enum image_type image, const char * file) { if ( strncmp(buf, "internal", strlen("internal")) != 0 ) continue; - snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001", dirent->d_name, dirent->d_name); + snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/", dirent->d_name, dirent->d_name); dir2 = opendir(buf); if ( ! dir2 ) @@ -338,44 +341,79 @@ int local_dump_image(enum image_type image, const char * file) { if ( strncmp(dirent2->d_name, "block:mmcblk", strlen("block:mmcblk")) != 0 ) continue; - snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/%s", dirent->d_name, dirent->d_name, dirent2->d_name); + snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/%s/dev", dirent->d_name, dirent->d_name, dirent2->d_name); - blk[0] = 0; - if ( readlink(buf, blk, sizeof(blk)) < 0 ) + f = fopen(buf, "r"); + if ( ! f ) continue; - ptr = strrchr(blk, '/'); - if ( ! ptr ) { - blk[0] = 0; + if ( fscanf(f, "%d:%d", &maj, &min) != 2 ) { + maj = -1; + min = -1; + fclose(f); continue; } - strcpy(blk, "/dev/"); - i = strlen("/dev/"); - ++ptr; - - while ( *ptr ) - blk[i++] = *(ptr++); - - strcpy(blk+i, "p1"); + fclose(f); break; } closedir(dir2); - if ( blk[0] ) + if ( maj != -1 && min != -1 ) break; } closedir(dir); + if ( maj == -1 || min == -1 ) { + ERROR("Cannot find MyDocs mmc device: Slot 'internal' was not found"); + goto clean; + } + + VERBOSE("Detected internal mmc device: major=%d minor=%d\n", maj, min); + + blk[0] = 0; + + dir = opendir("/dev/"); + if ( ! dir ) { + ERROR("Cannot find MyDocs mmc device: Opening '/dev/' failed"); + goto clean; + } + + while ( ( dirent = readdir(dir) ) ) { + + snprintf(buf, sizeof(buf), "/dev/%s", dirent->d_name); + + if ( stat(buf, &st) != 0 ) + continue; + + if ( ! S_ISBLK(st.st_mode) ) + continue; + + if ( makedev(maj, min) != st.st_rdev ) + continue; + + strcpy(blk, buf); + break; + + } + + closedir(dir); + if ( ! blk[0] ) { - ERROR("Cannot find MyDocs mmc device"); + ERROR("Cannot find MyDocs mmc device: Block device in /dev/ was not found"); goto clean; } + VERBOSE("Detected internal mmc device: '%s'\n", blk); + + strncat(blk, "p1", sizeof(blk)); + + printf("Using MyDocs mmc device: '%s'\n", blk); + ret = disk_dump_raw(blk, file); } else { -- cgit v1.2.3