]> git.proxmox.com Git - mirror_kronosnet.git/commitdiff
[compress] fix library init to work for multiple knet_handle
authorFabio M. Di Nitto <fdinitto@redhat.com>
Sun, 20 Aug 2017 14:27:37 +0000 (16:27 +0200)
committerFabio M. Di Nitto <fdinitto@redhat.com>
Thu, 14 Sep 2017 13:03:35 +0000 (15:03 +0200)
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
libknet/compress.c
libknet/compress.h
libknet/compress_lzo2.c
libknet/compress_lzo2.h

index 9007001209738eca9ea0f97c373515aca01a25ec..caf0f850988f9f24ca27e2fa169ae62731e8ad78 100644 (file)
  */
 
 compress_model_t compress_modules_cmds[] = {
-       { 0, 1, 0, "none", NULL, NULL, NULL, NULL, NULL },
+       { 0, 1, 0, "none", NULL, NULL, NULL, NULL, NULL, NULL },
 #ifdef BUILDCOMPZLIB
-       { 1, 1, 0, "zlib", NULL, NULL, zlib_val_level, zlib_compress, zlib_decompress },
+       { 1, 1, 0, "zlib", NULL, NULL, NULL, zlib_val_level, zlib_compress, zlib_decompress },
 #else
-       { 1, 0, 0, "zlib", NULL, NULL, NULL, NULL, NULL },
+       { 1, 0, 0, "zlib", NULL, NULL, NULL, NULL, NULL, NULL },
 #endif
 #ifdef BUILDCOMPLZ4
-       { 2, 1, 0, "lz4", NULL, NULL, lz4_val_level, lz4_compress, lz4_decompress },
-       { 3, 1, 0, "lz4hc", NULL, NULL, lz4hc_val_level, lz4hc_compress, lz4_decompress },
+       { 2, 1, 0, "lz4", NULL, NULL, NULL, lz4_val_level, lz4_compress, lz4_decompress },
+       { 3, 1, 0, "lz4hc", NULL, NULL, NULL, lz4hc_val_level, lz4hc_compress, lz4_decompress },
 #else
-       { 2, 0, 0, "lz4", NULL, NULL, NULL, NULL, NULL },
-       { 3, 0, 0, "lz4hc", NULL, NULL, NULL, NULL, NULL },
+       { 2, 0, 0, "lz4", NULL, NULL, NULL, NULL, NULL, NULL },
+       { 3, 0, 0, "lz4hc", NULL, NULL, NULL, NULL, NULL, NULL },
 #endif
 #ifdef BUILDCOMPLZO2
-       { 4, 1, 0, "lzo2", lzo2_init, lzo2_fini, lzo2_val_level, lzo2_compress, lzo2_decompress },
+       { 4, 1, 0, "lzo2", lzo2_is_init, lzo2_init, lzo2_fini, lzo2_val_level, lzo2_compress, lzo2_decompress },
 #else
-       { 4, 0, 0, "lzo2", NULL, NULL, NULL, NULL, NULL },
+       { 4, 0, 0, "lzo2", NULL, NULL, NULL, NULL, NULL, NULL },
 #endif
 #ifdef BUILDCOMPLZMA
-       { 5, 1, 0, "lzma", NULL, NULL, lzma_val_level, lzma_compress, lzma_decompress },
+       { 5, 1, 0, "lzma", NULL, NULL, NULL, lzma_val_level, lzma_compress, lzma_decompress },
 #else
-       { 5, 0, 0, "lzma", NULL, NULL, NULL, NULL, NULL },
+       { 5, 0, 0, "lzma", NULL, NULL, NULL, NULL, NULL, NULL },
 #endif
 #ifdef BUILDCOMPBZIP2
-       { 6, 1, 0, "bzip2", NULL, NULL, bzip2_val_level, bzip2_compress, bzip2_decompress },
+       { 6, 1, 0, "bzip2", NULL, NULL, NULL, bzip2_val_level, bzip2_compress, bzip2_decompress },
 #else
-       { 6, 0, 0, "bzip2", NULL, NULL, NULL, NULL, NULL },
+       { 6, 0, 0, "bzip2", NULL, NULL, NULL, NULL, NULL, NULL },
 #endif
-       { 255, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
+       { 255, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
 };
 
 static int get_model(const char *model)
@@ -133,16 +133,22 @@ static int check_init_lib(knet_handle_t knet_h, int cmp_model)
        }
 
        /*
-        * if the module is already loaded, we will return
-        * and keep the lock to avoid any race condition
-        * on other threads potentially unloading or reloading
+        * if the module is already loaded and init for this handle,
+        * we will return and keep the lock to avoid any race condition
+        * on other threads potentially unloading or reloading.
+        *
+        * lack of a .is_init function means that the module does not require
+        * init per handle
         */
-       if (compress_modules_cmds[cmp_model].loaded == 1) {
+       if ((compress_modules_cmds[cmp_model].loaded == 1) &&
+           ((compress_modules_cmds[cmp_model].is_init == NULL) ||
+            (compress_modules_cmds[cmp_model].is_init(knet_h, cmp_model) == 1))) {
                return 0;
        }
 
        /*
         * need to switch to write lock, load the lib, and return with a write lock
+        * this is not racy because .init should be written idempotent.
         */
        pthread_rwlock_unlock(&shlib_rwlock);
        savederrno = pthread_rwlock_wrlock(&shlib_rwlock);
@@ -154,17 +160,16 @@ static int check_init_lib(knet_handle_t knet_h, int cmp_model)
        }
 
        /*
-        * check again after changing locking context
+        * every module must provide a .init function
+        * but this is useful while transition to dlopen model
         */
-       if (compress_modules_cmds[cmp_model].loaded == 0) {
-               if (compress_modules_cmds[cmp_model].init != NULL) {
-                       if (compress_modules_cmds[cmp_model].init(knet_h, cmp_model) < 0) {
-                               pthread_rwlock_unlock(&shlib_rwlock);
-                               return -1;
-                       }
+       if (compress_modules_cmds[cmp_model].init != NULL) {
+               if (compress_modules_cmds[cmp_model].init(knet_h, cmp_model) < 0) {
+                       pthread_rwlock_unlock(&shlib_rwlock);
+                       return -1;
                }
-               compress_modules_cmds[cmp_model].loaded = 1;
        }
+       compress_modules_cmds[cmp_model].loaded = 1;
 
        return 0;
 }
index f9fe7c44d12669464e67d5528779a50a6f8aadc9..18f434cb78c1ec569537a9843fe786b4e4b805af 100644 (file)
@@ -16,6 +16,7 @@ typedef struct {
        uint8_t         built_in;
        uint8_t         loaded;
        const char      *model_name;
+       int (*is_init)  (knet_handle_t knet_h, int method_idx);
        int (*init)     (knet_handle_t knet_h, int method_idx);
        void (*fini)    (knet_handle_t knet_h, int method_idx);
        int (*val_level)(knet_handle_t knet_h,
index b26fd5e46886ad3278ec9b8656fd0edc4edee7b3..114ba0758d1520a91c22d77a3170a90686ce1df8 100644 (file)
@@ -23,6 +23,7 @@
  * global vars for dlopen
  */
 static void* lzo2_lib;
+static int lzo2_libref = 0;
 
 /*
  * symbols remapping
@@ -120,15 +121,24 @@ void lzo2_fini(
        if (knet_h->compress_int_data[method_idx]) {
                free(knet_h->compress_int_data[method_idx]);
                knet_h->compress_int_data[method_idx] = NULL;
+               lzo2_libref--;
        }
-       /*
-       if ((lzo2_libref == 0) && (lzo2_data->lib)) {
-               dlclose(lzo2_data->lib);
+       if ((lzo2_lib) && (lzo2_libref == 0)) {
+               dlclose(lzo2_lib);
        }
-       */
        return;
 }
 
+int lzo2_is_init(
+       knet_handle_t knet_h,
+       int method_idx)
+{
+       if (knet_h->compress_int_data[method_idx]) {
+               return 1;
+       }
+       return 0;
+}
+
 int lzo2_init(
        knet_handle_t knet_h,
        int method_idx)
@@ -136,37 +146,42 @@ int lzo2_init(
        int err = 0, savederrno = 0;
        char *error = NULL;
 
-       /*
-        * clear any pending error
-        */
-       dlerror();
+       if (!lzo2_lib) {
+               /*
+                * clear any pending error
+                */
+               dlerror();
 
-       lzo2_lib = dlopen("liblzo2.so.2", RTLD_LAZY | RTLD_GLOBAL);
-       error = dlerror();
-       if (error != NULL) {
-               log_err(knet_h, KNET_SUB_LZO2COMP, "unable to dlopen liblzo2.so.2: %s", error);
-               savederrno = EAGAIN;
-               err = -1;
-               goto out;
-       }
+               lzo2_lib = dlopen("liblzo2.so.2", RTLD_LAZY | RTLD_GLOBAL);
+               error = dlerror();
+               if (error != NULL) {
+                       log_err(knet_h, KNET_SUB_LZO2COMP, "unable to dlopen liblzo2.so.2: %s", error);
+                       savederrno = EAGAIN;
+                       err = -1;
+                       goto out;
+               }
 
-       if (lzo2_remap_symbols(knet_h) < 0) {
-               savederrno = errno;
-               err = -1;
-               goto out;
+               if (lzo2_remap_symbols(knet_h) < 0) {
+                       savederrno = errno;
+                       err = -1;
+                       goto out;
+               }
        }
 
        /*
         * LZO1X_999_MEM_COMPRESS is the highest amount of memory lzo2 can use
         */
-       knet_h->compress_int_data[method_idx] = malloc(LZO1X_999_MEM_COMPRESS);
        if (!knet_h->compress_int_data[method_idx]) {
-               log_err(knet_h, KNET_SUB_LZO2COMP, "lzo2 unable to allocate work memory");
-               savederrno = ENOMEM;
-               err = -1;
-               goto out;
+               knet_h->compress_int_data[method_idx] = malloc(LZO1X_999_MEM_COMPRESS);
+               if (!knet_h->compress_int_data[method_idx]) {
+                       log_err(knet_h, KNET_SUB_LZO2COMP, "lzo2 unable to allocate work memory");
+                       savederrno = ENOMEM;
+                       err = -1;
+                       goto out;
+               }
+               memset(knet_h->compress_int_data[method_idx], 0, LZO1X_999_MEM_COMPRESS);
+               lzo2_libref++;
        }
-       memset(knet_h->compress_int_data[method_idx], 0, LZO1X_999_MEM_COMPRESS);
 
 out:
        if (err) {
index c391211b7e592a1605308bd94d933fbc48a04bbe..b82f470e366f4ffc0ca4da24b3ec083afd8361bc 100644 (file)
 
 #include "internals.h"
 
+int lzo2_is_init(
+       knet_handle_t knet_h,
+       int method_idx);
+
 int lzo2_init(
        knet_handle_t knet_h,
        int method_idx);