Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 Apr 2020 00:57:51 +0000 (UTC)
From:      "Simon J. Gerraty" <sjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r359911 - in stable/12: lib/libsecureboot stand/libsa
Message-ID:  <202004140057.03E0vpc6009321@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sjg
Date: Tue Apr 14 00:57:50 2020
New Revision: 359911
URL: https://svnweb.freebsd.org/changeset/base/359911

Log:
  Improve interaction of vectx and tftp
  
  On slow platforms, it helps to spread the hashing load
  over time so that tftp does not timeout.
  
  Also, some .4th files are too big to fit in cache of pkgfs,
  so increase cache size and ensure fully populated.
  
  MFC of r359700
  
  Reviewed by:	stevek
  Differential Revision: https://reviews.freebsd.org/D24287

Modified:
  stable/12/lib/libsecureboot/vectx.c
  stable/12/stand/libsa/pkgfs.c
  stable/12/stand/libsa/tftp.c

Modified: stable/12/lib/libsecureboot/vectx.c
==============================================================================
--- stable/12/lib/libsecureboot/vectx.c	Tue Apr 14 00:01:26 2020	(r359910)
+++ stable/12/lib/libsecureboot/vectx.c	Tue Apr 14 00:57:50 2020	(r359911)
@@ -211,6 +211,7 @@ ssize_t
 vectx_read(struct vectx *ctx, void *buf, size_t nbytes)
 {
 	unsigned char *bp = buf;
+	int d;
 	int n;
 	int delta;
 	int x;
@@ -221,23 +222,30 @@ vectx_read(struct vectx *ctx, void *buf, size_t nbytes
 
 	off = 0;
 	do {
-		n = read(ctx->vec_fd, &bp[off], nbytes - off);
-		if (n < 0)
+		/*
+		 * Do this in reasonable chunks so
+		 * we don't timeout if doing tftp
+		 */
+		x = nbytes - off;
+		x = MIN(PAGE_SIZE, x);
+		d = n = read(ctx->vec_fd, &bp[off], x);
+		if (n < 0) {
 			return (n);
-		if (n > 0) {
+		}
+		if (d > 0) {
 			/* we may have seeked backwards! */
 			delta = ctx->vec_hashed - ctx->vec_off;
 			if (delta > 0) {
-				x = MIN(delta, n);
+				x = MIN(delta, d);
 				off += x;
-				n -= x;
+				d -= x;
 				ctx->vec_off += x;
 			}
-			if (n > 0) {
-				ctx->vec_md->update(&ctx->vec_ctx.vtable, &bp[off], n);
-				off += n;
-				ctx->vec_off += n;
-				ctx->vec_hashed += n;
+			if (d > 0) {
+				ctx->vec_md->update(&ctx->vec_ctx.vtable, &bp[off], d);
+				off += d;
+				ctx->vec_off += d;
+				ctx->vec_hashed += d;
 			}
 		}
 	} while (n > 0 && off < nbytes);

Modified: stable/12/stand/libsa/pkgfs.c
==============================================================================
--- stable/12/stand/libsa/pkgfs.c	Tue Apr 14 00:01:26 2020	(r359910)
+++ stable/12/stand/libsa/pkgfs.c	Tue Apr 14 00:57:50 2020	(r359911)
@@ -60,7 +60,7 @@ struct fs_ops pkgfs_fsops = {
 };
 
 #define PKG_BUFSIZE	512
-#define	PKG_MAXCACHESZ	16384
+#define	PKG_MAXCACHESZ	(16384 * 3)
 
 #define	PKG_FILEEXT	".tgz"
 
@@ -132,6 +132,7 @@ struct package
 static struct package *package = NULL;
 
 static int new_package(int, struct package **);
+static int cache_data(struct tarfile *tf, int);
 
 void
 pkgfs_cleanup(void)
@@ -282,6 +283,9 @@ pkg_read(struct open_file *f, void *buf, size_t size, 
 		return (EBADF);
 	}
 
+	if (tf->tf_cachesz == 0)
+		cache_data(tf, 1);
+
 	fp = tf->tf_fp;
 	p = buf;
 	sz = 0;
@@ -311,16 +315,6 @@ pkg_read(struct open_file *f, void *buf, size_t size, 
 		fp += sz;
 		p += sz;
 		size -= sz;
-
-		if (tf->tf_cachesz != 0)
-			continue;
-
-		tf->tf_cachesz = (sz <= PKG_MAXCACHESZ) ? sz : PKG_MAXCACHESZ;
-		tf->tf_cache = malloc(tf->tf_cachesz);
-		if (tf->tf_cache != NULL)
-			memcpy(tf->tf_cache, buf, tf->tf_cachesz);
-		else
-			tf->tf_cachesz = 0;
 	}
 
 	tf->tf_fp = fp;
@@ -484,8 +478,20 @@ get_zipped(struct package *pkg, void *buf, size_t bufs
 	return (0);
 }
 
+/**
+ * @brief
+ * cache data of a tarfile
+ *
+ * @param[in] tf
+ *	tarfile pointer
+ *
+ * @param[in] force
+ *	If file size > PKG_MAXCACHESZ, cache that much
+ *
+ * @return 0, -1 (errno set to error value)
+ */
 static int
-cache_data(struct tarfile *tf)
+cache_data(struct tarfile *tf, int force)
 {
 	struct package *pkg;
 	size_t sz;
@@ -503,21 +509,28 @@ cache_data(struct tarfile *tf)
 		return (-1);
 	}
 
+	if (tf->tf_cachesz > 0) {
+		DBG(("%s: data already cached\n", __func__));
+		errno = EINVAL;
+		return (-1);
+	}
+
 	if (tf->tf_ofs != pkg->pkg_ofs) {
-		DBG(("%s: caching after partial read of file %s?\n",
+		DBG(("%s: caching after force read of file %s?\n",
 		    __func__, tf->tf_hdr.ut_name));
 		errno = EINVAL;
 		return (-1);
 	}
 
 	/* We don't cache everything... */
-	if (tf->tf_size > PKG_MAXCACHESZ) {
-		errno = ENOMEM;
+	if (tf->tf_size > PKG_MAXCACHESZ && !force)  {
+		errno = ENOBUFS;
 		return (-1);
 	}
 
+	sz = tf->tf_size < PKG_MAXCACHESZ ? tf->tf_size : PKG_MAXCACHESZ;
 	/* All files are padded to a multiple of 512 bytes. */
-	sz = (tf->tf_size + 0x1ff) & ~0x1ff;
+	sz = (sz + 0x1ff) & ~0x1ff;
 
 	tf->tf_cache = malloc(sz);
 	if (tf->tf_cache == NULL) {
@@ -741,7 +754,7 @@ scan_tarfile(struct package *pkg, struct tarfile *last
 
 		if (ofs != pkg->pkg_ofs) {
 			if (last != NULL && pkg->pkg_ofs == last->tf_ofs) {
-				if (cache_data(last) == -1)
+				if (cache_data(last, 0) == -1)
 					return (NULL);
 			} else {
 				sz = ofs - pkg->pkg_ofs;

Modified: stable/12/stand/libsa/tftp.c
==============================================================================
--- stable/12/stand/libsa/tftp.c	Tue Apr 14 00:01:26 2020	(r359910)
+++ stable/12/stand/libsa/tftp.c	Tue Apr 14 00:57:50 2020	(r359911)
@@ -100,11 +100,13 @@ static int	is_open = 0;
  * Jumbo frames in the future.
  */
 #define	TFTP_MAX_BLKSIZE 9008
+#define TFTP_TRIES 2
 
 struct tftp_handle {
 	struct iodesc  *iodesc;
 	int		currblock;	/* contents of lastdata */
-	int		islastblock;	/* flag */
+	int		islastblock:1;	/* flag */
+	int		tries:4;	/* number of read attempts */
 	int		validsize;
 	int		off;
 	char		*path;	/* saved for re-requests */
@@ -530,7 +532,12 @@ tftp_read(struct open_file *f, void *addr, size_t size
 #ifdef TFTP_DEBUG
 				printf("tftp: read error\n");
 #endif
-				return (rc);
+				if (tftpfile->tries > TFTP_TRIES) {
+					return (rc);
+				} else {
+					tftpfile->tries++;
+					tftp_makereq(tftpfile);
+				}
 			}
 			if (tftpfile->islastblock)
 				break;



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