mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-21 22:04:19 +03:00
Fix another bug in memlock handling, this time the "global" dmeventd memlock
was preventing device scans in lvconvert --repair running from inside dmeventd.
This commit is contained in:
parent
c85222c461
commit
4514bdcfa2
@ -53,6 +53,7 @@ static size_t _size_malloc = 2000000;
|
|||||||
|
|
||||||
static void *_malloc_mem = NULL;
|
static void *_malloc_mem = NULL;
|
||||||
static int _memlock_count = 0;
|
static int _memlock_count = 0;
|
||||||
|
static int _memlock_count_daemon = 0;
|
||||||
static int _priority;
|
static int _priority;
|
||||||
static int _default_priority;
|
static int _default_priority;
|
||||||
|
|
||||||
@ -123,22 +124,61 @@ static void _unlock_mem(void)
|
|||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _lock_mem_if_needed(void) {
|
||||||
|
if ((_memlock_count + _memlock_count_daemon) == 1)
|
||||||
|
_lock_mem();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _unlock_mem_if_possible(void) {
|
||||||
|
if ((_memlock_count + _memlock_count_daemon) == 0)
|
||||||
|
_unlock_mem();
|
||||||
|
}
|
||||||
|
|
||||||
void memlock_inc(void)
|
void memlock_inc(void)
|
||||||
{
|
{
|
||||||
if (!_memlock_count++)
|
++_memlock_count;
|
||||||
_lock_mem();
|
_lock_mem_if_needed();
|
||||||
log_debug("memlock_count inc to %d", _memlock_count);
|
log_debug("memlock_count inc to %d", _memlock_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void memlock_dec(void)
|
void memlock_dec(void)
|
||||||
{
|
{
|
||||||
if (_memlock_count && (!--_memlock_count))
|
if (!_memlock_count)
|
||||||
_unlock_mem();
|
|
||||||
log_debug("memlock_count dec to %d", _memlock_count);
|
|
||||||
if (_memlock_count < 0)
|
|
||||||
log_error("Internal error: _memlock_count has dropped below 0.");
|
log_error("Internal error: _memlock_count has dropped below 0.");
|
||||||
|
--_memlock_count;
|
||||||
|
_unlock_mem_if_possible();
|
||||||
|
log_debug("memlock_count dec to %d", _memlock_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The memlock_*_daemon functions will force the mlockall() call that we need
|
||||||
|
* to stay in memory, but they will have no effect on device scans (unlike
|
||||||
|
* normal memlock_inc and memlock_dec). Memory is kept locked as long as either
|
||||||
|
* of memlock or memlock_daemon is in effect.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void memlock_inc_daemon(void)
|
||||||
|
{
|
||||||
|
++_memlock_count_daemon;
|
||||||
|
_lock_mem_if_needed();
|
||||||
|
log_debug("memlock_count_daemon inc to %d", _memlock_count_daemon);
|
||||||
|
}
|
||||||
|
|
||||||
|
void memlock_dec_daemon(void)
|
||||||
|
{
|
||||||
|
if (!_memlock_count_daemon)
|
||||||
|
log_error("Internal error: _memlock_count_daemon has dropped below 0.");
|
||||||
|
--_memlock_count_daemon;
|
||||||
|
_unlock_mem_if_possible();
|
||||||
|
log_debug("memlock_count_daemon dec to %d", _memlock_count_daemon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This disregards the daemon (dmeventd) locks, since we use memlock() to check
|
||||||
|
* whether it is safe to run a device scan, which would normally coincide with
|
||||||
|
* !memlock() -- but the daemon global memory lock breaks this assumption, so
|
||||||
|
* we do not take those into account here.
|
||||||
|
*/
|
||||||
int memlock(void)
|
int memlock(void)
|
||||||
{
|
{
|
||||||
return _memlock_count;
|
return _memlock_count;
|
||||||
|
@ -20,6 +20,8 @@ struct cmd_context;
|
|||||||
|
|
||||||
void memlock_inc(void);
|
void memlock_inc(void);
|
||||||
void memlock_dec(void);
|
void memlock_dec(void);
|
||||||
|
void memlock_inc_daemon(void);
|
||||||
|
void memlock_dec_daemon(void);
|
||||||
int memlock(void);
|
int memlock(void);
|
||||||
void memlock_init(struct cmd_context *cmd);
|
void memlock_init(struct cmd_context *cmd);
|
||||||
|
|
||||||
|
@ -82,9 +82,9 @@ int lvm2_run(void *handle, const char *cmdline)
|
|||||||
/* FIXME Temporary - move to libdevmapper */
|
/* FIXME Temporary - move to libdevmapper */
|
||||||
ret = ECMD_PROCESSED;
|
ret = ECMD_PROCESSED;
|
||||||
if (!strcmp(cmdline, "_memlock_inc"))
|
if (!strcmp(cmdline, "_memlock_inc"))
|
||||||
memlock_inc();
|
memlock_inc_daemon();
|
||||||
else if (!strcmp(cmdline, "_memlock_dec"))
|
else if (!strcmp(cmdline, "_memlock_dec"))
|
||||||
memlock_dec();
|
memlock_dec_daemon();
|
||||||
else
|
else
|
||||||
ret = lvm_run_command(cmd, argc, argv);
|
ret = lvm_run_command(cmd, argc, argv);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user