Joe Davis(m...@jo.ie) on 2019.08.16 12:26:36 +0100:
> By the looks of it, openrsync does attempt to map the entire file, from
> usr.bin/rsync/uploader.c:
> 
>     mapsz = st.st_size;
>     map = mmap(NULL, mapsz, PROT_READ, MAP_SHARED, *fileinfd, 0);
> 
> The likely reason for your out of memory error is the default datasize
> in login.conf. IIRC on some arches it's set to 768MB by default, which
> would allow your 300MB file to transfer, but would cause mmap to fail
> upon attempting to map the 1.6GB one.
> 
> Increasing the default limits in /etc/login.conf should fix the problem.
> 
> Note that rsync (not openrsync), doesn't use mmap for other reasons,
> from rsync-3.1.3/fileio.c:
> 
> /* This provides functionality somewhat similar to mmap() but using read().
>  * It gives sliding window access to a file.  mmap() is not used because of
>  * the possibility of another program (such as a mailer) truncating the
>  * file thus giving us a SIGBUS. */
> 
> Cheers,
> Joe

Hi,

this replaces the mmap() with pread(), please try it out.

I dont much like the error handling here, but its a start.

ok?


diff --git usr.bin/rsync/uploader.c usr.bin/rsync/uploader.c
index fd07b22caeb..cce8b47a4c9 100644
--- usr.bin/rsync/uploader.c
+++ usr.bin/rsync/uploader.c
@@ -158,8 +158,8 @@ init_blk(struct blk *p, const struct blkset *set, off_t 
offs,
        p->len = idx < set->blksz - 1 ? set->len : set->rem;
        p->offs = offs;
 
-       p->chksum_short = hash_fast(map + offs, p->len);
-       hash_slow(map + offs, p->len, p->chksum_long, sess);
+       p->chksum_short = hash_fast(map, p->len);
+       hash_slow(map, p->len, p->chksum_long, sess);
 }
 
 /*
@@ -741,8 +741,9 @@ rsync_uploader(struct upload *u, int *fileinfd,
 {
        struct blkset       blk;
        struct stat         st;
-       void               *map, *bufp;
-       size_t              i, mapsz, pos, sz;
+       void               *mbuf, *bufp;
+       ssize_t             msz;
+       size_t              i, pos, sz;
        off_t               offs;
        int                 c;
        const struct flist *f;
@@ -909,35 +910,46 @@ rsync_uploader(struct upload *u, int *fileinfd,
        blk.csum = u->csumlen;
 
        if (*fileinfd != -1 && st.st_size > 0) {
-               mapsz = st.st_size;
-               map = mmap(NULL, mapsz, PROT_READ, MAP_SHARED, *fileinfd, 0);
-               if (map == MAP_FAILED) {
-                       ERR("%s: mmap", u->fl[u->idx].path);
-                       close(*fileinfd);
-                       *fileinfd = -1;
-                       return -1;
-               }
-
                init_blkset(&blk, st.st_size);
                assert(blk.blksz);
 
                blk.blks = calloc(blk.blksz, sizeof(struct blk));
                if (blk.blks == NULL) {
                        ERR("calloc");
-                       munmap(map, mapsz);
+                       close(*fileinfd);
+                       *fileinfd = -1;
+                       return -1;
+               }
+
+               if ((mbuf = calloc(1, blk.len)) == NULL) {
+                       ERR("calloc");
                        close(*fileinfd);
                        *fileinfd = -1;
                        return -1;
                }
 
                offs = 0;
-               for (i = 0; i < blk.blksz; i++) {
-                       init_blk(&blk.blks[i],
-                               &blk, offs, i, map, sess);
+               i = 0;
+               do {
+                       msz = pread(*fileinfd, mbuf, blk.len, offs);
+                       if (msz < 0) {
+                               ERR("pread");
+                               close(*fileinfd);
+                               *fileinfd = -1;
+                               return -1;
+                       }
+                       if ((size_t)msz != blk.len && (size_t)msz != blk.rem) {
+                               /* short read, try again */
+                               continue;
+                       }
+                       init_blk(&blk.blks[i], &blk, offs, i, mbuf, sess);
                        offs += blk.len;
-               }
+                       LOG3(
+                           "i=%ld, offs=%lld, msz=%ld, blk.len=%lu, 
blk.rem=%lu",
+                           i, offs, msz, blk.len, blk.rem);
+                       i++;
+               } while (i < blk.blksz);
 
-               munmap(map, mapsz);
                close(*fileinfd);
                *fileinfd = -1;
                LOG3("%s: mapped %jd B with %zu blocks",

Reply via email to