All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Wagner <tripolar@gmx.at>
To: Chuck Lever <chuck.lever@oracle.com>,
	Linux NFS Mailing List <linux-nfs@vger.kernel.org>
Subject: Re: [PATCH] nfs-utils: fix addrinfo usage with musl-1.1.21
Date: Mon, 18 Feb 2019 22:22:33 +0100	[thread overview]
Message-ID: <20190218222233.04a318fa@onion.lan> (raw)
In-Reply-To: <0B1E18B0-0034-4612-B63B-41155D2E0D64@oracle.com>

Hi Chuck,

> We need a different solution here that works with all C libraries.
> If Peter agrees, I'll volunteer to have a look at this.

yeah I'm fine with this :)


The code in support/export/hostname.c

	if (ai->ai_canonname == NULL) {
		nfs_freeaddrinfo(ai);
		ai = NULL;
	}

could also be removed as the "if (ai-> if (ai->ai_canonname == NULL)"
just checks if the not anymore existing strdup was successful.

as it seems the "ai->ai_canonname = strdup(buf);" isn't necessary, as
it just copies the IP address which can be done in host_pton with the 

	.ai_flags       = AI_CANONNAME

directly.


From 260fb3ea7f06eca4498c00a07e097939652db6c2 Mon Sep 17 00:00:00 2001
From: Peter Wagner <tripolar@gmx.at>
Date: Mon, 18 Feb 2019 22:07:50 +0100
Subject: [PATCH] define and use wrapper function nfs_freeaddrinfo to
handle freeaddrinfo versions that don't tolerate NULL pointers set
AI_CANONNAME flag in host_pton to set the ip address of the connected
host to ai_canonname

---
 support/export/client.c       |  6 +++---
 support/export/hostname.c     | 12 +++++-------
 support/include/exportfs.h    | 11 +++++++++++
 support/nfs/getport.c         |  7 ++++---
 support/nfs/svc_create.c      |  8 +++++---
 support/nfsidmap/umich_ldap.c |  2 +-
 tests/nsm_client/nsm_client.c |  2 +-
 utils/exportfs/exportfs.c     | 10 +++++-----
 utils/gssd/gssd.c             |  4 ++--
 utils/gssd/krb5_util.c        |  2 +-
 utils/mount/network.c         |  7 ++++---
 utils/mount/stropts.c         |  3 ++-
 utils/mountd/auth.c           |  2 +-
 utils/mountd/cache.c          | 10 +++++-----
 utils/mountd/mountd.c         |  4 ++--
 utils/mountd/rmtab.c          |  2 +-
 utils/nfsd/nfssvc.c           |  4 ++--
 utils/statd/hostname.c        | 11 ++++++-----
 utils/statd/sm-notify.c       | 14 +++++++-------
 19 files changed, 68 insertions(+), 53 deletions(-)

diff --git a/support/export/client.c b/support/export/client.c
index baf59c8..a1fba01 100644
--- a/support/export/client.c
+++ b/support/export/client.c
@@ -210,7 +210,7 @@ init_subnetwork(nfs_client *clp)
 	set_addrlist(clp, 0, ai->ai_addr);
 	family = ai->ai_addr->sa_family;
 
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 
 	switch (family) {
 	case AF_INET:
@@ -309,7 +309,7 @@ client_lookup(char *hname, int canonical)
 		init_addrlist(clp, ai);
 
 out:
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 	return clp;
 }
 
