1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-10 16:58:47 +03:00

Add age filter to dmsetup udevcomplete_all to minimise concurrency problems.

This commit is contained in:
Alasdair Kergon 2011-06-29 21:56:46 +00:00
parent 5ffa914c59
commit f96cf55d36
4 changed files with 40 additions and 13 deletions

View File

@ -1,5 +1,6 @@
Version 1.02.65 - Version 1.02.65 -
================================== ==================================
Add age_in_minutes parameter to dmsetup udevcomplete_all.
Return immediately from dm_lib_exit() if called more than once. Return immediately from dm_lib_exit() if called more than once.
Disable udev fallback by default and add --verifyudev option to dmsetup. Disable udev fallback by default and add --verifyudev option to dmsetup.
Warn if a table is loaded while a device is known to be in suspended state. Warn if a table is loaded while a device is known to be in suspended state.

View File

@ -80,6 +80,7 @@ dmsetup \- low level logical volume management
.I cookie .I cookie
.br .br
.B dmsetup udevcomplete_all .B dmsetup udevcomplete_all
.I [age_in_minutes]
.br .br
.B dmsetup udevcookies .B dmsetup udevcookies
.br .br
@ -389,8 +390,10 @@ always reported as DM_SUBSYSTEM_UDEV_FLAG<flag_position>='1'. There are
.br .br
Wake any processes that are waiting for udev to complete processing the specified cookie. Wake any processes that are waiting for udev to complete processing the specified cookie.
.br .br
.IP \fBudevcomplete_all .IP \fBudevcomplete_all
Remove all cookies. Any process waiting on a cookie will be resumed immediately. .I[age_in_minutes]
Remove all cookies older than the specified number of minutes.
Any process waiting on a cookie will be resumed immediately.
.br .br
.IP \fBudevcookies .IP \fBudevcookies
List all existing cookies. Cookies are system-wide semaphores with keys List all existing cookies. Cookies are system-wide semaphores with keys

View File

