Blame SOURCES/bz720543-pcmk-crmd_cache_rsc_info_retrieved_from_lrmd_and_pacemaker_remoted.patch

ed0026
commit 701e10aba853afb4cd1ab4a1e4e3dd64ea96e907
ed0026
Author: David Vossel <dvossel@redhat.com>
ed0026
Date:   Thu Oct 10 17:22:29 2013 -0500
ed0026
ed0026
    Low: crmd: Cache rsc_info retrieved from lrmd and pacemaker_remoted
ed0026
    
ed0026
    (cherry picked from commit d65b2703d2107665365b0db06cff67386981e346)
ed0026
ed0026
diff --git a/crmd/crmd_lrm.h b/crmd/crmd_lrm.h
ed0026
index d0ca58c..2239638 100644
ed0026
--- a/crmd/crmd_lrm.h
ed0026
+++ b/crmd/crmd_lrm.h
ed0026
@@ -56,6 +56,8 @@ typedef struct lrm_state_s {
ed0026
     GHashTable *pending_ops;
ed0026
     GHashTable *deletion_ops;
ed0026
 
ed0026
+    GHashTable *rsc_info_cache;
ed0026
+
ed0026
     int num_lrm_register_fails;
ed0026
 } lrm_state_t;
ed0026
 
ed0026
diff --git a/crmd/lrm_state.c b/crmd/lrm_state.c
ed0026
index b1b1b7f..57eb87e 100644
ed0026
--- a/crmd/lrm_state.c
ed0026
+++ b/crmd/lrm_state.c
ed0026
@@ -60,6 +60,13 @@ history_cache_destroy(gpointer data)
ed0026
     free(entry->id);
ed0026
     free(entry);
ed0026
 }
ed0026
+static void
ed0026
+free_rsc_info(gpointer value)
ed0026
+{
ed0026
+    lrmd_rsc_info_t *rsc_info = value;
ed0026
+
ed0026
+    lrmd_free_rsc_info(rsc_info);
ed0026
+}
ed0026
 
ed0026
 static void
ed0026
 free_deletion_op(gpointer value)
ed0026
@@ -99,6 +106,9 @@ lrm_state_create(const char *node_name)
ed0026
 
ed0026
     state->node_name = strdup(node_name);
ed0026
 
ed0026
+    state->rsc_info_cache = g_hash_table_new_full(crm_str_hash,
ed0026
+                                                g_str_equal, NULL, free_rsc_info);
ed0026
+
ed0026
     state->deletion_ops = g_hash_table_new_full(crm_str_hash,
ed0026
                                                 g_str_equal, g_hash_destroy_str, free_deletion_op);
ed0026
 
ed0026
@@ -146,6 +156,10 @@ internal_lrm_state_destroy(gpointer data)
ed0026
     remote_ra_cleanup(lrm_state);
ed0026
     lrmd_api_delete(lrm_state->conn);
ed0026
 
ed0026
+    if (lrm_state->rsc_info_cache) {
ed0026
+        crm_trace("Destroying rsc info cache with %d members", g_hash_table_size(lrm_state->rsc_info_cache));
ed0026
+        g_hash_table_destroy(lrm_state->rsc_info_cache);
ed0026
+    }
ed0026
     if (lrm_state->resource_history) {
ed0026
         crm_trace("Destroying history op cache with %d members", g_hash_table_size(lrm_state->resource_history));
ed0026
         g_hash_table_destroy(lrm_state->resource_history);
ed0026
@@ -181,6 +195,11 @@ lrm_state_reset_tables(lrm_state_t * lrm_state)
ed0026
                   g_hash_table_size(lrm_state->pending_ops));
ed0026
         g_hash_table_remove_all(lrm_state->pending_ops);
ed0026
     }
ed0026
+    if (lrm_state->rsc_info_cache) {
ed0026
+        crm_trace("Re-setting rsc info cache with %d members",
ed0026
+                  g_hash_table_size(lrm_state->rsc_info_cache));
ed0026
+        g_hash_table_remove_all(lrm_state->rsc_info_cache);
ed0026
+    }
ed0026
 }
ed0026
 
ed0026
 static void
ed0026
@@ -590,16 +609,28 @@ lrm_state_cancel(lrm_state_t * lrm_state, const char *rsc_id, const char *action
ed0026
 lrmd_rsc_info_t *
ed0026
 lrm_state_get_rsc_info(lrm_state_t * lrm_state, const char *rsc_id, enum lrmd_call_options options)
ed0026
 {
ed0026
+    lrmd_rsc_info_t *rsc = NULL;
ed0026
+
ed0026
     if (!lrm_state->conn) {
ed0026
         return NULL;
ed0026
     }
ed0026
-    /* optimize this... this function is a synced round trip from client to daemon.
ed0026
-     * It should be possible to cache the resource info in the lrmd client to prevent this. */
ed0026
     if (is_remote_lrmd_ra(NULL, NULL, rsc_id)) {
ed0026
         return remote_ra_get_rsc_info(lrm_state, rsc_id);
ed0026
     }
ed0026
 
ed0026
-    return ((lrmd_t *) lrm_state->conn)->cmds->get_rsc_info(lrm_state->conn, rsc_id, options);
ed0026
+    rsc = g_hash_table_lookup(lrm_state->rsc_info_cache, rsc_id);
ed0026
+    if (rsc == NULL) {
ed0026
+        /* only contact the lrmd if we don't already have a cached rsc info */
ed0026
+        rsc = ((lrmd_t *) lrm_state->conn)->cmds->get_rsc_info(lrm_state->conn, rsc_id, options);
ed0026
+        if (rsc == NULL) {
ed0026
+		    return NULL;
ed0026
+        }
ed0026
+        /* cache the result */
ed0026
+        g_hash_table_insert(lrm_state->rsc_info_cache, rsc->id, rsc);
ed0026
+    }
ed0026
+
ed0026
+    return lrmd_copy_rsc_info(rsc);
ed0026
+
ed0026
 }
ed0026
 
ed0026
 int
ed0026
@@ -667,5 +698,7 @@ lrm_state_unregister_rsc(lrm_state_t * lrm_state,
ed0026
         return pcmk_ok;
ed0026
     }
ed0026
 
ed0026
+    g_hash_table_remove(lrm_state->rsc_info_cache, rsc_id);
ed0026
+
ed0026
     return ((lrmd_t *) lrm_state->conn)->cmds->unregister_rsc(lrm_state->conn, rsc_id, options);
ed0026
 }