multipath: make devt2devname use lstat to check sysfs links
Benjamin Marzinski
maintainerPATCH v2 1/1 multipath: make devt2devname use lstat to check sysfs links
dm_reassign wasn't working correctly for me because devt2devname used stat() to check if /sys/dev/block/major:minor was a symlink. But stat() never returns a symlink, if follows it. It needs to use lstat() instead. Also, I made multipath log a message when a dm device gets reassigned to use multipath.
Signed-off-by Benjamin Marzinski <[email protected]>
--- libmultipath/devmapper.c | 4 +++- libmultipath/sysfs.c | 6 ++++-- libmultipath/util.c | 3 ++- 3 files changed, 9 insertions(+), 4 deletions(-)
libmultipath/devmapper.c +3 -1
@@ -1394,8 +1394,10 @@ int dm_reassign(const char *mapname)return 1 ; } -if (!(dmt =dm_task_create (DM_DEVICE_DEPS ))) +if (!(dmt =dm_task_create (DM_DEVICE_DEPS ))) { +condlog (3 ,"%s: couldn't make dm task" , mapname);return 0 ; + }if (!dm_task_set_name (dmt, mapname)) goto out;
libmultipath/sysfs.c +4 -2
@@ -125,8 +125,10 @@ int sysfs_check_holders(char * check_devreturn 0 ; } -if (devt2devname (check_dev,PATH_SIZE , check_devt)) +if (devt2devname (check_dev,PATH_SIZE , check_devt)) { +condlog (1 ,"can't get devname for %s" , check_devt);return 0 ; + }condlog (3 ,"%s: checking holder" , check_dev);
@@ -153,7 +155,7 @@ int sysfs_check_holders(char * check_dev } table_name =dm_mapname (major, table_minor); -condlog (3 ,"%s: reassign table %s old %s new %s" , check_dev, +condlog (0 ,"%s: reassign table %s old %s new %s" , check_dev, table_name, check_devt, new_devt);dm_reassign_table (table_name, check_devt, new_devt);
libmultipath/util.c +2 -1
@@ -161,6 +161,7 @@ devt2devname (char *devname, int devnamestruct stat statbuf;memset (block_path,0 ,sizeof (block_path)); +memset (dev,0 ,sizeof (dev));if (sscanf (devt,"%u:%u" , &major, &minor) !=2 ) {condlog (0 ,"Invalid device number %s" , devt);return 1 ;
@@ -172,7 +173,7 @@ devt2devname (char *devname, int devnameif (stat ("/sys/dev/block" , &statbuf) ==0 ) {/* Newer kernels have /sys/dev/block */ sprintf (block_path,"/sys/dev/block/%u:%u" , major, minor); -if (stat (block_path, &statbuf) ==0 ) { +if (lstat (block_path, &statbuf) ==0 ) {if (S_ISLNK (statbuf.st_mode) &&readlink (block_path, dev,FILE_NAME_SIZE ) >0 ) {char *p =strrchr (dev,'/' );
Quoted 6 lines · Benjamin Marzinski
dm_reassignwasn't working correctly for me because devt2devname usedstat()to check if /sys/dev/block/major:minor was a symlink. Butstat()never returns a symlink, if follows it. It needs to uselstat()instead. Also, I made multipath log a message when a dm device gets reassigned to use multipath.Signed-off-by Benjamin Marzinski <[email protected]>
Acked-by Hannes Reinecke <[email protected]>
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)