Rebase on upstream 2.1.7 final release
- Fix documentation for Pacemaker Remote schema transfers - Do not check CIB feature set version when CIB_file is set - Consolidate attrd cache handling - Avoid duplicating option metadata across daemons - Related: RHEL-7665 - Related: RHEL-13216 - Resolves: RHEL-7702
This commit is contained in:
parent
bee6fa1a1f
commit
230b7a9ac1
42
003-schema-doc.patch
Normal file
42
003-schema-doc.patch
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
From a3bffc7c66bf6f796f977cffd44f223635b008c5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Reid Wahl <nrwahl@protonmail.com>
|
||||||
|
Date: Wed, 20 Dec 2023 13:33:47 -0800
|
||||||
|
Subject: [PATCH] Doc: Pacemaker Explained: Add replace for
|
||||||
|
PCMK__REMOTE_SCHEMA_DIR
|
||||||
|
|
||||||
|
So that the existing use in local-options.rst expands correctly.
|
||||||
|
|
||||||
|
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
|
||||||
|
---
|
||||||
|
doc/sphinx/Makefile.am | 1 +
|
||||||
|
doc/sphinx/conf.py.in | 1 +
|
||||||
|
3 files changed, 2 insertions(+)
|
||||||
|
create mode 100644 doc/sphinx/conf.py.in.rej
|
||||||
|
|
||||||
|
diff --git a/doc/sphinx/Makefile.am b/doc/sphinx/Makefile.am
|
||||||
|
index e48e19a..d0309ff 100644
|
||||||
|
--- a/doc/sphinx/Makefile.am
|
||||||
|
+++ b/doc/sphinx/Makefile.am
|
||||||
|
@@ -134,6 +134,7 @@ $(BOOKS:%=%/conf.py): conf.py.in
|
||||||
|
-e 's#%CRM_SCHEMA_DIRECTORY%#@CRM_SCHEMA_DIRECTORY@#g' \
|
||||||
|
-e 's#%PACEMAKER_CONFIG_DIR%#@PACEMAKER_CONFIG_DIR@#g' \
|
||||||
|
-e 's#%PCMK_GNUTLS_PRIORITIES%#@PCMK_GNUTLS_PRIORITIES@#g' \
|
||||||
|
+ -e 's#%PCMK__REMOTE_SCHEMA_DIR%#@PCMK__REMOTE_SCHEMA_DIR@#g' \
|
||||||
|
$(<) > "$@"
|
||||||
|
|
||||||
|
$(BOOK)/_build: $(STATIC_FILES) $(BOOK)/conf.py $(DEPS_$(BOOK)) $(wildcard $(srcdir)/$(BOOK)/*.rst)
|
||||||
|
diff --git a/doc/sphinx/conf.py.in b/doc/sphinx/conf.py.in
|
||||||
|
index 556eb72..511f029 100644
|
||||||
|
--- a/doc/sphinx/conf.py.in
|
||||||
|
+++ b/doc/sphinx/conf.py.in
|
||||||
|
@@ -40,6 +40,7 @@ rst_prolog="""
|
||||||
|
.. |PCMK_INIT_ENV_FILE| replace:: ``%PACEMAKER_CONFIG_DIR%/pcmk-init.env``
|
||||||
|
.. |PCMK_LOG_FILE| replace:: %CRM_LOG_DIR%/pacemaker.log
|
||||||
|
.. |PCMK_GNUTLS_PRIORITIES| replace:: %PCMK_GNUTLS_PRIORITIES%
|
||||||
|
+.. |PCMK__REMOTE_SCHEMA_DIR| replace:: %PCMK__REMOTE_SCHEMA_DIR%
|
||||||
|
.. |REMOTE_DISTRO| replace:: AlmaLinux
|
||||||
|
.. |REMOTE_DISTRO_VER| replace:: 9
|
||||||
|
"""
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
1443
004-attrd-cache-1.patch
Normal file
1443
004-attrd-cache-1.patch
Normal file
File diff suppressed because it is too large
Load Diff
2786
005-attrd-cache-2.patch
Normal file
2786
005-attrd-cache-2.patch
Normal file
File diff suppressed because it is too large
Load Diff
276
006-cib-file-feature-set.patch
Normal file
276
006-cib-file-feature-set.patch
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
From d50bbafc32428e873c0052a9defcf93d2e52667e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Chris Lumens <clumens@redhat.com>
|
||||||
|
Date: Wed, 10 Jan 2024 11:35:11 -0500
|
||||||
|
Subject: [PATCH 1/3] Refactor: libcrmcommon: Split feature set check into its
|
||||||
|
own function.
|
||||||
|
|
||||||
|
---
|
||||||
|
include/crm/common/cib_internal.h | 4 +++-
|
||||||
|
lib/cib/cib_utils.c | 12 ++++++------
|
||||||
|
lib/common/cib.c | 18 +++++++++++++++++-
|
||||||
|
3 files changed, 26 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/include/crm/common/cib_internal.h b/include/crm/common/cib_internal.h
|
||||||
|
index c41c12e..fa65e58 100644
|
||||||
|
--- a/include/crm/common/cib_internal.h
|
||||||
|
+++ b/include/crm/common/cib_internal.h
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
/*
|
||||||
|
- * Copyright 2023 the Pacemaker project contributors
|
||||||
|
+ * Copyright 2023-2024 the Pacemaker project contributors
|
||||||
|
*
|
||||||
|
* The version control history for this file may have further details.
|
||||||
|
*
|
||||||
|
@@ -16,6 +16,8 @@ extern "C" {
|
||||||
|
|
||||||
|
const char *pcmk__cib_abs_xpath_for(const char *element);
|
||||||
|
|
||||||
|
+int pcmk__check_feature_set(const char *cib_version);
|
||||||
|
+
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
diff --git a/lib/cib/cib_utils.c b/lib/cib/cib_utils.c
|
||||||
|
index 0082eef..bf2982c 100644
|
||||||
|
--- a/lib/cib/cib_utils.c
|
||||||
|
+++ b/lib/cib/cib_utils.c
|
||||||
|
@@ -353,7 +353,6 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query,
|
||||||
|
xmlNode *patchset_cib = NULL;
|
||||||
|
xmlNode *local_diff = NULL;
|
||||||
|
|
||||||
|
- const char *new_version = NULL;
|
||||||
|
const char *user = crm_element_value(req, F_CIB_USER);
|
||||||
|
bool with_digest = false;
|
||||||
|
|
||||||
|
@@ -470,12 +469,13 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scratch) {
|
||||||
|
- new_version = crm_element_value(scratch, XML_ATTR_CRM_VERSION);
|
||||||
|
+ const char *new_version = crm_element_value(scratch, XML_ATTR_CRM_VERSION);
|
||||||
|
|
||||||
|
- if (new_version && compare_version(new_version, CRM_FEATURE_SET) > 0) {
|
||||||
|
- crm_err("Discarding update with feature set '%s' greater than our own '%s'",
|
||||||
|
- new_version, CRM_FEATURE_SET);
|
||||||
|
- rc = -EPROTONOSUPPORT;
|
||||||
|
+ rc = pcmk__check_feature_set(new_version);
|
||||||
|
+ if (rc != pcmk_rc_ok) {
|
||||||
|
+ pcmk__config_err("Discarding update with feature set '%s' greater than our own '%s'",
|
||||||
|
+ new_version, CRM_FEATURE_SET);
|
||||||
|
+ rc = pcmk_rc2legacy(rc);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/lib/common/cib.c b/lib/common/cib.c
|
||||||
|
index fee7881..cbebc2e 100644
|
||||||
|
--- a/lib/common/cib.c
|
||||||
|
+++ b/lib/common/cib.c
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
/*
|
||||||
|
* Original copyright 2004 International Business Machines
|
||||||
|
- * Later changes copyright 2008-2023 the Pacemaker project contributors
|
||||||
|
+ * Later changes copyright 2008-2024 the Pacemaker project contributors
|
||||||
|
*
|
||||||
|
* The version control history for this file may have further details.
|
||||||
|
*
|
||||||
|
@@ -173,3 +173,19 @@ pcmk_find_cib_element(xmlNode *cib, const char *element_name)
|
||||||
|
{
|
||||||
|
return get_xpath_object(pcmk_cib_xpath_for(element_name), cib, LOG_TRACE);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ * \internal
|
||||||
|
+ * \brief Check that the feature set in the CIB is supported on this node
|
||||||
|
+ *
|
||||||
|
+ * \param[in] new_version XML_ATTR_CRM_VERSION attribute from the CIB
|
||||||
|
+ */
|
||||||
|
+int
|
||||||
|
+pcmk__check_feature_set(const char *cib_version)
|
||||||
|
+{
|
||||||
|
+ if (cib_version && compare_version(cib_version, CRM_FEATURE_SET) > 0) {
|
||||||
|
+ return EPROTONOSUPPORT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return pcmk_rc_ok;
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
|
From d89fd8336ae47d892201513c99773705d57f15f0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Chris Lumens <clumens@redhat.com>
|
||||||
|
Date: Wed, 10 Jan 2024 13:46:42 -0500
|
||||||
|
Subject: [PATCH 2/3] Feature: scheduler: Check the CIB feature set in
|
||||||
|
cluster_status.
|
||||||
|
|
||||||
|
This adds the check that was previously only in cib_perform_op to the
|
||||||
|
scheduler code, ensuring that any daemon or tool that calls the
|
||||||
|
scheduler will check that the feature set in the CIB is supported.
|
||||||
|
---
|
||||||
|
lib/pengine/status.c | 10 ++++++++++
|
||||||
|
1 file changed, 10 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/lib/pengine/status.c b/lib/pengine/status.c
|
||||||
|
index e6ec237..1294803 100644
|
||||||
|
--- a/lib/pengine/status.c
|
||||||
|
+++ b/lib/pengine/status.c
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#include <crm/crm.h>
|
||||||
|
#include <crm/msg_xml.h>
|
||||||
|
#include <crm/common/xml.h>
|
||||||
|
+#include <crm/common/cib_internal.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
@@ -70,12 +71,21 @@ pe_free_working_set(pcmk_scheduler_t *scheduler)
|
||||||
|
gboolean
|
||||||
|
cluster_status(pcmk_scheduler_t * scheduler)
|
||||||
|
{
|
||||||
|
+ const char *new_version = NULL;
|
||||||
|
xmlNode *section = NULL;
|
||||||
|
|
||||||
|
if ((scheduler == NULL) || (scheduler->input == NULL)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ new_version = crm_element_value(scheduler->input, XML_ATTR_CRM_VERSION);
|
||||||
|
+
|
||||||
|
+ if (pcmk__check_feature_set(new_version) != pcmk_rc_ok) {
|
||||||
|
+ pcmk__config_err("Can't process CIB with feature set '%s' greater than our own '%s'",
|
||||||
|
+ new_version, CRM_FEATURE_SET);
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
crm_trace("Beginning unpack");
|
||||||
|
|
||||||
|
if (scheduler->failed != NULL) {
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
|
From a3428926d37af506014a6b462d1308d8541c5932 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Chris Lumens <clumens@redhat.com>
|
||||||
|
Date: Wed, 10 Jan 2024 14:56:36 -0500
|
||||||
|
Subject: [PATCH 3/3] Low: libcib: Do not check CIB feature set for files in
|
||||||
|
cib_perform_op.
|
||||||
|
|
||||||
|
This is related to the previous feature for transferring schema files to
|
||||||
|
older remote nodes. In that case, the newer schema files may also have
|
||||||
|
a newer feature set than the node supports, so the transferred files are
|
||||||
|
still not usable.
|
||||||
|
|
||||||
|
However, the feature set only matters for the scheduler, not for most
|
||||||
|
command line tools (obviously, crm_simulate would still care). So in
|
||||||
|
those cases, we can just disable the feature set check if the CIB was
|
||||||
|
read in from a file. For the scheduler, the check is still performed as
|
||||||
|
part of cluster_status.
|
||||||
|
---
|
||||||
|
cts/cli/regression.tools.exp | 2 +-
|
||||||
|
daemons/based/based_callbacks.c | 4 ++--
|
||||||
|
include/crm/cib/internal.h | 4 ++--
|
||||||
|
lib/cib/cib_file.c | 2 +-
|
||||||
|
lib/cib/cib_utils.c | 15 +++++++++------
|
||||||
|
5 files changed, 15 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cts/cli/regression.tools.exp b/cts/cli/regression.tools.exp
|
||||||
|
index 417b5cd..c81c420 100644
|
||||||
|
--- a/cts/cli/regression.tools.exp
|
||||||
|
+++ b/cts/cli/regression.tools.exp
|
||||||
|
@@ -7939,7 +7939,7 @@ unpack_config warning: Blind faith: not fencing unseen nodes
|
||||||
|
=#=#=#= End test: Verbosely verify a file-specified invalid configuration, outputting as xml - Invalid configuration (78) =#=#=#=
|
||||||
|
* Passed: crm_verify - Verbosely verify a file-specified invalid configuration, outputting as xml
|
||||||
|
=#=#=#= Begin test: Verbosely verify another file-specified invalid configuration, outputting as xml =#=#=#=
|
||||||
|
-(cluster_status@status.c:113) warning: Fencing and resource management disabled due to lack of quorum
|
||||||
|
+(cluster_status@status.c:123) warning: Fencing and resource management disabled due to lack of quorum
|
||||||
|
<pacemaker-result api-version="X" request="crm_verify_invalid_no_stonith.xml --output-as=xml --verbose">
|
||||||
|
<status code="78" message="Invalid configuration">
|
||||||
|
<errors>
|
||||||
|
diff --git a/daemons/based/based_callbacks.c b/daemons/based/based_callbacks.c
|
||||||
|
index 5f3dc62..f16e4d9 100644
|
||||||
|
--- a/daemons/based/based_callbacks.c
|
||||||
|
+++ b/daemons/based/based_callbacks.c
|
||||||
|
@@ -1362,7 +1362,7 @@ cib_process_command(xmlNode *request, const cib__operation_t *operation,
|
||||||
|
input = prepare_input(request, operation->type, §ion);
|
||||||
|
|
||||||
|
if (!pcmk_is_set(operation->flags, cib__op_attr_modifies)) {
|
||||||
|
- rc = cib_perform_op(op, call_options, op_function, true, section,
|
||||||
|
+ rc = cib_perform_op(NULL, op, call_options, op_function, true, section,
|
||||||
|
request, input, false, &config_changed, &the_cib,
|
||||||
|
&result_cib, NULL, &output);
|
||||||
|
|
||||||
|
@@ -1395,7 +1395,7 @@ cib_process_command(xmlNode *request, const cib__operation_t *operation,
|
||||||
|
}
|
||||||
|
|
||||||
|
// result_cib must not be modified after cib_perform_op() returns
|
||||||
|
- rc = cib_perform_op(op, call_options, op_function, false, section,
|
||||||
|
+ rc = cib_perform_op(NULL, op, call_options, op_function, false, section,
|
||||||
|
request, input, manage_counters, &config_changed,
|
||||||
|
&the_cib, &result_cib, cib_diff, &output);
|
||||||
|
|
||||||
|
diff --git a/include/crm/cib/internal.h b/include/crm/cib/internal.h
|
||||||
|
index 9d54d52..b6d6871 100644
|
||||||
|
--- a/include/crm/cib/internal.h
|
||||||
|
+++ b/include/crm/cib/internal.h
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
/*
|
||||||
|
- * Copyright 2004-2023 the Pacemaker project contributors
|
||||||
|
+ * Copyright 2004-2024 the Pacemaker project contributors
|
||||||
|
*
|
||||||
|
* The version control history for this file may have further details.
|
||||||
|
*
|
||||||
|
@@ -206,7 +206,7 @@ int cib__get_notify_patchset(const xmlNode *msg, const xmlNode **patchset);
|
||||||
|
|
||||||
|
bool cib__element_in_patchset(const xmlNode *patchset, const char *element);
|
||||||
|
|
||||||
|
-int cib_perform_op(const char *op, int call_options, cib__op_fn_t fn,
|
||||||
|
+int cib_perform_op(cib_t *cib, const char *op, int call_options, cib__op_fn_t fn,
|
||||||
|
bool is_query, const char *section, xmlNode *req,
|
||||||
|
xmlNode *input, bool manage_counters, bool *config_changed,
|
||||||
|
xmlNode **current_cib, xmlNode **result_cib, xmlNode **diff,
|
||||||
|
diff --git a/lib/cib/cib_file.c b/lib/cib/cib_file.c
|
||||||
|
index a279823..9dd952c 100644
|
||||||
|
--- a/lib/cib/cib_file.c
|
||||||
|
+++ b/lib/cib/cib_file.c
|
||||||
|
@@ -245,7 +245,7 @@ cib_file_process_request(cib_t *cib, xmlNode *request, xmlNode **output)
|
||||||
|
data = pcmk_find_cib_element(data, section);
|
||||||
|
}
|
||||||
|
|
||||||
|
- rc = cib_perform_op(op, call_options, op_function, read_only, section,
|
||||||
|
+ rc = cib_perform_op(cib, op, call_options, op_function, read_only, section,
|
||||||
|
request, data, true, &changed, &private->cib_xml,
|
||||||
|
&result_cib, &cib_diff, output);
|
||||||
|
|
||||||
|
diff --git a/lib/cib/cib_utils.c b/lib/cib/cib_utils.c
|
||||||
|
index bf2982c..9c3f9f1 100644
|
||||||
|
--- a/lib/cib/cib_utils.c
|
||||||
|
+++ b/lib/cib/cib_utils.c
|
||||||
|
@@ -339,11 +339,10 @@ should_copy_cib(const char *op, const char *section, int call_options)
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
-cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query,
|
||||||
|
- const char *section, xmlNode *req, xmlNode *input,
|
||||||
|
- bool manage_counters, bool *config_changed,
|
||||||
|
- xmlNode **current_cib, xmlNode **result_cib, xmlNode **diff,
|
||||||
|
- xmlNode **output)
|
||||||
|
+cib_perform_op(cib_t *cib, const char *op, int call_options, cib__op_fn_t fn,
|
||||||
|
+ bool is_query, const char *section, xmlNode *req, xmlNode *input,
|
||||||
|
+ bool manage_counters, bool *config_changed, xmlNode **current_cib,
|
||||||
|
+ xmlNode **result_cib, xmlNode **diff, xmlNode **output)
|
||||||
|
{
|
||||||
|
int rc = pcmk_ok;
|
||||||
|
bool check_schema = true;
|
||||||
|
@@ -468,7 +467,11 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (scratch) {
|
||||||
|
+ /* If the CIB is from a file, we don't need to check that the feature set is
|
||||||
|
+ * supported. All we care about in that case is the schema version, which
|
||||||
|
+ * is checked elsewhere.
|
||||||
|
+ */
|
||||||
|
+ if (scratch && (cib == NULL || cib->variant != cib_file)) {
|
||||||
|
const char *new_version = crm_element_value(scratch, XML_ATTR_CRM_VERSION);
|
||||||
|
|
||||||
|
rc = pcmk__check_feature_set(new_version);
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
3689
007-option-metadata.patch
Normal file
3689
007-option-metadata.patch
Normal file
File diff suppressed because it is too large
Load Diff
373
008-attrd-prep.patch
Normal file
373
008-attrd-prep.patch
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
From 4823643bef8801b33688167b159bb531bcdf8911 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ken Gaillot <kgaillot@redhat.com>
|
||||||
|
Date: Thu, 4 Jan 2024 17:10:08 -0600
|
||||||
|
Subject: [PATCH 1/5] Refactor: pacemaker-attrd: drop redundant argument from
|
||||||
|
update_attr_on_host()
|
||||||
|
|
||||||
|
It can check for a force-write via its xml argument, to simplify the caller
|
||||||
|
---
|
||||||
|
daemons/attrd/attrd_corosync.c | 13 +++++++------
|
||||||
|
1 file changed, 7 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c
|
||||||
|
index 158d82f..1b56923 100644
|
||||||
|
--- a/daemons/attrd/attrd_corosync.c
|
||||||
|
+++ b/daemons/attrd/attrd_corosync.c
|
||||||
|
@@ -266,7 +266,7 @@ record_peer_nodeid(attribute_value_t *v, const char *host)
|
||||||
|
static void
|
||||||
|
update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
|
||||||
|
const char *attr, const char *value, const char *host,
|
||||||
|
- bool filter, int is_force_write)
|
||||||
|
+ bool filter)
|
||||||
|
{
|
||||||
|
attribute_value_t *v = NULL;
|
||||||
|
|
||||||
|
@@ -309,6 +309,10 @@ update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
+ int is_force_write = 0;
|
||||||
|
+
|
||||||
|
+ crm_element_value_int(xml, PCMK__XA_ATTR_FORCE, &is_force_write);
|
||||||
|
+
|
||||||
|
if (is_force_write == 1 && a->timeout_ms && a->timer) {
|
||||||
|
/* Save forced writing and set change flag. */
|
||||||
|
/* The actual attribute is written by Writer after election. */
|
||||||
|
@@ -338,15 +342,12 @@ attrd_peer_update_one(const crm_node_t *peer, xmlNode *xml, bool filter)
|
||||||
|
const char *attr = crm_element_value(xml, PCMK__XA_ATTR_NAME);
|
||||||
|
const char *value = crm_element_value(xml, PCMK__XA_ATTR_VALUE);
|
||||||
|
const char *host = crm_element_value(xml, PCMK__XA_ATTR_NODE_NAME);
|
||||||
|
- int is_force_write = 0;
|
||||||
|
|
||||||
|
if (attr == NULL) {
|
||||||
|
crm_warn("Could not update attribute: peer did not specify name");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- crm_element_value_int(xml, PCMK__XA_ATTR_FORCE, &is_force_write);
|
||||||
|
-
|
||||||
|
a = attrd_populate_attribute(xml, attr);
|
||||||
|
if (a == NULL) {
|
||||||
|
return;
|
||||||
|
@@ -361,12 +362,12 @@ attrd_peer_update_one(const crm_node_t *peer, xmlNode *xml, bool filter)
|
||||||
|
g_hash_table_iter_init(&vIter, a->values);
|
||||||
|
|
||||||
|
while (g_hash_table_iter_next(&vIter, (gpointer *) & host, NULL)) {
|
||||||
|
- update_attr_on_host(a, peer, xml, attr, value, host, filter, is_force_write);
|
||||||
|
+ update_attr_on_host(a, peer, xml, attr, value, host, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Update attribute value for the given host
|
||||||
|
- update_attr_on_host(a, peer, xml, attr, value, host, filter, is_force_write);
|
||||||
|
+ update_attr_on_host(a, peer, xml, attr, value, host, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this is a message from some attrd instance broadcasting its protocol
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
|
From c7a1ab819b25e3225c185c1630a7139a96fb5c71 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ken Gaillot <kgaillot@redhat.com>
|
||||||
|
Date: Tue, 9 Jan 2024 16:48:37 -0600
|
||||||
|
Subject: [PATCH 2/5] Refactor: pacemaker-attrd: drop unused argument from
|
||||||
|
attrd_peer_sync()
|
||||||
|
|
||||||
|
---
|
||||||
|
daemons/attrd/attrd_corosync.c | 10 ++++++++--
|
||||||
|
daemons/attrd/attrd_elections.c | 2 +-
|
||||||
|
daemons/attrd/attrd_messages.c | 2 +-
|
||||||
|
daemons/attrd/pacemaker-attrd.h | 2 +-
|
||||||
|
4 files changed, 11 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c
|
||||||
|
index 1b56923..088f00c 100644
|
||||||
|
--- a/daemons/attrd/attrd_corosync.c
|
||||||
|
+++ b/daemons/attrd/attrd_corosync.c
|
||||||
|
@@ -233,7 +233,7 @@ attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *da
|
||||||
|
*/
|
||||||
|
if (attrd_election_won()
|
||||||
|
&& !pcmk_is_set(peer->flags, crm_remote_node)) {
|
||||||
|
- attrd_peer_sync(peer, NULL);
|
||||||
|
+ attrd_peer_sync(peer);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Remove all attribute values associated with lost nodes
|
||||||
|
@@ -535,8 +535,14 @@ attrd_peer_remove(const char *host, bool uncache, const char *source)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*!
|
||||||
|
+ * \internal
|
||||||
|
+ * \brief Send all known attributes and values to a peer
|
||||||
|
+ *
|
||||||
|
+ * \param[in] peer Peer to send sync to (if NULL, broadcast to all peers)
|
||||||
|
+ */
|
||||||
|
void
|
||||||
|
-attrd_peer_sync(crm_node_t *peer, xmlNode *xml)
|
||||||
|
+attrd_peer_sync(crm_node_t *peer)
|
||||||
|
{
|
||||||
|
GHashTableIter aIter;
|
||||||
|
GHashTableIter vIter;
|
||||||
|
diff --git a/daemons/attrd/attrd_elections.c b/daemons/attrd/attrd_elections.c
|
||||||
|
index 82fbe8a..9dbf133 100644
|
||||||
|
--- a/daemons/attrd/attrd_elections.c
|
||||||
|
+++ b/daemons/attrd/attrd_elections.c
|
||||||
|
@@ -23,7 +23,7 @@ attrd_election_cb(gpointer user_data)
|
||||||
|
attrd_declare_winner();
|
||||||
|
|
||||||
|
/* Update the peers after an election */
|
||||||
|
- attrd_peer_sync(NULL, NULL);
|
||||||
|
+ attrd_peer_sync(NULL);
|
||||||
|
|
||||||
|
/* After winning an election, update the CIB with the values of all
|
||||||
|
* attributes as the winner knows them.
|
||||||
|
diff --git a/daemons/attrd/attrd_messages.c b/daemons/attrd/attrd_messages.c
|
||||||
|
index 5525d4b..13ac01f 100644
|
||||||
|
--- a/daemons/attrd/attrd_messages.c
|
||||||
|
+++ b/daemons/attrd/attrd_messages.c
|
||||||
|
@@ -180,7 +180,7 @@ handle_sync_request(pcmk__request_t *request)
|
||||||
|
crm_node_t *peer = pcmk__get_node(0, request->peer, NULL,
|
||||||
|
pcmk__node_search_cluster);
|
||||||
|
|
||||||
|
- attrd_peer_sync(peer, request->xml);
|
||||||
|
+ attrd_peer_sync(peer);
|
||||||
|
pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
diff --git a/daemons/attrd/pacemaker-attrd.h b/daemons/attrd/pacemaker-attrd.h
|
||||||
|
index 7384188..bacaad6 100644
|
||||||
|
--- a/daemons/attrd/pacemaker-attrd.h
|
||||||
|
+++ b/daemons/attrd/pacemaker-attrd.h
|
||||||
|
@@ -175,7 +175,7 @@ extern GHashTable *peer_protocol_vers;
|
||||||
|
int attrd_cluster_connect(void);
|
||||||
|
void attrd_peer_update(const crm_node_t *peer, xmlNode *xml, const char *host,
|
||||||
|
bool filter);
|
||||||
|
-void attrd_peer_sync(crm_node_t *peer, xmlNode *xml);
|
||||||
|
+void attrd_peer_sync(crm_node_t *peer);
|
||||||
|
void attrd_peer_remove(const char *host, bool uncache, const char *source);
|
||||||
|
void attrd_peer_clear_failure(pcmk__request_t *request);
|
||||||
|
void attrd_peer_sync_response(const crm_node_t *peer, bool peer_won,
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
|
From abafae0068e10abb135b0496086947728365299a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ken Gaillot <kgaillot@redhat.com>
|
||||||
|
Date: Thu, 11 Jan 2024 17:31:17 -0600
|
||||||
|
Subject: [PATCH 3/5] Refactor: pacemaker-attrd: de-functionize
|
||||||
|
attrd_lookup_or_create_value()
|
||||||
|
|
||||||
|
... to make planned changes easier
|
||||||
|
---
|
||||||
|
daemons/attrd/attrd_corosync.c | 62 +++++++++++++---------------------
|
||||||
|
1 file changed, 24 insertions(+), 38 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c
|
||||||
|
index 088f00c..59e6a26 100644
|
||||||
|
--- a/daemons/attrd/attrd_corosync.c
|
||||||
|
+++ b/daemons/attrd/attrd_corosync.c
|
||||||
|
@@ -168,40 +168,6 @@ broadcast_local_value(const attribute_t *a)
|
||||||
|
|
||||||
|
#define state_text(state) pcmk__s((state), "in unknown state")
|
||||||
|
|
||||||
|
-/*!
|
||||||
|
- * \internal
|
||||||
|
- * \brief Return a node's value from hash table (creating one if needed)
|
||||||
|
- *
|
||||||
|
- * \param[in,out] values Hash table of values
|
||||||
|
- * \param[in] node_name Name of node to look up
|
||||||
|
- * \param[in] xml XML describing the attribute
|
||||||
|
- *
|
||||||
|
- * \return Pointer to new or existing hash table entry
|
||||||
|
- */
|
||||||
|
-static attribute_value_t *
|
||||||
|
-attrd_lookup_or_create_value(GHashTable *values, const char *node_name,
|
||||||
|
- const xmlNode *xml)
|
||||||
|
-{
|
||||||
|
- attribute_value_t *v = g_hash_table_lookup(values, node_name);
|
||||||
|
- int is_remote = 0;
|
||||||
|
-
|
||||||
|
- if (v == NULL) {
|
||||||
|
- v = calloc(1, sizeof(attribute_value_t));
|
||||||
|
- CRM_ASSERT(v != NULL);
|
||||||
|
-
|
||||||
|
- pcmk__str_update(&v->nodename, node_name);
|
||||||
|
- g_hash_table_replace(values, v->nodename, v);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- crm_element_value_int(xml, PCMK__XA_ATTR_IS_REMOTE, &is_remote);
|
||||||
|
- if (is_remote) {
|
||||||
|
- attrd_set_value_flags(v, attrd_value_remote);
|
||||||
|
- CRM_ASSERT(crm_remote_peer_get(node_name) != NULL);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return(v);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static void
|
||||||
|
attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *data)
|
||||||
|
{
|
||||||
|
@@ -268,18 +234,38 @@ update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
|
||||||
|
const char *attr, const char *value, const char *host,
|
||||||
|
bool filter)
|
||||||
|
{
|
||||||
|
+ int is_remote = 0;
|
||||||
|
+ bool changed = false;
|
||||||
|
attribute_value_t *v = NULL;
|
||||||
|
|
||||||
|
- v = attrd_lookup_or_create_value(a->values, host, xml);
|
||||||
|
+ // Create entry for value if not already existing
|
||||||
|
+ v = g_hash_table_lookup(a->values, host);
|
||||||
|
+ if (v == NULL) {
|
||||||
|
+ v = calloc(1, sizeof(attribute_value_t));
|
||||||
|
+ CRM_ASSERT(v != NULL);
|
||||||
|
+
|
||||||
|
+ pcmk__str_update(&v->nodename, host);
|
||||||
|
+ g_hash_table_replace(a->values, v->nodename, v);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // If value is for a Pacemaker Remote node, remember that
|
||||||
|
+ crm_element_value_int(xml, PCMK__XA_ATTR_IS_REMOTE, &is_remote);
|
||||||
|
+ if (is_remote) {
|
||||||
|
+ attrd_set_value_flags(v, attrd_value_remote);
|
||||||
|
+ CRM_ASSERT(crm_remote_peer_get(host) != NULL);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Check whether the value changed
|
||||||
|
+ changed = !pcmk__str_eq(v->current, value, pcmk__str_casei);
|
||||||
|
|
||||||
|
- if (filter && !pcmk__str_eq(v->current, value, pcmk__str_casei)
|
||||||
|
- && pcmk__str_eq(host, attrd_cluster->uname, pcmk__str_casei)) {
|
||||||
|
+ if (changed && filter && pcmk__str_eq(host, attrd_cluster->uname,
|
||||||
|
+ pcmk__str_casei)) {
|
||||||
|
|
||||||
|
crm_notice("%s[%s]: local value '%s' takes priority over '%s' from %s",
|
||||||
|
attr, host, v->current, value, peer->uname);
|
||||||
|
v = broadcast_local_value(a);
|
||||||
|
|
||||||
|
- } else if (!pcmk__str_eq(v->current, value, pcmk__str_casei)) {
|
||||||
|
+ } else if (changed) {
|
||||||
|
crm_notice("Setting %s[%s]%s%s: %s -> %s "
|
||||||
|
CRM_XS " from %s with %s write delay",
|
||||||
|
attr, host, a->set_type ? " in " : "",
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
|
From 72529ec512fb4938bd8dbbd2caf44bbb1a616826 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ken Gaillot <kgaillot@redhat.com>
|
||||||
|
Date: Thu, 11 Jan 2024 18:04:33 -0600
|
||||||
|
Subject: [PATCH 4/5] Refactor: pacemaker-attrd: minor shuffling to make
|
||||||
|
planned changes easier
|
||||||
|
|
||||||
|
---
|
||||||
|
daemons/attrd/attrd_cib.c | 19 +++++++++++--------
|
||||||
|
1 file changed, 11 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemons/attrd/attrd_cib.c b/daemons/attrd/attrd_cib.c
|
||||||
|
index bdc0a10..481fea7 100644
|
||||||
|
--- a/daemons/attrd/attrd_cib.c
|
||||||
|
+++ b/daemons/attrd/attrd_cib.c
|
||||||
|
@@ -51,6 +51,7 @@ attrd_cib_updated_cb(const char *event, xmlNode *msg)
|
||||||
|
{
|
||||||
|
const xmlNode *patchset = NULL;
|
||||||
|
const char *client_name = NULL;
|
||||||
|
+ bool status_changed = false;
|
||||||
|
|
||||||
|
if (attrd_shutting_down(true)) {
|
||||||
|
return;
|
||||||
|
@@ -64,20 +65,22 @@ attrd_cib_updated_cb(const char *event, xmlNode *msg)
|
||||||
|
mainloop_set_trigger(attrd_config_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!attrd_election_won()) {
|
||||||
|
- // Don't write attributes if we're not the writer
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
+ status_changed = cib__element_in_patchset(patchset, XML_CIB_TAG_STATUS);
|
||||||
|
|
||||||
|
client_name = crm_element_value(msg, F_CIB_CLIENTNAME);
|
||||||
|
if (!cib__client_triggers_refresh(client_name)) {
|
||||||
|
- // The CIB is still accurate
|
||||||
|
+ /* This change came from a source that ensured the CIB is consistent
|
||||||
|
+ * with our attributes table, so we don't need to write anything out.
|
||||||
|
+ */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (cib__element_in_patchset(patchset, XML_CIB_TAG_NODES)
|
||||||
|
- || cib__element_in_patchset(patchset, XML_CIB_TAG_STATUS)) {
|
||||||
|
-
|
||||||
|
+ if (!attrd_election_won()) {
|
||||||
|
+ // Don't write attributes if we're not the writer
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (status_changed || cib__element_in_patchset(patchset, XML_CIB_TAG_NODES)) {
|
||||||
|
/* An unsafe client modified the nodes or status section. Write
|
||||||
|
* transient attributes to ensure they're up-to-date in the CIB.
|
||||||
|
*/
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
|
From b83c2567fb450eec5b18882ded16403831d2c3c0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ken Gaillot <kgaillot@redhat.com>
|
||||||
|
Date: Thu, 11 Jan 2024 17:53:55 -0600
|
||||||
|
Subject: [PATCH 5/5] Log: pacemaker-attrd: make sure we don't try to log NULL
|
||||||
|
|
||||||
|
---
|
||||||
|
daemons/attrd/attrd_corosync.c | 15 +++++++++++----
|
||||||
|
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c
|
||||||
|
index 59e6a26..b348d52 100644
|
||||||
|
--- a/daemons/attrd/attrd_corosync.c
|
||||||
|
+++ b/daemons/attrd/attrd_corosync.c
|
||||||
|
@@ -229,6 +229,11 @@ record_peer_nodeid(attribute_value_t *v, const char *host)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+#define readable_value(rv_v) pcmk__s((rv_v)->current, "(unset)")
|
||||||
|
+
|
||||||
|
+#define readable_peer(p) \
|
||||||
|
+ (((p) == NULL)? "all peers" : pcmk__s((p)->uname, "unknown peer"))
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
|
||||||
|
const char *attr, const char *value, const char *host,
|
||||||
|
@@ -262,14 +267,14 @@ update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
|
||||||
|
pcmk__str_casei)) {
|
||||||
|
|
||||||
|
crm_notice("%s[%s]: local value '%s' takes priority over '%s' from %s",
|
||||||
|
- attr, host, v->current, value, peer->uname);
|
||||||
|
+ attr, host, readable_value(v), value, peer->uname);
|
||||||
|
v = broadcast_local_value(a);
|
||||||
|
|
||||||
|
} else if (changed) {
|
||||||
|
crm_notice("Setting %s[%s]%s%s: %s -> %s "
|
||||||
|
CRM_XS " from %s with %s write delay",
|
||||||
|
attr, host, a->set_type ? " in " : "",
|
||||||
|
- pcmk__s(a->set_type, ""), pcmk__s(v->current, "(unset)"),
|
||||||
|
+ pcmk__s(a->set_type, ""), readable_value(v),
|
||||||
|
pcmk__s(value, "(unset)"), peer->uname,
|
||||||
|
(a->timeout_ms == 0)? "no" : pcmk__readable_interval(a->timeout_ms));
|
||||||
|
pcmk__str_update(&v->current, value);
|
||||||
|
@@ -543,12 +548,14 @@ attrd_peer_sync(crm_node_t *peer)
|
||||||
|
while (g_hash_table_iter_next(&aIter, NULL, (gpointer *) & a)) {
|
||||||
|
g_hash_table_iter_init(&vIter, a->values);
|
||||||
|
while (g_hash_table_iter_next(&vIter, NULL, (gpointer *) & v)) {
|
||||||
|
- crm_debug("Syncing %s[%s] = %s to %s", a->id, v->nodename, v->current, peer?peer->uname:"everyone");
|
||||||
|
+ crm_debug("Syncing %s[%s]='%s' to %s",
|
||||||
|
+ a->id, v->nodename, readable_value(v),
|
||||||
|
+ readable_peer(peer));
|
||||||
|
attrd_add_value_xml(sync, a, v, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- crm_debug("Syncing values to %s", peer?peer->uname:"everyone");
|
||||||
|
+ crm_debug("Syncing values to %s", readable_peer(peer));
|
||||||
|
attrd_send_message(peer, sync, false);
|
||||||
|
free_xml(sync);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -36,10 +36,10 @@
|
|||||||
## can be incremented to build packages reliably considered "newer"
|
## can be incremented to build packages reliably considered "newer"
|
||||||
## than previously built packages with the same pcmkversion)
|
## than previously built packages with the same pcmkversion)
|
||||||
%global pcmkversion 2.1.7
|
%global pcmkversion 2.1.7
|
||||||
%global specversion 2
|
%global specversion 3
|
||||||
|
|
||||||
## Upstream commit (full commit ID, abbreviated commit ID, or tag) to build
|
## Upstream commit (full commit ID, abbreviated commit ID, or tag) to build
|
||||||
%global commit c858c13cb79431b5c8e5dda3ca44dd305fce946c
|
%global commit 0f7f88312f7a1ccedee60bf768aba79ee13d41e0
|
||||||
|
|
||||||
## Since git v2.11, the extent of abbreviation is autoscaled by default
|
## Since git v2.11, the extent of abbreviation is autoscaled by default
|
||||||
## (used to be constant of 7), so we need to convey it for non-tags, too.
|
## (used to be constant of 7), so we need to convey it for non-tags, too.
|
||||||
@ -249,6 +249,12 @@ Source2: pacemaker.sysusers
|
|||||||
# upstream commits
|
# upstream commits
|
||||||
Patch001: 001-schema-glib.patch
|
Patch001: 001-schema-glib.patch
|
||||||
Patch002: 002-schema-transfer.patch
|
Patch002: 002-schema-transfer.patch
|
||||||
|
Patch003: 003-schema-doc.patch
|
||||||
|
Patch004: 004-attrd-cache-1.patch
|
||||||
|
Patch005: 005-attrd-cache-2.patch
|
||||||
|
Patch006: 006-cib-file-feature-set.patch
|
||||||
|
Patch007: 007-option-metadata.patch
|
||||||
|
Patch008: 008-attrd-prep.patch
|
||||||
|
|
||||||
Requires: resource-agents
|
Requires: resource-agents
|
||||||
Requires: %{pkgname_pcmk_libs}%{?_isa} = %{version}-%{release}
|
Requires: %{pkgname_pcmk_libs}%{?_isa} = %{version}-%{release}
|
||||||
@ -907,6 +913,16 @@ exit 0
|
|||||||
%license %{nagios_name}-%{nagios_hash}/COPYING
|
%license %{nagios_name}-%{nagios_hash}/COPYING
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jan 16 2024 Chris Lumens <clumens@redhat.com> - 2.1.7-3
|
||||||
|
- Rebase on upstream 2.1.7 final release
|
||||||
|
- Fix documentation for Pacemaker Remote schema transfers
|
||||||
|
- Do not check CIB feature set version when CIB_file is set
|
||||||
|
- Consolidate attrd cache handling
|
||||||
|
- Avoid duplicating option metadata across daemons
|
||||||
|
- Related: RHEL-7665
|
||||||
|
- Related: RHEL-13216
|
||||||
|
- Resolves: RHEL-7702
|
||||||
|
|
||||||
* Wed Dec 13 2023 Chris Lumens <clumens@redhat.com> - 2.1.7-2
|
* Wed Dec 13 2023 Chris Lumens <clumens@redhat.com> - 2.1.7-2
|
||||||
- Rebase on upstream 2.1.7-rc4 release
|
- Rebase on upstream 2.1.7-rc4 release
|
||||||
- Use systemd-sysusers to create user/group
|
- Use systemd-sysusers to create user/group
|
||||||
|
2
sources
2
sources
@ -1,2 +1,2 @@
|
|||||||
SHA512 (nagios-agents-metadata-105ab8a7b2c16b9a29cf1c1596b80136eeef332b.tar.gz) = 11ddeb48a4929e7642b6dfa9c7962aa1d7a1af1c569830f55ed6cd6773abac13377317327bc1db8411c8077884f83f81cc54d746c834b63a99fa6dc219b5caad
|
SHA512 (nagios-agents-metadata-105ab8a7b2c16b9a29cf1c1596b80136eeef332b.tar.gz) = 11ddeb48a4929e7642b6dfa9c7962aa1d7a1af1c569830f55ed6cd6773abac13377317327bc1db8411c8077884f83f81cc54d746c834b63a99fa6dc219b5caad
|
||||||
SHA512 (pacemaker-c858c13cb.tar.gz) = 67a6669bb42dd7adcde2a99155086746a95a37262a14b6ca2c4f8f2706ba572ef2a3715cc40bbeb6988ae6a8979ed8ce208c890934ea0eb5d8448d84510cf3ce
|
SHA512 (pacemaker-0f7f88312.tar.gz) = 9bea37a11594aa4dc1470d212faff91e577856955278b37ec23c6fcdf5baf7bd8948d304e2fb8dcd9d078a344663ae3656b40ba94feda03aca2ec425b7d0d16b
|
||||||
|
Loading…
Reference in New Issue
Block a user