@@ -674,7 +674,7 @@ check_netgroup(const nfs_client *clp, const struct
addrinfo *ai) tmp = host_pton(hname);
 	if (tmp != NULL) {
 		char *cname = host_canonname(tmp->ai_addr);
-		freeaddrinfo(tmp);
+		nfs_freeaddrinfo(tmp);
 
 		/* The resulting FQDN may be in our netgroup. */
 		if (cname != NULL) {
diff --git a/support/export/hostname.c b/support/export/hostname.c
index 5c4c824..a6032ad 100644
--- a/support/export/hostname.c
+++ b/support/export/hostname.c
@@ -101,6 +101,7 @@ host_pton(const char *paddr)
 		.ai_protocol	= (int)IPPROTO_UDP,
 		.ai_flags	= AI_NUMERICHOST,
 		.ai_family	= AF_UNSPEC,
+		.ai_flags	= AI_CANONNAME,
 	};
 	struct sockaddr_in sin;
 	int error, inet4;
@@ -130,7 +131,7 @@ host_pton(const char *paddr)
 		if (!inet4 && ai->ai_addr->sa_family == AF_INET) {
 			xlog(D_GENERAL, "%s: failed to convert %s",
 					__func__, paddr);
-			freeaddrinfo(ai);
+			nfs_freeaddrinfo(ai);
 			break;
 		}
 		return ai;
@@ -290,7 +291,7 @@ host_reliable_addrinfo(const struct sockaddr *sap)
 		if (nfs_compare_sockaddr(a->ai_addr, sap))
 			break;
 
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 	if (!a)
 		goto out_free_hostname;
 
@@ -354,10 +355,8 @@ host_numeric_addrinfo(const struct sockaddr *sap)
 	 * getaddrinfo(AI_NUMERICHOST) never fills in ai_canonname
 	 */
 	if (ai != NULL) {
-		free(ai->ai_canonname);		/* just in case
*/
-		ai->ai_canonname = strdup(buf);
 		if (ai->ai_canonname == NULL) {
-			freeaddrinfo(ai);
+			nfs_freeaddrinfo(ai);
 			ai = NULL;
 		}
 	}
@@ -388,9 +387,8 @@ host_numeric_addrinfo(const struct sockaddr *sap)
 	 * getaddrinfo(AI_NUMERICHOST) never fills in ai_canonname
 	 */
 	if (ai != NULL) {
-		ai->ai_canonname = strdup(buf);
 		if (ai->ai_canonname == NULL) {
-			freeaddrinfo(ai);
+			nfs_freeaddrinfo(ai);
 			ai = NULL;
 		}
 	}
diff --git a/support/include/exportfs.h b/support/include/exportfs.h
index 4e0d9d1..b81f963 100644
--- a/support/include/exportfs.h
+++ b/support/include/exportfs.h
@@ -47,6 +47,17 @@ typedef struct mclient {
 	int			m_count;
 } nfs_client;
 
+/*
+ * Some versions of freeaddrinfo(3) do not tolerate being
+ * passed a NULL pointer.
+ */
+static inline void nfs_freeaddrinfo(struct addrinfo *ai)
+{
+	if (ai) {
+		freeaddrinfo(ai);
+	}
+}
+
 static inline const struct sockaddr *
 get_addrlist(const nfs_client *clp, const int i)
 {
diff --git a/support/nfs/getport.c b/support/nfs/getport.c
index 081594c..26ec85e 100644
--- a/support/nfs/getport.c
+++ b/support/nfs/getport.c
@@ -47,6 +47,7 @@
 
 #include "sockaddr.h"
 #include "nfsrpc.h"
+#include "exportfs.h"
 
 /*
  * Try a local socket first to access the local rpcbind daemon
@@ -109,7 +110,7 @@ static int nfs_gp_loopback_address(struct sockaddr
*sap, socklen_t *salen) ret = 1;
 	}
 
-	freeaddrinfo(gai_results);
+	nfs_freeaddrinfo(gai_results);
 	return ret;
 }
 
@@ -134,8 +135,8 @@ static in_port_t nfs_gp_getservbyname(const char
*service, 
 	sin = (const struct sockaddr_in *)gai_results->ai_addr;
 	port = sin->sin_port;
-	
-	freeaddrinfo(gai_results);
+
+	nfs_freeaddrinfo(gai_results);
 	return port;
 }
 
diff --git a/support/nfs/svc_create.c b/support/nfs/svc_create.c
index ef7ff05..d0b747b 100644
--- a/support/nfs/svc_create.c
+++ b/support/nfs/svc_create.c
@@ -39,6 +39,8 @@
 #include <rpc/rpc.h>
 #include <rpc/svc.h>
 
+#include "exportfs.h"
+
 #ifdef HAVE_TCP_WRAPPER
 #include "tcpwrapper.h"
 #endif
@@ -273,7 +275,7 @@ svc_create_nconf_rand_port(const char *name, const
rpcprog_t program, bindaddr.qlen = SOMAXCONN;
 
 	xprt = svc_tli_create(RPC_ANYFD, nconf, &bindaddr, 0, 0);
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 	if (xprt == NULL) {
 		xlog(L_ERROR, "Failed to create listener xprt "
 			"(%s, %u, %s)", name, version,
nconf->nc_netid); @@ -364,11 +366,11 @@
svc_create_nconf_fixed_port(const char *name, const rpcprog_t program, 
 	svc_create_cache_xprt(xprt);
 
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 	return 1;
 
 out_free:
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 	return 0;
 }
 
diff --git a/support/nfsidmap/umich_ldap.c
b/support/nfsidmap/umich_ldap.c index b661110..b8ee184 100644
--- a/support/nfsidmap/umich_ldap.c
+++ b/support/nfsidmap/umich_ldap.c
@@ -1089,7 +1089,7 @@ get_canonical_hostname(const char *inname)
 	return_name = strdup (tmphost);
 
 out_free:
-	freeaddrinfo(ap);
+	nfs_freeaddrinfo(ap);
 out_err:
 	return return_name;
 }
diff --git a/tests/nsm_client/nsm_client.c
b/tests/nsm_client/nsm_client.c index 0fa3422..8dc0591 100644
--- a/tests/nsm_client/nsm_client.c
+++ b/tests/nsm_client/nsm_client.c
@@ -243,7 +243,7 @@ nsm_client_get_rpcclient(const char *node)
 		printf("RPC client creation failed\n");
 	}
 out:
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 	return client;
 }
 
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
index cd3c979..333eadc 100644
--- a/utils/exportfs/exportfs.c
+++ b/utils/exportfs/exportfs.c
@@ -282,7 +282,7 @@ exportfs_parsed(char *hname, char *path, char
*options, int verbose) validate_export(exp);
 
 out:
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 }
 
 static int exportfs_generic(char *arg, char *options, int verbose)
@@ -395,7 +395,7 @@ unexportfs_parsed(char *hname, char *path, int
verbose) if (!success)
 		xlog(L_ERROR, "Could not find '%s:%s' to unexport.",
hname, path); 
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 }
 
 static int unexportfs_generic(char *arg, int verbose)
@@ -588,7 +588,7 @@ address_list(const char *hostname)
 	if (ai != NULL) {
 		/* @hostname was a presentation address */
 		cname = host_canonname(ai->ai_addr);
-		freeaddrinfo(ai);
+		nfs_freeaddrinfo(ai);
 		if (cname != NULL)
 			goto out;
 	}
@@ -639,8 +639,8 @@ matchhostname(const char *hostname1, const char
*hostname2) }
 
 out:
