- all macros in consts.h that depend on NR_TASKS replaced by a FP_BLOCKED_ON_*
- fp_suspended removed and replaced by fp_blocked_on. Testing whether a process
is supended is qeual to testing whether fp_blocked_on is FP_BLOCKED_ON_NONE or
not
- fp_task is valid only if fp_blocked_on == FP_BLOCKED_ON_OTHER
- no need of special values that do not colide with valid and special endpoints
since they are not used as endpoints anymore
- suspend only takes FP_BLOCKED_ON_* values not endpoints anymore
- suspend(task) replaced by wait_for(task) which sets fp_task so we remember who
are we waiting for and suspend sets fp_blocked_on to FP_BLOCKED_ON_OTHER to
signal that we are waiting for some other process
- some functions should take endpoint_t instead of int, fixed
shared with the kernel, mapped into kernel address space;
kernel is notified of its location. kernel segment size is
increased to make it fit.
- map in kernel and other processes that don't have their
own page table using single 4MB (global) mapping.
- new sanity check facility: objects that are allocated with
the slab allocator are, when running with sanity checking on,
marked readonly until they are explicitly unlocked using the USE()
macro.
- another sanity check facility: collect all uses of memory and
see if they don't overlap with (a) eachother and (b) free memory
- own munmap() and munmap_text() functions.
- exec() recovers from out-of-memory conditions properly now; this
solves some weird exec() behaviour
- chew off memory from the same side of the chunk as where we
start scanning, solving some memory fragmentation issues
- use avl trees for freelist and phys_ranges in regions
- implement most useful part of munmap()
- remap() stuff is GQ's for shared memory
addr and taddr don't have to be defined any more, so that <sys/mman.h>
can be included for proper prototypes of munmap() and friends.
- rename our GETPID to MINIX_GETPID to avoid a name conflict with
other sources
- PM needs its own munmap() and munmap_text() to avoid sending messages
to VM at the startup phase. It *does* want to do that, but only
after initialising. So they're called again with unmap_ok set to 1
later.
- getnuid(), getngid() implementation
- If allocation of a new buffer fails, use an already-allocated
unused buffer if available (low memory conditions)
- Allocate buffers dynamically, so memory isn't wasted on wrong-sized
buffers.
- No more _MAX_BLOCK_SIZE.
bin_img=1 in the boot monitor will make sure that during the boot procedure the
mfs binary that is part of the boot image is the only binary that is used to
mount partitions. This is useful when for some reason the mfs binary on disk
malfunctions, rendering Minix unable to boot. By setting bin_img=1, the binary
on disk is ignored and the binary in the boot image is used instead.
- 'service' now accepts an additional flag -r. -r implies -c. -r instructs RS
to first look in memory if the binary has already been copied to memory and
execute that version, instead of loading the binary from disk. For example,
the first time a MFS is being started it is copied (-c) to memory and
executed from there. The second time MFS is being started this way, RS will
look in memory for a previously copied MFS binary and reuse it if it exists.
- The mount and newroot commands now accept an additional flag -i, which
instructs them to set the MS_REUSE flag in the mount flags.
- The mount system call now supports the MS_REUSE flag and invokes 'service'
with the -r flag when MS_REUSE is set.
- /etc/rc and the rc script that's included in the boot image check for the
existence of the bin_img flag in the boot monitor, and invoke mount and
newroot with the -i flag accordingly.
- When one does a select on a file descriptor that is meaningless for that particular file type, select shall indicate that the file descriptor is ready for that particular operation and that the file descriptor has no exceptional condition pending.
o Don't call vm_willexit() more than once upon normal process exit
o Correct two cases of indenting of the no-discussion-possible kind
o Perform slightly stricter ptrace(2) checks:
- process calling ptrace must be target process's parent
- process must call wait/waitpid before using ptrace on stopped child
- no ptrace on zombies
o Allow user processes to use ptrace(T_STOP) to stop an active child
Kernel:
o Remove s_ipc_sendrec, instead using s_ipc_to for all send primitives
o Centralize s_ipc_to bit manipulation,
- disallowing assignment of bits pointing to unused priv structs;
- preventing send-to-self by not setting bit for own priv struct;
- preserving send mask matrix symmetry in all cases
o Add IPC send mask checks to SENDA, which were missing entirely somehow
o Slightly improve IPC stats accounting for SENDA
o Remove SYSTEM from user processes' send mask
o Half-fix the dependency between boot image order and process numbers,
- correcting the table order of the boot processes;
- documenting the order requirement needed for proper send masks;
- warning at boot time if the order is violated
RS:
o Add support in /etc/drivers.conf for servers that talk to user processes,
- disallowing IPC to user processes if no "ipc" field is present
- adding a special "USER" label to explicitly allow IPC to user processes
o Always apply IPC masks when specified; remove -i flag from service(8)
o Use kernel send mask symmetry to delay adding IPC permissions for labels
that do not exist yet, adding them to that label's process upon creation
o Add VM to ipc permissions list for rtl8139 and fxp in drivers.conf
Left to future fixes:
o Removal of the table order vs process numbers dependency altogether,
possibly using per-process send list structures as used for SYSTEM calls
o Proper assignment of send masks to boot processes;
some of the assigned (~0) masks are much wider than necessary
o Proper assignment of IPC send masks for many more servers in drivers.conf
o Removal of the debugging warning about the now legitimate case where RS's
add_forward_ipc cannot find the IPC destination's label yet
POSIX compliance.
VFS changes:
* truncate() on a file system mounted read-only no longer panics MFS.
* ftruncate() and fcntl(F_FREESP) now check for write permission on
the file descriptor instead of the file, write().
* utime(), chown() and fchown() now check for file system read-only
status.
MFS changes:
* link() and rename() no longer return the internal EENTERMOUNT and
ELEAVEMOUNT errors to the application as part of a check on the
source path.
* rename() now treats EENTERMOUNT from the destination path check as
an error, preventing file system corruption from renaming a normal
directory to an existing mountpoint directory.
* mountpoints (mounted-on dirs) are hidden better during lookups:
- if a lookup starts from a mountpoint, the first component has to
be ".." (anything else being a VFS-FS protocol violation).
- in that case, the permissions of the mountpoint are not checked.
- in all other cases, visiting a mountpoint always results in
EENTERMOUNT.
* a lookup on ".." from a mount root or chroot(2) root no longer
succeeds if the caller does not have search permission on that
directory.
* POSIX: getdents() now updates directory access times.
* POSIX: readlink() now returns partial results instead of ERANGE.
Miscellaneous changes:
* semaphore file handling bug (leading to hangs) fixed in test 32.
The VFS changes should now put the burden of checking for read-only
status of file systems entirely on VFS, and limit the access
permission checks that file systems have to perform, to checking
search permission on directories during lookups. From this point on,
any deviation from that spceification should be considered a bug.
Note that for legacy reasons, the root partition is assumed to be
mounted read-write.
- Changed VFS-FS protocol to only store OK or negative error code in
m_type field of reply messages.
- Changed VFS to treat nonzero positive replies from FS as requests.
- Added backwards compatibility to VFS and MFS.
No protection of global data structures is provided in VFS, so many
VFS calls cannot be made safely by FS servers during many FS calls.
Use with caution (or, preferably, not at all).
if the process was REVIVING. (susp_count doesn't count those
processes.) this together with dev_io SELECT suspend side effect
for asynch. character devices solves the hanging pipe bug. or
at last vastly improves it.
added sanity checks, turned off by default.
made the {NOT_,}{SUSPENDING,REVIVING} constants weirder to
help sanity checking.
- slight code cleanup
- neater exit procedure: exit when unmount
message received and kill signal (from RS 'down' or
reboot/shutdown) received (speed up unmount, but don't
confuse VFS by exiting before/during unmount msg)
read/write writable in the pagetable right away instead of waiting for
a pagefault. minor optimization.
some a sanity check of SLAB-allocated pointers.
vm gets its own _exit and __exit like PM, so the stock (library) panic works.
- ipc checking code in kernel didn't properly catch the
sendrec() to self case; added special case check
- triggered by PM using stock panic() - needs its own _exit()
reported by Joren l'Ami.
now used for printing diagnostic messages through the kernel message
buffer. this lets processes print diagnostics without sending messages
to tty and log directly, simplifying the message protocol a lot and
reducing difficulties with deadlocks and other situations in which
diagnostics are blackholed (e.g. grants don't work). this makes
DIAGNOSTICS(_S), ASYN_DIAGNOSTICS and DIAG_REPL obsolete, although tty
and log still accept the codes for 'old' binaries. This also simplifies
diagnostics in several servers and drivers - only tty needs its own
kputc() now.
. simplifications in vfs, and some effort to get the vnode references
right (consistent) even during shutdown. m_mounted_on is now NULL
for root filesystems (!) (the original and new root), a less awkward
special case than 'm_mounted_on == m_root_node'. root now has exactly
one reference, to root, if no files are open, just like all other
filesystems. m_driver_e is unused.
. map kernel in non-user
. don't map in first pages of kernel code and data
if possible
these first pages could actually be freed but as the
kernel isn't allowed to touch them either we can't reuse
them until VM has totally taken over page table management
and kernel doesn't rely on identity mapping any more.
their own fully fledged virtual address space and freeing
their pre-allocated heap+stack area (necessary to let memory
driver map in arbitrary areas of memory for /dev/mem without
sys_vm_map)
- small optimization preallocating memory on exec
- finished VR_DIRECT physical mapping code
flag to suspend a process until the filedescriptor is re-opened. Added
dev_reopen, asyn_io, suspended_ep, reopen_reply, asynsend, diag_repl,
close_filp, close_reply, unpause, select_reply1, select_reply2.
. print newline
. when recursive panic detected, don't simply return, confusing
the caller, but print a diagnostic and exit
. don't call sys_exit as this may confuse PM; it should be OK
to call PM exit() nowadays.
case of directories extended by subfilesystem. Rely on subfilesystem to
do read size truncating and return actual i/o size. This fixes bug 81 in
gforge, and unbreaks test 23.
Select now returns such a filedescriptor as ready (instead of EBADF).
Reply before dev_up in FSSIGNON to avoid the problem that a DEV_OPEN
request is received by a driver that expects a reply from the FSSIGNON.
. vfs: 64-bit offset support for character device i/o
(also remove unused dev_bio function)
. memory: /dev/null and /dev/zero are infinitely large, don't stop
reading/writing at 4GB
as a first component of an absolute path failed (e.g. 'touch /file'),
due to leading slashes not being skipped in the processed path counter
in that case, causing create to fail.
bugfixes:
SYSTEM:
. removed
rc->p_priv->s_flags = 0;
for the priv struct shared by all user processes in get_priv(). this
should only be done once. doing a SYS_PRIV_USER in sys_privctl()
caused the flags of all user processes to be reset, so they were no
longer PREEMPTIBLE. this happened when RS executed a policy script.
(this broke test1 in the test set)
VFS/MFS:
. chown can change the mode of a file, and chmod arguments are only
part of the full file mode so the full filemode is slightly magic.
changed these calls so that the final modes are returned to VFS, so
that the vnode can be kept up-to-date.
(this broke test11 in the test set)
MFS:
. lookup() checked for sizeof(string) instead of sizeof(user_path),
truncating long path names
(caught by test 23)
. truncate functions neglected to update ctime
(this broke test16)
VFS:
. corner case of an empty filename lookup caused fields of a request
not to be filled in in the lookup functions, not making it clear
that the lookup had failed, causing messages to garbage processes,
causing strange failures.
(caught by test 30)
. trust v_size in vnode when doing reads or writes on non-special
files, truncating i/o where necessary; this is necessary for pipes,
as MFS can't tell when a pipe has been truncated without it being
told explicitly each time.
when the last reader/writer on a pipe closes, tell FS about
the new size using truncate_vn().
(this broke test 25, among others)
. permission check for chdir() had disappeared; added a
forbidden() call
(caught by test 23)
new code, shouldn't change anything:
. introduced RTS_SET, RTS_UNSET, and RTS_ISSET macro's, and their
LOCK variants. These macros set and clear the p_rts_flags field,
causing a lot of duplicated logic like
old_flags = rp->p_rts_flags; /* save value of the flags */
rp->p_rts_flags &= ~NO_PRIV;
if (old_flags != 0 && rp->p_rts_flags == 0) lock_enqueue(rp);
to change into the simpler
RTS_LOCK_UNSET(rp, NO_PRIV);
so the macros take care of calling dequeue() and enqueue() (or lock_*()),
as the case may be). This makes the code a bit more readable and a
bit less fragile.
. removed return code from do_clocktick in CLOCK as it currently
never replies
. removed some debug code from VFS
. fixed grant debug message in device.c
preemptive checks, tests, changes:
. added return code checks of receive() to SYSTEM and CLOCK
. O_TRUNC should never arrive at MFS (added sanity check and removed
O_TRUNC code)
. user_path declared with PATH_MAX+1 to let it be null-terminated
. checks in MFS to see if strings passed by VFS are null-terminated
IS:
. static irq name table thrown out
. changed umount() and mount() to call 'service', so that it can include
a custom label, so that umount() works again (RS slot gets freed now).
merged umount() and mount() into one file to encode keep this label
knowledge in one file.
. removed obsolete RS_PID field and RS_RESCUE rescue command
. added label to RS_START struct
. vfs no longer does kill of fs process on unmount (which was failing
due to RS_PID request not working)
. don't assume that if error wasn't one of three errors, that no error
occured in vfs/request.c
mfs changes:
. added checks to copy statements to truncate copies at buffer sizes
(left in debug code for now)
. added checks for null-terminatedness, if less than NAME_MAX was copied
. added checks for copy function success
is changes:
. dump rs label
drivers.conf changes:
. added acl for mfs so that mfs can be started with 'service start',
so that a custom label can be provided
print debug message if copy is truncated
. increased buffer in lookup() to be PATH_MAX instead of NAME_MAX
. sanity check in fetch_name() in vfs to see if name fits, and
is null-terminated
. first check i < NAME_MAX, then string[i] in search_dir, as we're
not supposed to look at string[NAME_MAX]
. corrected device match for unmount (otherwise unmount would
proceed with bogus mount slot, often sending messages to 0 (PM))
. added some sanity checking to fs process number
. made fs_sendrec PRIVATE to request.c
mainly in the kernel and headers. This split based on work by
Ingmar Alting <iaalting@cs.vu.nl> done for his Minix PowerPC architecture
port.
. kernel does not program the interrupt controller directly, do any
other architecture-dependent operations, or contain assembly any more,
but uses architecture-dependent functions in arch/$(ARCH)/.
. architecture-dependent constants and types defined in arch/$(ARCH)/include.
. <ibm/portio.h> moved to <minix/portio.h>, as they have become, for now,
architecture-independent functions.
. int86, sdevio, readbios, and iopenable are now i386-specific kernel calls
and live in arch/i386/do_* now.
. i386 arch now supports even less 86 code; e.g. mpx86.s and klib86.s have
gone, and 'machine.protected' is gone (and always taken to be 1 in i386).
If 86 support is to return, it should be a new architecture.
. prototypes for the architecture-dependent functions defined in
kernel/arch/$(ARCH)/*.c but used in kernel/ are in kernel/proto.h
. /etc/make.conf included in makefiles and shell scripts that need to
know the building architecture; it defines ARCH=<arch>, currently only
i386.
. some basic per-architecture build support outside of the kernel (lib)
. in clock.c, only dequeue a process if it was ready
. fixes for new include files
files deleted:
. mpx/klib.s - only for choosing between mpx/klib86 and -386
. klib86.s - only for 86
i386-specific files files moved (or arch-dependent stuff moved) to arch/i386/:
. mpx386.s (entry point)
. klib386.s
. sconst.h
. exception.c
. protect.c
. protect.h
. i8269.c
as living processes before they are cleaned up (fixes
wait()/waitpid() hanging forever on previously-ZOMBIE processes)
. stop processes from running using sys_nice() with PRIO_STOP
when a handled signal is delivered, before computing
stack locations for sys_sigsend(). (fixes race condition
when runnable processes get signals, and e.g. get scheduled
before FS sends a reply to unpause(), which can make the
signal stack location wrong.)
-script argument to service for crash recovery scripts
-config argument to service for driver resource configuration
restart command in service to restart a driver after a crash (for use in
crash recovery scripts).
down and refresh now take labels instead of pids.
verious changes in rs to make this work.
argument from the fd bitmasks are copied from and back to userspace. This
solves an ABI dependency on OPEN_MAX. If nfds is too big for the current
OPEN_MAX, select() fails (but that's relatively easy to fix by 'just'
recompiling the system and not the application binaries), but if it's
smaller, binaries keep working.
size field. The TIOCSFON ioctl size (8192) didn't get encoded properly,
as there weren't enough bits for it (12) in the regular format.
The new format has only one type field, and an extra flag (_IOC_BIG)
turned on. FS checks for this flag and uses the alternative decoding
of the ioctl codes to determine the size when doing grants.
This unbreaks loadfont, although that still uses a phys copy in tty.
form. Subscriptions are regular expressions.
. different types are stored per key; currently u32 and/or string.
the same key can be referenced (publish, subscribe, check) as any type.
. notify()s are sent when subscriptions are triggered (publishing or
updating of matching keys); optionally, a subscribe flag sends
updates for all matching keys at subscription time, instead of only
after updates after subscribing
. all interfacing to ds is in /usr/src/lib/syslib/ds.c.
. subscribe is ds_subscribe
publish functions are ds_publish_<type>
retrieve functions are ds_retrieve_<type> (one-time retrieval of a value)
check functions are ds_check_<type> (check for updated key caller
subscribes to not yet checked for, or ESRCH for none)
. ramdisk driver updated with new ds interface
Safecopies renders the NWIOQUERYPARAM ioctl useless. This functionality
is now replaced with /dev/ipstat. Write the request to the device and
read the answer in one read request.
. don't loop doing a receive() after sendrec() - chance of recovering is not
high, and can lead to receive()ing a notify() (which can't happen in sendrec()),
which is terrible
. return status from device when DEV_CANCEL is done on a signal; hardcode EAGAIN to
become EINTR though
For character device i/o, FS does a so-called 'magic' grant to let the
driver copy from or to user space. As this is done in FS address space,
the driver is told to do this in FS address space. The redirection to
the right user process then happens at copy-time in the kernel, using the
FS grant table. This also happens for DEV_READ and DEV_WRITE on block
devices.
For other block device i/o, which happens from/to FS buffers, FS does
a 'direct' grant to its own address space for the driver.
After the i/o returns, this access has to be K-I-L-L-E-D, revoked.
Sometimes this is after a SUSPEND and DEV_REVIVE, in which case the
revoking happens in pipe.c.
This conversion happens in safe_io_conversion() in device.c, called
by dev_io and dev_bio.
FS has to pre-allocate its own space for these grant tables. This happens
in main.c.
library to the memory driver. Always put output from within TTY directly on
the console. Removed second include of driver.h from tty.c. Made tty_inrepcode
bigger. First step to move PM and FS calls that are not regular (API)
system calls out of callnr.h (renumbered them, and removed them from the
table.c files). Imported the Minix-vmd uname implementation. This provides
a more stable ABI than the current implementation. Added a bit of security
checking. Unfortunately not nearly enough to get a secure system. Fixed a
bug related to the sizes of the programs in the image (in PM patch_mem_chunks).
instead of keeping a running total of enqueued processes
(because somehow the load average was broken)
. added SI_KPROC_TAB to get a copy of kernel process table from PM, for
a top implementation
. fixed arg to sys_nice() to make it an endpoint, not a slot number
. loops checked for PID_FREE
. exit broken down in exit and cleanup functions; when reboot happens,
cleanup is done but not exit (as processes have not actually exited),
this keeps drivers working
. fixed a few uninitialized and unused variables
scripts:
. new packaging system
pm: fixed rebooting by making a copy of the monitor code from the user
process. this is necessary because that process is dead by the time
sys_abort() is called.
also added more info to the "can't reply" panic.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
Implemented by changing write_map to accept a WMAP_FREE flag. In that
case, it doesn't update the datablock (creating indirect zones as
necessary) pointer, but it frees the datablock if present. Also it
frees the single and double indirect blocks if unused.
This makes the implementation of truncate_inode() simpler.
truncate_inode() now accepts a truncation length which makes
implementing truncate() and ftruncate() simple.
This also allowed implementing the F_FREESP fcntl().
. new_node() now returns inode of parent dir as argument that
has to be put_node()d again by the caller of new_node().
it can also return the name of the last component as last_dir()
did.
. advance() takes a pointer to a pointer of an inode as the
parent now. This parent can change, in which case the old
one is put_node()d and a new one is put there.
. eat_path() replaced by more flexible parse_path()
. last_dir() replaced by call to parse_path().
. do_slink(), do_readlink(), do_lstat() and slink_traverse() added.
Also added some truncate()/ftruncate()-introduction related changes.
(e.g. renamed truncate() to truncate_inode().)
. When drivers disappear that have pending select()s, wake up
those user processes with EAGAIN so that they can retry their
select() and won't hang forever on it.
. When drivers re-appear and are mapped into the dmap, run through
the list of mounted filesystems and re-dev_open() every one (for
partition tables and such). This can't happen before the driver
has exec()ced itself, so processes that have fork()ed but not
exec()ced yet are marked as DMAP_BABY in the dmap table if they
are dmapped before they are execced. If that happens, the above
procedure happens after the exec(). If the exec() happens before
the dmapping, it (the dev_open()ing) happens right away.
New Shift-F6 dump for RS server at IS.
New getnpid, getnproc, getpproc library calls at PM.
New reincarnation server (basic functionality is there now).
. unmap device drivers from dmap when PM signals they are dead
. new null-io function (no_dev_io) to fill in for io functions
of unmapped drivers
. driver (process number) of unmapped drivers is NONE instead of
0 (a valid process number)
IS:
. print mutable flag of dmap table too
FS changes require sync() to be done 'manually' (currently by
reboot/shutdown) at shutdown time; could be caught by SIGTERM in
the future.