From d5bdff6092a60b8211840ce9db1637dd38b362b1 Mon Sep 17 00:00:00 2001 From: Anton Fedorov Date: Thu, 29 Mar 2012 22:25:38 +0700 Subject: [PATCH] Use sysfs to detect correct device parent name. --- ptmax.c | 58 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/ptmax.c b/ptmax.c index d6e1d7b..4c35364 100644 --- a/ptmax.c +++ b/ptmax.c @@ -12,7 +12,6 @@ * */ - #define _GNU_SOURCE #include #include @@ -152,19 +151,50 @@ void print_pt() char* get_parent(const char* path) { -/*we supports only for pirmary partitions, feel free to add more*/ - int l=strlen(path)-1; - char *newpath; - if (path[l]<'1' || path[l] >'4') - return NULL; - // For /dev/cciss/c0d0p0 we should cut "p0", not only "0" - if (strstr(path, "/cciss/")!=NULL && path[l-1]=='p') - l--; - newpath=malloc(l); - assert(newpath); - memcpy(newpath,path,l); - return newpath; - + /* try to find parent device name via sysfs */ + if (strstr(path, "/dev/")==path) { + int len=strlen(path)-5; + char name[PATH_MAX] = "/sys/class/block/"; + char *t; + const char *p; + for(t = name+strlen(name), p = path+5; *p; p++,t++) { + if(*p == '/') *t = '!'; + else *t = *p; + } + if(readlink(name, name, sizeof(name))>0) { + char *suf = name+strlen(name); + while(suf>=name && *suf != '/') suf--; + if(suf > name) { + char *end = suf--; + while(suf>=name && *suf != '/') suf--; + if(suf > name) { + char * newpath = malloc(5/*"/dev/"*/+(end-suf)+1); + strcpy(newpath, "/dev/"); + for(t=newpath+5/*"/dev/"*/, suf++; *suf && *suf!='/'; suf++,t++) { + if(*suf == '!') *t = '/'; + else *t = *suf; + } + *t = 0; + return newpath; + } + } + } + } + /* else try to find parent device using guess */ + { + /*we supports only for pirmary partitions, feel free to add more*/ + int l=strlen(path)-1; + char *newpath; + if (path[l]<'1' || path[l] >'4') + return NULL; + // For /dev/cciss/c0d0p0 we should cut "p0", not only "0" + if (strstr(path, "/cciss/")!=NULL && path[l-1]=='p') + l--; + newpath=malloc(l); + assert(newpath); + memcpy(newpath,path,l); + return newpath; + } } int is_valid(int num)