aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-05-14 15:14:21 +0000
committerrsc <devnull@localhost>2004-05-14 15:14:21 +0000
commit1a8f27c35024af7b4ed857a388d20f0a4a560db0 (patch)
treeb70f33150772d665fd2c254655b2782289b0c9da
parenta796abef1632f379ced703b1b2e691d8f63436e2 (diff)
downloadplan9port-1a8f27c35024af7b4ed857a388d20f0a4a560db0.tar.gz
plan9port-1a8f27c35024af7b4ed857a388d20f0a4a560db0.tar.bz2
plan9port-1a8f27c35024af7b4ed857a388d20f0a4a560db0.zip
various bug fixes
-rw-r--r--man/man1/graph.1148
-rw-r--r--man/man1/plot.161
-rw-r--r--man/man5/venti.conf.587
-rw-r--r--man/man8/venti.8232
-rw-r--r--man/man8/ventiaux.8504
-rw-r--r--sky/.cvsignore2
-rw-r--r--src/cmd/acme/exec.c2
-rw-r--r--src/cmd/acme/rows.c4
-rw-r--r--src/cmd/acme/text.c5
-rw-r--r--src/lib9/rendez-futex.c167
-rw-r--r--src/libdraw/md-alloc.c8
-rw-r--r--src/libfs/fs.c14
-rw-r--r--src/libfs/ns.c3
-rw-r--r--src/libthread/fdwait.c8
14 files changed, 1236 insertions, 9 deletions
diff --git a/man/man1/graph.1 b/man/man1/graph.1
new file mode 100644
index 00000000..4cdc6b24
--- /dev/null
+++ b/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.
diff --git a/man/man1/plot.1 b/man/man1/plot.1
new file mode 100644
index 00000000..cd1a1b81
--- /dev/null
+++ b/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)
diff --git a/man/man5/venti.conf.5 b/man/man5/venti.conf.5
new file mode 100644
index 00000000..d08aca3b
--- /dev/null
+++ b/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)
diff --git a/man/man8/venti.8 b/man/man8/venti.8
new file mode 100644
index 00000000..be112a6a
--- /dev/null
+++ b/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.
diff --git a/man/man8/ventiaux.8 b/man/man8/ventiaux.8
new file mode 100644
index 00000000..fb6d8522
--- /dev/null
+++ b/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.
diff --git a/sky/.cvsignore b/sky/.cvsignore
new file mode 100644
index 00000000..39bb8099
--- /dev/null
+++ b/sky/.cvsignore
@@ -0,0 +1,2 @@
+*.scat
+constelnames
diff --git a/src/cmd/acme/exec.c b/src/cmd/acme/exec.c
index 7dc1e88b..3bc10371 100644
--- a/src/cmd/acme/exec.c
+++ b/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);
diff --git a/src/cmd/acme/rows.c b/src/cmd/acme/rows.c
index 11014c2c..9fa54248 100644
--- a/src/cmd/acme/rows.c
+++ b/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);
diff --git a/src/cmd/acme/text.c b/src/cmd/acme/text.c
index aa58be1a..37613d80 100644
--- a/src/cmd/acme/text.c
+++ b/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)
diff --git a/src/lib9/rendez-futex.c b/src/lib9/rendez-futex.c
new file mode 100644
index 00000000..7d5e21eb
--- /dev/null
+++ b/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;
+}
+
diff --git a/src/libdraw/md-alloc.c b/src/libdraw/md-alloc.c
index 801c3930..b4204f4e 100644
--- a/src/libdraw/md-alloc.c
+++ b/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;
diff --git a/src/libfs/fs.c b/src/libfs/fs.c
index 31515250..a42af96b 100644
--- a/src/libfs/fs.c
+++ b/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);
}
diff --git a/src/libfs/ns.c b/src/libfs/ns.c
index 28c9d1cf..763080ba 100644
--- a/src/libfs/ns.c
+++ b/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);
diff --git a/src/libthread/fdwait.c b/src/libthread/fdwait.c
index e583da60..b544f16d 100644
--- a/src/libthread/fdwait.c
+++ b/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);