-	freeaddrinfo(results1);
-	freeaddrinfo(results2);
+	nfs_freeaddrinfo(results1);
+	nfs_freeaddrinfo(results2);
 	return result;
 }
 
diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c
index 2e92f28..7eeb05f 100644
--- a/utils/gssd/gssd.c
+++ b/utils/gssd/gssd.c
@@ -172,14 +172,14 @@ gssd_addrstr_to_sockaddr(struct sockaddr *sa,
const char *node, const char *port if (sin6->sin6_scope_id) {
 			printerr(0, "ERROR: address %s has non-zero "
 				    "sin6_scope_id!\n", node);
-			freeaddrinfo(res);
+			nfs_freeaddrinfo(res);
 			return false;
 		}
 	}
 #endif /* IPV6_SUPPORTED */
 
 	memcpy(sa, res->ai_addr, res->ai_addrlen);
-	freeaddrinfo(res);
+	nfs_freeaddrinfo(res);
 	return true;
 }
 
diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c
index eba1aac..adbde93 100644
--- a/utils/gssd/krb5_util.c
+++ b/utils/gssd/krb5_util.c
@@ -587,7 +587,7 @@ get_full_hostname(const char *inhost, char
*outhost, int outhostlen) goto out;
 	}
 	strncpy(outhost, addrs->ai_canonname, outhostlen);
