there was a diff that went in a while ago to improve
this, but it got backed out because it encounters a
bug in upstream git -- the spec says that a single
ACK should be sent when not using multi-ack modes,
but they send back multiple ones.
This commit brings back the functionality, and works
around the upstream git bug in two different ways.
First, it skips the packets up until it finds the
start of a pack header.
Second, it deduplicates the want messages, which
is what seems to trigger the duplicate ACKs that
cause us trouble.
This patch makes sam's = cmd output what seems to me a more
useful (plumbable) format: /full/path/to/file:addr , where
addr is line(s) under = and rune(s) under =#.
Although git9 always uses the same commit date and author date, other
implementation do make a distinction. Since commit date is more
representative of the commit graph order, use this as a traversal hint
instead of author date.
If the server only supports the dumb protocol, the first 4 bytes of
response will be the initial part of the hash of the first ref.
The http-protocol documentation says that we should fall back to the
dumb protocol when we don't see a content-type of
application/x-$servicename-advertisement. Check this before
attempting to read a smart git packet.
We now keep track of 3 sets during traversal:
- keep: commits we've reached from head commits
- drop: commits we've reached from tail commits
- skip: ancestors of commits in both 'keep' and 'drop'
Commits in 'keep' and/or 'drop' may be added later to the 'skip' set
if we discover later that they are part of a common subgraph of the
head and tail commits.
From these sets we can calculate the commits we are interested in:
lca commits are those in 'keep' and 'drop', but not in 'skip'.
findtwixt commits are those in 'keep', but not in 'drop' or 'skip'.
The "LCA" commit returned is a common ancestor such that there are no
other common ancestors that can reach that commit. Although there can
be multiple commits that meet this criteria, where one is technically
lower on the commit-graph than the other, these cases only happen in
complex merge arrangements and any choice is likely a decent merge
base.
Repainting is now done in paint() directly. When we find a boundary
commit, we switch our paint color to 'skip'. 'skip' painting does
not stop when it hits another color; we continue until we are left
with only 'skip' commits on the queue.
This fixes several mishandled cases in the current algorithm:
1. If we hit the common subgraph from tail commits first (if the tail
commit was newer than the head commit), we ended up traversing the
entire commit graph. This is because we couldn't distinguish
between 'drop' commits that were part of the common subgraph, and
those that were still looking for it.
2. If we traversed through an initial part of the common subgraph from
head commits before reaching it from tail commits, these commits
were returned from findtwixt even though they were also reachable
from tail commits.
3. In the same case as 2, we might end up choosing an incorrect
commit as the LCA, which is an ancestor of the real LCA.
When loading an acme dump file that contains a window with only one
tag line, there are cases where acme hides that window (i.e. not even
its tag is visible).
The following commands reproduce the issue:
% ed <<EOE
1
i
/tmp
/lib/font/bit/pelm/unicode.8.font
/lib/font/bit/pelm/unicode.8.font
0
f 0 5 175 175 1
5 40 175 1 0 /sys/src/cmd/acme/ Del Snarf Get | Look
f 0 4 330 330 3
4 27 330 1 0 /tmp/ Del Snarf Get | Look
.
,w /tmp/test.dump
Q
EOE
% window -dx 900 -dy 600 'acme -l /tmp/test.dump'
This issue was introduced in commit 47b7dc5ccd.
This avoids ipconfig having to explicitely specify the tag
when we want to set route type, as the tag can be provided
implicitely thru the "tag" command.
the bug happens when we did the fast exit thru "done" label,
where we would not make sure that theres space in the buffer
for the NUL terminator.
instead, avoid the fast exit and always do the final
adjbuf() that makes sure we have space for the NUL terminator.
remove the pointless pb checks, they'r wrong (should'v
been bp >= buf+bufsz) and adjbuf() already makes sure this
can never happen.
EDID 1.3 section 5 gives a table describing the priority order of
timing information. Use this ordering when constructing the EDID
mode list.
Since aux/vga selects the first mode in the modelist that matches
the given size, it will now select the mode of that size with the
highest preference. Or, if you set vgasize=auto (or some other
string without an 'x'), aux/vga will select the Preferred Detailed
Timing.
This should make it unnecessary to modify vgadb in many cases.
when reverting files, 'cp -x' updates the mtime
to the time the file was committed. this prevents
'mk' from rebuilding the file, leading to stale
builds.
this change touches the file on revert, so that
we rebuild the file.
The altsetting was handled only for a single endpoint
(per interface number), but has to be handled for each
endpoint (per interface *AND* altsetting number).
A multi function device (like a disk) can have
multiple interfaces, all with the same interface number
but varying altsetting numbers and each of these
interfaces would list distict endpoint configurations.
Multiple interfaces can even share some endpoints (they
use the same endpoint addresses), but
we still have to duplicate them for each
interface+altsetting number (as they'r part of
actually distict interfaces with distict endpoint
configurations).
It is also important to *NOT* make endpoints bi-directional
(dir == Eboth) when only one direction is used in a
interface/altsetting and the other direction in another.
This was the case for nusb/disk with some seagate drive
where endpoints where shared between the UAS and
usb storage class interface (but with distict altsettings).
The duplicate endpoints (as in using the same endpoint address)
are chained together by a next pointer and the head
is stored in Usbdev.ep[addr], where addr is the endpoint
address. These Ep structures will have distinct endpoint
numbers Ep.id (when they have conflicting types), but all
will share the endpoint address (lower 4 bits of the
endpoint number).
The consequence is that all of the endpoints configuration
(attributes, interval) is now stored in the Ep struct and
no more Altc struct is present.
A pointer to the Ep struct has to be passed to openep()
for it to configure the endpoint.
For the Iface struct, we will now create multiple of them:
one for each interface *AND* altsetting nunber,
chained together on a next pointer and the head being
stored in conf->iface[ifaceid].
--
cinap
Pattern matching with lists no longer works:
; ls /tmp/*.c
/tmp/npage.c
/tmp/pagedebug.c
/tmp/pageold.c
/tmp/scheduler.c
/tmp/writeimagetest.c
; ls /tmp/^(*.c)
ls: /tmp/*.c: '/tmp/*.c' directory entry not found
; 9fs dump
; bind /n/dump/2021/1002/amd64/bin/rc /bin/rc
; rc
; ls /tmp/^(*.c)
/tmp/npage.c
/tmp/pagedebug.c
/tmp/pageold.c
/tmp/scheduler.c
/tmp/writeimagetest.c
the fix:
we have to propagate the glob attribute thru lists
as well. before it was only handled for single words
and propagated thru concatenations...
the Xglob instruction now works on list, and we
propagate the glob attribute thru PAREN and WORDS
and ARGLIST nodes.
also, avoid using negative numbers for the Tree.glob
field as char might be unsigned on some targets.
Before applying this patch the following will fail to open ed
in the '/tmp/s p a c e' folder:
<snip>
% mkdir '/tmp/s p a c e'
% window -cd '/tmp/s p a c e' ed
!pwd
/tmp/s p a c e
!
q
<snap>
After applying the patch the above sequence works as expected,
opening ed in the '/tmp/s p a c e' folder, printing the present
working directory, and quitting ed.
The root cause was a faulty computation of the pointer `s`,
being off by one, leading to any arguments after the
directory path to be skipped.
This regression was introduced in revision:
• 614f1d6268
Thanks umbraticus for finding and reporting the issue.
The device address is highly variable and depends on
all prior enumerated devices.
This can happen with some devices that do not have
a serial number and all devices of the same type
having the same hname.
Using a counter of collisions per hname makes more sense
and is more stable (given that the order devices are
enumerated is deterministic).
This allows mapping incoming filenames to a different name
using regular expressions, followed by subtitutions
of the %[ICE] format strings.
I needed this to have individual cmdline.txt files for
netbooted raspberry pi's. In this example, i map cmdline.txt
to %C, which gets substituted for /cfg/pxe/$ether of the client.
The transitional PCI device ID for block devices is 0x1001, and the
virtio spec says that devices must have the transitional device ID or
0x1040 + the virtio device ID (2).
Mothra does not currently render text inside <samp> tags inline
similar to <code>, but instead treats them like <pre> which is actually
incorrect behavior. The following small patch should fixes issue.
This does not have any adverse effect, since yylex never calls mpatov
with a string with leading 0 (and not 0x) that contains non-octal
digits, but the condition was wrong regardless.
Strings for existing codes in the most used server (OpenSSH) just
repeat the error code name. OTOH we like to have wording of the
strings under our control as much as possible, so we can easier find
and process them. Error strings are still usefull as fallback for
compatibility with future versions of the server.
- fix showpage1 only decrementing proc counter once limit is reached;
this blocked having more than one loadpages process after NPROC calls,
since the next one has to wait until the last has exited
- allow procs to skip pages currently being loaded by others; this
forced processes to wait for each other at the same page
- bump NPROC from 4 to 8
- (hack) immediately fork a few times after adding all pages at
startup to force loading a batch of pages in parallel
programs that try to use /srv would choke when running
under iostats, because we intercepted operations on the
special, magic fd passing; we should instead give them
access to the real /srv.
when running outside of a repository, we would try to
remove '$msgfile.tmp', but we had never actually set
'$msgfile'.
the error is harmless, but annoying.
The following patch fixes acme display glitches at the bottom fringe
of columns when adding/moving/resizing windows.
Here an example of an easy to reproduce case:
• https://invidio.xamh.de/watch?v=iLekQrxycaM
…opening acme and resizing a column to the right is all that is needed.
The functions winresize(…) and textresize(…) are extended with an
additional parameter `fillfringe` to indicate if a window/tag shall
fill a potential fringe area that would otherwise remain white.
The changes have been inspired by the approach taken in plan9port
acme.
Eckard's test case:
cat <<! | cat
asdf
!
The issue is that we have to continue parsing until we see
the '\n' before consuming the here document.
So we revert to the old approach of having two functions:
heredoc() which remembers if we'v seen a heredoc redirection
and a second readhere() function that reads the doc from
the lexers input and sets Tree.str on thee REDIR node.
due to the way the size of buf was calculated, the parent
file had one trailing null byte for each parent. also, while
we're here, replace the sprint with seprint, and compute the
size from how much we printed in.
Fixup remaining Plan9 dependencies (chartorune()).
Add Makefile for UNIX-like systems (tested with Linux and APE).
Make error printing consistent, use Errstr() explicitely.
Get rid of NSTATUS buffer limit, just malloc it.
git used to track cache size in object
count, rather than bytes. This had the
unfortunate effect of making memory use
depend on the size of objects -- repos
with lots of large objects could cause
out of memory deaths.
now, we track sizes in bytes, which should
keep our memory usage flatter.
Untangle the lexer and interpreter thread state.
Fix the file and line number error reporting, getting rid of
Xsrcfile instruction, as the whole code block can only come
from a single file, stuff the source file in slot[1] of the
code block instead.
Remove limitations for globber (path element limits)
and be more intelligent about handling globbing by
inserting Xglob instruction only when needed and not
run it over every Xsimple argument list.
Remove fragile ndot magic and make it explicit by adding
the -q flag to . builtin command.
Add -b flag for full compilation.
Make exitnext() smart, so we can speculate thru rcmain and
avoid the fork().
Get rid of all print(2) format functions and use io
instead.
Improve the io library, adding rstr() to handle tokenization,
which allows us to look ahead in the already read buffer
for the terminators, avoiding alot of string copies.
Auto indent pcmd(), to make line number reporting more usefull.
Implement here documents properly, so they can work everywhere.
We seem to have a botch in the protocol negotiation, where
we leak some protocol packets into the packfile; this will
need to be fixed before we put this change in.
The initial working directory of a new window may be set by a
`-cd directory` option. However, the `-cd directory` option is
not capable of handling paths with spaces when used via wctl.
To enable paths with spaces the function
/sys/src/cmd/rio/wctl.c:/^parsewctl is extended to handle quoted
directory paths.
Before applying the patch the following will fail to open a new
window by writing to /dev/wctl:
<snip>
% rio -i window
% mkdir '/tmp/path with space'
% echo new -cd '''/tmp/path with space''' window -x rc >> /dev/wctl
% pwd
/tmp/path with space
<snap>
The following invocation fails as well:
<snip>
% window -cd '/tmp/path with space'
% pwd
/tmp/path with space
<snap>
After applying the patch the above sequences work as expected,
opening a window running rc with the working directory set to
'/tmp/path with space'.
SSL is implemented by devssl. It's extremely
obsolete by now, and is not used anywhere but
cpu, import, and oexportfs.
This change strips out the devssl bits, but
does not (yet) remove the code from libsec.
If we don’t explicitly check for ‘h’ in troff, we can’t reliably check
for non-htmlroff well.
Consider the following:
.if h \{\
. de M
. tm m
..\}
Without this change, this will print m and not define macro M.
the pack cache was very stupid: it would close packs
as early as possible, which would prevent packs from
getting reused effectively. It would also select a
bad pack to close.
This picks the oldest pack, refcounts correctly, and
keeps up to Npackcache open at once (though it will
go over if more are in use).
To reproduce run the following on a terminal:
<snip>
cpu% leak -s `{pstree | grep termrc | sed 1q | awk '{print $1}'}
src(0x00209a82); // 12
src(0x0020b2a6); // 1
cpu% acid `{pstree | grep termrc | sed 1q | awk '{print $1}'}
/proc/358/text:amd64 plan 9 executable
/sys/lib/acid/port
/sys/lib/acid/amd64
acid: src(0x0020b2a6)
/sys/src/cmd/rc/plan9.c:169
164 if(runq->argv->words == 0)
165 poplist();
166 else {
167 free(runq->cmdfile);
168 int f = open(runq->argv->words->word, 0);
>169 runq->cmdfile = strdup(runq->argv->words->word);
170 runq->lexline = 1;
171 runq->pc--;
172 popword();
173 if(f>=0) execcmds(openfd(f));
174 }
acid:
</snap>
Another `runq->cmdfile` leak is present here (captured on a cpu server):
<snip>
277 ├listen [tcp * /rc/bin/service <nil>]
321 │├listen [/net/tcp/2 tcp!*!80]
322 │├listen [/net/tcp/3 tcp!*!17019]
324 ││└rc [/net/tcp/5 tcp!185.64.155.70!3516]
334 ││ ├rc -li
382 ││ │└pstree
336 ││ └rc
338 ││ └cat
323 │└listen [/net/tcp/4 tcp!*!17020]
278 ├listen [tcp * /rc/bin/service.auth <nil>]
320 │└listen [/net/tcp/1 tcp!*!567]
381 └closeproc
cpu% leak -s 336
src(0x00209a82); // 2
src(0x002051d2); // 1
cpu% acid 336
/proc/336/text:amd64 plan 9 executable
/sys/lib/acid/port
/sys/lib/acid/amd64
acid: src(0x002051d2)
/sys/src/cmd/rc/exec.c:1056
1051
1052 void
1053 Xsrcfile(void)
1054 {
1055 free(runq->cmdfile);
>1056 runq->cmdfile = strdup(runq->code[runq->pc++].s);
1057 }
acid:
</snap>
These leaks happen because we do not free cmdfile on all execution paths
where `Xreturn()` is invoked. In `/sys/src/cmd/rc/exec.c:/^Xreturn`
<snip>
void
Xreturn(void)
{
struct thread *p = runq;
turfredir();
while(p->argv) poplist();
codefree(p->code);
runq = p->ret;
free(p);
if(runq==0)
Exit(getstatus());
}
</snip>
Note how the function `Xreturn()` frees a heap allocated instance of type
`thread` with its members *except* the `cmdfile` member.
On some code paths where `Xreturn()` is called there is an attempt to free
`cmdfile`, however, there are some code paths where `Xreturn()` is called
where `cmdfile` is not freed, leading to a leak.
The attached patch calls `free(p->cmdfile)` in `Xreturn()` to avoid leaking
memory and handling the free in one place.
After applying the patch this particular leak is removed. There are still
other leaks in rc:
<snip>
277 ├listen [tcp * /rc/bin/service <nil>]
321 │├listen [/net/tcp/2 tcp!*!80]
322 │├listen [/net/tcp/3 tcp!*!17019]
324 ││└rc [/net/tcp/5 tcp!185.64.155.70!3516]
334 ││ ├rc -li
382 ││ │└pstree
336 ││ └rc
338 ││ └cat
323 │└listen [/net/tcp/4 tcp!*!17020]
278 ├listen [tcp * /rc/bin/service.auth <nil>]
320 │└listen [/net/tcp/1 tcp!*!567]
381 └closeproc
cpu% leak -s 336
src(0x00209a82); // 2
src(0x002051d2); // 1
cpu% acid 336
/proc/336/text:amd64 plan 9 executable
/sys/lib/acid/port
/sys/lib/acid/amd64
acid: src(0x00209a82)
/sys/src/cmd/rc/subr.c:9
4 #include "fns.h"
5
6 void *
7 emalloc(long n)
8 {
>9 void *p = malloc(n);
10 if(p==0)
11 panic("Can't malloc %d bytes", n);
12 return p;
13 }
14
</snap>
To help fixing those leaks emalloc(…) and erealloc(…) have been amended to use
setmalloctag(…) and setrealloctag(…). The actual fixes for other reported leaks
are *not* part of this merge and will follow.