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>