svn commit: r359700 - in head: lib/libsecureboot stand/libsa

Simon J. Gerraty sjg at FreeBSD.org
Tue Apr 7 16:56:35 UTC 2020


Author: sjg
Date: Tue Apr  7 16:56:34 2020
New Revision: 359700
URL: https://svnweb.freebsd.org/changeset/base/359700

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.
  
  Reviewed by:	stevek
  MFC after:	1 week
  Differential Revision: https://reviews.freebsd.org/D24287

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

Modified: head/lib/libsecureboot/vectx.c
==============================================================================
--- head/lib/libsecureboot/vectx.c	Tue Apr  7 16:52:45 2020	(r359699)
+++ head/lib/libsecureboot/vectx.c	Tue Apr  7 16:56:34 2020	(r359700)
@@ -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: head/stand/libsa/pkgfs.c
==============================================================================
--- head/stand/libsa/pkgfs.c	Tue Apr  7 16:52:45 2020	(r359699)
+++ head/stand/libsa/pkgfs.c	Tue Apr  7 16:56:34 2020	(r359700)
@@ -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: head/stand/libsa/tftp.c
==============================================================================
--- head/stand/libsa/tftp.c	Tue Apr  7 16:52:45 2020	(r359699)
+++ head/stand/libsa/tftp.c	Tue Apr  7 16:56:34 2020	(r359700)
@@ -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;


More information about the svn-src-head mailing list