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;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to