@ -149,7 +149,9 @@ finish_udev_transaction() {
teardown_udev_cookies() { teardown_udev_cookies() {
if test "$DM_UDEV_SYNCHRONISATION" = 1; then if test "$DM_UDEV_SYNCHRONISATION" = 1; then
dmsetup udevcomplete_all -y # Delete any cookies created more than 10 minutes ago
# and not used in the last 10 minutes.
dmsetup udevcomplete_all -y 10
fi fi
} }

View File

@ -1085,10 +1085,19 @@ static int _udevcomplete_all(CMD_ARGS)
struct seminfo sinfo; struct seminfo sinfo;
struct semid_ds sdata; struct semid_ds sdata;
int counter = 0; int counter = 0;
int skipped = 0;
unsigned age = 0;
time_t t;
if (argc == 2 && (sscanf(argv[1], "%i", &age) != 1)) {
log_error("Failed to read age_in_minutes parameter.");
return 0;
}
if (!_switches[YES_ARG]) { if (!_switches[YES_ARG]) {
log_warn("This operation will destroy all semaphores with keys " log_warn("This operation will destroy all semaphores %s%.0d%swith keys "
"that have a prefix %" PRIu16 " (0x%" PRIx16 ").", "that have a prefix %" PRIu16 " (0x%" PRIx16 ").",
age ? "older than " : "", age, age ? " minutes " : "",
DM_COOKIE_MAGIC, DM_COOKIE_MAGIC); DM_COOKIE_MAGIC, DM_COOKIE_MAGIC);
if (_yes_no_prompt("Do you really want to continue? [y/n]: ") == 'n') { if (_yes_no_prompt("Do you really want to continue? [y/n]: ") == 'n') {
@ -1109,6 +1118,13 @@ static int _udevcomplete_all(CMD_ARGS)
continue; continue;
if (sdata.sem_perm.__key >> 16 == DM_COOKIE_MAGIC) { if (sdata.sem_perm.__key >> 16 == DM_COOKIE_MAGIC) {
t = time(NULL);
if (sdata.sem_ctime + age * 60 > t ||
sdata.sem_otime + age * 60 > t) {
skipped++;
continue;
}
if (semctl(sid, 0, IPC_RMID, 0) < 0) { if (semctl(sid, 0, IPC_RMID, 0) < 0) {
log_error("Could not cleanup notification semaphore " log_error("Could not cleanup notification semaphore "
"with semid %d and cookie value " "with semid %d and cookie value "
@ -1122,8 +1138,8 @@ static int _udevcomplete_all(CMD_ARGS)
} }
log_print("%d semaphores with keys prefixed by " log_print("%d semaphores with keys prefixed by "
"%" PRIu16 " (0x%" PRIx16 ") destroyed.", "%" PRIu16 " (0x%" PRIx16 ") destroyed. %d skipped.",
counter, DM_COOKIE_MAGIC, DM_COOKIE_MAGIC); counter, DM_COOKIE_MAGIC, DM_COOKIE_MAGIC, skipped);
return 1; return 1;
} }
@ -1134,14 +1150,15 @@ static int _udevcookies(CMD_ARGS)
struct seminfo sinfo; struct seminfo sinfo;
struct semid_ds sdata; struct semid_ds sdata;
int val; int val;
char *time_str; char otime_str[26], ctime_str[26];
char *otimes, *ctimes;
if ((max_id = semctl(0, 0, SEM_INFO, &sinfo)) < 0) { if ((max_id = semctl(0, 0, SEM_INFO, &sinfo)) < 0) {
log_sys_error("sem_ctl", "SEM_INFO"); log_sys_error("sem_ctl", "SEM_INFO");
return 0; return 0;
} }
printf("cookie semid value last_semop_time\n"); printf("Cookie Semid Value Last semop time Last change time\n");
for (id = 0; id <= max_id; id++) { for (id = 0; id <= max_id; id++) {
if ((sid = semctl(id, 0, SEM_STAT, &sdata)) < 0) if ((sid = semctl(id, 0, SEM_STAT, &sdata)) < 0)
@ -1156,10 +1173,14 @@ static int _udevcookies(CMD_ARGS)
continue; continue;
} }
time_str = ctime((const time_t *) &sdata.sem_otime); if ((otimes = ctime_r((const time_t *) &sdata.sem_otime, (char *)&otime_str)))
otime_str[strlen(otimes)-1] = '\0';
if ((ctimes = ctime_r((const time_t *) &sdata.sem_ctime, (char *)&ctime_str)))
ctime_str[strlen(ctimes)-1] = '\0';
printf("0x%-10x %-10d %-10d %s", sdata.sem_perm.__key, printf("0x%-10x %-10d %-10d %s %s\n", sdata.sem_perm.__key,
sid, val, time_str ? time_str : "unknown\n"); sid, val, otimes ? : "unknown",
ctimes? : "unknown");
} }
} }
@ -2728,7 +2749,7 @@ static struct command _commands[] = {
{"udevreleasecookie", "[<cookie>]", 0, 1, 0, _udevreleasecookie}, {"udevreleasecookie", "[<cookie>]", 0, 1, 0, _udevreleasecookie},
{"udevflags", "<cookie>", 1, 1, 0, _udevflags}, {"udevflags", "<cookie>", 1, 1, 0, _udevflags},
{"udevcomplete", "<cookie>", 1, 1, 0, _udevcomplete}, {"udevcomplete", "<cookie>", 1, 1, 0, _udevcomplete},
{"udevcomplete_all", "", 0, 0, 0, _udevcomplete_all}, {"udevcomplete_all", "<age_in_minutes>", 0, 1, 0, _udevcomplete_all},
{"udevcookies", "", 0, 0, 0, _udevcookies}, {"udevcookies", "", 0, 0, 0, _udevcookies},
{"targets", "", 0, 0, 0, _targets}, {"targets", "", 0, 0, 0, _targets},
{"version", "", 0, 0, 0, _version}, {"version", "", 0, 0, 0, _version},
@ -2745,7 +2766,7 @@ static void _usage(FILE *out)
fprintf(out, "dmsetup [--version] [-h|--help [-c|-C|--columns]]\n" fprintf(out, "dmsetup [--version] [-h|--help [-c|-C|--columns]]\n"
" [-v|--verbose [-v|--verbose ...]]\n" " [-v|--verbose [-v|--verbose ...]]\n"
" [-r|--readonly] [--noopencount] [--nolockfs] [--inactive]\n" " [-r|--readonly] [--noopencount] [--nolockfs] [--inactive]\n"
" [--udevcookie] [--noudevrules] [--noudevsync] [--verifyudev]\n" " [--udevcookie [cookie]] [--noudevrules] [--noudevsync] [--verifyudev]\n"
" [-y|--yes] [--readahead [+]<sectors>|auto|none]\n" " [-y|--yes] [--readahead [+]<sectors>|auto|none]\n"
" [-c|-C|--columns] [-o <fields>] [-O|--sort <sort_fields>]\n" " [-c|-C|--columns] [-o <fields>] [-O|--sort <sort_fields>]\n"
" [--nameprefixes] [--noheadings] [--separator <separator>]\n\n"); " [--nameprefixes] [--noheadings] [--separator <separator>]\n\n");