From b5f7ac6c368a07b3d35191bf56fdf58145c4e44b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 23 Aug 2019 15:51:13 +0200 Subject: [PATCH] gpg: Implement keybox compression run * kbx/keybox-init.c (keybox_lock): Add arg TIMEOUT and change all callers to pass -1. * g10/keydb.c (keydb_add_resource): Call keybox_compress. -- Note that here in the 2.2 branch the way we call the locking in gpgsm is different from the one in gpg. So we could not cherry-pick from master. GnuPG-bug-id: 4644 Signed-off-by: Werner Koch --- g10/keydb.c | 23 ++++++++++++++++++----- kbx/keybox-init.c | 12 +++++++++--- kbx/keybox.h | 2 +- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/g10/keydb.c b/g10/keydb.c index 670a8a191..45b3c8512 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -812,14 +812,27 @@ keydb_add_resource (const char *url, unsigned int flags) err = gpg_error (GPG_ERR_RESOURCE_LIMIT); else { + KEYBOX_HANDLE kbxhd; + if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) primary_keydb = token; all_resources[used_resources].type = rt; all_resources[used_resources].u.kb = NULL; /* Not used here */ all_resources[used_resources].token = token; - /* FIXME: Do a compress run if needed and no other - user is currently using the keybox. */ + /* Do a compress run if needed and no other user is + * currently using the keybox. */ + kbxhd = keybox_new_openpgp (token, 0); + if (kbxhd) + { + if (!keybox_lock (kbxhd, 1, 0)) + { + keybox_compress (kbxhd); + keybox_lock (kbxhd, 0, 0); + } + + keybox_release (kbxhd); + } used_resources++; } @@ -1083,7 +1096,7 @@ lock_all (KEYDB_HANDLE hd) rc = keyring_lock (hd->active[i].u.kr, 1); break; case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_lock (hd->active[i].u.kb, 1); + rc = keybox_lock (hd->active[i].u.kb, 1, -1); break; } } @@ -1101,7 +1114,7 @@ lock_all (KEYDB_HANDLE hd) keyring_lock (hd->active[i].u.kr, 0); break; case KEYDB_RESOURCE_TYPE_KEYBOX: - keybox_lock (hd->active[i].u.kb, 0); + keybox_lock (hd->active[i].u.kb, 0, 0); break; } } @@ -1134,7 +1147,7 @@ unlock_all (KEYDB_HANDLE hd) keyring_lock (hd->active[i].u.kr, 0); break; case KEYDB_RESOURCE_TYPE_KEYBOX: - keybox_lock (hd->active[i].u.kb, 0); + keybox_lock (hd->active[i].u.kb, 0, 0); break; } } diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c index 6d656f2f8..e6c3ad284 100644 --- a/kbx/keybox-init.c +++ b/kbx/keybox-init.c @@ -262,9 +262,12 @@ _keybox_close_file (KEYBOX_HANDLE hd) /* * Lock the keybox at handle HD, or unlock if YES is false. + * Lock the keybox at handle HD, or unlock if YES is false. TIMEOUT + * is the value used for dotlock_take. In general -1 should be used + * when taking a lock; use 0 when releasing a lock. */ gpg_error_t -keybox_lock (KEYBOX_HANDLE hd, int yes) +keybox_lock (KEYBOX_HANDLE hd, int yes, long timeout) { gpg_error_t err = 0; KB_NAME kb = hd->kb; @@ -298,10 +301,13 @@ keybox_lock (KEYBOX_HANDLE hd, int yes) * in a deadlock. */ _keybox_close_file (hd); #endif /*HAVE_W32_SYSTEM*/ - if (dotlock_take (kb->lockhd, -1)) + if (dotlock_take (kb->lockhd, timeout)) { err = gpg_error_from_syserror (); - log_info ("can't lock '%s'\n", kb->fname ); + if (!timeout && gpg_err_code (err) == GPG_ERR_EACCES) + ; /* No diagnostic if we only tried to lock. */ + else + log_info ("can't lock '%s'\n", kb->fname ); } else kb->is_locked = 1; diff --git a/kbx/keybox.h b/kbx/keybox.h index 665b05fc0..4d941571e 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -76,7 +76,7 @@ void keybox_pop_found_state (KEYBOX_HANDLE hd); const char *keybox_get_resource_name (KEYBOX_HANDLE hd); int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes); -gpg_error_t keybox_lock (KEYBOX_HANDLE hd, int yes); +gpg_error_t keybox_lock (KEYBOX_HANDLE hd, int yes, long timeout); /*-- keybox-file.c --*/ /* Fixme: This function does not belong here: Provide a better