Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 11 Sep 2015 09:24:12 -0700
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-arch@freebsd.org
Cc:        Edward Tomasz =?utf-8?B?TmFwaWVyYcWCYQ==?= <trasz@freebsd.org>
Subject:   Re: Make kern.ipc.shm_allow_removed default to 1.
Message-ID:  <5328060.4avXYiGHFa@ralph.baldwin.cx>
In-Reply-To: <20150908191310.GA3104@brick.home>
References:  <20150908191310.GA3104@brick.home>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tuesday, September 08, 2015 09:13:10 PM Edward Tomasz Napiera=C5=82a=
 wrote:
> I'd like to commit - well, discuss it first - the following change:
>=20
> https://reviews.freebsd.org/D3603
>=20
> This changes the default setting of kern.ipc.shm_allow_removed from 0=
 to 1.
> This removes the need of manually changing this flag for Google Chrom=
e
> users. It also improves compatibility with Linux applications running=
 under
> Linuxulator compatibility layer, and possibly also helps in porting s=
oftware
> from Linux.
>=20
> Generally speaking, the flag allows applications to create the shared=
 memory
> segment, attach it, remove it, and then continue to use it and to rea=
ttach it
> later. This means that the kernel will automatically "clean up" after=
 the
> application exits.
>=20
> It could be argued that it's against POSIX. However, SUSv3 says this
> about IPC_RMID: "Remove the shared memory identifier specified by shm=
id from
> the system and destroy the shared memory segment and shmid_ds data st=
ructure
> associated with it." From my reading, we break it in any case by defe=
rring
> removal of the segment until it's detached; we won't break it any mor=
e
> by also deferring removal of the identifier.

It is against POSIX.  When I last raised this with kib@ and alc@, Alan =
noted
that our current behavior is not really against POSIX as he felt there =
was
enough wriggle room to permit existing mappings to remain valid.

That said, in the thread kib@ felt it was ok to change the default.  I =
think
it's probably fine.  It's a hack for the fact that shmget() isn't retur=
ning
a real fd the way shm_open() does, so in that sense it is ok.  That is,=

in shm_open() you can do this:

=09fd =3D shm_open("/some/path");
=09shm_unlink("/some/path");
=09
=09mmap(..., fd);

=09/* later */

=09mmap(..., fd);

=09/* or pass fd over a UNIX domain socket and map it in another proces=
s */

=09close(fd);

=09/* now mmap won't work */

With FreeBSD's SHM_ANON you can collapse the first two steps down to:

=09fd =3D shm_open(SHM_ANON);

If you think of the return value from shmget() as an fd, then setting t=
his to 1
does make sense in a way.  That is you can have a sequence of:

=09id =3D shmget(...);

=09hold =3D shmat(id, ...);  /* "hold" mapping */

=09shmctl(IPC_RMID, id);

=09/* later */

=09shmat(id, ...);

=09/* or pass 'id' as a value across a socket and shmat in another proc=
ess */

    shmdt(hold);

    /* now shmat may or may not work */

However, note that this does require you to do some things carefully:

  1) You have to keep an existing mapping around via shmat() that serve=
s as
     the equivalent of the open file descriptor to keep the 'id' valid.=

     This also means you have to defer the IPC_RMID until after you hav=
e
     created this "hold" mapping.

  2) You always have to invoke IPC_RMID.  In particular, even if you us=
e
     shmget() with IPC_PRIVATE you have to explicitly IPC_RMID.

So, I think it is fine to change this (and have asked about doing it my=
self
in the past).  However, I think shm_open() is definitely a superior API=
 for
this sort of thing with semantics that are clearer and more inline with=
 UNIX.

--=20
John Baldwin



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