this code was if(0) for a long time due to wrong parentesis,
fixed parentesis cause print spam on some machines making them
unusage (kenji okomoto). removing the check alltogether.
theres a bootstrap problem:
when /bin/init is run, it processes /lib/namespace where we might want to
mount or bind resources to /n or /mnt. but mntgen was run later in
cpurc/termrc so these mounts would be ignored.
we already have mntgen in bootfs, so we can provide these mountpoints early.
i keep the termrc/cpurc mntgens where they are, but ignore the error
prints. this way old kernels will continue to work.
apparently, this causes some quadcore ramnode vm to hang on boot,
even tho all cores successfully started up and are operational.
i suspect some side effect from timersinit()... this would also
mean *notsc= would break it (syncclock() would continue)...
its unclear.
i'm reverting this for now until the problem is better understood.
when testing in qemu, launching each ap became slower and slower
because all the ap's where spinning in syncclock() waiting for
cpu0 to update its mach0->tscticks, which happens only much later
after all cpu's have been started up.
now we wait for each cpu to do its timer callibration and
manually update our tscticks while we wait and each cpu will
not spin but halt while waiting for active.thunderbirdsarego.
this reduces the system load and noise for timer callibration
and makes the mp startup linear with regard to the number of
cores.
introduce cpushutdown() function that does the common
operation of initiating shutdown, returning once all
cpu's got the message and are about to shutdown. this
avoids duplicated code which isnt really machine specific.
automatic reboot on panic only when *debug= is not set
and the machine is a cpu server or has no display,
otherwise just hang.
to solve the usb device enumeration race on boot, usbd creates /env/usbbusy
on startup and once all devices have been enumerated and readers have consumed
all the events, we remove the file so nusbrc/bootrc can continue. this makes
sure all the usb devices that where plugged in on boot are made available.
when opening a /env file ORCLOSE, and the process exits, envgrp() would
return nil can crash in envremove() because procexit will have set up->egrp
to nil before calling closefgrp().
the solution is to capture the environment on open, keeping a reference in
Chan.aux, so it doesnt matter on what process the close happens and a
env chan will always refer to its original environment group.
instead of checking addr+len >= addr, check len >= -addr so
that addr == 0 is never valid for len > 0 even if we decide
to have memory at the zero page so theres never any chance
user can pass in "nil" pointers.
put up some signs where we fall thru the switch cases in
fixfault()
sha256 is only defined for TLS1.2, however, technically, theres
no reason not to use it in TLS1.0/TLS1.1. the choice is up to
tlshand and pushtls, not the kernel.
introduce wificfg() function to convert ether->opt[] strings
to wifictl messages, which needs quoting for the value. so
etherX=type=iwl essid='something with spaces' works.
- fix missing runlock(ifc) when ifcid != a->ifcid in rxmitsols() (thanks erik quanstro)
- don't leak packets when transfering blocks from arp entry hold list to droplist
- free rest of droplist when bwrite() errors in arpenter(), remove useless checks (ifc != nil)
- free arp entry hold list from cleanarpent()
- consistent use of nil for pointers
for incoming connection, we used s->laddr to lookup the interface
for the incoming call, but this does not work when the announce
address is tcp!*!123, then s->laddr is all zeros "::". instead,
use the incoming destination address for interface mtu lookup.
thanks mycroftix for troubleshooting!
instead of ordering the source mount list, order the new destination
list which has the advantage that we do not need to wlock the source
namespace, so copying can be done in parallel and we do not need the
copy forward pointer in the Mount structure.
the Mhead back pointer in the Mount strcture was unused, removed.
there was a race between cunmount() and walk() on Mhead.from as Mhead.from was
unconditionally freed when we cunmount(), but findmount might have already
returned the Mhead in walk(). we have to ensure that Mhead.from is not freed
before the Mhead itself (now done in putmhead() once the reference count of the
Mhead drops to zero).
the Mhead struct contained two unused locks, removing.
no need to hold Pgrp.ns lock in closegrp() as nobody can get to it (refcount
droped to zero).
avoid cclose() and freemount() while holding Mhead.lock or Pgrp.ns locks as
it might block on a hung up fileserver.
remove the debug prints...
cleanup: use nil for pointers, remove redundant nil checks before putmhead().
we have to validaddr() and vmemchr() all argv[] elements a second
time when we copy to the new stack to deal with the fact that another
process can come in and modify the memory of the process doing the
exec. so the argv[] strings could have changed and increased in
length. we just make sure the data being copied will fit into the
new stack and error when we would overflow.
also make sure to free the ESEG in case the copy pass errors.
argv[] strings get copied to the new processes stack segment, which
has a maximum size of USTKSIZE, so limit the size of the strings to
that and check early for overflow.
this moves the name validation out of segattach() to syssegattach()
to make sure the segment name cannot be changed by the user while
segattach looks at it.
when executing a script, we did advance argp0 unconditionally
to replace argv[0] with the script name. this fails when
argv[] is empty, then we'd advance argp0 past the nil terminator.
the alternative would be to *not* advance if *argp0 == nil, but that
would require another validaddr() check for a case that is unlikely
to have been anticipated in most programs being invoked as
libc's ARGBEGIN macro assumes argv[0] being non-nil as it also
unconditionally advances the argv pointer.
to keep us sane, we now reject an empty argv[]. on entry, we
verify that argv[] is valid for at least two elements:
- the program name argv[0], has to be non-nil
- the first potential nil terminator in argv[1]
when argv[0] == nil, we throw Ebadarg "bad arg in system call"
the psaux driver is not used in any kernel configuration and theres
no userspace mouse daemon. i8042auxcmds() is wrong as access
to the user buffer can fault and we are holding an ilocks.
little cleanups in devkbd.
on vmware, loading a new kernel sometimes reboots when
wiggling the mouse. disabling keyboard and mouse on
shutdown fixes the issue.
make sure ps2 mouse is disabled on init, will get re-enabled
in i8042auxenable().
keyboard isnt special anymore, we can just use the devreset
entry point in the device to do the keyboard initialization,
so kbdinit()/kbdenable() are not needed anymore.
the keyboard stops sending interrupts when its fifo gets full,
which can happen on boot when keys get mashed while interrupts
are still disabled. to work arround this, call the keyboard
interrupt handler when kbd.q is starved before blocking.
add bootscreenconf(VGAscr *) function, that is called whenever
the framebuffer configuration is changed by devvga. that way, we
can pass the current setting of the framebuffer to the new
kernel when using /dev/reboot.
we already export mntauth() and mntversion(), so why not stop
being sneaky and just export mntattach() so bindmount() and
devshr can just call it directly with proper arguments being
checked.
we can also avoid handling #M attach specially in namec()
by having the devmnt's attach function do error(Enoattach).
to avoid double caching, attachimage() and setswapchan() clear
the CCACHE flag on the channel but this keeps the read ahread
state of the cache arround (until the chan gets closed), so also
call cclunk() to detach the mcp and free the read ahead state.
avoid the call to cread() when CCACHE flag is clear.
use the actual iounit returned from Ropen/Rcreate to chunk reads and writes
instead of c->mux->msize-IOHDRSZ.
dont preallocate the rpc buffers to msize, most 9p requests are rather small
(except Twrite of course). so we allocate the buffer on demand in mountio()
with some rounding to avoid frequent reallocations.
avoid malloc()/free() while holding mntalloc lock.
this changes devmnt adding mntrahread() function and some helpers
for it to do pipelined sequential read ahead for the mount cache.
basically, cread() calls mntrahread() with Mntrah structure and it
figures out if we where reading sequentially and if thats the case
issues reads of c->iounit size in advance.
the read ahead state (Mntrah) is kept in the mount cache so we can
handle (read ahead) cache invalidation in the presence of writes.
as the Fgrp can be shared with other processes, we have to
recheck the fd index after locking the Fgrp in fdclose()
to make sure not to read beyond the bounds of the fd array.
using the user buffer has a race where the user can modify
the buffer from another process before it is copied into the cache.
this allows poisoning the cache for every file where the user
has read access.
instead, we update the cache from kernel memory.
Wnode gets two new counters: txcount and txerror
and actrate pointer that will be between minrate
and maxrate.
driver should use actrate instead of maxrate for
transmission when it can provide error feedback.
when a driver detects a transmission failed, it calls
wifitxfail() with the original packet. wifitxfail() then
reduces wn->actrate.
every 256th packet, we optimistically increase wn->actrate
before transmitting.
- reject files smaller or equal to two bytes, they are bogus
- fix out of bounds access in shargs() when n <= 2
- only copy the bytes read into line buffer
- use nil for pointers instead of 0
imagereclaim(), pagereclaim():
- move imagereclaim() and pagereclaim() declarations to portfns.h
- consistently use ulong type for page counts
- name number of pages to free "pages" instead of "min"
- check for pages == 0 on entry
freepages():
- move pagechaindone() call to wakeup newpage() consumers inside
palloc critical section.
putimage():
- use long type for refcount
- reduce delay for channel hop to 200ms
- use 1000ms timeout for auth response (dont hop channels while we wait)
- bunny hop sequence is mathematically prooven
addresses va's of 0 and -BY2PG cause trouble with some memmove()/memset()
implementations and possibly other code because of the nil pointer
and end pointers wrapping to zero.
unlock()/iunlock():
we need to place the coherence() *before* "l->key = 0", so that any
stores that where done while holding the lock become observable
*before* other processors see the lock released.
cas()/tas():
place memory barrier before successfull return to prevent reordering.
making sure to close the dot in every kproc appears repetitive,
so instead stop inheriting the dot in kproc() as this is usually
never what you wanted in the first place.
give kernel processes and local disk file servers (procs
having noswap flag set) a clear advantage for page allocation
under starved condition by giving them ther own wait queue so
they get readied as soon as pages become available.
yoann padioleaus report on 9fans:
> I think I’ve found a bug in the network stack.
> in 9/ip/ip.h there is
> struct Ipht
> {
> Lock;
> Iphash *tab[Nipht];
> };
>
> where Night is 521,
>
> but then in 9/ip/ipaux.c there is
>
> ulong
> iphash(uchar *sa, ushort sp, uchar *da, ushort dp)
> {
> return ((sa[IPaddrlen-1]<<24) ^ (sp << 16) ^ (da[IPaddrlen-1]<<8) ^ dp ) % Nhash;
> }
>
> where Nhash is just 64,