-	freeaddrinfo(addrs);
+	nfs_freeaddrinfo(addrs);
 	for (c = outhost; *c != '\0'; c++)
 	    *c = tolower(*c);
 
diff --git a/utils/mount/network.c b/utils/mount/network.c
index 356f663..fcb0b9f 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -53,6 +53,7 @@
 #include <net/if.h>
 #include <ifaddrs.h>
 
+#include "exportfs.h"
 #include "sockaddr.h"
 #include "xcommon.h"
 #include "mount.h"
@@ -250,7 +251,7 @@ int nfs_lookup(const char *hostname, const
sa_family_t family, break;
 	}
 
-	freeaddrinfo(gai_results);
+	nfs_freeaddrinfo(gai_results);
 	return ret;
 }
 
@@ -307,7 +308,7 @@ int nfs_string_to_sockaddr(const char *address,
struct sockaddr *sap, }
 			break;
 		}
-		freeaddrinfo(gai_results);
+		nfs_freeaddrinfo(gai_results);
 	}
 
 	return ret;
@@ -1180,7 +1181,7 @@ static int nfs_ca_gai(const struct sockaddr *sap,
 	*buflen = gai_results->ai_addrlen;
 	memcpy(buf, gai_results->ai_addr, *buflen);
 
-	freeaddrinfo(gai_results);
+	nfs_freeaddrinfo(gai_results);
 
 	return 1;
 }
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
index 0a25b1f..b170552 100644
--- a/utils/mount/stropts.c
+++ b/utils/mount/stropts.c
@@ -35,6 +35,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
+#include "exportfs.h"
 #include "sockaddr.h"
 #include "xcommon.h"
 #include "mount.h"
@@ -1268,7 +1269,7 @@ int nfsmount_string(const char *spec, const char
*node, char *type, } else
 		nfs_error(_("%s: internal option parsing error"),
progname); 
-	freeaddrinfo(mi.address);
+	nfs_freeaddrinfo(mi.address);
 	free(mi.hostname);
 	return retval;
 }
diff --git a/utils/mountd/auth.c b/utils/mountd/auth.c
index 8299256..8f7cbd4 100644
--- a/utils/mountd/auth.c
+++ b/utils/mountd/auth.c
@@ -297,7 +297,7 @@ auth_authenticate(const char *what, const struct
sockaddr *caller, path, epath, error);
 	}
 
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 	return exp;
 }
 
diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
index 7e8d403..2cb370f 100644
--- a/utils/mountd/cache.c
+++ b/utils/mountd/cache.c
@@ -113,7 +113,7 @@ static void auth_unix_ip(int f)
 		ai = client_resolve(tmp->ai_addr);
 		if (ai) {
 			client = client_compose(ai);
-			freeaddrinfo(ai);
+			nfs_freeaddrinfo(ai);
 		}
 	}
 	bp = buf; blen = sizeof(buf);
@@ -133,7 +133,7 @@ static void auth_unix_ip(int f)
 	xlog(D_CALL, "auth_unix_ip: client %p '%s'", client,
client?client: "DEFAULT"); 
 	free(client);
-	freeaddrinfo(tmp);
+	nfs_freeaddrinfo(tmp);
 
 }
 
@@ -667,7 +667,7 @@ static struct addrinfo *lookup_client_addr(char
*dom) if (tmp == NULL)
 		return NULL;
 	ret = client_resolve(tmp->ai_addr);
