* creates or updates mpp->paths reading mpp->pg
*/
extern int
-update_mpp_paths(struct multipath * mpp)
+update_mpp_paths(struct multipath * mpp, vector pathvec)
{
struct pathgroup * pgp;
struct path * pp;
vector_foreach_slot (mpp->pg, pgp, i) {
vector_foreach_slot (pgp->paths, pp, j) {
if (!find_path_by_devt(mpp->paths, pp->dev_t) &&
+ (find_path_by_devt(pathvec, pp->dev_t)) &&
store_path(mpp->paths, pp))
return 1;
}
if (!mpp)
return 0;
- if (update_mpp_paths(mpp))
+ if (update_mpp_paths(mpp, pathvec))
return 1;
vector_foreach_slot (pathvec, pp, i) {
if (!mpp)
return 0;
- update_mpp_paths(mpp);
+ update_mpp_paths(mpp, vecs->pathvec);
verify_paths(mpp, vecs, NULL);
if (!VECTOR_SIZE(mpp->paths))
if (mpp->action == ACT_RELOAD) {
condlog(0, "%s: uev_add_path sleep", mpp->alias);
sleep(1);
- update_mpp_paths(mpp);
+ update_mpp_paths(mpp, vecs->pathvec);
goto rescan;
}
else
{
struct multipath * mpp;
struct path * pp;
- int redo, i;
+ int i;
int rm_path = 1;
condlog(3, "%s: uev_remove_path", devname);
*/
if (pathcount(mpp, PATH_WILD) > 1) {
vector rpvec = vector_alloc();
- struct path * mypp;
- int j;
/*
* transform the mp->pg vector of vectors of paths
* into a mp->params string to feed the device-mapper
*/
- update_mpp_paths(mpp);
+ update_mpp_paths(mpp, vecs->pathvec);
if ((i = find_slot(mpp->paths, (void *)pp)) != -1)
vector_del_slot(mpp->paths, i);
-rescan:
- redo = verify_paths(mpp, vecs, rpvec);
if (VECTOR_SIZE(mpp->paths) == 0) {
char alias[WWID_SIZE];
* flush_map will fail if the device is open
*/
strncpy(alias, mpp->alias, WWID_SIZE);
- if (flush_map(mpp, vecs)) {
+ if (flush_map(mpp, vecs))
rm_path = 0;
- vector_foreach_slot(rpvec, mypp, i)
- if (store_path(mpp->paths, mypp))
- goto out;
- }
- else {
- vector_foreach_slot(rpvec, mypp, i) {
- if ((j = find_slot(vecs->pathvec,
- (void *)mypp)) != -1) {
- vector_del_slot(vecs->pathvec, j);
- free_path(mypp);
- }
- }
+ else
condlog(3, "%s: removed map after removing"
" multiple paths", alias);
- }
}
else {
- vector_foreach_slot(rpvec, mypp, i) {
- if ((j = find_slot(vecs->pathvec,
- (void *)mypp)) != -1) {
- vector_del_slot(vecs->pathvec, j);
- free_path(mypp);
- }
- }
-
if (setup_map(mpp)) {
condlog(0, "%s: failed to setup map for"
" removal of path %s", mpp->alias, devname);
"removal of path %s",
mpp->alias, devname);
/*
- * deal with asynchronous uevents :((
- */
- if (!redo) {
- condlog(3, "%s: uev_remove_path sleep",
- mpp->alias);
- sleep(1);
- }
- update_mpp_paths(mpp);
- free_pathvec(rpvec, KEEP_PATHS);
- rpvec = vector_alloc();
- goto rescan;
+ * Delete path from pathvec so that
+ * update_mpp_paths wont find it later
+ * when/if another path is removed.
+ */
+ if ((i = find_slot(vecs->pathvec, (void *)pp)) != -1)
+ vector_del_slot(vecs->pathvec, i);
+ free_path(pp);
+ return 1;
}
/*
* update our state from kernel
* flush_map will fail if the device is open
*/
strncpy(alias, mpp->alias, WWID_SIZE);
- if (flush_map(mpp, vecs)) {
+ if (flush_map(mpp, vecs))
rm_path = 0;
- }
else
condlog(3, "%s: removed map", alias);
}