Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multipath-tools 0.11.1 #110

Merged
merged 9 commits into from
Feb 10, 2025
2 changes: 2 additions & 0 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ata
autoconfig
autodetected
autoresize
backported
barbie
BINDIR
blkid
Expand Down Expand Up @@ -123,6 +124,7 @@ Lun
lvm
lvmteam
Marzinski
misdetection
mpath
mpathb
mpathpersist
Expand Down
16 changes: 12 additions & 4 deletions .github/workflows/abi-stable.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ on:

jobs:
reference-abi:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: get parent tag
run: >
echo ${{ github.ref }} |
sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV
if: ${{ github.event_name == 'push' }}
- name: get parent tag
run: echo PARENT_TAG=${{ github.base_ref }} >> $GITHUB_ENV
if: ${{ github.event_name == 'pull_request' }}
- name: assert parent tag
run: /bin/false
if: ${{ env.PARENT_TAG == '' }}
Expand All @@ -45,20 +49,24 @@ jobs:
path: abi

check-abi:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
needs: reference-abi
steps:
- name: get parent tag
run: >
echo ${{ github.ref }} |
sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV
if: ${{ github.event_name == 'push' }}
- name: get parent tag
run: echo PARENT_TAG=${{ github.base_ref }} >> $GITHUB_ENV
if: ${{ github.event_name == 'pull_request' }}
- name: assert parent tag
run: /bin/false
if: ${{ env.PARENT_TAG == '' }}
- name: checkout ${{ env.PARENT_TAG }}
- name: checkout ${{ github.base_ref }}
uses: actions/checkout@v4
with:
ref: ${{ env.PARENT_TAG }}
ref: ${{ github.base_ref }}
- name: download ABI for ${{ env.PARENT_TAG }}
id: download_abi
uses: actions/download-artifact@v4
Expand Down
21 changes: 21 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,27 @@ release. These bug fixes will be tracked in stable branches.

See [README.md](README.md) for additional information.

## multipath-tools 0.11.1, 2025/02

This release contains backported bug fixes from the master branch up to 0.12.

### Bug fixes

* Fix multipathd crash because of invalid path group index value, for example
if an invalid path device was removed from a map.
Fixes [#105](https://github.com/opensvc/multipath-tools/issues/105).
* Make sure maps are reloaded in the path checker loop after detecting an
inconsistent or wrong kernel state (e.g. missing or falsely mapped path
device). Wrongly mapped paths will be unmapped and released to the system.
Fixes another issue reported in
[#105](https://github.com/opensvc/multipath-tools/issues/105).
* Fix the problem that `group_by_tpg` might be disabled if one or more
paths were offline during initial configuration.
* Fix possible misdetection of changed pathgroups in a map.
* Fix the problem that if a map was scheduled to be reloaded already,
`max_sectors_kb` might not be set on a path device that
was being added to a multipath map. This problem was introduced in 0.9.9.

## multipath-tools 0.11.0, 2024/11

### User-visible changes
Expand Down
29 changes: 22 additions & 7 deletions libmultipath/configure.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,23 +426,37 @@ compute_pgid(struct pathgroup * pgp)
pgp->id ^= (long)pp;
}

static void cleanup_bitfield(struct bitfield **p)
{
free(*p);
}

static int
pgcmp (struct multipath * mpp, struct multipath * cmpp)
{
int i, j;
struct pathgroup * pgp;
struct pathgroup * cpgp;
int r = 0;
struct bitfield *bf __attribute__((cleanup(cleanup_bitfield))) = NULL;

if (!mpp)
return 0;

if (VECTOR_SIZE(mpp->pg) != VECTOR_SIZE(cmpp->pg))
return 1;

bf = alloc_bitfield(VECTOR_SIZE(cmpp->pg));
if (!bf)
return 1;

vector_foreach_slot (mpp->pg, pgp, i) {
compute_pgid(pgp);

vector_foreach_slot (cmpp->pg, cpgp, j) {
if (pgp->id == cpgp->id &&
!pathcmp(pgp, cpgp)) {
set_bit_in_bitfield(j, bf);
r = 0;
break;
}
Expand All @@ -451,6 +465,10 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp)
if (r)
return r;
}
vector_foreach_slot (cmpp->pg, cpgp, j) {
if (!is_bit_set_in_bitfield(j, bf))
return 1;
}
return r;
}

Expand Down Expand Up @@ -563,8 +581,6 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath)
vector_foreach_slot(pgp->paths, pp, j)
trigger_path_udev_change(pp, is_mpath);
}