-	freeaddrinfo(tmp);
+	nfs_freeaddrinfo(tmp);
 	return ret;
 }
 
@@ -834,7 +834,7 @@ static void nfsd_fh(int f)
 out:
 	if (found_path)
 		free(found_path);
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 	free(dom);
 	xlog(D_CALL, "nfsd_fh: found %p path %s", found, found ?
found->e_path : NULL); }
@@ -1355,7 +1355,7 @@ static void nfsd_export(int f)
 	xlog(D_CALL, "nfsd_export: found %p path %s", found, path ?
path : NULL); if (dom) free(dom);
 	if (path) free(path);
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 }
 
 
diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
index 086c39b..fb7bba4 100644
--- a/utils/mountd/mountd.c
+++ b/utils/mountd/mountd.c
@@ -578,10 +578,10 @@ static void prune_clients(nfs_export *exp, struct
exportnode *e) *cp = c->gr_next;
 				xfree(c->gr_name);
 				xfree(c);
-				freeaddrinfo(ai);
+				nfs_freeaddrinfo(ai);
 				continue;
 			}
-			freeaddrinfo(ai);
+			nfs_freeaddrinfo(ai);
 		}
 		cp = &(c->gr_next);
 	}
diff --git a/utils/mountd/rmtab.c b/utils/mountd/rmtab.c
index 3ae0dbb..c896243 100644
--- a/utils/mountd/rmtab.c
+++ b/utils/mountd/rmtab.c
@@ -226,7 +226,7 @@ mountlist_list(void)
 				ai = host_pton(rep->r_client);
 				if (ai != NULL) {
 					m->ml_hostname =
host_canonname(ai->ai_addr);
-					freeaddrinfo(ai);
+					nfs_freeaddrinfo(ai);
 				}
 			}
 			if (m->ml_hostname == NULL)
diff --git a/utils/nfsd/nfssvc.c b/utils/nfsd/nfssvc.c
index 1e6ffd6..47b1882 100644
--- a/utils/nfsd/nfssvc.c
+++ b/utils/nfsd/nfssvc.c
@@ -25,6 +25,7 @@
 #include "nfslib.h"
 #include "xlog.h"
 #include "nfssvc.h"
+#include "exportfs.h"
 #include "../mount/version.h"
 
 #ifndef NFSD_FS_DIR
@@ -246,8 +247,7 @@ error:
 		close(fd);
 	if (sockfd >= 0)
 		close(sockfd);
-	if (addrhead)
-		freeaddrinfo(addrhead);
+	nfs_freeaddrinfo(addrhead);
 	return (bounded ? 0 : rc);
 }
 
diff --git a/utils/statd/hostname.c b/utils/statd/hostname.c
index 8cccdb8..c9e22d3 100644
--- a/utils/statd/hostname.c
+++ b/utils/statd/hostname.c
@@ -35,6 +35,7 @@
 #include <netdb.h>
 #include <arpa/inet.h>
 
+#include "exportfs.h"
 #include "sockaddr.h"
 #include "statd.h"
 #include "xlog.h"
@@ -203,7 +204,7 @@ statd_canonical_name(const char *hostname)
 		_Bool result;
 		result = get_nameinfo(ai->ai_addr, ai->ai_addrlen,
 					buf, (socklen_t)sizeof(buf));
-		freeaddrinfo(ai);
+		nfs_freeaddrinfo(ai);
 		if (!result || buf[0] == '\0')
 			/* OK to use presentation address,
 			 * if no reverse map exists */
@@ -217,7 +218,7 @@ statd_canonical_name(const char *hostname)
 	if (ai == NULL)
 		return NULL;
 	strcpy(buf, ai->ai_canonname);
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 
 	return strdup(buf);
 }
@@ -253,7 +254,7 @@ statd_canonical_list(const char *hostname)
 		_Bool result;
 		result = get_nameinfo(ai->ai_addr, ai->ai_addrlen,
 					buf, (socklen_t)sizeof(buf));
