Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Mar 2017 01:57:23 +0000
From:      Rick Macklem <rmacklem@uoguelph.ca>
To:        Dimitry Andric <dim@FreeBSD.org>, Ian Lepore <ian@FreeBSD.org>
Cc:        Gergely Czuczy <gergely.czuczy@harmless.hu>, FreeBSD Current <freebsd-current@freebsd.org>
Subject:   Re: process killed: text file modification
Message-ID:  <YTXPR01MB01898D49933A82170FCAB7A0DD390@YTXPR01MB0189.CANPRD01.PROD.OUTLOOK.COM>
In-Reply-To: <FF55DB37-4A6B-4D88-B201-B3BCA1A11E87@FreeBSD.org>
References:  <d4d04499-17f8-e3d7-181f-c8ee8285e32b@harmless.hu> <646c1395-9482-b214-118c-01573243ae5a@harmless.hu> <45436522-77df-f894-0569-737a6a74958f@harmless.hu> <55189643.aaZPuY77s8@ralph.baldwin.cx> <3ed3e4a3-23af-7267-39f1-9090093c9c1e@harmless.hu> <5ac94b9a-7ced-9eff-d746-7dddaaeca516@harmless.hu> <1489340839.40576.82.camel@freebsd.org>, <FF55DB37-4A6B-4D88-B201-B3BCA1A11E87@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Dimitry Andric wrote:
[lots of stuff snipped]
> I'm also running into this problem, but while using lld.  I must set
> vfs.timestamp_precision to 1 (e.g. sec + ns accurate to 1/HZ) on both
> the client and the server, to make it work.
>=20
> Instead of GNU ld, lld uses mmap to write to the output executable.  If
> this executable is more than one page, and resides on an NFS share,
> running it will almost always result in "text file modification", if
> vfs_timestamp_precision >=3D 2.
>=20
> A small test case: http://www.andric.com/freebsd/test-mmap-write.c,
> which writes a simple "hello world" i386-freebsd executable file, using
> the sequence: open() -> ftruncate() -> mmap() -> memcpy() -> munmap() ->
> close().
Hopefully Kostik will correct me if I have this wrong, but I don't believe =
any
of the above syscalls guarantee that dirty pages have been flushed.
At least for cases without munmap(), the writes of dirty pages can occur af=
ter
the file descriptor is closed. I run into this in NFSv4, where there is a C=
lose (NFSv4 one)
that can't be done until VOP_INACTIVE().
If you look in the NFS VOP_INACTIVE() { called ncl_inactive() } you'll see:
if (NFS_ISV4(vp) && vp->v_type =3D=3D VREG) {
237 	                /*
238 	                 * Since mmap()'d files do I/O after VOP_CLOSE(), the =
NFSv4
239 	                 * Close operations are delayed until now. Any dirty
240 	                 * buffers/pages must be flushed before the close, so =
that the
241 	                 * stateid is available for the writes.
242 	                 */
243 	                if (vp->v_object !=3D NULL) {
244 	                        VM_OBJECT_WLOCK(vp->v_object);
245 	                        retv =3D vm_object_page_clean(vp->v_object, 0,=
 0,
246 	                            OBJPC_SYNC);
247 	                        VM_OBJECT_WUNLOCK(vp->v_object);
248 	                } else
249 	                        retv =3D TRUE;
250 	                if (retv =3D=3D TRUE) {
251 	                        (void)ncl_flush(vp, MNT_WAIT, NULL, ap->a_td, =
1, 0);
252 	                        (void)nfsrpc_close(vp, 1, ap->a_td);
253 	                }
254 	        }
Note that nothing like this is done for NFSv3.
What might work is implementing a VOP_SET_TEXT() vnode op for the NFS
client that does most of the above (except for nfsrpc_close()) and then set=
s
VV_TEXT.
--> That way, all the dirty pages will be flushed to the server before the =
executable
     starts executing.

> Running this on an NFS share, and then attempting to run the resulting
> 'helloworld' executable will result in the "text file modification"
> error, and it will be killed.  But if you simply copy the executable to
> something else, then it runs fine, even if you use -p to retain the
> properties!
>
> IMHO this is a rather surprising problem with the NFS code, and Kostik
> remarked that the problem seems to be that the VV_TEXT flag is set too
> early, before the nfs cache is invalidated.  Rick, do you have any ideas
> about this?
I don't think it is the "nfs cache" that needs invalidation, but the dirty
pages written by the mmap'd file need to be flushed, before the VV_TEXT
is set, I think?

If Kostik meant "attribute cache" when he said "nfs cache", I'll note that =
the
cached attributes (including mtime) are updated by the reply to every write=
.
(As such, I think it is the writes that must be done before setting VV_TEXT
  that is needed.)

It is a fairly simple patch to create. I'll post one to this thread in a da=
y or so
unless Kostik thinks this isn't correct and not worth trying.

rick





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?YTXPR01MB01898D49933A82170FCAB7A0DD390>