setrlimit and vnd fun

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

setrlimit and vnd fun

Tobias Ulmer
There's this strange bug that postfix can't deliver mail to svnd
devices http://archives.neohapsis.com/archives/openbsd/2006-01/0953.html
It recently turned up on irc again. After a bit of torturing my eyes
with postfix code, it became clear that it has to do with setrlimit(2).

#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>

#include <err.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

static void
sig_xfsz(int s)
{
        warnx("SIGXFSZ received");
}

int
main(int argc, char *argv[])
{
        int fd, i;
        struct rlimit r;

        if (argc != 2)
                errx(1, "argument missing");

        if (signal(SIGXFSZ, sig_xfsz) == SIG_ERR)
                err(1, "signal");
       
        r.rlim_cur = r.rlim_max = 10;
        if (setrlimit(RLIMIT_FSIZE, &r) == -1)
                err(1, "setrlimit");

        if (unlink(argv[1]) == -1)
                warn("unlink");

        if ((fd = open(argv[1], O_WRONLY|O_CREAT|O_EXCL, 0600)) == -1)
                err(1, "open");

        for (i = 0; i < 5; ++i)
                if (write(fd, "1234567890", 10) == -1)
                        err(1, "write");

        exit(0);
}

dd if=/dev/zero of=crypt bs=1m count=2500
sudo vnconfig -k svnd1 crypt
sudo fdisk -i svnd1
sudo disklabel -E svnd1
sudo newfs svnd1a
mkdir crypttest
sudo mount /dev/svnd1a crypttest
sudo chown tobiasu:tobiasu crypttest
gcc sigxfsz.c
rm -f /tmp/foo crypttest/foo

./a.out /tmp/foo
a.out: unlink: No such file or directory
a.out: SIGXFSZ received
a.out: write: File too large

./a.out crypttest/foo
a.out: unlink: No such file or directory
a.out: SIGXFSZ received
a.out: open: File too large

touch /tmp/foo
touch crypttest/foo

./a.out /tmp/foo
a.out: SIGXFSZ received
a.out: write: File too large

./a.out crypttest/foo
a.out: SIGXFSZ received
a.out: unlink: File too large
a.out: open: File exists

cd crypttest/
ls
ls: foo: Bad file descriptor
cd ..
sudo umount crypttest
sudo fsck_ffs -f /dev/rsvnd1a
** /dev/rsvnd1a
** File system is already clean
** Last Mounted on /home/tobiasu/crypttest
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
UNALLOCATED  I=3  OWNER=tobiasu MODE=0
SIZE=0 MTIME=Feb 20 00:28 2007
NAME=/foo

REMOVE? [Fyn?] y

** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Cyl groups
1 files, 1 used, 1259109 free (21 frags, 157386 blocks, 0.0% fragmentation)

***** FILE SYSTEM WAS MODIFIED *****

I suspect that the limit also applies to the underlying vnd file, but
i've not been able to come up with a patch. The behaviour is
reproducable on -current and 4.0

Tobias

Reply | Threaded
Open this post in threaded view
|

Re: setrlimit and vnd fun

Pedro Martelletto
On Tue, Feb 20, 2007 at 08:32:45AM +0100, Tobias Ulmer wrote:
> I suspect that the limit also applies to the underlying vnd file, but
> i've not been able to come up with a patch. The behaviour is
> reproducable on -current and 4.0

That is a known problem. The bottom file system enforces the limit on
the upper file system's metadata writes. The diff below should fix it.

-p.

Index: sys/vnode.h
===================================================================
RCS file: /cvs/src/sys/sys/vnode.h,v
retrieving revision 1.71
diff -u -p -r1.71 vnode.h
--- sys/vnode.h 2 Aug 2006 21:55:27 -0000 1.71
+++ sys/vnode.h 9 Feb 2007 19:53:15 -0000
@@ -187,6 +187,7 @@ struct vattr {
 #define IO_SYNC 0x04 /* do I/O synchronously */
 #define IO_NODELOCKED 0x08 /* underlying node already locked */
 #define IO_NDELAY 0x10 /* FNDELAY flag set in file table */
+#define IO_NOLIMIT 0x20 /* don't enforce limits on i/o */
 
 /*
  *  Modes.  Some values same as Ixxx entries from inode.h for now.
Index: dev/vnd.c
===================================================================
RCS file: /cvs/src/sys/dev/vnd.c,v
retrieving revision 1.62
diff -u -p -r1.62 vnd.c
--- dev/vnd.c 13 Aug 2006 17:55:07 -0000 1.62
+++ dev/vnd.c 9 Feb 2007 19:53:16 -0000
@@ -501,8 +501,8 @@ vndstrategy(bp)
  vndencrypt(vnd, bp->b_data,
    bp->b_bcount, bp->b_blkno, 1);
  auio.uio_rw = UIO_WRITE;
- bp->b_error = VOP_WRITE(vnd->sc_vp, &auio, 0,
-    vnd->sc_cred);
+ bp->b_error = VOP_WRITE(vnd->sc_vp, &auio,
+    IO_NOLIMIT, vnd->sc_cred);
  /* Data in buffer cache needs to be in clear */
  if (vnd->sc_keyctx)
  vndencrypt(vnd, bp->b_data,
Index: ufs/ufs/ufs_readwrite.c
===================================================================
RCS file: /cvs/src/sys/ufs/ufs/Attic/ufs_readwrite.c,v
retrieving revision 1.28
diff -u -p -r1.28 ufs_readwrite.c
--- ufs/ufs/ufs_readwrite.c 28 Dec 2005 20:48:18 -0000 1.28
+++ ufs/ufs/ufs_readwrite.c 9 Feb 2007 19:53:16 -0000
@@ -231,7 +231,7 @@ WRITE(void *v)
  * file servers have no limits, I don't think it matters.
  */
  p = uio->uio_procp;
- if (vp->v_type == VREG && p &&
+ if (vp->v_type == VREG && p && !(ioflag & IO_NOLIMIT) &&
     uio->uio_offset + uio->uio_resid >
     p->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
  psignal(p, SIGXFSZ);

Reply | Threaded
Open this post in threaded view
|

Re: setrlimit and vnd fun

Tobias Ulmer
On Tue, Feb 20, 2007 at 08:45:40AM +0100, Pedro Martelletto wrote:
> On Tue, Feb 20, 2007 at 08:32:45AM +0100, Tobias Ulmer wrote:
> > I suspect that the limit also applies to the underlying vnd file, but
> > i've not been able to come up with a patch. The behaviour is
> > reproducable on -current and 4.0
>
> That is a known problem. The bottom file system enforces the limit on
> the upper file system's metadata writes. The diff below should fix it.
>

Hi Pedro,
works well for me (applied last patch to ufs/ffs/ffs_vnops.c). Postfix
can now deliver mails to a vnd encrypted Maildir.

Tobias

Reply | Threaded
Open this post in threaded view
|

Re: setrlimit and vnd fun

Pedro Martelletto
On Wed, Feb 21, 2007 at 03:37:28PM +0100, Tobias Ulmer wrote:
> works well for me (applied last patch to ufs/ffs/ffs_vnops.c). Postfix
> can now deliver mails to a vnd encrypted Maildir.

The diff was against 4.0, which is what the initial submitter was
running. Sorry about that.

-p.