mpp->needs_paths_uevent = 0;
}

static int sysfs_set_max_sectors_kb(struct multipath *mpp)
Expand Down Expand Up @@ -955,10 +971,10 @@ int domap(struct multipath *mpp, char *params, int is_daemon)
* succeeded
*/
mpp->force_udev_reload = 0;
if (mpp->action == ACT_CREATE &&
(remember_wwid(mpp->wwid) == 1 ||
mpp->needs_paths_uevent))
if (mpp->action == ACT_CREATE) {
remember_wwid(mpp->wwid);
trigger_paths_udev_change(mpp, true);
}
if (!is_daemon) {
/* multipath client mode */
dm_switchgroup(mpp->alias, mpp->bestpg);
Expand All @@ -983,8 +999,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon)
}
dm_setgeometry(mpp);
return DOMAP_OK;
} else if (r == DOMAP_FAIL && mpp->action == ACT_CREATE &&
mpp->needs_paths_uevent)
} else if (r == DOMAP_FAIL && mpp->action == ACT_CREATE)
trigger_paths_udev_change(mpp, false);

return DOMAP_FAIL;
Expand Down
9 changes: 3 additions & 6 deletions libmultipath/devmapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ static uint16_t build_udev_flags(const struct multipath *mpp, int reload)
MPATH_UDEV_RELOAD_FLAG : 0);
}

int dm_addmap_create (struct multipath *mpp, char * params)
int dm_addmap_create (struct multipath *mpp, char *params)
{
int ro;
uint16_t udev_flags = build_udev_flags(mpp, 0);
Expand All @@ -547,9 +547,7 @@ int dm_addmap_create (struct multipath *mpp, char * params)

if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, ro,
udev_flags)) {
if (unmark_failed_wwid(mpp->wwid) ==
WWID_FAILED_CHANGED)
mpp->needs_paths_uevent = 1;
unmark_failed_wwid(mpp->wwid);
return 1;
}
/*
Expand All @@ -570,8 +568,7 @@ int dm_addmap_create (struct multipath *mpp, char * params)
break;
}
}
if (mark_failed_wwid(mpp->wwid) == WWID_FAILED_CHANGED)
mpp->needs_paths_uevent = 1;
mark_failed_wwid(mpp->wwid);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion libmultipath/foreign.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ static void free_pre(void *arg)
static int _init_foreign(const char *enable)
{
char pathbuf[PATH_MAX];
struct dirent **di;
struct dirent **di = NULL;
struct scandir_result sr;
int r, i;
regex_t *enable_re = NULL;
Expand Down
6 changes: 6 additions & 0 deletions libmultipath/pgpolicies.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ split_marginal_paths(vector paths, vector *normal_p, vector *marginal_p)
int group_paths(struct multipath *mp, int marginal_pathgroups)
{
vector normal, marginal;
struct path *pp;
int i;

if (!mp->pg)
mp->pg = vector_alloc();
Expand All @@ -138,6 +140,10 @@ int group_paths(struct multipath *mp, int marginal_pathgroups)
if (!mp->pgpolicyfn)
goto fail;

/* Reset pgindex, we're going to invalidate it */
vector_foreach_slot(mp->paths, pp, i)
pp->pgindex = 0;

