Hi,
On i386: before patch:
$ dd if=/dev/urandom  of=in bs=1M count=2k
$ openrsync --rsync-path=/usr/bin/openrsync  -av in localhost:out
Transfer starting: 1 files
sender.c:551: error: in: mmap: Cannot allocate memory
client.c:85: error: rsync_sender
receiver.c:345: error: poll: hangup
server.c:145: error: rsync_receiver

With your patch:
$ patch -p0 < /tmp/1
Hmm...  Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|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
--------------------------
Patching file usr.bin/rsync/uploader.c using Plan A...
Hunk #1 succeeded at 158.
Hunk #2 succeeded at 741.
Hunk #3 succeeded at 910.
Hmm...  Ignoring the trailing garbage.
done

$ cd usr.bin/rsync/ && make -j3 && doas make install
…

$ openrsync --rsync-path=/usr/bin/openrsync  -av in localhost:out
Transfer starting: 1 files
sender.c:551: error: in: mmap: Cannot allocate memory
client.c:85: error: rsync_sender
receiver.c:345: error: poll: hangup
server.c:145: error: rsync_receiver

>From what I see, the mmap problem is on sender.c

Cheers,



On Sat, Aug 17, 2019 at 4:53 PM Sebastian Benoit <[email protected]> wrote:
>
> Joe Davis([email protected]) 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