mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-10 16:58:47 +03:00
mirrors: fix leak in device_is_usable mirror check
Function _ignore_blocked_mirror_devices was not release allocated strings images_health and log_health. In error paths it was also not releasing dm_task structure. Swaped return code of _ignore_blocked_mirror_devices and use 1 as success. In _parse_mirror_status use log_error if memory allocation fails and few more errors so they are no going unnoticed as debug messages. On error path always clear return values and free strings. For dev_create_file use cache mem pool to avoid memleak.
This commit is contained in:
parent
f942ae4a7a
commit
ec49f07b0d
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.99 -
|
Version 2.02.99 -
|
||||||
===================================
|
===================================
|
||||||
|
Fix memleak in device_is_usable mirror testing function.
|
||||||
Do not ignore -f in lvconvert --repair -y -f for mirror and raid volumes.
|
Do not ignore -f in lvconvert --repair -y -f for mirror and raid volumes.
|
||||||
Disallow pvmove on RAID LVs until they are addressed properly
|
Disallow pvmove on RAID LVs until they are addressed properly
|
||||||
Allow empty activation/{auto_activation|read_only|}_volume_list config option.
|
Allow empty activation/{auto_activation|read_only|}_volume_list config option.
|
||||||
|
@ -158,6 +158,10 @@ static int _parse_mirror_status(char *mirror_status_str,
|
|||||||
char **args, **log_args;
|
char **args, **log_args;
|
||||||
unsigned num_devs, log_argc;
|
unsigned num_devs, log_argc;
|
||||||
|
|
||||||
|
*images_health = NULL;
|
||||||
|
*log_health = NULL;
|
||||||
|
*log_dev = 0;
|
||||||
|
|
||||||
if (!dm_split_words(mirror_status_str, 1, 0, &p) ||
|
if (!dm_split_words(mirror_status_str, 1, 0, &p) ||
|
||||||
!(num_devs = (unsigned) atoi(p)))
|
!(num_devs = (unsigned) atoi(p)))
|
||||||
/* On errors, we must assume the mirror is to be avoided */
|
/* On errors, we must assume the mirror is to be avoided */
|
||||||
@ -176,19 +180,31 @@ static int _parse_mirror_status(char *mirror_status_str,
|
|||||||
log_argc, 0, log_args) < log_argc)
|
log_argc, 0, log_args) < log_argc)
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
*log_health = NULL;
|
|
||||||
*log_dev = 0;
|
|
||||||
if (!strcmp(log_args[0], "disk")) {
|
if (!strcmp(log_args[0], "disk")) {
|
||||||
if (!(*log_health = dm_strdup(log_args[2])))
|
if (!(*log_health = dm_strdup(log_args[2]))) {
|
||||||
return_0;
|
log_error("Allocation of log string failed.");
|
||||||
if (sscanf(log_args[1], "%d:%d", &major, &minor) != 2)
|
return 0;
|
||||||
return_0;
|
}
|
||||||
|
if (sscanf(log_args[1], "%d:%d", &major, &minor) != 2) {
|
||||||
|
log_error("Parsing of log's major minor failed.");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
*log_dev = MKDEV((dev_t)major, minor);
|
*log_dev = MKDEV((dev_t)major, minor);
|
||||||
}
|
}
|
||||||
if (!(*images_health = dm_strdup(args[2 + num_devs])))
|
|
||||||
return_0;
|
if (!(*images_health = dm_strdup(args[2 + num_devs]))) {
|
||||||
|
log_error("Allocation of images string failed.");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
dm_free(*log_health);
|
||||||
|
*log_health = NULL;
|
||||||
|
*log_dev = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -227,11 +243,12 @@ static int _ignore_blocked_mirror_devices(struct device *dev,
|
|||||||
uint64_t s,l;
|
uint64_t s,l;
|
||||||
char *params, *target_type = NULL;
|
char *params, *target_type = NULL;
|
||||||
void *next = NULL;
|
void *next = NULL;
|
||||||
struct dm_task *dmt;
|
struct dm_task *dmt = NULL;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
if (!_parse_mirror_status(mirror_status_str,
|
if (!_parse_mirror_status(mirror_status_str,
|
||||||
&images_health, &log_dev, &log_health))
|
&images_health, &log_dev, &log_health))
|
||||||
goto_out;
|
return_0;
|
||||||
|
|
||||||
for (i = 0; images_health[i]; i++)
|
for (i = 0; images_health[i]; i++)
|
||||||
if (images_health[i] != 'A') {
|
if (images_health[i] != 'A') {
|
||||||
@ -254,7 +271,7 @@ static int _ignore_blocked_mirror_devices(struct device *dev,
|
|||||||
(int)MINOR(log_dev)) < 0)
|
(int)MINOR(log_dev)) < 0)
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
if (!(tmp_dev = dev_create_file(buf, NULL, NULL, 1)))
|
if (!(tmp_dev = dev_create_file(buf, NULL, NULL, 0)))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
tmp_dev->dev = log_dev;
|
tmp_dev->dev = log_dev;
|
||||||
@ -263,8 +280,10 @@ static int _ignore_blocked_mirror_devices(struct device *dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!check_for_blocking)
|
if (!check_for_blocking) {
|
||||||
return 0;
|
r = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We avoid another system call if we can, but if a device is
|
* We avoid another system call if we can, but if a device is
|
||||||
@ -293,16 +312,19 @@ static int _ignore_blocked_mirror_devices(struct device *dev,
|
|||||||
strstr(params, "handle_errors")) {
|
strstr(params, "handle_errors")) {
|
||||||
log_debug("%s: I/O blocked to mirror device",
|
log_debug("%s: I/O blocked to mirror device",
|
||||||
dev_name(dev));
|
dev_name(dev));
|
||||||
return 1;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (next);
|
} while (next);
|
||||||
dm_task_destroy(dmt);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
r = 1;
|
||||||
out:
|
out:
|
||||||
return 1;
|
if (dmt)
|
||||||
|
dm_task_destroy(dmt);
|
||||||
|
dm_free(log_health);
|
||||||
|
dm_free(images_health);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int device_is_usable(struct device *dev)
|
int device_is_usable(struct device *dev)
|
||||||
@ -356,7 +378,7 @@ int device_is_usable(struct device *dev)
|
|||||||
&target_type, ¶ms);
|
&target_type, ¶ms);
|
||||||
|
|
||||||
if (target_type && !strcmp(target_type, "mirror") &&
|
if (target_type && !strcmp(target_type, "mirror") &&
|
||||||
_ignore_blocked_mirror_devices(dev, start, length, params)) {
|
!_ignore_blocked_mirror_devices(dev, start, length, params)) {
|
||||||
log_debug("%s: Mirror device %s not usable.",
|
log_debug("%s: Mirror device %s not usable.",
|
||||||
dev_name(dev), name);
|
dev_name(dev), name);
|
||||||
goto out;
|
goto out;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user