Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Sep 2012 08:39:41 +0000 (UTC)
From:      Mikolaj Golub <trociny@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r240269 - stable/9/sbin/hastd
Message-ID:  <201209090839.q898dfqt035730@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trociny
Date: Sun Sep  9 08:39:41 2012
New Revision: 240269
URL: http://svn.freebsd.org/changeset/base/240269

Log:
  MFC r236507, r237931, r238120, r238538:
  
  r236507 (pjd):
  
  Simplify the code by using snprlcat().
  
  r237931 (pjd):
  
  Check if there is cmsg at all.
  
  r238120 (pjd):
  
  Make use of GEOM Gate direct reads feature. This allows HAST to serve
  reads with native speed of the underlying provider.
  There are three situations when direct reads are not used:
  1. Data is being synchronized and synchronization source is the secondary
     node, which means secondary node has more recent data and we should read
     from it.
  2. Local read failed and we have to try to read from the secondary node.
  3. Local component is unavailable and all I/O requests are served from the
     secondary node.
  
  Sponsored by:	Panzura, http://www.panzura.com
  
  r238538:
  
  Metaflush on/off values don't need quotes.
  
  Reviewed by:	pjd

Modified:
  stable/9/sbin/hastd/hast.conf.5
  stable/9/sbin/hastd/primary.c
  stable/9/sbin/hastd/proto_common.c
Directory Properties:
  stable/9/sbin/hastd/   (props changed)

Modified: stable/9/sbin/hastd/hast.conf.5
==============================================================================
--- stable/9/sbin/hastd/hast.conf.5	Sun Sep  9 08:30:22 2012	(r240268)
+++ stable/9/sbin/hastd/hast.conf.5	Sun Sep  9 08:39:41 2012	(r240269)
@@ -63,7 +63,7 @@ checksum <algorithm>
 compression <algorithm>
 timeout <seconds>
 exec <path>