if (!marginal_pathgroups ||
split_marginal_paths(mp->paths, &normal, &marginal) != 0) {
if (mp->pgpolicyfn(mp, mp->paths) != 0)
Expand Down
6 changes: 5 additions & 1 deletion libmultipath/propsel.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,14 +255,18 @@ verify_alua_prio(struct multipath *mp)
{
int i;
struct path *pp;
bool assume_alua = false;

vector_foreach_slot(mp->paths, pp, i) {
const char *name = prio_name(&pp->prio);
if (!prio_selected(&pp->prio))
continue;
if (strncmp(name, PRIO_ALUA, PRIO_NAME_LEN) &&
strncmp(name, PRIO_SYSFS, PRIO_NAME_LEN))
return false;
assume_alua = true;
}
return true;
return assume_alua;
}

int select_detect_pgpolicy(struct config *conf, struct multipath *mp)
Expand Down
12 changes: 11 additions & 1 deletion libmultipath/structs.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,18 @@ free_pgvec (vector pgvec, enum free_path_mode free_paths)
if (!pgvec)
return;

vector_foreach_slot(pgvec, pgp, i)
vector_foreach_slot(pgvec, pgp, i) {

/* paths are going to be re-grouped, reset pgindex */
if (free_paths != FREE_PATHS) {
struct path *pp;
int j;

vector_foreach_slot(pgp->paths, pp, j)
pp->pgindex = 0;
}
free_pathgroup(pgp, free_paths);
}

vector_free(pgvec);
}
Expand Down
18 changes: 16 additions & 2 deletions libmultipath/structs_vec.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp,
struct config *conf;
bool mpp_has_wwid;
bool must_reload = false;
bool pg_deleted = false;

if (!mpp->pg)
return false;
Expand All @@ -125,6 +126,10 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp,

vector_foreach_slot(pgp->paths, pp, j) {

/* A pathgroup has been deleted before. Invalidate pgindex */
if (pg_deleted)
pp->pgindex = 0;

if (pp->mpp && pp->mpp != mpp) {
condlog(0, "BUG: %s: found path %s which is already in %s",
mpp->alias, pp->dev, pp->mpp->alias);
Expand All @@ -139,6 +144,13 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp,
must_reload = true;
dm_fail_path(mpp->alias, pp->dev_t);
vector_del_slot(pgp->paths, j--);
/*
* pp->pgindex has been set in disassemble_map(),
* which has probably been called just before for
* mpp. So he pgindex relates to mpp and may be
* wrong for pp->mpp. Invalidate it.
*/
pp->pgindex = 0;
continue;
}
pp->mpp = mpp;
Expand Down Expand Up @@ -237,6 +249,8 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp,
vector_del_slot(mpp->pg, i--);
free_pathgroup(pgp, KEEP_PATHS);
must_reload = true;
/* Invalidate pgindex for all other pathgroups */
pg_deleted = true;
}
mpp->need_reload = mpp->need_reload || must_reload;
return must_reload;
Expand Down Expand Up @@ -335,8 +349,7 @@ int adopt_paths(vector pathvec, struct multipath *mpp,
*/
if (!current_mpp ||
!mp_find_path_by_devt(current_mpp, pp->dev_t))
mpp->need_reload = mpp->need_reload ||
set_path_max_sectors_kb(pp, mpp->max_sectors_kb);
mpp->need_reload = set_path_max_sectors_kb(pp, mpp->max_sectors_kb) || mpp->need_reload;
}

pp->mpp = mpp;
Expand All @@ -354,6 +367,7 @@ void orphan_path(struct path *pp, const char *reason)
{
condlog(3, "%s: orphan path, %s", pp->dev, reason);
pp->mpp = NULL;
pp->pgindex = 0;
uninitialize_path(pp);
}

Expand Down
4 changes: 3 additions & 1 deletion multipathd/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,8 +794,10 @@ coalesce_maps(struct vectors *vecs, vector nmpv)
vector_del_slot(ompv, i);
i--;
}
else
else {
condlog(2, "%s devmap removed", ompp->alias);
trigger_paths_udev_change(ompp, false);
}
} else if (reassign_maps) {
condlog(3, "%s: Reassign existing device-mapper"
" devices", ompp->alias);
Expand Down
Loading