mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
dmeventd: use dm_get_status_snapshot()
Switch to use libdm dm_get_status_snapshot() function for reading status info. This fixes bug, where the code was using 32bit integers, while the snapshot target is able to return 64bit sizes. However this also means, someone is using >1TB snapshot cow devices, which is actually very bad idea anyway, since the perfomance and memory usage in this case is very bad.
This commit is contained in:
parent
06e8ff29ff
commit
e992cb253c
@ -1,5 +1,6 @@
|
|||||||
Version 1.02.78 -
|
Version 1.02.78 -
|
||||||
===================================
|
===================================
|
||||||
|
Fix parsing of 64bit snapshot status in dmeventd snapshot plugin.
|
||||||
Add dm_get_status_snapshot() for parsing snapshot status.
|
Add dm_get_status_snapshot() for parsing snapshot status.
|
||||||
Detecte mounted fs also via reading /proc/self/mountinfo.
|
Detecte mounted fs also via reading /proc/self/mountinfo.
|
||||||
Add dm_mountinfo_read() for parsing /proc/self/mountinfo.
|
Add dm_mountinfo_read() for parsing /proc/self/mountinfo.
|
||||||
|
@ -32,52 +32,13 @@
|
|||||||
|
|
||||||
#define UMOUNT_COMMAND "/bin/umount"
|
#define UMOUNT_COMMAND "/bin/umount"
|
||||||
|
|
||||||
struct snap_status {
|
|
||||||
int invalid;
|
|
||||||
int used;
|
|
||||||
int max;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dso_state {
|
struct dso_state {
|
||||||
|
struct dm_pool *mem;
|
||||||
int percent_check;
|
int percent_check;
|
||||||
int known_size;
|
uint64_t known_size;
|
||||||
char cmd_str[1024];
|
char cmd_str[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FIXME possibly reconcile this with target_percent when we gain
|
|
||||||
access to regular LVM library here. */
|
|
||||||
static void _parse_snapshot_params(char *params, struct snap_status *status)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
/*
|
|
||||||
* xx/xx -- fractions used/max
|
|
||||||
* Invalid -- snapshot invalidated
|
|
||||||
* Unknown -- status unknown
|
|
||||||
*/
|
|
||||||
status->used = status->max = 0;
|
|
||||||
|
|
||||||
if (!strncmp(params, "Invalid", 7)) {
|
|
||||||
status->invalid = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When we return without setting non-zero max, the parent is
|
|
||||||
* responsible for reporting errors.
|
|
||||||
*/
|
|
||||||
if (!strncmp(params, "Unknown", 7))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!(p = strstr(params, "/")))
|
|
||||||
return;
|
|
||||||
|
|
||||||
*p = '\0';
|
|
||||||
p++;
|
|
||||||
|
|
||||||
status->used = atoi(params);
|
|
||||||
status->max = atoi(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _run(const char *cmd, ...)
|
static int _run(const char *cmd, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@ -171,9 +132,9 @@ void process_event(struct dm_task *dmt,
|
|||||||
uint64_t start, length;
|
uint64_t start, length;
|
||||||
char *target_type = NULL;
|
char *target_type = NULL;
|
||||||
char *params;
|
char *params;
|
||||||
struct snap_status status = { 0 };
|
struct dm_status_snapshot *status = NULL;
|
||||||
const char *device = dm_task_get_name(dmt);
|
const char *device = dm_task_get_name(dmt);
|
||||||
int percent;
|
uint64_t percent;
|
||||||
struct dso_state *state = *private;
|
struct dso_state *state = *private;
|
||||||
|
|
||||||
/* No longer monitoring, waiting for remove */
|
/* No longer monitoring, waiting for remove */
|
||||||
@ -186,9 +147,10 @@ void process_event(struct dm_task *dmt,
|
|||||||
if (!target_type)
|
if (!target_type)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
_parse_snapshot_params(params, &status);
|
if (!dm_get_status_snapshot(state->mem, params, &status))
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (status.invalid) {
|
if (status->invalid) {
|
||||||
struct dm_info info;
|
struct dm_info info;
|
||||||
if (dm_task_get_info(dmt, &info)) {
|
if (dm_task_get_info(dmt, &info)) {
|
||||||
dmeventd_lvm2_unlock();
|
dmeventd_lvm2_unlock();
|
||||||
@ -198,22 +160,22 @@ void process_event(struct dm_task *dmt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Snapshot size had changed. Clear the threshold. */
|
/* Snapshot size had changed. Clear the threshold. */
|
||||||
if (state->known_size != status.max) {
|
if (state->known_size != status->total_sectors) {
|
||||||
state->percent_check = CHECK_MINIMUM;
|
state->percent_check = CHECK_MINIMUM;
|
||||||
state->known_size = status.max;
|
state->known_size = status->total_sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the snapshot has been invalidated or we failed to parse
|
* If the snapshot has been invalidated or we failed to parse
|
||||||
* the status string. Report the full status string to syslog.
|
* the status string. Report the full status string to syslog.
|
||||||
*/
|
*/
|
||||||
if (status.invalid || !status.max) {
|
if (status->invalid || !status->total_sectors) {
|
||||||
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
|
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
|
||||||
state->percent_check = 0;
|
state->percent_check = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
percent = 100 * status.used / status.max;
|
percent = 100 * status->used_sectors / status->total_sectors;
|
||||||
if (percent >= state->percent_check) {
|
if (percent >= state->percent_check) {
|
||||||
/* Usage has raised more than CHECK_STEP since the last
|
/* Usage has raised more than CHECK_STEP since the last
|
||||||
time. Run actions. */
|
time. Run actions. */
|
||||||
@ -227,6 +189,8 @@ void process_event(struct dm_task *dmt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (status)
|
||||||
|
dm_pool_free(state->mem, status);
|
||||||
dmeventd_lvm2_unlock();
|
dmeventd_lvm2_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,28 +200,31 @@ int register_device(const char *device,
|
|||||||
int minor __attribute__((unused)),
|
int minor __attribute__((unused)),
|
||||||
void **private)
|
void **private)
|
||||||
{
|
{
|
||||||
|
struct dm_pool *statemem = NULL;
|
||||||
struct dso_state *state;
|
struct dso_state *state;
|
||||||
|
|
||||||
if (!dmeventd_lvm2_init())
|
if (!dmeventd_lvm2_init())
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!(state = dm_zalloc(sizeof(*state))))
|
if (!(statemem = dm_pool_create("snapshot_state", 512)) ||
|
||||||
|
!(state = dm_pool_zalloc(statemem, sizeof(*state))))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(),
|
if (!dmeventd_lvm2_command(statemem, state->cmd_str,
|
||||||
state->cmd_str, sizeof(state->cmd_str),
|
sizeof(state->cmd_str),
|
||||||
"lvextend --use-policies", device))
|
"lvextend --use-policies", device))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
|
state->mem = statemem;
|
||||||
state->percent_check = CHECK_MINIMUM;
|
state->percent_check = CHECK_MINIMUM;
|
||||||
state->known_size = 0;
|
|
||||||
*private = state;
|
*private = state;
|
||||||
|
|
||||||
syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
|
syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
bad:
|
bad:
|
||||||
dm_free(state);
|
if (statemem)
|
||||||
|
dm_pool_destroy(statemem);
|
||||||
dmeventd_lvm2_exit();
|
dmeventd_lvm2_exit();
|
||||||
out:
|
out:
|
||||||
syslog(LOG_ERR, "Failed to monitor snapshot %s.\n", device);
|
syslog(LOG_ERR, "Failed to monitor snapshot %s.\n", device);
|
||||||
@ -274,7 +241,7 @@ int unregister_device(const char *device,
|
|||||||
struct dso_state *state = *private;
|
struct dso_state *state = *private;
|
||||||
|
|
||||||
syslog(LOG_INFO, "No longer monitoring snapshot %s\n", device);
|
syslog(LOG_INFO, "No longer monitoring snapshot %s\n", device);
|
||||||
dm_free(state);
|
dm_pool_destroy(state->mem);
|
||||||
dmeventd_lvm2_exit();
|
dmeventd_lvm2_exit();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user