Man pages are usually terse reference documents. Wikipedia is a better place to turn to for conceptual explanations.
Fork duplicates a process: it creates a child process which is almost identical to the parent process (the most obvious difference is that the new process has a different process ID). In particular, fork (conceptually) must copy all the parent process's memory.
As this is rather costly, vfork was invented to handle a common special case where the copy is not necessary. Often, the first thing the child process does is to load a new program image, so this is what happens:
if (fork()) {
# parent process …
} else {
# child process (with a new copy of the process memory)
execve("/bin/sh", …); # discard the process memory
}
The execve
call loads a new executable program, and this replaces the process's code and data memory by the code of the new executable and a fresh data memory. So the whole memory copy created by fork
was all for nothing.
Thus the vfork
call was invented. It does not make a copy of the memory. Therefore vfork
is cheap, but it's hard to use since you have to make sure you don't access any of the process's stack or heap space in the child process. Note that even reading could be a problem, because the parent process keeps executing. For example, this code is broken (it may or may not work depending on whether the child or the parent gets a time slice first):
if (vfork()) {
# parent process
cmd = NULL; # modify the only copy of cmd
} else {
# child process
execve("/bin/sh", "sh", "-c", cmd, (char*)NULL); # read the only copy of cmd
}
Since the invention of vfork, better optimizations have been invented. Most modern systems, including Linux, use a form of copy-on-write, where the pages in the process memory are not copied at the time of the fork
call, but later when the parent or child first writes to the page. That is, each page starts out as shared, and remains shared until either process writes to that page; the process that writes gets a new physical page (with the same virtual address). Copy-on-write makes vfork mostly useless, since fork
won't make any copy in the cases where vfork
would be usable.
Linux does retain vfork. The fork
system call must still make a copy of the process's virtual memory table, even if it doesn't copy the actual memory; vfork
doesn't even need to do this. The performance improvement is negligible in most applications.
No reason to have both /run and /tmp
I think you're right. /tmp
is essentially deprecated now we have /run
. If your program is in a position to do so (which requires that it was installed as a privileged operation), then nowadays you would use a sub-directory of /run
. This is for security reasons.
E.g. the CUPS printing daemon does not run as root, but is generally installed from an OS package. The package installs /usr/lib/tmpfiles.d/cups.conf
, and systemd-tmpfiles
creates a directory it can access. Since the directory is under /run
, the name cannot have been maliciously claimed by an unprivileged user, unlike /tmp
which is world-writable.
"Unprivileged programs" which can't use /run
directly
The real distinction is if your program is being run by an arbitrary unprivileged user, under their own user ID. But you still generally don't want to use /tmp
, because it can be accessed by other unprivileged users. You would prefer to use $XDG_RUNTIME_DIR
. Typically this is implemented as /run/user/$(id -u)
- so it happens to be a subdirectory of /run
as well. The location isn't guaranteed though; programs should always use the environment variable.
/tmp
would only be useful for ad-hoc co-operation between different unprivileged users on the system. Such ad-hoc systems are vulnerable to a malicious user refusing to co-operate and spoiling things for everyone :). One example would be unprivileged users deciding to run a version of the talk
daemon, using a unix socket.
Note, Poettering's checklist below claimed that /tmp
would be useful for "small files", whereas /run
should only be used for "communication primitives". I don't think this distinction is true either. The poster-boy for /run
is udev
, and I'm pretty sure /run/udev
includes internal databases . Once you have a /run
directory, I don't think anyone wants to follow the claimed distinction and create another directory, to clutter /tmp
. So in practice we just use /run
nowadays.
Usage of world-writable shared namespaces [like /tmp] for communication purposes has always been problematic, since to establish communication you need stable names, but stable names open the doors for DoS attacks. This can be corrected partially, by establishing protected per-app directories for certain services during early boot (like we do for X11), but this only fixes the problem partially, since this only works correctly if every package installation is followed by a reboot.
...
Another Fedora feature (for Fedora 17) changed the semantics of /tmp for many system services to make them more secure, by isolating the /tmp namespaces of the various services
...
Because /tmp is no longer necessarily a shared namespace it is generally unsuitable as a location for communication primitives.
...
[/run] is guaranteed to be a tmpfs and is hence automatically flushed at boots. No automatic clean-up is done beyond that.
...
Here's a rough guide how we suggest you (a Linux application developer) pick the right directory to use:
- You need a place to put your socket (or other communication primitive) and your code runs privileged: use a subdirectory beneath /run. (Or beneath /var/run for extra compatibility.)
- You need a place to put your socket (or other communication primitive) and your code runs unprivileged: use a subdirectory beneath $XDG_RUNTIME_DIR.
- You need a place to put your larger downloads and downloads in progress and run unprivileged: use $XDG_DOWNLOAD_DIR.
- You need a place to put cache files which should be persistent and run unprivileged: use $XDG_CACHE_HOME.
- Nothing of the above applies and you need to place a small file that needs no persistency: use $TMPDIR with a fallback on /tmp. And use mkstemp(), and mkdtemp() and nothing homegrown.
- Otherwise use $TMPDIR with a fallback on /var/tmp. Also use mkstemp()/mkdtemp().
Note that these rules above are only suggested by us. These rules take into account everything we know about this topic and avoid problems with current and future distributions, as far as we can see them. Please consider updating your projects to follow these rules, and keep them in mind if you write new code.
One thing we'd like to stress is that /tmp and /var/tmp more often than not are actually not the right choice for your usecase. There are valid uses of these directories, but quite often another directory might actually be the better place. So, be careful, consider the other options, but if you do go for /tmp or /var/tmp then at least make sure to use mkstemp()/mkdtemp().
We kind of get away with the legacy /tmp
socket used by the X window system, as described above. I misread tmpfiles.d/x11.conf
. Looks more like it relies on co-operation :). I assume the code's been audited, such that denial of service is the worst that can happen.
Best Answer
ULOG
was the original user space logging added in Kernel 2.4 for ipv4.NFLOG
is the newer, generic (layer3 independent) logging framework for 2.6 kernels based on the original ULOG but implemented via libnfnetlinkBoth will send logs to
ulogd
which will then log via whatever output plugin you choose.Use
ULOG
if you are stuck withulogd-1.x
as 1.x might not play nicely withNFLOG
. You really should be usingulogd-2.x
as1.x
is considered legacy and is EOL.Otherwise, just use
NFLOG