Index: multipath-tools-0.4.8/libmultipath/devmapper.c =================================================================== --- multipath-tools-0.4.8.orig/libmultipath/devmapper.c +++ multipath-tools-0.4.8/libmultipath/devmapper.c @@ -912,6 +912,60 @@ bad: return NULL; } +dm_get_full_uuid(char *name, char *uuid) +{ + struct dm_task *dmt; + const char *uuidtmp; + int r = 1; + + dmt = dm_task_create(DM_DEVICE_INFO); + if (!dmt) + return 1; + + if (!dm_task_set_name (dmt, name)) + goto uuidout; + + if (!dm_task_run(dmt)) + goto uuidout; + + uuidtmp = dm_task_get_uuid(dmt); + if (uuidtmp) { + strcpy(uuid, uuidtmp); + } + else + uuid[0] = '\0'; + + r = 0; +uuidout: + dm_task_destroy(dmt); + return r; +} + +/* + * returns: + * 0 : if both uuids end with same suffix which starts with UUID_PREFIX + * 1 : otherwise + */ +int +dm_compare_uuid(const char* mapname1, const char* mapname2) +{ + char *p1, *p2; + char uuid1[WWID_SIZE], uuid2[WWID_SIZE]; + + if (dm_get_full_uuid(mapname1, uuid1)) + return 1; + + if (dm_get_full_uuid(mapname2, uuid2)) + return 1; + + p1 = strstr(uuid1, UUID_PREFIX); + p2 = strstr(uuid2, UUID_PREFIX); + if (p1 && p2 && !strcmp(p1, p2)) + return 0; + + return 1; +} + int dm_remove_partmaps (const char * mapname) { @@ -950,15 +1004,10 @@ dm_remove_partmaps (const char * mapname (dm_type(names->name, TGT_PART) > 0) && /* - * and the multipath mapname and the part mapname start - * the same + * and the both uuid end with same suffix which + * starts with UUID_PREFIX */ - !strncmp(names->name, mapname, strlen(mapname)) && - - /* - * and the opencount is 0 for us to allow removal - */ - !dm_get_opencount(names->name) && + !dm_compare_uuid(names->name, mapname) && /* * and we can fetch the map table from the kernel @@ -974,6 +1023,19 @@ dm_remove_partmaps (const char * mapname * then it's a kpartx generated partition. * remove it. */ + + /* + * if the opencount is not 0, maybe some other + * partitons depend on it. + */ + if (dm_get_opencount(names->name)) { + dm_remove_partmaps(names->name); + if (dm_get_opencount(names->name)) { + condlog(2, "%s: map in use", names->name); + goto out; + } + } + condlog(4, "partition map %s removed", names->name); dm_simplecmd_flush(DM_DEVICE_REMOVE, names->name);