Peter Varkoly 2021-06-01 14:20:46 +00:00 committed by Git OBS Bridge
parent 864db64eae
commit c5a162b3fb
4 changed files with 3 additions and 444 deletions

View File

@ -1,200 +0,0 @@
From d963c2ab6cac0bf18355159afd815c0eb78e4aa8 Mon Sep 17 00:00:00 2001
From: Jan Friesse <jfriesse@redhat.com>
Date: Mon, 27 Jul 2020 16:10:54 +0200
Subject: [PATCH] totemip: Add support for sin6_scope_id
sin6_scope_id is not present in totemip structure making impossible to
use link-local ipv6 address.
Patch adds new call totemip_totemip_to_sockaddr_convert_with_scopeid
which can be instructed to fill scope id. This function calls
totemip_getif_scopeid which walks local addresses and returns
scope id if interface matches.
Main difference between this patch and
934c47ed4384daf2819c26306bebba3225807499 is fact, that totemip
structure keeps unchanged so corosync stays wire compatible.
This makes corosync work with link-local addresses fine for both UDPU
and UDP transport as long as there is only one matching interface with
this patch.
Big thanks to Aleksei Burlakov <aburlakov@suse.com> who brought idea
(and implementation) of using totemip_getif_scopeid.
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
---
exec/totemip.c | 69 ++++++++++++++++++++++++++++++--
exec/totemudp.c | 7 ++--
exec/totemudpu.c | 6 ++-
include/corosync/totem/totemip.h | 4 ++
4 files changed, 77 insertions(+), 9 deletions(-)
diff --git a/exec/totemip.c b/exec/totemip.c
index f89c70a04..4f08f5375 100644
--- a/exec/totemip.c
+++ b/exec/totemip.c
@@ -50,6 +50,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <ifaddrs.h>
+#include <corosync/logsys.h>
#include <corosync/totem/totemip.h>
#include <corosync/swab.h>
@@ -267,11 +268,58 @@ const char *totemip_print(const struct totem_ip_address *addr)
return (inet_ntop(addr->family, addr->addr, buf, sizeof(buf)));
}
-/* Make a totem_ip_address into a usable sockaddr_storage */
-int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr,
- uint16_t port, struct sockaddr_storage *saddr, int *addrlen)
+static int totemip_getif_scopeid(const unsigned char *addr16, unsigned int *scopeid)
+{
+ struct ifaddrs *ifa;
+ const struct sockaddr_in6 *sin6;
+ const socklen_t addr_len = sizeof(struct in6_addr);
+ int rc = -1; // 0 = found 1 match; -1 = found 0 matches; -2 = found >1 matches
+ struct ifaddrs *totemip_getif_scopeid_ifap;
+
+ if (getifaddrs(&totemip_getif_scopeid_ifap) != 0) {
+ return (-1);
+ }
+
+ for (ifa = totemip_getif_scopeid_ifap; ifa; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL)
+ continue ;
+
+ if ((ifa->ifa_addr->sa_family != AF_INET6) ||
+ (ifa->ifa_netmask->sa_family != AF_INET6 &&
+ ifa->ifa_netmask->sa_family != 0))
+ continue ;
+
+ sin6 = (const struct sockaddr_in6 *)ifa->ifa_addr;
+
+ if (memcmp(&sin6->sin6_addr, addr16, addr_len) == 0) {
+ *scopeid = sin6->sin6_scope_id;
+
+ if (rc == -1) {
+ rc = 0;
+ } else {
+ rc = -2;
+ }
+ }
+ }
+
+ if (rc == -2) {
+ log_printf(LOGSYS_LEVEL_WARNING, "(%s) exists on several interfaces."
+ " Use 'ip a' to see details.",
+ totemip_sa_print(ifa->ifa_addr));
+ }
+
+ freeifaddrs(totemip_getif_scopeid_ifap);
+
+ return rc;
+}
+
+
+int totemip_totemip_to_sockaddr_convert_with_scopeid(const struct totem_ip_address *ip_addr,
+ uint16_t port, struct sockaddr_storage *saddr, int *addrlen,
+ int fill_scopeid)
{
int ret = -1;
+ unsigned int scopeid;
if (ip_addr->family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
@@ -296,7 +344,11 @@ int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr,
#endif
sin->sin6_family = ip_addr->family;
sin->sin6_port = ntohs(port);
- sin->sin6_scope_id = 2;
+ if (fill_scopeid) {
+ if (totemip_getif_scopeid(ip_addr->addr, &scopeid) == 0) {
+ sin->sin6_scope_id = scopeid;
+ }
+ }
memcpy(&sin->sin6_addr, ip_addr->addr, sizeof(struct in6_addr));
*addrlen = sizeof(struct sockaddr_in6);
@@ -306,6 +358,15 @@ int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr,
return ret;
}
+/* Make a totem_ip_address into a usable sockaddr_storage */
+int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr,
+ uint16_t port, struct sockaddr_storage *saddr, int *addrlen)
+{
+
+ return (totemip_totemip_to_sockaddr_convert_with_scopeid(ip_addr, port, saddr, addrlen, 0));
+}
+
+
/* Converts an address string string into a totem_ip_address.
family can be AF_INET, AF_INET6 or 0 ("for "don't care")
*/
diff --git a/exec/totemudp.c b/exec/totemudp.c
index 4b644aee3..c11bbe8e6 100644
--- a/exec/totemudp.c
+++ b/exec/totemudp.c
@@ -834,8 +834,8 @@ static int totemudp_build_sockets_ip (
return (-1);
}
- totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port - 1,
- &sockaddr, &addrlen);
+ totemip_totemip_to_sockaddr_convert_with_scopeid(bound_to, instance->totem_interface->ip_port - 1,
+ &sockaddr, &addrlen, 1);
retries = 0;
while (1) {
@@ -890,7 +890,8 @@ static int totemudp_build_sockets_ip (
* Bind to unicast socket used for token send/receives
* This has the side effect of binding to the correct interface
*/
- totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port, &sockaddr, &addrlen);
+ totemip_totemip_to_sockaddr_convert_with_scopeid(bound_to, instance->totem_interface->ip_port,
+ &sockaddr, &addrlen, 1);
retries = 0;
while (1) {
diff --git a/exec/totemudpu.c b/exec/totemudpu.c
index f9d50af26..1d9410f65 100644
--- a/exec/totemudpu.c
+++ b/exec/totemudpu.c
@@ -824,7 +824,9 @@ static int totemudpu_build_sockets_ip (
* Bind to unicast socket used for token send/receives
* This has the side effect of binding to the correct interface
*/
- totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port, &sockaddr, &addrlen);
+ totemip_totemip_to_sockaddr_convert_with_scopeid(bound_to, instance->totem_interface->ip_port,
+ &sockaddr, &addrlen, 1);
+
while (1) {
res = bind (instance->token_socket, (struct sockaddr *)&sockaddr, addrlen);
if (res == 0) {
@@ -1331,7 +1333,7 @@ static int totemudpu_create_sending_socket(
/*
* Bind to sending interface
*/
- totemip_totemip_to_sockaddr_convert(&instance->my_id, 0, &sockaddr, &addrlen);
+ totemip_totemip_to_sockaddr_convert_with_scopeid(&instance->my_id, 0, &sockaddr, &addrlen, 1);
res = bind (fd, (struct sockaddr *)&sockaddr, addrlen);
if (res == -1) {
LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
diff --git a/include/corosync/totem/totemip.h b/include/corosync/totem/totemip.h
index 891a0524b..2a63317b1 100644
--- a/include/corosync/totem/totemip.h
+++ b/include/corosync/totem/totemip.h
@@ -97,6 +97,10 @@ extern int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr,
uint16_t port, struct sockaddr_storage *saddr, int *addrlen);
extern int totemip_parse(struct totem_ip_address *totemip, const char *addr,
int family);
+extern int totemip_totemip_to_sockaddr_convert_with_scopeid(const struct totem_ip_address *ip_addr,
+ uint16_t port, struct sockaddr_storage *saddr, int *addrlen,
+ int fill_scopeid);
+
extern int totemip_iface_check(struct totem_ip_address *bindnet,
struct totem_ip_address *boundto,
int *interface_up,

View File

@ -1,241 +0,0 @@
From a95e28cc35e1d59cedb406914ba437e21bc3e1ea Mon Sep 17 00:00:00 2001
From: Jan Friesse <jfriesse@redhat.com>
Date: Thu, 14 Feb 2019 16:05:59 +0100
Subject: [PATCH] quorumtool: Fix exit status codes
1. Use EXIT_SUCCESS and EXIT_FAILURE when possible
2. For -s option return EXIT_SUCCESS when no problem appeared and node
is quorate, EXIT_FAILURE if problem appeared and exit code 2
(EXIT_NOT_QUORATE) when no problem appeared but node is not quorate.
3. Document exit codes in the man page
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
(cherry picked from commit db38e3958c4f88d5d06e8f7c83d6d90334d9fbd2)
---
man/corosync-quorumtool.8 | 17 +++++++++++-
tools/corosync-quorumtool.c | 53 ++++++++++++++++++++++---------------
2 files changed, 47 insertions(+), 23 deletions(-)
diff --git a/man/corosync-quorumtool.8 b/man/corosync-quorumtool.8
index 915f35ff..2fc4e020 100644
--- a/man/corosync-quorumtool.8
+++ b/man/corosync-quorumtool.8
@@ -31,7 +31,7 @@
.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
.\" * THE POSSIBILITY OF SUCH DAMAGE.
.\" */
-.TH COROSYNC-QUORUMTOOL 8 2012-01-12
+.TH COROSYNC-QUORUMTOOL 8 2019-02-14
.SH NAME
corosync-quorumtool \- Set and display quorum settings.
.SH SYNOPSIS
@@ -89,6 +89,21 @@ show this help text
show version and exit
.PP
* Starred items only work if votequorum is the quorum provider for corosync
+.SH EXIT STATUS
+corosync-quorumtool may return one of several error codes if it encounters problems.
+.TP
+0
+No problems occurred (quorate for
+.B -s
+operation).
+.TP
+1
+Generic error code.
+.TP
+2
+Not quorate (returned only for
+.B -s
+operation).
.SH SEE ALSO
.BR corosync_overview (8),
.BR votequorum_overview (8),
diff --git a/tools/corosync-quorumtool.c b/tools/corosync-quorumtool.c
index e5d17b16..66ca7de5 100644
--- a/tools/corosync-quorumtool.c
+++ b/tools/corosync-quorumtool.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2014 Red Hat, Inc.
+ * Copyright (c) 2009-2019 Red Hat, Inc.
*
* All rights reserved.
*
@@ -75,6 +75,8 @@ typedef enum {
SORT_NODENAME
} sorttype_t;
+#define EXIT_NOT_QUORATE 2
+
/*
* global vars
*/
@@ -238,7 +240,7 @@ static int set_votes(uint32_t nodeid, int votes)
votes, nodeid, cs_strerror(err));
}
- return err==CS_OK?0:err;
+ return (err == CS_OK ? EXIT_SUCCESS : EXIT_FAILURE);
}
static int set_expected(int expected_votes)
@@ -249,7 +251,7 @@ static int set_expected(int expected_votes)
fprintf(stderr, "Unable to set expected votes: %s\n", cs_strerror(err));
}
- return err==CS_OK?0:err;
+ return (err == CS_OK ? EXIT_SUCCESS : EXIT_FAILURE);
}
/*
@@ -638,9 +640,9 @@ static int display_quorum_data(int is_quorate,
}
/*
- * return 1 if quorate
- * 0 if not quorate
- * -1 on error
+ * return EXIT_SUCCESS if quorate
+ * EXIT_NOT_QUORATE if not quorate
+ * EXIT_FAILURE on error
*/
static int show_status(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type)
{
@@ -689,15 +691,15 @@ static int show_status(nodeid_format_t nodeid_format, name_format_t name_format,
quorum_err:
if (err != CS_OK) {
- return -1;
+ return EXIT_FAILURE;
}
err = display_quorum_data(is_quorate, nodeid_format, name_format, sort_type, 0);
if (err != CS_OK) {
- return -1;
+ return EXIT_FAILURE;
}
- return is_quorate;
+ return (is_quorate ? EXIT_SUCCESS : EXIT_NOT_QUORATE);
}
static int monitor_status(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type) {
@@ -750,7 +752,7 @@ static int monitor_status(nodeid_format_t nodeid_format, name_format_t name_form
}
quorum_err:
- return -1;
+ return EXIT_FAILURE;
}
static int show_nodes(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type)
@@ -784,23 +786,30 @@ static int unregister_qdevice(void)
{
int err;
struct votequorum_info info;
+ int result;
+
+ result = EXIT_FAILURE;
err = votequorum_getinfo(v_handle, our_nodeid, &info);
if (err != CS_OK) {
fprintf(stderr, "Unable to get quorum device info: %s\n", cs_strerror(err));
- return -1;
+ goto err_exit;
}
if (!(info.flags & VOTEQUORUM_INFO_QDEVICE_REGISTERED)) {
- return 0;
+ result = EXIT_SUCCESS;
+ goto err_exit;
}
err = votequorum_qdevice_unregister(v_handle, info.qdevice_name);
if (err != CS_OK) {
fprintf(stderr, "Unable to unregister quorum device: %s\n", cs_strerror(err));
- return -1;
+ goto err_exit;
}
- return 0;
+
+ result = EXIT_SUCCESS;
+err_exit:
+ return result;
}
/*
@@ -884,7 +893,7 @@ int main (int argc, char *argv[]) {
if (init_all()) {
close_all();
- exit(1);
+ exit(EXIT_FAILURE);
}
while ( (opt = getopt(argc, argv, options)) != -1 ) {
@@ -894,7 +903,7 @@ int main (int argc, char *argv[]) {
command_opt = CMD_UNREGISTER_QDEVICE;
} else {
fprintf(stderr, "You cannot unregister quorum device, corosync is not using votequorum\n");
- exit(2);
+ exit(EXIT_FAILURE);
}
break;
case 's':
@@ -928,14 +937,14 @@ int main (int argc, char *argv[]) {
}
} else {
fprintf(stderr, "You cannot change expected votes, corosync is not using votequorum\n");
- exit(2);
+ exit(EXIT_FAILURE);
}
break;
case 'n':
l = strtol(optarg, &endptr, 0);
if ((l == 0 && endptr == optarg) || l < 0) {
fprintf(stderr, "The nodeid was not valid, try a positive number\n");
- exit(2);
+ exit(EXIT_FAILURE);
}
nodeid = l;
nodeid_set = 1;
@@ -945,14 +954,14 @@ int main (int argc, char *argv[]) {
votes = strtol(optarg, &endptr, 0);
if ((votes == 0 && endptr == optarg) || votes < 0) {
fprintf(stderr, "New votes value was not valid, try a positive number or zero\n");
- exit(2);
+ exit(EXIT_FAILURE);
} else {
command_opt = CMD_SETVOTES;
}
}
else {
fprintf(stderr, "You cannot change node votes, corosync is not using votequorum\n");
- exit(2);
+ exit(EXIT_FAILURE);
}
break;
case 'o':
@@ -966,7 +975,7 @@ int main (int argc, char *argv[]) {
break;
default:
fprintf(stderr, "Invalid ordering option. valid orders are a(address), i(node ID) or n(name)\n");
- exit(2);
+ exit(EXIT_FAILURE);
break;
}
break;
@@ -985,7 +994,7 @@ int main (int argc, char *argv[]) {
switch (command_opt) {
case CMD_UNKNOWN:
show_usage(argv[0]);
- ret = -1;
+ ret = EXIT_FAILURE;
break;
case CMD_SHOWNODES:
ret = show_nodes(nodeid_format, address_format, sort_opt);
--
2.21.1

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bb2776e7c7bea38d05779c79357335ae4d3af37ce0bda39137a51cdf9d702dd7
size 454259

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b67dfc8de715e1366abdb73dbdfb5676b9551f9e2f61c2b2a3271e605cf8583c
size 453945