All functions prefixed with bdev_ are moved into bdev.c, and those
prefixed with cdev_ are now in cdev.c. The code in both files are
converted to KNF. The little (IOCTL-related) code left in device.c
is also cleaned up but should probably be moved into other existing
source files. This is left to a future patch. In general, VFS is
long overdue for a source code rebalancing, and the patch here is
only a step in the right direction.
Change-Id: I2fb25734b5778b44f2ff6d2ce331a8e2146e20b0
Previously, VFS would use various subsets of a number of fproc
structure fields to store state when the process is blocked
(suspended) for various reasons. As a result, there was a fair
amount of abuse of fields, hidden state, and confusion as to
which fields were used with which suspension states.
Instead, the suspension state is now split into per-state
structures, which are then stored in a union. Each of the union's
structures should be accessed only right before, during, and right
after the fp_blocked_on field is set to the corresponding blocking
type. As a result, it is now very clear which fields are in use
at which times, and we even save a bit of memory as a side effect.
Change-Id: I5c24e353b6cb0c32eb41c70f89c5cfb23f6c93df
Any attempt to use open(2) to open a socket file now fails with
EOPNOTSUPP, as is common and in the process of being standardized.
The behavior and error code is now tested in test56.
Any attempt to open a file of which the type is not known to VFS
(e.g., as a result of bogus file system contents) now fails with EIO.
For now, this is a safety feature, to prevent VFS tripping over such
types in unchecked cases. In the future, a proper VFS code audit
should determine whether we can lift this restriction again, although
it does not seem particularly useful to be able to open files of
unknown types anyway. Another error code may be assigned to this case
later, too.
Change-Id: Ib4cb4341eec954f0448fe469ecf28bd78edebde2
By now it has become clear that the VFS select code has an unusually
high concentration of bugs, and there is no indication that any form
of convergence to a bug-free state is in sight. Thus, for now, it
may be helpful to be able to dump the contents of the select tables
in order to track down any bugs in the future. Hopefully that will
allow the next bugs to be resolved slightly after than before.
The debug dump can be triggered with "svrctl vfs get print_select".
Change-Id: Ia826746dce0f065d7f3b46aa9047945067b8263d
A select query could deadlock if..
- it was querying a character or socket device that, at the start of
the select query, was not known to be ready for the requested
operations;
- this device could not be checked immediately, due to another ongoing
query to the same character or socket driver;
- the select query had a timer that triggered before the device could
be checked, thereby changing the select query to non-blocking.
In this situation, a missing flag check would cause the select code to
conclude erroneously that the operations which it flagged for later,
were satisfied. At the same time, the same flag remained set, so that
the select query would continue to wait for that device. This
resulted in a deadlock. The same bug could most likely be triggered
through other scenarios that were even less likely to occur.
This patch fixes the race condition and puts in a hopefully slightly
more informative comment for the affected block of code.
In practice, the bug could be triggered fairly reliably by generating
lots of output in tmux.
Change-Id: I1c909255dcf552e6c7cef08b0cf5cbc41294b99c
Now that clock_t is an unsigned value, we can also allow the system
uptime to wrap. Essentially, instead of using (a <= b) to see if time
a occurs no later than time b, we use (b - a <= CLOCK_MAX / 2). The
latter value does not exist, so instead we add TMRDIFF_MAX for that
purpose.
We must therefore also avoid using values like 0 and LONG_MAX as
special values for absolute times. This patch extends the libtimers
interface so that it no longer uses 0 to indicate "no timeout".
Similarly, TMR_NEVER is now used as special value only when
otherwise a relative time difference would be used. A minix_timer
structure is now considered in use when it has a watchdog function set,
rather than when the absolute expiry time is not TMR_NEVER. A few new
macros in <minix/timers.h> help with timer comparison and obtaining
properties from a minix_timer structure.
This patch also eliminates the union of timer arguments, instead using
the only union element that is only used (the integer). This prevents
potential problems with e.g. live update. The watchdog function
prototype is changed to pass in the argument value rather than a
pointer to the timer structure, since obtaining the argument value was
the only current use of the timer structure anyway. The result is a
somewhat friendlier timers API.
The VFS select code required a few more invasive changes to restrict
the timer value to the new maximum, effectively matching the timer
code in PM. As a side effect, select(2) has been changed to reject
invalid timeout values. That required a change to the test set, which
relied on the previous, erroneous behavior.
Finally, while we're rewriting significant chunks of the timer code
anyway, also covert it to KNF and add a few more explanatory comments.
Change-Id: Id43165c3fbb140b32b90be2cca7f68dd646ea72e
The new asserts from git-29e004d exposed an issue in how VFS handles
aborting file system (FS) requests that are queued for a FS (as
opposed to sent to it) when that FS crashes. In that scenario, the
queued worker has its w_task set to NONE, because there is no ongoing
communication. However, worker_stop() is called on it regardless,
which used to abort the request only if w_task was not set to NONE,
leading to an improperly aborted request, a warning, and a VFS crash a
bit later. This patch changes worker_stop() so that w_task need not
be set to a valid endpoint for FS requests to be properly aborted.
Change-Id: Ib73db285e689ae4742b15cba26137bf340bc303b
Currently, the BSD socket API is implemented in libc, translating the
API calls to character driver operations underneath. This approach
has several issues:
- it is inefficient, as most character driver operations are specific
to the socket type, thus requiring that each operation start by
bruteforcing the socket protocol family and type of the given file
descriptor using several system calls;
- it requires that libc itself be changed every time system support
for a new protocol is added;
- various parts of the libc implementations violate the asynchronous
signal safety POSIX requirements.
In order to resolve all these issues at once, the plan is to turn the
BSD socket calls into system calls, thus making the BSD socket API the
"native" ABI, removing the complexity from libc and instead letting
VFS deal with the socket calls.
The overall change is going to break all networking functionality. In
order to smoothen the transition, this patch introduces the fifteen
new BSD socket system calls, and makes libc try these first before
falling back on the old behavior. For now, the VFS implementations of
the new calls fail such that libc will always use the fallback cases.
Later on, when we introduce the actual implementation of the native
BSD socket calls, all statically linked programs will automatically
use the new ABI, thus limiting actual application breakage.
In other words: by itself, this patch does nothing, except add a bit
of transitional overhead that will disappear in the future. The
largest part of the patch is concerned with adding full support for
the new BSD socket system calls to trace(1) - this early addition has
the advantage of making system call tracing output of several socket
calls much more readable already.
Both the system call interfaces and the trace(1) support have already
been tested using code that will be committed later on.
Change-Id: I3460812be50c78be662d857f9d3d6840f3ca917f
There is no reason to use a single message for nonoverlapping requests
and replies combined, and in fact splitting them out allows reuse of
messages and avoids various problems with field layouts. Since the
upcoming socketpair(2) system call will be using the same reply as
pipe2(2), split up the single message used for the latter. In order
to keep the used parts of messages at the front, start a transitional
phase to move the pipe(2) flags field to the front of its request.
Change-Id: If3f1c3d348ec7e27b7f5b7147ce1b9ef490dfab9
In order to resolve page faults on file-mapped pages, VM may need to
communicate (through VFS) with a file system. The file system must
therefore not be the one to cause, and thus end up being blocked on,
such page faults. To resolve this potential deadlock, the safecopy
system was previously extended with the CPF_TRY flag, which causes the
kernel to return EFAULT to the caller of a safecopy function upon
getting a pagefault, bypassing VM and thus avoiding the loop. VFS was
extended to repeat relevant file system calls that returned EFAULT,
after resolving the page fault, to keep these soft faults from being
exposed to applications.
However, general UNIX I/O semantics dictate that if an I/O transfer
partially succeeded before running into a failure, the partial result
is to be returned. Proper file system implementations may therefore
end up returning partial success rather than the EFAULT code resulting
from a soft fault. Since VFS does not get the EFAULT code in this
case, it does not know that a soft fault occurred, and thus does not
repeat the call either. The end result is that an application may get
partial I/O results (e.g., a short read(2)) even on regular files.
Applications cannot reasonably be expected to deal with this.
Due to the fact that most of the current file system implementations
do not implement proper partial-failure semantics, this problem is not
yet widespread. In fact, it has only occurred on direct block device
I/O so far. However, the next generation of file system services will
be implementing proper I/O semantics, thus exacerbating the problem.
To remedy this situation, this patch changes the CPF_TRY semantics:
whenever the kernel experiences a soft fault during a safecopy call,
in addition to returning FAULT, the kernel also stores a mark in the
grant created with CPF_TRY. Instead of testing on EFAULT, VFS checks
whether the grant was marked, as part of revoking the grant. If the
grant was indeed marked by the kernel, VFS repeats the file system
operation, regardless of its initial return value. Thus, the EFAULT
code now only serves to make the file system fail the call faster.
The approach is currently supported for both direct and magic grants,
but is used only with magic grants - arguably the only case where it
makes sense. Indirect grants should not have CPF_TRY set; in a chain
of indirect grants, the original grant is marked, as it should be.
In order to avoid potential SMP issues, the mark stored in the grant
is its grant identifier, so as to discard outdated kernel writes.
Whether this is necessary or effective remains to be evaluated.
This patch also cleans up the grant structure a bit, removing reserved
space and thus making the structure slightly smaller. The structure
is used internally between system services only, so there is no need
for binary compatibility.
Change-Id: I6bb3990dce67a80146d954546075ceda4d6567f8
- About 80% of PM's process table consisted of per-signal sigaction
structures. This is information not used by the MIB service, and
can safely be stored outside the main process table.
- The MIB service does not need most of the VFS process table, so VFS
now generates a "light" version of its table upon request, with just
the fields used by the MIB service.
The result is a size reduction of the MIB service of about 700KB.
Change-Id: I79fe7239361fbfb45286af8e86a10aed4c2d2be7
This brings our tree to NetBSD 7.0, as found on -current on the
10-10-2015.
This updates:
- LLVM to 3.6.1
- GCC to GCC 5.1
- Replace minix/commands/zdump with usr.bin/zdump
- external/bsd/libelf has moved to /external/bsd/elftoolchain/
- Import ctwm
- Drop sprintf from libminc
Change-Id: I149836ac18e9326be9353958bab9b266efb056f0
- the userland call is now made to PM only, and PM relays the call to
other servers as appropriate; this is an ABI change that will
ultimately allow us to add proper support for wait3() and the like;
for the moment there is backward compatibility;
- the getrusage-specific kernel subcall has been removed, as it
provided only redundant functionality, and did not provide the means
to be extended correctly in the future - namely, allowing the kernel
to return different values depending on whether resource usage of
the caller (self) or its children was requested;
- VM is now told whether resource usage of the caller (self) or its
children is requested, and it refrains from filling in wrong values
for information it does not have;
- VM now uses the correct unit for the ru_maxrss values;
- VFS is cut out of the loop entirely, since it does not provide any
values at the moment; a comment explains how it should be readded.
Change-Id: I27b0f488437dec3d8e784721c67b03f2f853120f
The current values were both inaccurate (especially for dynamically
linked executables) and using the wrong unit (bytes, instead of
kilobytes times ticks-of-execution). For now we are better off not
populating these fields at all.
Change-Id: I195a8fa8db909e64a833eec25f59c9ee0b89bdc5
Currently, the userland ABI uses a single field ('user_sp') far
into the very large 'kinfo' structure on the shared kernel
information page. This precludes us from modifying or getting
rid of 'kinfo' in the future without breaking userland. This
patch adds a separate 'kuserinfo' structure to the kernel
information page, with only information that is part of the
userland ABI, in an extensible manner. Userland now uses this
field if it is present, and falls back to the old field if not.
Change-Id: Ib7b24b53a440f40a2edc28cdfa48447ac2179288
Instead of importing an external _minix_kerninfo variable, any code
using the shared kernel page should now call get_minix_kerninfo(3).
Since this is the only logical name for such a function, rename the
previous get_minix_kerninfo call to ipc_minix_kerninfo.
Change-Id: I2e424b6fb55aa55d3da850187f1f7a0b7cbbf910
The libexec ELF parser expects to be given a word-aligned buffer,
but the ASR pass may cause VM and VFS to pass it an arbitrarily
aligned buffer, causing libexec to refuse loading the executable.
This patch aligns the buffers explicitly.
Change-Id: Ic2d5fd3a8f204c3e4f000cffdb7ac71c8339257a
- do not allow live update for request and protocol free states if
there are any worker threads that have pending or active work;
- destroy all worker threads before such live updates and recreate
them afterwards, because transferring (the contents of) the
thread stacks is not an option at this time;
- recreate worker threads in the new instance only if they were
shut down before the state transfer, by letting RS provide the
original preparation state as initialization information.
Change-Id: I846225f5b7281f19e69175485f2c88a4b4891dc2
The following services have been updated to support stateful restarts:
- Drivers: tty
- Filesystems: isofs, mfs, pfs, libvtreefs-based file servers
- System servers: tty, ds, pm, vfs, vm
Change-Id: Ie84baa3ba1774047b3ae519808fe4116928edabb
Some select queries require a response from device drivers. If a
select call is nonblocking (with a zero timeout), the response to
the caller may have to be deferred until all involved drivers have
responded to the initial query. This is handled just fine.
However, if the select call has a timeout that is so short that it
triggers before all the involved drivers have responded, the
resulting alarm would be discarded, possibly resulting in the call
blocking forever. This fix changes the alarm handler such that if
the alarm triggers too early, the select call is further handled
as though it was nonblocking.
This fix resolves a test77 deadlock on really slow systems.
Change-Id: Ib487c8fe436802c3e11c57355ae0c8480721f06e
Fix /dev/tty-related issues in tmux(1) by hardcoding the PTY major
in VFS in addition to the TTY major. Even though this is exactly
what we did NOT want to have to do, the actual fix for this issue
is going to take a little longer.
Change-Id: I24c75eaf688b9ebd28e931f2e445b8442cfdac78
The previous approach of storing pointers to messages structures for
thread-blocking sendrec operations relied on several assumptions,
which if violated could lead to odd cases of memory corruption.
With this patch, VFS resets pointers right after use, avoiding that
any dangling pointers are accidentally dereferenced later. This
approach was already used in some cases, but not all of them.
Change-Id: I752d994ea847b46228bd2ccf4e537deceb78fbaf
For dynamically linked executables, the interpreter is passed a
file descriptor of the binary being executed. To this end, VFS
opens the target executable, but opening the file fails if it is
not readable, even when it is executable. With this patch, when
opening the executable, it verifies the X bit rather than the R
bit on the file, thus allowing the execution of dynamically
linked binaries that are executable but not readable.
Add test86 to verify correctness.
Change-Id: If3514add6a33b33d52c05a0a627d757bff118d77
There is no reason to keep these tightly coupled data structures
separate. Moreover, there is no reason to have a union of file
descriptor and file pointer, since the second can be derived from
the first. The result are somewhat cleaner VFS internals.
Change-Id: I854da7d8291177878eecfc3077ef0a9e0cc82aaa
Commit 723e513 erroneously removed a yield() call from VFS which was
necessary to get resumed pipe read/write threads to run before VFS
blocks on receive(). The removal caused those threads to run only
once VFS received another message, effectively slowing down activity
on pipes to a crawl in some cases.
Instead of readding the yield() call, this patch restructures the
get_work() code to go back through the main message loop even when no
new work is received, thus ensuring that newly started threads are
always activated without requiring a special case.
This fixes#65.
Change-Id: I59b7fb9e403d87dba1a5deecb04539cc37517742
For VFS, initialization is a special case for processing work: PFS
and the ramdisk MFS must be fully mounted before VFS can process any
other requests, in particular from init(8). This case was handled by
receiving reply messages only from the FS service being mounted, but
this effectively disallowed PFS from calling setuid(2) at startup.
This patch lets VFS receive all messages during the mounting process,
but defer processing any new requests. As a result, the FS services
have a bit more freedom in what they can do during startup.
Change-Id: I18275f458952a8d790736a9c9559b27bbef97b7b
This patch fixes two related issues:
- If a large (>PIPE_BUF) pipe write is processed partially, only to be
followed by a write error condition, then the process is left in an
incorrect state, possibly causing VFS to crash on a subsequent call.
- If such a partially processed large pipe write ends up resulting in
an EPIPE error, no corresponding SIGPIPE signal is generated.
The corrected behavior is tested in test68.
Change-Id: I5540e61ab6bcc60a31201485eda04bc49ece2ca8
- synchronize request type with ioctl by making it unsigned long;
- unbreak VFS requests, as they were being sent to PM;
- use proper ioctl direction flags (and new numbers) for requests;
- remove some needless header inclusions;
- svrctl is in libc, make its message name reflect this;
- keep backward compatibility: svrctl is part of the userland ABI.
Change-Id: I44902e8d0d11b8ebc1ef3bda94d2202481743c9b
In order to avoid creating libfsdriver exceptions, two changes to VFS
are necessary:
- the returned position field for reads/writes is no longer abused to
return the new pipe size; VFS is perfectly capable of updating the
size itself;
- during system startup, PFS is now sent a mount request, just like all
other file systems.
In proper "two steps forward, one step back" fashion, the latter point
has the consequence that PFS can no longer drop its privileges at
startup. This is probably best resolved with a more general solution
for all boot image system services. The upside is that PFS no longer
needs to be linked with libc.
Change-Id: I92e2410cdb0d93d0e6107bae10bc08efc2dbb8b3
The conversion was never properly implemented for asynchronous
character drivers, and got lost during the removal of the
synchronous character protocol.
Change-Id: Ib858806859aa7a52d6b391d4c6c521a2be361fdd
The remapping from /dev/tty to the real controlling terminal in the
device code was confusing the select code. The latter is now aware
of this case and should handle it properly, at the cost of one extra
field in the filp structure.
There is a nasty, hopefully sufficiently rare case of /dev/tty being
kept open while controlling terminals are changing, that we are still
not handling. Doing so would require more than just a few changes,
but the code should at least detect and cleanly fail on this case.
Test77 now has a basic test set for selecting on /dev/tty.
Change-Id: Iaedea449cdb728d0e66a9de8faacdfd9638dfe92