-		freeaddrinfo(ai);
+		nfs_freeaddrinfo(ai);
 		if (result)
 			goto out;
 	}
@@ -308,8 +309,8 @@ statd_matchhostname(const char *hostname1, const
char *hostname2) }
 
 out:
-	freeaddrinfo(results2);
-	freeaddrinfo(results1);
+	nfs_freeaddrinfo(results2);
+	nfs_freeaddrinfo(results1);
 
 	xlog(D_CALL, "%s: hostnames %s and %s %s", __func__,
 			hostname1, hostname2,
diff --git a/utils/statd/sm-notify.c b/utils/statd/sm-notify.c
index 29dad38..05d72a3 100644
--- a/utils/statd/sm-notify.c
+++ b/utils/statd/sm-notify.c
@@ -37,6 +37,7 @@
 #include "xlog.h"
 #include "nsm.h"
 #include "nfsrpc.h"
+#include "exportfs.h"
 
 /* glibc before 2.3.4 */
 #ifndef AI_NUMERICSERV
@@ -179,7 +180,7 @@ smn_verify_my_name(const char *name)
 	case 0:
 		/* @name was a presentation address */
 		retval = smn_get_hostname(ai->ai_addr, ai->ai_addrlen,
name);
-		freeaddrinfo(ai);
+		nfs_freeaddrinfo(ai);
 		if (retval == NULL)
 			return NULL;
 		break;
@@ -253,8 +254,7 @@ static void smn_forget_host(struct nsm_host *host)
 	free((void *)host->my_name);
 	free((void *)host->mon_name);
 	free(host->name);
-	if (host->ai)
-		freeaddrinfo(host->ai);
+	nfs_freeaddrinfo(host->ai);
 
 	free(host);
 }
@@ -430,7 +430,7 @@ retry:
 	if (srcport) {
 		if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
 			xlog(L_ERROR, "Failed to bind RPC socket: %m");
-			freeaddrinfo(ai);
+			nfs_freeaddrinfo(ai);
 			(void)close(sock);
 			return -1;
 		}
@@ -440,7 +440,7 @@ retry:
 		if (smn_bindresvport(sock, ai->ai_addr) == -1) {
 			xlog(L_ERROR,
 				"bindresvport on RPC socket failed:
%m");
-			freeaddrinfo(ai);
+			nfs_freeaddrinfo(ai);
 			(void)close(sock);
 			return -1;
 		}
@@ -449,13 +449,13 @@ retry:
 		se = getservbyport((int)nfs_get_port(ai->ai_addr),
"udp"); if (se != NULL && retry_cnt < 100) {
 			retry_cnt++;
-			freeaddrinfo(ai);
+			nfs_freeaddrinfo(ai);
 			(void)close(sock);
 			goto retry;
 		}
 	}
 
-	freeaddrinfo(ai);
+	nfs_freeaddrinfo(ai);
 	return sock;
 }
 
-- 
2.20.1

  reply	other threads:[~2019-02-18 21:21 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-17 16:39 [PATCH] nfs-utils: fix addrinfo usage with musl-1.1.21 Peter Wagner
2019-02-17 17:40 ` Chuck Lever
2019-02-17 23:11   ` Peter Wagner
2019-02-18  2:21     ` Chuck Lever
2019-02-18 16:34       ` Steve Dickson
2019-02-18 17:00         ` Chuck Lever
2019-02-18 17:59           ` Steve Dickson
2019-02-18 18:23             ` Chuck Lever
2019-02-18 21:22               ` Peter Wagner [this message]
2019-02-18 21:26               ` Peter Wagner
2019-02-19  9:03                 ` Peter Wagner
2019-02-19 14:52                   ` Chuck Lever
2019-02-19 16:07                   ` Steve Dickson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190218222233.04a318fa@onion.lan \
    --to=tripolar@gmx.at \
    --cc=chuck.lever@oracle.com \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.