diff --git a/include/lib/ap.h b/include/lib/ap.h index 58baeeb5..057a78e4 100644 --- a/include/lib/ap.h +++ b/include/lib/ap.h @@ -21,7 +21,9 @@ #define AP_UDEV_FILE "/etc/udev/rules.d/41-ap.rules" #define AP_LOCKFILE "/run/lock/s390apconfig.lock" -#define AP_LOCK_RETRIES 15 +#define AP_LOCK_RETRIES 3000 +#define AP_LOCK_DELAY_US 30000 /* wait at least 30ms between lock retries */ +#define AP_LOCK_VARIANCE_US 3000 /* or as much as 33ms */ /* apmask and aqmask are each represented as 67 character strings with: * '0x' leading characters diff --git a/libap/ap.c b/libap/ap.c index e683b291..5c2f406d 100644 --- a/libap/ap.c +++ b/libap/ap.c @@ -11,12 +11,15 @@ #include #include #include +#include #include +#include #include #include #include #include #include +#include #ifdef HAVE_JSONC #include @@ -698,6 +701,20 @@ void ap_list_remove_all(struct util_list *list) } } +static unsigned int random_delay(void) +{ + static bool libap_seed = true; + struct timeval t; + + if (libap_seed) { + gettimeofday(&t, NULL); + srand((unsigned int)((t.tv_sec + t.tv_usec) % UINT_MAX)); + libap_seed = false; + } + + return AP_LOCK_DELAY_US + (rand() % AP_LOCK_VARIANCE_US); +} + /** * Acquire the ap config lock using this Process ID * @@ -707,7 +724,9 @@ void ap_list_remove_all(struct util_list *list) */ int ap_get_lock(void) { - return util_lockfile_lock(AP_LOCKFILE, AP_LOCK_RETRIES); + unsigned int delay = random_delay(); + + return util_lockfile_lock_cw(AP_LOCKFILE, AP_LOCK_RETRIES, delay, delay); } /** @@ -719,7 +738,10 @@ int ap_get_lock(void) */ int ap_get_lock_callout(void) { - return util_lockfile_parent_lock(AP_LOCKFILE, AP_LOCK_RETRIES); + unsigned int delay = random_delay(); + + return util_lockfile_parent_lock_cw(AP_LOCKFILE, AP_LOCK_RETRIES, delay, + delay); } /**