-metaflush "on" | "off"
+metaflush on | off
 pidfile <path>
 
 on <node> {
@@ -89,14 +89,14 @@ resource <name> {
 	local <path>
 	timeout <seconds>
 	exec <path>
-	metaflush "on" | "off"
+	metaflush on | off
 
 	on <node> {
 		# Resource-node section
 		name <name>
 		# Required
 		local <path>
-		metaflush "on" | "off"
+		metaflush on | off
 		# Required
 		remote <addr>
 		source <addr>
@@ -106,7 +106,7 @@ resource <name> {
 		name <name>
 		# Required
 		local <path>
-		metaflush "on" | "off"
+		metaflush on | off
 		# Required
 		remote <addr>
 		source <addr>

Modified: stable/9/sbin/hastd/primary.c
==============================================================================
--- stable/9/sbin/hastd/primary.c	Sun Sep  9 08:30:22 2012	(r240268)
+++ stable/9/sbin/hastd/primary.c	Sun Sep  9 08:39:41 2012	(r240269)
@@ -543,6 +543,27 @@ primary_connect(struct hast_resource *re
 
 	return (0);
 }
+ 
+/*
+ * Function instructs GEOM_GATE to handle reads directly from within the kernel.
+ */
+static void
+enable_direct_reads(struct hast_resource *res)
+{
+	struct g_gate_ctl_modify ggiomodify;
+
+	bzero(&ggiomodify, sizeof(ggiomodify));
+	ggiomodify.gctl_version = G_GATE_VERSION;
+	ggiomodify.gctl_unit = res->hr_ggateunit;
+	ggiomodify.gctl_modify = GG_MODIFY_READPROV | GG_MODIFY_READOFFSET;
+	strlcpy(ggiomodify.gctl_readprov, res->hr_localpath,
+	    sizeof(ggiomodify.gctl_readprov));
+	ggiomodify.gctl_readoffset = res->hr_localoff;
+	if (ioctl(res->hr_ggatefd, G_GATE_CMD_MODIFY, &ggiomodify) == 0)
+		pjdlog_debug(1, "Direct reads enabled.");
+	else
+		pjdlog_errno(LOG_WARNING, "Failed to enable direct reads");
+}
 
 static int
 init_remote(struct hast_resource *res, struct proto_conn **inp,
@@ -692,6 +713,8 @@ init_remote(struct hast_resource *res, s
 	res->hr_secondary_localcnt = nv_get_uint64(nvin, "localcnt");
 	res->hr_secondary_remotecnt = nv_get_uint64(nvin, "remotecnt");
 	res->hr_syncsrc = nv_get_uint8(nvin, "syncsrc");
+	if (res->hr_syncsrc == HAST_SYNCSRC_PRIMARY)
+		enable_direct_reads(res);
 	if (nv_exists(nvin, "virgin")) {
 		/*
 		 * Secondary was reinitialized, bump localcnt if it is 0 as
@@ -990,36 +1013,33 @@ reqlog(int loglevel, int debuglevel, str
 {
 	char msg[1024];
 	va_list ap;
-	int len;
 
 	va_start(ap, fmt);
-	len = vsnprintf(msg, sizeof(msg), fmt, ap);
+	(void)vsnprintf(msg, sizeof(msg), fmt, ap);
 	va_end(ap);
-	if ((size_t)len < sizeof(msg)) {
-		switch (ggio->gctl_cmd) {
-		case BIO_READ:
-			(void)snprintf(msg + len, sizeof(msg) - len,
-			    "READ(%ju, %ju).", (uintmax_t)ggio->gctl_offset,
-			    (uintmax_t)ggio->gctl_length);
-			break;
-		case BIO_DELETE:
-			(void)snprintf(msg + len, sizeof(msg) - len,
-			    "DELETE(%ju, %ju).", (uintmax_t)ggio->gctl_offset,
-			    (uintmax_t)ggio->gctl_length);
-			break;
-		case BIO_FLUSH:
-			(void)snprintf(msg + len, sizeof(msg) - len, "FLUSH.");
-			break;
-		case BIO_WRITE:
-			(void)snprintf(msg + len, sizeof(msg) - len,
-			    "WRITE(%ju, %ju).", (uintmax_t)ggio->gctl_offset,
-			    (uintmax_t)ggio->gctl_length);
-			break;
-		default:
-			(void)snprintf(msg + len, sizeof(msg) - len,
-			    "UNKNOWN(%u).", (unsigned int)ggio->gctl_cmd);
-			break;
-		}
+	switch (ggio->gctl_cmd) {
+	case BIO_READ:
+		(void)snprlcat(msg, sizeof(msg), "READ(%ju, %ju).",
+		    (uintmax_t)ggio->gctl_offset,
+		    (uintmax_t)ggio->gctl_length);
+		break;
+	case BIO_DELETE:
+		(void)snprlcat(msg, sizeof(msg), "DELETE(%ju, %ju).",
+		    (uintmax_t)ggio->gctl_offset,
+		    (uintmax_t)ggio->gctl_length);
+		break;
+	case BIO_FLUSH:
+		(void)snprlcat(msg, sizeof(msg), "FLUSH.");
+		break;
+	case BIO_WRITE:
+		(void)snprlcat(msg, sizeof(msg), "WRITE(%ju, %ju).",
+		    (uintmax_t)ggio->gctl_offset,
+		    (uintmax_t)ggio->gctl_length);
+		break;
+	default:
+		(void)snprlcat(msg, sizeof(msg), "UNKNOWN(%u).",
+		    (unsigned int)ggio->gctl_cmd);
+		break;
 	}
 	pjdlog_common(loglevel, debuglevel, -1, "%s", msg);
 }
@@ -1792,13 +1812,14 @@ sync_thread(void *arg __unused)
 	struct timeval tstart, tend, tdiff;
 	unsigned int ii, ncomp, ncomps;
 	off_t offset, length, synced;
-	bool dorewind;
+	bool dorewind, directreads;
 	int syncext;
 
 	ncomps = HAST_NCOMPONENTS;
 	dorewind = true;
 	synced = 0;
 	offset = -1;
+	directreads = false;
 
 	for (;;) {
 		mtx_lock(&sync_lock);
@@ -1870,6 +1891,8 @@ sync_thread(void *arg __unused)
 					event_send(res, EVENT_SYNCDONE);
 				}
 				mtx_lock(&metadata_lock);
+				if (res->hr_syncsrc == HAST_SYNCSRC_SECONDARY)
+					directreads = true;
 				res->hr_syncsrc = HAST_SYNCSRC_UNDEF;
 				res->hr_primary_localcnt =
 				    res->hr_secondary_remotecnt;
@@ -1883,6 +1906,10 @@ sync_thread(void *arg __unused)
 				mtx_unlock(&metadata_lock);
 			}
 			rw_unlock(&hio_remote_lock[ncomp]);
+			if (directreads) {
+				directreads = false;
+				enable_direct_reads(res);
+			}
 			continue;
 		}
 		pjdlog_debug(2, "sync: Taking free request.");

Modified: stable/9/sbin/hastd/proto_common.c
==============================================================================
--- stable/9/sbin/hastd/proto_common.c	Sun Sep  9 08:30:22 2012	(r240268)
+++ stable/9/sbin/hastd/proto_common.c	Sun Sep  9 08:39:41 2012	(r240269)
@@ -181,7 +181,7 @@ proto_descriptor_recv(int sock, int *fdp
 		return (errno);
 
 	cmsg = CMSG_FIRSTHDR(&msg);
-	if (cmsg->cmsg_level != SOL_SOCKET ||
+	if (cmsg == NULL || cmsg->cmsg_level != SOL_SOCKET ||
 	    cmsg->cmsg_type != SCM_RIGHTS) {
 		return (EINVAL);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209090839.q898dfqt035730>