Commit Diff


commit - a796abef1632f379ced703b1b2e691d8f63436e2
commit + 1a8f27c35024af7b4ed857a388d20f0a4a560db0
blob - /dev/null
blob + 4cdc6b24a66d05979963666d18a2fb79b2df0ef8 (mode 644)
--- /dev/null
+++ man/man1/graph.1
@@ -0,0 +1,148 @@
+.TH GRAPH 1
+.CT 1 numbers graphics
+.SH NAME
+graph \- draw a graph
+.SH SYNOPSIS
+.B graph
+[
+.I option ...
+]
+.SH DESCRIPTION
+.I Graph
+with no options takes pairs of numbers from the
+standard input as abscissas
+.RI ( x -values)
+and ordinates
+.RI ( y -values)
+of a graph.
+Successive points are connected by straight lines.
+The graph is encoded on the standard output
+for display by
+.IR  plot (1)
+filters.
+.PP
+If an ordinate is followed by
+a nonnumeric string, that string is printed as a
+label beginning on the point.
+Labels may be surrounded with quotes
+.L
+" "
+in which case they may be empty or contain blanks
+and numbers;
+labels never contain newlines.
+.PP
+The following options are recognized,
+each as a separate argument.
+.TP
+.B  -a
+Supply abscissas automatically; no
+.IR x -values
+appear in the input.
+Spacing is given by the next
+argument (default 1).
+A second optional argument is the starting point for
+automatic abscissas (default 0, or 1
+with a log scale in
+.IR x ,
+or the lower limit given by
+.BR -x ).
+.TP
+.B  -b
+Break (disconnect) the graph after each label in the input.
+.TP
+.B  -c
+Character string given by next argument
+is default label for each point.
+.TP
+.B  -g
+Next argument is grid style,
+0 no grid, 1 frame with ticks, 2 full grid (default).
+.TP
+.B  -l
+Next argument is a legend to title the graph.
+Grid ranges
+are automatically printed as part
+of the title unless a
+.B -s
+option is present.
+.TP
+.B  -m
+Next argument is mode (style)
+of connecting lines:
+0 disconnected, 1 connected.
+Some devices give distinguishable line styles
+for other small integers.
+Mode \-1 (default) begins with style 1 and
+rotates styles for successive curves under option
+.BR -o .
+.TP
+.B -o
+(Overlay.)
+The ordinates for
+.I n
+superposed curves appear in the input
+with each abscissa value.
+The next argument is
+.IR n .
+.TP
+.B  -s
+Save screen; no new page for this graph.
+.TP
+.B -x l
+If
+.B l
+is present,
+.IR x -axis
+is logarithmic.
+Next 1 (or 2) arguments are lower (and upper)
+.I x
+limits.
+Third argument, if present, is grid spacing on
+.I x
+axis.
+Normally these quantities are determined automatically.
+.TP
+.B -y l
+Similarly for
+.IR y .
+.TP
+.B -e
+Make automatically determined
+.I x
+and
+.I y
+scales equal.
+.TP
+.B  -h
+Next argument is fraction of space for height.
+.TP
+.B  -w
+Similarly for width.
+.TP
+.B  -r
+Next argument is fraction of space to move right before plotting.
+.TP
+.B  -u
+Similarly to move up before plotting.
+.TP
+.B  -t
+Transpose horizontal and vertical axes.
+(Option
+.B -a
+now applies to the vertical axis.)
+.PP
+If a specified lower limit exceeds the upper limit,
+the axis
+is reversed.
+.SH SOURCE
+.B /sys/src/cmd/graph
+.SH "SEE ALSO"
+.IR plot (1), 
+.IR grap (1)
+.SH BUGS
+Segments that run out of bounds are dropped, not windowed.
+Logarithmic axes may not be reversed.
+Option
+.B -e
+actually makes automatic limits, rather than automatic scaling,
+equal.
blob - /dev/null
blob + cd1a1b8160601cce614f10c2ef0bcb9eaa5e97d7 (mode 644)
--- /dev/null
+++ man/man1/plot.1
@@ -0,0 +1,61 @@
+.TH PLOT 1
+.SH NAME
+plot \- graphics filter
+.SH SYNOPSIS
+.B plot
+[
+.I file ...
+]
+.SH DESCRIPTION
+.I Plot
+interprets plotting instructions (see
+.IR  plot (6))
+from the
+.I files
+or standard input,
+drawing the results in a newly created
+.IR rio (1)
+window.
+Plot persists until a newline is typed in the window.
+Various options may be interspersed with the
+.I file
+arguments; they take effect at the given point in processing.
+Options are:
+.TP "\w'\fL-g \fIgrade\fLXX'u"
+.B -d
+Double buffer: accumulate the plot off-screen and write to the screen all at once
+when an erase command is encountered or at end of file.
+.TP
+.B -e
+Erase the screen.
+.TP
+.BI -c " col"
+Set the foreground color (see
+.IR plot (6)
+for color names).
+.TP
+.BI -f " fill"
+Set the background color.
+.TP
+.BI -g " grade"
+Set the quality factor for arcs.
+Higher grades give better quality.
+.TP
+.BI -p " col"
+Set the pen color.
+.TP
+.BI -w
+Pause until a newline is typed on standard input.
+.TP
+.B -C
+Close the current plot.
+.TP
+.B -W " x0,y0,x1,y1"
+Specify the bounding rectangle of plot's window.
+By default it uses a 512×512 window in the
+middle of the screen.
+.SH SOURCE
+.B /sys/src/cmd/plot
+.SH "SEE ALSO"
+.IR rio (1),
+.IR plot (6)
blob - /dev/null
blob + d08aca3bb29e2130291ff48c7dd84c923f7acc85 (mode 644)
--- /dev/null
+++ man/man5/venti.conf.5
@@ -0,0 +1,87 @@
+.TH VENTI.CONF 6
+.SH NAME
+venti.conf  \- a venti configuration file
+.SH DESCRIPTION
+A venti configuration file enumerates the various index sections and
+arenas that constitute a venti system.
+The components are indicated by the name of the file, typically
+a disk partition, in which they reside.  The configuration
+file is the only location that file names are used.  Internally,
+venti uses the names assigned when the components were formatted
+with 
+.I fmtarenas
+or 
+.I fmtisect
+(see
+.IR ventiaux (8)).
+In particular, by changing the configuration a
+component can be copied to a different file.
+.PP
+The configuration file consists of lines in the form described below.
+Lines starting with
+.B #
+are comments.
+.TP
+.BI index " name
+Names the index for the system.
+.TP
+.BI arenas " file
+.I File
+contains a collection of arenas, formatted using
+.IR fmtarenas .
+.TP
+.BI isect " file
+.I File
+contains an index section, formatted using
+.IR fmtisect .
+.PP
+After formatting a venti system using
+.IR fmtindex ,
+the order of arenas and index sections should not be changed.
+Additional arenas can be appended to the configuration.
+.PP
+The configuration file optionally holds configuration parameters
+for the venti server itself.
+These are:
+.TP
+.BI mem " cachesize
+.TP
+.BI bcmem " blockcachesize
+.TP
+.BI icmem " indexcachesize
+.TP
+.BI addr " ventiaddress
+.TP
+.BI httpaddr " httpaddress
+.TP
+.B queuewrites
+.PD
+See 
+.IR venti (8)
+for descriptions of these variables.
+.SH EXAMPLE
+.EX
+# a sample venti configuration file
+#
+# formatted with
+#	venti/fmtarenas arena. /tmp/disks/arenas
+# 	venti/fmtisect isect0 /tmp/disks/isect0
+# 	venti/fmtisect isect1 /tmp/disks/isect1
+#	venti/fmtindex venti.conf
+#
+# server is started with
+#	venti/venti
+
+# the name of the index
+index main
+
+# the index sections
+isect /tmp/disks/isect0
+isect /tmp/disks/isect1
+
+# the arenas
+arenas /tmp/disks/arenas
+.EE
+.SH "SEE ALSO"
+.IR venti (8),
+.IR ventiaux (8)
blob - /dev/null
blob + be112a6af8d98fa97a344b21fb207976ea59e259 (mode 644)
--- /dev/null
+++ man/man8/venti.8
@@ -0,0 +1,232 @@
+.TH VENTI 8
+.SH NAME
+venti \- an archival block storage server
+.SH SYNOPSIS
+.B venti/venti
+[
+.B -dsw
+]
+[
+.B -a
+.I ventiaddress
+]
+[
+.B -B
+.I blockcachesize
+]
+[
+.B -c
+.I config
+]
+[
+.B -C
+.I cachesize
+]
+[
+.B -h
+.I httpaddress
+]
+[
+.B -I
+.I icachesize
+]
+.PP
+.B venti/sync
+[
+.B -h
+.I host
+]
+.SH DESCRIPTION
+.I Venti
+is a block storage server intended for archival data.
+In a Venti server,
+the SHA1 hash of a block's contents acts as the block
+identifier for read and write operations.
+This approach enforces a write-once policy, preventing accidental or
+malicious destruction of data.  In addition, duplicate copies of a
+block are coalesced, reducing the consumption of storage and
+simplifying the implementation of clients.
+.PP
+Storage for
+.I venti
+consists of a data log and an index, both of which
+can be spread across multiple files.
+The files containing the data log are themselves divided into self-contained sections called arenas.
+Each arena contains a large number of data blocks and is sized to
+facilitate operations such as copying to removable media.
+The index provides a mapping between the a Sha1 fingerprint and
+the location of the corresponding block in the data log.
+.PP
+The index and data log are typically stored on raw disk partitions.
+To improve the robustness, the data log should be stored on
+a device that provides RAID functionality.  The index does
+not require such protection, since if necessary, it can
+can be regenerated from the data log.
+The performance of
+.I venti
+is typically limited to the random access performance
+of the index.  This performance can be improved by spreading the
+index accross multiple disks.  
+.PP
+The storage for
+.I venti
+is initialized using
+.IR fmtarenas ,
+.IR fmtisect ,
+and
+.I fmtindex
+(see
+.IR ventiaux (8)).
+A configuration file,
+.IR venti.conf (6),
+ties the index sections and data arenas together.
+.PP
+A Venti
+server is accessed via an undocumented network protocol.
+Two client applications are included in this distribution:
+.IR vac (1)
+and
+.IR vacfs (4).
+.I Vac
+copies files from a Plan 9 file system to Venti, creating an
+archive and returning the fingerprint of the root.
+This archive can be mounted in Plan 9 using 
+.IR vacfs .
+These two commands enable a rudimentary backup system.
+A future release will include a Plan 9 file system that uses
+Venti as a replacement for the WORM device of 
+.IR fs (4).
+.PP
+The
+.I venti
+server provides rudimentary status information via
+a built-in http server.  The URL files it serves are:
+.TP
+.B stats
+Various internal statistics.
+.TP
+.B index
+An enumeration of the index sections and all non empty arenas, including various statistics.
+.TP
+.B storage
+A summary of the state of the data log.
+.TP
+.B xindex
+An enumeration of the index sections and all non empty arenas, in XML format.
+.PP
+Several auxiliary utilities (see
+.IR ventiaux (8))
+aid in maintaining the storage for Venti.
+With the exception of
+.I rdarena ,
+these utilities should generally be run after killing the
+.I venti
+server.
+The utilities are:
+.TP
+.I checkarenas
+Check the integrity, and optionally fix, Venti arenas.
+.TP
+.I checkindex
+Check the integrity, and optionally fix, a Venti index.
+.TP
+.I buildindex
+Rebuild a Venti index from scratch.
+.TP
+.I rdarena
+Extract a Venti arena and write to standard output.
+.PD
+.PP
+Options to 
+.I venti
+are:
+.TP
+.BI -a " ventiaddress
+The network address on which the server listens for incoming connections.
+The default is
+.LR tcp!*!venti .
+.TP
+.BI -B " blockcachesize
+The size, in bytes, of memory allocated to caching raw disk blocks.
+.TP
+.BI -c " config
+Specifies the
+Venti
+configuration file.
+Defaults to
+.LR venti.conf .
+.TP
+.BI -C " cachesize
+The size, in bytes, of memory allocated to caching 
+Venti
+blocks.
+.TP
+.BI -d
+Produce various debugging information on standard error.
+.TP
+.BI -h " httpaddress
+The network address of Venti's built-in
+http
+server.
+The default is
+.LR tcp!*!http .
+.TP
+.BI -I " icachesize
+The size, in bytes, of memory allocated to caching the index mapping fingerprints
+to locations in 
+.IR venti 's
+data log.
+.TP
+.B -s
+Do not run in the background.
+Normally,
+the foreground process will exit once the Venti server
+is initialized and ready for connections.
+.TP
+.B -w
+Enable write buffering.  This option increase the performance of writes to
+.I venti
+at the cost of returning success to the client application before the
+data has been written to disk.
+The server implements a
+.I sync
+rpc that waits for completion of all the writes buffered at the time
+the rpc was received.
+Applications such as
+.IR vac (1)
+and the
+.I sync
+command described below
+use this rpc to make sure that the data is correctly written to disk.
+Use of this option is recommended.
+.PD
+.PP
+The units for the various cache sizes above can be specified by appending a
+.LR k ,
+.LR m ,
+or
+.LR g
+to indicate kilobytes, megabytes, or gigabytes respectively.
+The command line options override options found in the
+.IR venti.conf (6)
+file.
+.PP
+.I Sync
+connects to a running Venti server and executes a sync rpc
+(described with the
+.B -w
+option above). 
+If sync exits successfully, it means that all writes buffered at the
+time the command was issued are now on disk.
+.SH SOURCE
+.B /sys/src/cmd/venti
+.SH "SEE ALSO"
+.IR venti.conf (6),
+.IR ventiaux (8),
+.IR vac (1),
+.IR vacfs (4).
+.br
+Sean Quinlan and Sean Dorward,
+``Venti: a new approach to archival storage'',
+.I "Usenix Conference on File and Storage Technologies" ,
+2002.
blob - /dev/null
blob + fb6d852271223dfde1b6923f26db4f68da2c6d4c (mode 644)
--- /dev/null
+++ man/man8/ventiaux.8
@@ -0,0 +1,504 @@
+.TH VENTIAUX 8
+.SH NAME
+buildindex,
+checkarenas,
+checkindex,
+conf,
+copy,
+fmtarenas,
+fmtindex,
+fmtisect,
+rdarena,
+rdarenablocks,
+read,
+wrarenablocks,
+write \- Venti maintenance and debugging commands
+.SH SYNOPSIS
+.B venti/buildindex
+[
+.B -B
+.I blockcachesize
+]
+[
+.B -Z
+]
+.I venti.config
+.I tmp
+.PP
+.B venti/checkarenas
+[
+.B -afv 
+]
+.I file
+.PP
+.B venti/checkindex
+[
+.B -f
+]
+[
+.B -B
+.I blockcachesize
+]
+.I venti.config
+.I tmp
+.PP
+.B venti/conf
+[
+.B -w
+]
+.I partition
+[
+.I configfile
+]
+.PP
+.B venti/copy
+[
+.B -f
+]
+.I src
+.I dst
+.I score
+[
+.I type
+]
+.PP
+.B venti/fmtarenas
+[
+.B -Z
+]
+[
+.B -a
+.I arenasize
+]
+[
+.B -b
+.I blocksize
+]
+.I name
+.I file
+.PP
+.B venti/fmtindex
+[
+.B -a
+]
+.I venti.config
+.PP
+.B venti/fmtisect
+[
+.B -Z
+]
+[
+.B -b
+.I blocksize
+]
+.I name
+.I file
+.PP
+.B venti/rdarena
+[
+.B -v
+]
+.I arenapart
+.I arenaname
+.PP
+.B venti/read
+[
+.B -h
+.I host
+]
+.I score
+[
+.I type
+]
+.PP
+.B venti/wrarena
+[
+.B -o
+.I fileoffset
+]
+[
+.B -h
+.I host
+]
+.I arenafile
+[
+.I clumpoffset
+]
+.PP
+.B venti/write
+[
+.B -h
+.I host
+]
+[
+.B -t
+.I type
+]
+[
+.B -z
+]
+.SH DESCRIPTION
+These commands aid in the setup, maintenance, and debugging of
+Venti servers.
+See
+.IR venti (8)
+and
+.IR venti.conf (6)
+for an overview of the data structures stored by Venti.
+.PP
+Note that the units for the various sizes in the following
+commands can be specified by appending
+.LR k ,
+.LR m ,
+or
+.LR g
+to indicate kilobytes, megabytes, or gigabytes respectively.
+.PP
+.I Buildindex
+populates the index for the Venti system described in
+.IR venti.config .
+The index must have previously been formatted using
+.IR fmtindex .
+This command is typically used to build a new index for a Venti
+system when the old index becomes too small, or to rebuild
+an index after media failure.
+Small errors in an index can usually be fixed with
+.IR checkindex .
+.PP
+The
+.I tmp
+file, usually a disk partition, must be large enough to store a copy of the index.
+This temporary space is used to perform a merge sort of index entries
+generated by reading the arenas.
+.PP
+Options to 
+.I buildindex
+are:
+.TP
+.BI -B " blockcachesize
+The amount of memory, in bytes, to use for caching raw disk accesses while running
+.IR buildindex .
+(This is not a property of the created index.)
+The default is 8k.
+.TP
+.B -Z
+Do not zero the index.
+This option should only be used when it is known that the index was already zeroed.
+.PD
+.PP
+.I Checkarenas
+examines the Venti arenas contained in the given
+.IR file .
+The program detects various error conditions, and optionally attempts
+to fix any errors that are found.
+.PP
+Options to 
+.I checkarenas
+are:
+.TP
+.B -a
+For each arena, scan the entire data section.
+If this option is omitted, only the end section of
+the arena is examined.
+.TP
+.B -f
+Attempt to fix any errors that are found.
+.TP
+.B -v
+Increase the verbosity of output.
+.PD
+.PP
+.I Checkindex
+examines the Venti index described in
+.IR venti.config .
+The program detects various error conditions including:
+blocks that are not indexed, index entries for blocks that do not exist,
+and duplicate index entries.
+If requested, an attempt can be made to fix errors that are found.
+.PP
+The
+.I tmp
+file, usually a disk partition, must be large enough to store a copy of the index.
+This temporary space is used to perform a merge sort of index entries
+generated by reading the arenas.
+.PP
+Options to 
+.I checkindex
+are:
+.TP
+.BI -B " blockcachesize
+The amount of memory, in bytes, to use for caching raw disk accesses while running
+.IR checkindex .
+The default is 8k.
+.TP
+.B -f
+Attempt to fix any errors that are found.
+.PD
+.PP
+.I Fmtarenas
+formats the given
+.IR file ,
+typically a disk partition, into a number of
+Venti
+arenas.
+The arenas are given names of the form
+.IR name%d ,
+where
+.I %d
+is replaced with a sequential number starting at 0.
+.PP
+Options to 
+.I fmtarenas
+are:
+.TP
+.BI -a " arenasize
+The arenas are of
+.I arenasize
+bytes.  The default is 512 megabytes, which was selected to provide a balance
+between the number of arenas and the ability to copy an arena to external
+media such as recordable CDs and tapes.
+.TP
+.BI -b " blocksize
+The size, in bytes, for read and write operations to the file.
+The size is recorded in the file, and is used by applications that access the arenas.
+The default is 8k.
+.TP
+.B -Z
+Do not zero the data sections of the arenas.
+Using this option reduces the formatting time
+but should only be used when it is known that the file was already zeroed.
+.PD
+.I Fmtindex
+takes the
+.IR venti.conf (6)
+file
+.I venti.config
+and initializes the index sections to form a usable index structure.
+The arena files and index sections must have previously been formatted
+using 
+.I fmtarenas
+and 
+.I fmtisect
+respectively.
+.PP
+The function of a Venti index is to map a SHA1 fingerprint to a location
+in the data section of one of the arenas.  The index is composed of
+blocks, each of which contains the mapping for a fixed range of possible
+fingerprint values.
+.I Fmtindex
+determines the mapping between SHA1 values and the blocks
+of the collection of index sections.  Once this mapping has been determined,
+it cannot be changed without rebuilding the index. 
+The basic assumption in the current implementation is that the index
+structure is sufficiently empty that individual blocks of the index will rarely
+overflow.  The total size of the index should be about 2% to 10% of
+the total size of the arenas, but the exact depends both the index block size
+and the compressed size of block stored to Venti.
+.PP
+.I Fmtindex
+also computes a mapping between a linear address space and
+the data section of the collection of arenas.  The
+.B -a
+option can be used to add additional arenas to an index.
+To use this feature,
+add the new arenas to
+.I venti.config
+after the existing arenas and then run
+.I fmtindex
+.BR -a .
+.PP
+A copy of the above mappings is stored in the header for each of the index sections.
+These copies enable
+.I buildindex
+to restore a single index section without rebuilding the entire index.
+.PP
+.I Fmtisect
+formats the given
+.IR file ,
+typically a disk partition, as a Venti index section with the specified
+.IR name .
+One or more formatted index sections are combined into a Venti
+index using 
+.IR fmtindex .
+Each of the index sections within an index must have a unique name.
+.PP
+Options to 
+.I fmtisect
+are:
+.TP
+.BI -b " blocksize
+The size, in bytes, for read and write operations to the file.
+All the index sections within a index must have the same block size.
+The default is 8k.
+.TP
+.B -Z
+Do not zero the index.
+Using this option reduces the formatting time
+but should only be used when it is known that the file was already zeroed.
+.PD
+.PP
+.I Rdarena
+extracts the named
+.I arena
+from the arena partition
+.I arenapart
+and writes this arena to standard output.
+This command is typically used to back up an arena to external media.
+The
+.B -v
+option generates more verbose output on standard error.
+.PP
+.I Wrarena
+writes the blocks contained in the arena
+.I arenafile
+(typically, the output of
+.IR rdarena )
+to a Venti server.
+It is typically used to reinitialize a Venti server from backups of the arenas.
+For example,
+.IP
+.EX
+venti/rdarena /dev/sdC0/arenas arena.0 >external.media
+venti/wrarena -h venti2 external.media
+.EE
+.LP
+writes the blocks contained in
+.B arena.0
+to the Venti server
+.B venti2
+(typically not the one using
+.BR /dev/sdC0/arenas ).
+.PP
+The
+.B -o
+option specifies that the arena starts at byte
+.I fileoffset
+(default
+.BR 0 )
+in
+.I arenafile .
+This is useful for reading directly from
+the Venti arena partition:
+.IP
+.EX
+venti/wrarena -h venti2 -o 335872 /dev/sdC0/arenas
+.EE
+.LP
+(In this example, 335872 is the offset shown in the Venti
+server's index list (344064) minus one block (8192).
+You will need to substitute your own arena offsets
+and block size.)
+.PP
+Finally, the optional
+.I offset
+argument specifies that the writing should begin with the
+clump starting at
+.I offset
+within the arena.
+.I Wrarena
+prints the offset it stopped at (because there were no more data blocks).
+This could be used to incrementally back up a Venti server
+to another Venti server:
+.IP
+.EX
+last=`{cat last}
+venti/wrarena -h venti2 -o 335872 /dev/sdC0/arenas $last >output
+awk '/^end offset/ { print $3 }' offset >last
+.EE
+.LP
+Of course, one would need to add wrapper code to keep track
+of which arenas have been processed.
+See
+.B /sys/src/cmd/venti/backup.example
+for a version that does this.
+.PP
+.I Read
+and
+.I write
+read and write blocks from a running Venti server.
+They are intended to ease debugging of the server.
+The default
+.I host
+is the environment variable
+.BR $venti ,
+followed by the network metaname
+.BR $venti .
+The
+.I type
+is the decimal type of block to be read or written.
+If no 
+.I type
+is specified for
+.I read ,
+all types are tried, and a command-line is printed to
+show the type that eventually worked.
+If no
+.I type
+is specified for
+.I write ,
+.B VtDataType
+(13)
+is used.
+.I Read
+reads the block named by
+.I score
+(a SHA1 hash)
+from the Venti server and writes it to standard output.
+.I Write
+reads a block from standard input and attempts to write
+it to the Venti server.
+If successful, it prints the score of the block on the server.
+.PP
+.I Copy
+walks the entire tree of blocks rooted at
+.I score ,
+copying all the blocks visited during the walk from
+the Venti server at network address
+.I src
+to the Venti server at network address
+.I dst .
+If
+.I type
+(a decimal block type for
+.IR score )
+is omitted, all types will be tried in sequence
+until one is found that works.
+The
+.B -f
+flag runs the copy in ``fast'' mode: if a block is already on
+.IR dst ,
+the walk does not descend below it, on the assumption that all its
+children are also already on
+.IR dst .
+Without this flag, the copy often transfers many times more
+data than necessary.
+.PP
+To make it easier to bootstrap servers, the configuration
+file can be stored at the beginning of any Venti partitions using
+.IR conf .
+A partition so branded with a configuration file can
+be used in place of a configuration file when invoking any
+of the venti commands.
+By default,
+.I conf
+prints the configuration stored in
+.IR partition .
+When invoked with the
+.B -w
+flag,
+.I conf
+reads a configuration file from 
+.I configfile
+(or else standard input)
+and stores it in
+.IR partition .
+.SH SOURCE
+.B /sys/src/cmd/venti
+.SH "SEE ALSO"
+.IR venti (8),
+.IR venti.conf (6)
+.SH BUGS
+.I Buildindex
+should allow an individual index section to be rebuilt.
+The merge sort could be performed in the space used to store the
+index rather than requiring a temporary file.
blob - /dev/null
blob + 39bb8099db08fd35244944dfacf7b8f1b178d912 (mode 644)
--- /dev/null
+++ sky/.cvsignore
@@ -0,0 +1,2 @@
+*.scat
+constelnames
blob - 7dc1e88b64f0fff5d5d26af9fc8f6ce6209534bc
blob + 3bc1037105945ce46816a5889c2c206d9317daa9
--- src/cmd/acme/exec.c
+++ src/cmd/acme/exec.c
@@ -1308,7 +1308,7 @@ runproc(void *argvp)
 	name[e-t] = 0;
 	e = utfrrune(name, '/');
 	if(e)
-		strcpy(name, e+1);
+		memmove(name, e+1, strlen(e+1)+1);	/* strcpy but overlaps */
 	strcat(name, " ");	/* add blank here for ease in waittask */
 	c->name = bytetorune(name, &c->nname);
 	free(name);
blob - 11014c2cdbacd5d5b7e9069a2597448b946db42f
blob + 9fa5424821df3c0938d6a5411d42382f0f6f2fde
--- src/cmd/acme/rows.c
+++ src/cmd/acme/rows.c
@@ -663,12 +663,12 @@ rowload(Row *row, char *file, int initing)
 				break;
 		wincleartag(w);
 		textinsert(&w->tag, w->tag.file->b.nc, r+n+1, nr-(n+1), TRUE);
-		free(r);
 		if(ndumped >= 0){
 			/* simplest thing is to put it in a file and load that */
 			sprint(buf, "/tmp/d%d.%.4sacme", getpid(), getuser());
 			fd = create(buf, OWRITE|ORCLOSE, 0600);
 			if(fd < 0){
+				free(r);
 				warning(nil, "can't create temp file: %r\n");
 				goto Rescue2;
 			}
@@ -679,6 +679,7 @@ rowload(Row *row, char *file, int initing)
 				if(rune == '\n')
 					line++;
 				if(rune == (Rune)Beof){
+					free(r);
 					Bterm(bout);
 					free(bout);
 					close(fd);
@@ -696,6 +697,7 @@ rowload(Row *row, char *file, int initing)
 			winsettag(w);
 		}else if(dumpid==0 && r[ns+1]!='+' && r[ns+1]!='-')
 			get(&w->body, nil, nil, FALSE, XXX, nil, 0);
+		free(r);
 		if(fontr){
 			fontx(&w->body, nil, nil, 0, 0, fontr, nfontr);
 			free(fontr);
blob - aa58be1a59e56db3bdfc2e99a97be7386c4a7a38
blob + 37613d805e57f868ae55c2b987949ed1282c6d4e
--- src/cmd/acme/text.c
+++ src/cmd/acme/text.c
@@ -963,8 +963,11 @@ textshow(Text *t, uint q0, uint q1, int doselect)
 	int nl;
 	uint q;
 
-	if(t->what != Body)
+	if(t->what != Body){
+		if(doselect)
+			textsetselect(t, q0, q1);
 		return;
+	}
 	if(t->w!=nil && t->fr.maxlines==0)
 		colgrow(t->col, t->w, 1);
 	if(doselect)
blob - /dev/null
blob + 7d5e21ebf337de43ead276bd3138130ba06469aa (mode 644)
--- /dev/null
+++ src/lib9/rendez-futex.c
@@ -0,0 +1,167 @@
+/*
+     NAME
+          rendezvous - user level process synchronization
+
+     SYNOPSIS
+          ulong rendezvous(ulong tag, ulong value)
+
+     DESCRIPTION
+          The rendezvous system call allows two processes to synchro-
+          nize and exchange a value.  In conjunction with the shared
+          memory system calls (see segattach(2) and fork(2)), it
+          enables parallel programs to control their scheduling.
+
+          Two processes wishing to synchronize call rendezvous with a
+          common tag, typically an address in memory they share.  One
+          process will arrive at the rendezvous first; it suspends
+          execution until a second arrives.  When a second process
+          meets the rendezvous the value arguments are exchanged
+          between the processes and returned as the result of the
+          respective rendezvous system calls.  Both processes are
+          awakened when the rendezvous succeeds.
+
+          The set of tag values which two processes may use to
+          rendezvous-their tag space-is inherited when a process
+          forks, unless RFREND is set in the argument to rfork; see
+          fork(2).
+
+          If a rendezvous is interrupted the return value is ~0, so
+          that value should not be used in normal communication.
+
+ * This simulates rendezvous with shared memory, pause, and SIGUSR1.
+ */
+
+#include <u.h>
+typedef u32int u32;
+#include <errno.h>
+#include <sys/time.h>
+#define __user
+#include <linux/linkage.h>
+#include <linux/futex.h>
+#include <libc.h>
+
+enum
+{
+	VOUSHASH = 257,
+};
+
+typedef struct Vous Vous;
+struct Vous
+{
+	Vous *link;
+	Lock lk;
+	int pid;
+	ulong val;
+	ulong tag;
+};
+
+static Vous vouspool[2048];
+static int nvousused;
+static Vous *vousfree;
+static Vous *voushash[VOUSHASH];
+static Lock vouslock;
+
+static Vous*
+getvous(void)
+{
+	Vous *v;
+
+	if(vousfree){
+		v = vousfree;
+		vousfree = v->link;
+	}else if(nvousused < nelem(vouspool))
+		v = &vouspool[nvousused++];
+	else
+		abort();
+	return v;
+}
+
+static void
+putvous(Vous *v)
+{
+	lock(&vouslock);
+	v->link = vousfree;
+	vousfree = v;
+	unlock(&vouslock);
+}
+
+static Vous*
+findvous(ulong tag, ulong val, int pid)
+{
+	int h;
+	Vous *v, **l;
+
+	lock(&vouslock);
+	h = tag%VOUSHASH;
+	for(l=&voushash[h], v=*l; v; l=&(*l)->link, v=*l){
+		if(v->tag == tag){
+			*l = v->link;
+			unlock(&vouslock);
+			return v;
+		}
+	}
+	v = getvous();
+	v->pid = pid;
+	v->link = voushash[h];
+	v->val = val;
+	v->tag = tag;
+	lock(&v->lk);
+	voushash[h] = v;
+	unlock(&vouslock);
+	return v;
+}
+
+#define DBG 0
+ulong
+rendezvous(ulong tag, ulong val)
+{
+	int me, vpid;
+	ulong rval;
+	Vous *v;
+
+	me = getpid();
+	v = findvous(tag, val, me);
+	if(v->pid == me){
+		if(DBG)fprint(2, "pid is %d tag %lux, sleeping\n", me, tag);
+		/*
+		 * No rendezvous partner was found; the next guy
+		 * through will find v and wake us, so we must go
+		 * to sleep.
+		 *
+		 * To go to sleep:
+		 *	1. disable USR1 signals.
+		 *	2. unlock v->lk (tells waker okay to signal us).
+		 *	3. atomically suspend and enable USR1 signals.
+		 *
+		 * The call to ignusr1() could be done once at 
+		 * process creation instead of every time through rendezvous.
+		 */
+		v->val = val;
+		unlock(&v->lk);
+		while(sys_futex((u32int*)&v->tag, FUTEX_WAIT, tag, nil, nil) < 0 && errno==EINTR)
+			;
+		rval = v->val;
+		if(DBG)fprint(2, "pid is %d, awake\n", me);
+		putvous(v);
+	}else{
+		/*
+		 * Found someone to meet.  Wake him:
+		 *
+		 *	A. lock v->lk (waits for him to get to his step 2)
+		 *	B. send a USR1
+		 *
+		 * He won't get the USR1 until he suspends, which
+		 * means it must wake him up (it can't get delivered
+		 * before he sleeps).
+		 */
+		vpid = v->pid;
+		lock(&v->lk);
+		rval = v->val;
+		v->val = val;
+		v->tag++;
+		unlock(&v->lk);
+		sys_futex((u32int*)&v->tag, FUTEX_WAKE, 1, nil, nil);
+	}
+	return rval;
+}
+
blob - 801c39309b0c8436f1ca8d9605e0f525a07eb1c3
blob + b4204f4e1e2c9ba81dc2966187689f22742a6ed2
--- src/libdraw/md-alloc.c
+++ src/libdraw/md-alloc.c
@@ -86,7 +86,13 @@ _allocmemimage(Rectangle r, u32int chan)
 		return nil;
 
 	md->ref = 1;
-	md->base = poolalloc(imagmem, (2+nw)*sizeof(u32int));
+	/*
+	 * The first two words are the md and the callerpc.
+	 * Then nw words of data.
+	 * The final word lets the drawing routines be a little
+	 * sloppy about reading past the end of the block.
+	 */
+	md->base = poolalloc(imagmem, (2+nw+1)*sizeof(u32int));
 	if(md->base == nil){
 		free(md);
 		return nil;
blob - 3151525080c0ef7feaeec1cbfd41428e48a318bb
blob + a42af96bb807cf21df910ef1e0ed550e9fe27970
--- src/libfs/fs.c
+++ src/libfs/fs.c
@@ -86,19 +86,27 @@ fsunmount(Fsys *fs)
 void
 _fsdecref(Fsys *fs)
 {
-	Fid *f, *next;
+	Fid *f, **l, *next;
 
 	qlock(&fs->lk);
 	--fs->ref;
 	//fprint(2, "fsdecref %p to %d\n", fs, fs->ref);
 	if(fs->ref == 0){
 		close(fs->fd);
+		/* trim the list down to just the first in each chunk */
+		for(l=&fs->freefid; *l; ){
+			if((*l)->fid%Fidchunk == 0)
+				l = &(*l)->next;
+			else
+				*l = (*l)->next;
+		}
+		/* now free the list */
 		for(f=fs->freefid; f; f=next){
 			next = f->next;
-			if(f->fid%Fidchunk == 0)
-				free(f);
+			free(f);
 		}
 		free(fs);
+		return;
 	}
 	qunlock(&fs->lk);
 }
blob - 28c9d1cfd9bef4c0d5f4d3b779f4a15f8cbf8654
blob + 763080ba18dba35f01b933358dd21d7f7e7c825e
--- src/libfs/ns.c
+++ src/libfs/ns.c
@@ -23,8 +23,11 @@ nsmount(char *name, char *aname)
 	fd = dial(addr, 0, 0, 0);
 	if(fd < 0){
 		werrstr("dial %s: %r", addr);
+		free(addr);
 		return nil;
 	}
+	free(addr);
+
 	fcntl(fd, F_SETFL, FD_CLOEXEC);
 
 	fs = fsmount(fd, aname);
blob - e583da60dc84a41c793be690bc67387c01ff9592
blob + b544f16de2ea2dfe7216a23cb2537d31ed2f5fdd
--- src/libthread/fdwait.c
+++ src/libthread/fdwait.c
@@ -174,8 +174,8 @@ _threadfdwait(int fd, int rw, ulong pc)
 
 	struct {
 		Channel c;
-		Alt *qentry[2];
 		ulong x;
+		Alt *qentry[2];
 	} s;
 
 	threadfdwaitsetup();
@@ -214,11 +214,15 @@ threadsleep(int ms)
 	struct {
 		Channel c;
 		ulong x;
+		Alt *qentry[2];
 	} s;
 
 	threadfdwaitsetup();
 	chaninit(&s.c, sizeof(ulong), 1);
-
+	s.c.qentry = (volatile Alt**)s.qentry;
+	s.c.nentry = 2;
+	memset(s.qentry, 0, sizeof s.qentry);
+	
 	sleepchan[nsleep] = &s.c;
 	sleeptime[nsleep++] = p9nsec()/1000000+ms;
 	recvul(&s.c);