--- a/.hgignore Mon Aug 01 14:12:59 2011 -0700
+++ b/.hgignore Wed Aug 03 13:07:44 2011 -0700
@@ -38,6 +38,7 @@
^usr/src/cmd/zmgr/zmgr$
^usr/src/doc/manpage/.*\.1m?$
^usr/src/doc/rad-dev/rad-devguide.html$
+^usr/src/doc/rad-dev/.*-proc.xml$
^usr/src/java/vpanels/java.policy$
^usr/src/java/vpanels/vp$
^usr/src/lib.*_jni/.*\.h
--- a/usr/src/doc/Makefile.doc Mon Aug 01 14:12:59 2011 -0700
+++ b/usr/src/doc/Makefile.doc Wed Aug 03 13:07:44 2011 -0700
@@ -28,14 +28,10 @@
# The location of the DocBook XSL stylesheets to use. Most systems
# should provide a catalog which automatically maps from the
# DOCBOOK_XSL URL to a local path.
-#
-# STYLESHEET would ideally be set to profile-docbook.xsl, but the
-# stylesheets shipped with Solaris are old and broken. The effect
-# is that the STATUS variable, described below, doesn't work.
DOCBOOK_XSL= http://docbook.sourceforge.net/release/xsl/current
-STYLESHEET= docbook.xsl
+STYLESHEET= profile-docbook.xsl
FO_XSL= $(DOCBOOK_XSL)/fo/$(STYLESHEET)
HTML_XSL= $(DOCBOOK_XSL)/html/$(STYLESHEET)
MAN_XSL= $(DOCBOOK_XSL)/manpages/$(STYLESHEET)
@@ -43,8 +39,7 @@
# The sections of the documentation that make comments intended for an
# internal audience are given a status of "private". Setting STATUS to
# something other than "private" will cause those sections to be
-# eliminated from the generated output. Currently broken (see
-# STYLESHEET comment, above.)
+# eliminated from the generated output.
STATUS= private
DBOPTS= \
@@ -58,10 +53,12 @@
# We assume xsltproc, xmllint, and Apache fop are all in the user's
# path.
-XSLTPROC= xsltproc --xinclude --nonet $(DBOPTS)
+XSLTPROC= xsltproc --xinclude --nonet
XMLLINT= xmllint --xinclude --postvalid --noout
+
+DBXSLTPROC= $(XSLTPROC) $(DBOPTS)
FOP= fop
# Commands
-XSLT.man = $(XSLTPROC) $(MAN_XSL) $<
+XSLT.man = $(DBXSLTPROC) $(MAN_XSL) $<
--- a/usr/src/doc/manpage/man-rad.xml Mon Aug 01 14:12:59 2011 -0700
+++ b/usr/src/doc/manpage/man-rad.xml Wed Aug 03 13:07:44 2011 -0700
@@ -519,7 +519,6 @@
</para>
</refsection>
- <!-- Style sheets currently shipped misrender this section
<refsection><title>Attributes</title>
<para>
See <citerefentry>
@@ -548,7 +547,6 @@
</tgroup>
</informaltable>
</refsection>
- -->
<refsection><title>See Also</title>
<para>
--- a/usr/src/doc/rad-dev/Makefile Mon Aug 01 14:12:59 2011 -0700
+++ b/usr/src/doc/rad-dev/Makefile Wed Aug 03 13:07:44 2011 -0700
@@ -25,16 +25,21 @@
include ../Makefile.doc
+# Macro-processed files
+
+PROC= a-protocol-proc.xml
+
# Our primary source and output files
SRCS= rad-devguide.xml
+
TXT= $(SRCS:%.xml=%.txt)
HTML= $(SRCS:%.xml=%.html)
PDF= $(SRCS:%.xml=%.pdf)
FO= $(SRCS:%.xml=%.fo)
EXAMPLES= api_example.h api_example_impl.c
-CLEAN_FILES += $(EXAMPLES) $(FO)
+CLEAN_FILES += $(EXAMPLES) $(FO) $(PROC)
CLOBBER_FILES += $(TXT) $(HTML) $(PDF)
# Targets. Since some users may not have Apache fop installed, the
@@ -45,11 +50,13 @@
examples:
$(ADRGEN) -c example.xml
-html: examples
- $(XSLTPROC) --stringparam generate.toc "book toc" -o $(HTML) $(HTML_XSL) $(SRCS)
+docbook: examples $(PROC)
-# The old Solaris stylesheets misrender FO variablelists. This has
-# a noticeable effect on pdf output
+html: docbook
+ $(DBXSLTPROC) --stringparam generate.toc "book toc" -o $(HTML) $(HTML_XSL) $(SRCS)
+
+%-proc.xml: %.xml
+ $(XSLTPROC) -o $@ macros.xsl $<
pdf: fo
$(FOP) $(FO) -pdf $(PDF) 2> /dev/null
@@ -57,8 +64,8 @@
txt: fo
$(FOP) $(FO) -txt $(TXT) 2> /dev/null
-fo: examples
- $(XSLTPROC) -o $(FO) $(FO_XSL) $(SRCS)
+fo: docbook
+ $(DBXSLTPROC) -o $(FO) $(FO_XSL) $(SRCS)
# lint produces many benign errors due to older DocBook schemata not
# allowing for use of XInclude. The rest are meaningful.
--- a/usr/src/doc/rad-dev/a-logistics.xml Mon Aug 01 14:12:59 2011 -0700
+++ b/usr/src/doc/rad-dev/a-logistics.xml Wed Aug 03 13:07:44 2011 -0700
@@ -1,19 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<!--
- PDL HEADER START
+ PDL HEADER START
- Public Documentation License Notice
+ Public Documentation License Notice
- The contents of this Documentation are subject to the Public
- Documentation License Version 1.01 (the "License"); you may only
- use this Documentation if you comply with the terms of this License.
- A copy of the License is available at
- http://www.opensolaris.org/os/community/documentation/license.
+ The contents of this Documentation are subject to the Public
+ Documentation License Version 1.01 (the "License"); you may only
+ use this Documentation if you comply with the terms of this License.
+ A copy of the License is available at
+ http://www.opensolaris.org/os/community/documentation/license.
- PDL HEADER END
+ PDL HEADER END
- Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
-->
<appendix><title><command>rad</command> development</title>
@@ -70,11 +70,10 @@
<varlistentry>
<term><filename class='directory'>
-usr/src/cmd/rad
+usr/src/cmd/rad/daemon
</filename></term>
<listitem><para>
-The source code for rad. Building here will build both rad and
-its modules.
+The source code for <command>rad</command>.
</para></listitem>
</varlistentry>
@@ -129,7 +128,8 @@
usr/src/java/rad
</filename></term>
<listitem><para>
-The source code for the Java and JMX <command>rad</command> clients.
+The source code for the Java and <acronym>JMX</acronym>
+<command>rad</command> clients.
</para></listitem>
</varlistentry>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/doc/rad-dev/a-protocol.xml Wed Aug 03 13:07:44 2011 -0700
@@ -0,0 +1,1331 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
+<!--
+ PDL HEADER START
+
+ Public Documentation License Notice
+
+ The contents of this Documentation are subject to the Public
+ Documentation License Version 1.01 (the "License"); you may only
+ use this Documentation if you comply with the terms of this License.
+ A copy of the License is available at
+ http://www.opensolaris.org/os/community/documentation/license.
+
+ PDL HEADER END
+
+ Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+-->
+
+<appendix xmlns:rm="rad-macros">
+<title><command>rad</command> binary protocol</title>
+
+<!--
+ While it's not a very traditional way to document binary protocols,
+ BNF might be a clearer way to communicate some of the optional
+ paths. We should consider adding it as an addition to the textual /
+ diagrammatical description.
+-->
+
+<para>
+In addition to supporting multiple transports, <command>rad</command>
+is capable of talking different protocols. The default (and currently
+only) protocol is a proprietary binary protocol designated
+<literal>rad</literal>. This appendix documents version 1 of this
+protocol.
+</para>
+
+<section><title>Overview</title>
+ <para>
+ The <literal>rad</literal> protocol is a bi-directional binary protocol
+ that operates over a single stream. Communication in both directions
+ takes the form of discrete messages. These messages are framed using
+ <acronym>RPC</acronym> record marking (See <quote>RECORD MARKING
+ STANDARD</quote> in <citation>RPC</citation>).
+ </para>
+
+ <para>
+ The individual messages take the formats documented below. Even though
+ <acronym>RPC</acronym> record marking permits skipping messages of
+ unknown format, both the client and the server are free to immediately
+ drop the connection when an invalid message is seen.
+ </para>
+
+ <para>
+ The <literal>rad</literal> protocol is built using
+ <citation>XDR</citation>, so for simplicity and clarity the
+ <acronym>XDR</acronym> primitive type names and syntax will be used
+ throughout this appendix. For example:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <quote><literal>FOO<></literal></quote> would represent a
+ variable-length array of <literal>FOO</literal>s, communicated as
+ an <literal>unsigned int</literal> containing the size followed by
+ that number of <literal>FOO</literal>s.
+ </listitem>
+ <listitem>
+ <quote><literal>FOO[n]</literal></quote> would represent a
+ fixed-length array of a predetermined size, communicated only as
+ the <literal>n</literal> <literal>FOO</literal>s.
+ </listitem>
+ <listitem>
+ <quote><literal>FOO *</literal></quote> would represent an optional
+ value, communicated as a <literal>boolean</literal> value followed
+ by a <literal>FOO</literal> if and only if the
+ <literal>boolean</literal> value was true.
+ </listitem>
+ </itemizedlist>
+
+</section>
+
+<section><title>Common data formats</title>
+ <para>
+ There are a few types and concepts that appear repeatedly
+ throughout the <literal>rad</literal> protocol. They are described
+ here.
+ </para>
+
+ <section id="op-data-def"><title>Operations</title>
+ <para>
+ The various operations one can perform against the server are
+ communicated with an operation code.
+ </para>
+
+ <rm:proto name="OP-CODE">
+ <rm:data field="op_code" size="4" type="int">
+ <rm:codedef label="operation" prefix="oc">
+ <rm:code num="0" name="INVOKE" />
+ <rm:code num="1" name="GETATTR" />
+ <rm:code num="2" name="SETATTR" />
+ <rm:code num="3" name="LOOKUP" />
+ <rm:code num="4" name="DEFINE" />
+ <rm:code num="5" name="LIST" />
+ <rm:code num="6" name="SUB" />
+ <rm:code num="7" name="UNSUB" />
+ </rm:codedef>
+ </rm:data>
+ </rm:proto>
+ </section>
+
+ <section id="error-data-def"><title>Errors</title>
+ <para>
+ Errors in the <literal>rad</literal> protocol are communicated by
+ an error code, and optionally structured error data.
+ </para>
+
+ <rm:proto name="ERROR-CODE">
+ <rm:data field="error_code" size="4" type="int">
+ <rm:codedef label="error" prefix="ec">
+ <rm:code num="0" name="ok" />
+ <rm:code num="1" name="object" />
+ <rm:code num="2" name="nomem" />
+ <rm:code num="3" name="notfound" />
+ <rm:code num="4" name="priv" />
+ <rm:code num="5" name="system" />
+ <rm:code num="6" name="exists" />
+ <rm:code num="7" name="mismatch" />
+ <rm:code num="8" name="illegal" />
+ </rm:codedef>
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ For object-specific errors, <literal>EC-OBJECT</literal>, the
+ format of the structured data is defined by the object's interface
+ definition. For the remainder, save for <literal>EC-OK</literal>
+ (which is defined for completeness, but should never appear in the
+ protocol), the format is defined during the initial connection
+ handshake. See <xref linkend="proto-handshake" />.
+ </para>
+ </section>
+
+ <section id="time-data-def"><title>Time</title>
+ <para>
+ When a time needs to be represented in the <literal>rad</literal>
+ protocol, it is communicated as seconds and nanoseconds offset from
+ the epoch (January 1, 1970 UTC).
+ </para>
+
+ <para>
+ It is important to note that the accuracy of such time data is
+ determined by its context. In most, if not all, cases, the full
+ nanosecond precision is only relevant when compared to time data
+ obtained from the same host.
+ </para>
+
+<rm:proto name="TIME-DATA">
+ <rm:data field="secs" size="8" type="hyper">
+ number of seconds
+ </rm:data>
+ <rm:data field="nsecs" size="4" type="int">
+ number of nanoseconds (<mathphrase>0 ≤ nsec ≤
+ 10<superscript>9</superscript></mathphrase>)
+ </rm:data>
+</rm:proto>
+ </section>
+
+ <section id="name-data-def"><title>Object names</title>
+ <para>
+ <command>rad</command> object names are structured, consisting of a
+ domain and one or more key-value pairs. When an object name or
+ pattern needs to be represented in the <literal>rad</literal>
+ protocol, this structure is flattened to a canonical string
+ format. This string format consists of the domain, followed by a
+ colon (':'), followed by comma-separated key-value pairs. Each
+ key-value pair consists of the name, followed by an equals sign
+ ('='), followed by the value.
+ </para>
+
+ <para>
+ Because keys and values may contain the special characters '=' or
+ ',', a quoting algorithm is applied when constructing the string.
+ The following substitutions are applied to keys and values:
+ </para>
+
+ <table><title>Object Name Escaping</title>
+ <tgroup cols='2'>
+ <thead>
+ <row><entry>Plain Text</entry><entry>Escaped Text</entry></row>
+ </thead>
+ <tbody>
+ <row><entry>\</entry><entry>\S</entry></row>
+ <row><entry>,</entry><entry>\C</entry></row>
+ <row><entry>=</entry><entry>\E</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Note that under this transformation, backslashes are only found as
+ part of quoted characters, and commas and equals signs, when
+ present, always have their special meaning. Object names that use
+ no special characters are passed through unchanged. These facts
+ can be used to simplify parsing or preprocessing of
+ string-formatted object names.
+ </para>
+
+<rm:proto name="NAME-DATA">
+ <rm:data field="name" size="variable" type="string<>">
+ flattened object name
+ </rm:data>
+</rm:proto>
+
+ <example>
+ An object name in the domain <quote>com.example</quote> with the
+ following keys and values:
+
+ <informaltable>
+ <tgroup cols='2'>
+ <thead>
+ <row><entry>Key</entry><entry>Value</entry></row>
+ </thead>
+ <tbody>
+ <row><entry>directory</entry><entry>C:\</entry></row>
+ <row><entry>first,last</entry><entry>Doe,John</entry></row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ would be represented by the string
+ <quote>com.example:directory=C:\S,first\Clast=Doe\CJohn</quote>.
+ </example>
+ </section>
+
+ <section id="adr-data"><title><acronym>ADR</acronym> data</title>
+ <para>
+ Central to the <literal>rad</literal> protocol is the communication
+ of data defined by <acronym>ADR</acronym>. Most
+ <acronym>ADR</acronym> primitives map directly to
+ <acronym>XDR</acronym> types:
+ </para>
+
+ <table>
+ <title>Primitive <acronym>ADR</acronym> to Wire Type Mapping</title>
+ <tgroup cols='2'>
+ <thead>
+ <row>
+ <entry><acronym>ADR</acronym> Type</entry>
+ <entry>Wire Type</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>boolean</entry>
+ <entry><acronym>XDR</acronym> <literal>boolean</literal></entry>
+ </row>
+ <row>
+ <entry>integer</entry>
+ <entry><acronym>XDR</acronym> <literal>int</literal></entry>
+ </row>
+ <row>
+ <entry>uinteger</entry>
+ <entry><acronym>XDR</acronym> <literal>unsigned int</literal></entry>
+ </row>
+ <row>
+ <entry>long</entry>
+ <entry><acronym>XDR</acronym> <literal>hyper</literal></entry>
+ </row>
+ <row>
+ <entry>ulong</entry>
+ <entry><acronym>XDR</acronym> <literal>unsigned hyper</literal></entry>
+ </row>
+ <row>
+ <entry>float</entry>
+ <entry><acronym>XDR</acronym> <literal>float</literal></entry>
+ </row>
+ <row>
+ <entry>double</entry>
+ <entry><acronym>XDR</acronym> <literal>double</literal></entry>
+ </row>
+ <row>
+ <entry>string</entry>
+ <entry><acronym>XDR</acronym> <literal>string<></literal></entry>
+ </row>
+ <row>
+ <entry>opaque</entry>
+ <entry><acronym>XDR</acronym> <literal>opaque<></literal></entry>
+ </row>
+ <row>
+ <entry>password</entry>
+ <entry><acronym>XDR</acronym> <literal>string<></literal></entry>
+ </row>
+ <row>
+ <entry>time</entry>
+ <entry><literal>TIME-DATA</literal>
+ (see <xref linkend="time-data-def" />)</entry>
+ </row>
+ <row>
+ <entry>name</entry>
+ <entry><literal>NAME-DATA</literal>
+ (see <xref linkend="name-data-def" />)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Optional <acronym>ADR</acronym> data of any type is represented as
+ <acronym>XDR</acronym> optional data.
+ </para>
+
+ <rm:proto name="OPTIONAL-DATA">
+ <rm:data field="data" size="varies" type="ADR-DATA *">
+ Optional encoded data
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ Array data is communicated as an <acronym>XDR</acronym> array of
+ the element data. That is, it is represented by an
+ <acronym>XDR</acronym> <literal>unsigned int</literal> whose value
+ is the number of array elements, followed by that number of element
+ data.
+ </para>
+
+ <rm:proto name="ARRAY-DATA">
+ <rm:data field="elements" size="varies" type="ADR-DATA<>">
+ array elements
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ Structure data is communicated by communicating each structure
+ field in the order they are defined. This may consist of a mixture
+ of optional and non-optional data.
+ </para>
+
+ <rm:proto name="STRUCT-DATA">
+ <rm:data field="fields" size="varies" type="ADR-DATA[n]">
+ fixed-length array of structure fields
+ (n = type-defined field count)
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ Enumeration data is communicated as an <acronym>XDR</acronym>
+ <literal>unsigned int</literal> whose value is the 1-based index
+ into the list of enumerated values (i.e. 1 would be the first
+ enumerated value, n would be the nth enumerated value). A value of
+ 0 represents the fallback value. For enumerations without a
+ fallback value, the 0 value is unused.
+ </para>
+
+ <rm:proto name="ENUM-DATA">
+ <rm:data field="value" size="4" type="unsigned int">
+ 0 if fallback, 1-based index otherwise
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ Union data is communicated as an <acronym>XDR</acronym>
+ <literal>unsigned int</literal> whose value is the 1-based index
+ into the list of union arms. A value of 0 represents the default
+ arm. When a non-default arm is selected, the arm is followed by
+ that arm's data. When the default arm is selected, it is first
+ followed by the discriminant data value, and then is followed by
+ the default arm's data.
+ </para>
+
+ <rm:proto name="UNION-DATA (non default)">
+ <rm:data field="arm_index" size="4" type="unsigned int">
+ 1-based index into list of arms
+ </rm:data>
+ <rm:data field="arm_data" size="varies" type="ADR-DATA">
+ Arm data
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="UNION-DATA (default)">
+ <rm:data field="arm_index" size="4" type="unsigned int">
+ 0
+ </rm:data>
+ <rm:data field="discriminant" size="4" type="ENUM-DATA | boolean">
+ discriminant value
+ </rm:data>
+ <rm:data field="arm_data" size="varies" type="ADR-DATA">
+ Arm data
+ </rm:data>
+ </rm:proto>
+
+ </section>
+
+ <!-- Consider switching this section and the previous section -->
+ <section><title><acronym>ADR</acronym> types</title>
+ <para>
+ As discussed in <xref linkend="adr-data" />, the
+ <acronym>ADR</acronym> data communicated by the
+ <literal>rad</literal> protocol has a structure determined by its
+ type. Before that data can be communicated to the client, however,
+ the types themselves must be communicated.
+ </para>
+
+ <para>
+ For efficiency, type data is communicated using a system of type
+ spaces and type references. A type space is an array of type
+ definitions that is referenced by a protocol-defined set of
+ consumers. A consumer referring to a type will use a type
+ reference, which points to either a primitive type or to an element
+ of the type space.
+ </para>
+
+ <para>
+ Both type references and type spaces need to refer to the various
+ types. They do this using an integral type code:
+ </para>
+
+ <rm:proto name="TYPE-CODE">
+ <rm:data field="type_code" size="4" type="int">
+ <rm:codedef label="type" prefix="tc">
+ <rm:code num="0" name="void" />
+ <rm:code num="1" name="boolean" />
+ <rm:code num="2" name="integer" />
+ <rm:code num="3" name="uinteger" />
+ <rm:code num="4" name="long" />
+ <rm:code num="5" name="ulong" />
+ <rm:code num="6" name="float" />
+ <rm:code num="7" name="double" />
+ <rm:code num="8" name="time" />
+ <rm:code num="9" name="string" />
+ <rm:code num="10" name="opaque" />
+ <rm:code num="11" name="password" />
+ <rm:code num="12" name="name" />
+ <rm:code num="13" name="enum" />
+ <rm:code num="14" name="array" />
+ <rm:code num="15" name="struct" />
+ <rm:code num="16" name="union" />
+ </rm:codedef>
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ Concretely, a type reference consists of an XDR int whose value is
+ one of the above type constants. If the type is an enum, array,
+ union, or struct, the type reference also includes an XDR int whose
+ value is an index into the current type space:
+ </para>
+
+ <rm:proto name="TYPEREF (basic type)">
+ <rm:data field="type_code" size="4" type="TYPE-CODE">
+ a primitive type code
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="TYPEREF (derived type)">
+ <rm:data field="type_code" size="4" type="TYPE-CODE">
+ <literal>TC-ENUM</literal>, <literal>TC-ARRAY</literal>,
+ <literal>TC-STRUCT</literal>, or <literal>TC-UNION</literal>
+ </rm:data>
+ <rm:data field="type_index" size="4" type="int">
+ type space index
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ A type space is a topologically sorted array of type definitions.
+ A derived type may only reference derived types defined earlier in
+ the type space. That is, a type reference used by the type at
+ index <mathphrase>X</mathphrase> may only reference a primitive
+ type or a derived type a index less than
+ <mathphrase>X</mathphrase>. Recursively defined types are not
+ supported.
+ </para>
+
+ <para>
+ Apart from a common distinguishing type code, each derived type is
+ defined differently. Arrays are the simplest. An array definition
+ consists of only a reference to the element type:
+ </para>
+
+ <rm:proto name="ARRAY-TYPE">
+ <rm:data field="type_code" size="4" type="TYPE-CODE">
+ <literal>TC-ARRAY</literal>
+ </rm:data>
+ <rm:data field="element_type" size="varies" type="TYPEREF">
+ the element type
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ A structure type definition consists of a name and an array of
+ field definitions. The order in which the fields are specified in
+ <literal>STRUCT-TYPE</literal> is the order used to serialize the
+ fields in <literal>STRUCT-DATA</literal>.
+ </para>
+
+ <rm:proto name="FIELD-TYPE">
+ <rm:data field="name" size="varies" type="string<>">
+ the field name
+ </rm:data>
+ <rm:data field="optional" size="4" type="boolean">
+ is the field value optional?
+ </rm:data>
+ <rm:data field="type" size="varies" type="TYPEREF">
+ the field type
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="STRUCT-TYPE">
+ <rm:data field="type_code" size="4" type="TYPE-CODE">
+ <literal>TC-STRUCT</literal>
+ </rm:data>
+ <rm:data field="name" size="varies" type="string<>">
+ the structure name
+ </rm:data>
+ <rm:data field="fields" size="varies" type="FIELD-TYPE<>">
+ ordered list of structure fields
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ A union type definition consists of a name, a reference to the
+ discriminant type, optionally a default arm specification, and an
+ array of arm definitions. The arm index referenced by
+ <literal>UNION-DATA</literal> is an index into the array of arms
+ defined by the corresponding <literal>UNION-TYPE</literal>.
+ </para>
+
+ <rm:proto name="ARM-TYPE">
+ <rm:data field="value" size="4" type="ENUM-DATA | boolean">
+ the discriminant value that selects this arm
+ </rm:data>
+ <rm:data field="optional" size="4" type="boolean">
+ is the arm's value optional?
+ </rm:data>
+ <rm:data field="type" size="varies" type="TYPEREF">
+ the arm's type
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="UNION-TYPE (without default arm)">
+ <rm:data field="type_code" size="4" type="TYPE-CODE">
+ <literal>TC-UNION</literal>
+ </rm:data>
+ <rm:data field="name" size="varies" type="string<>">
+ the union name
+ </rm:data>
+ <rm:data field="disc_type" size="varies" type="TYPEREF">
+ the discriminant type
+ </rm:data>
+ <rm:data field="hasdefault" size="4" type="boolean">
+ false
+ </rm:data>
+ <rm:data field="arms" size="varies" type="ARM-TYPE<>">
+ ordered list of arms
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="UNION-TYPE (with default arm)">
+ <rm:data field="type_code" size="4" type="TYPE-CODE">
+ <literal>TC-UNION</literal>
+ </rm:data>
+ <rm:data field="name" size="varies" type="string<>">
+ the union name
+ </rm:data>
+ <rm:data field="disc_type" size="varies" type="TYPEREF">
+ the discriminant type
+ </rm:data>
+ <rm:data field="hasdefault" size="4" type="boolean">
+ true
+ </rm:data>
+ <rm:data field="def_optional" size="4" type="boolean">
+ is the default arm value optional?
+ </rm:data>
+ <rm:data field="def_type" size="varies" type="TYPEREF">
+ the default arm type
+ </rm:data>
+ <rm:data field="arms" size="varies" type="ARM-TYPE<>">
+ ordered list of arms
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ Lastly, an enum type definition consists of a name, an optional
+ fallback value, and a list of enumeration values. The value index
+ referenced by <literal>ENUM-DATA</literal> is an index into the
+ array of values defined by the corresponding
+ <literal>ENUM-TYPE</literal>.
+ </para>
+
+ <rm:proto name="VALUE-TYPE">
+ <rm:data field="name" size="varies" type="string<>">
+ the value's name
+ </rm:data>
+ <rm:data field="value" size="4" type="int">
+ the value's assigned value
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="ENUM-TYPE">
+ <rm:data field="type_code" size="4" type="TYPE-CODE">
+ <literal>TC-ENUM</literal>
+ </rm:data>
+ <rm:data field="name" size="varies" type="string<>">
+ the enum name
+ </rm:data>
+ <rm:data field="fb_name" size="varies" type="string<> *">
+ the fallback value's name, if one exists
+ </rm:data>
+ <rm:data field="values" size="varies" type="VALUE-TYPE<>">
+ ordered list of values
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ The type space itself is an array. Each element is one of these
+ four type definitions (<literal>ARRAY-TYPE</literal>,
+ <literal>STRUCT-TYPE</literal>, <literal>UNION-TYPE</literal>, or
+ <literal>ENUM-TYPE</literal>).
+ </para>
+
+ <rm:proto name="TYPESPACE">
+ <rm:data field="types" size="varies" type="?-TYPE<>">
+ ordered list of types in the type space
+ </rm:data>
+ </rm:proto>
+
+ </section>
+
+ <section><title><acronym>API</acronym> definitions</title>
+ <para>
+ The ultimate description of the interactions permitted with a
+ particular object is its <acronym>API</acronym> definition. An
+ <acronym>API</acronym> definition contains many elements: an
+ interface name, a list of versioned <acronym>API</acronym> names
+ the <acronym>API</acronym> supports, and definitions of the
+ <acronym>API</acronym>'s attributes, methods, and events.
+ </para>
+
+ <para>
+ Each <acronym>API</acronym> name has a set of stabilities and
+ versions:
+ </para>
+
+ <rm:proto name="STABILITY-CODE">
+ <rm:data field="stability_code" size="4" type="int">
+ <rm:codedef label="stability" prefix="sc">
+ <rm:code num="1" name="private" />
+ <rm:code num="2" name="uncommitted" />
+ <rm:code num="3" name="committed" />
+ </rm:codedef>
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="VERSION-DATA">
+ <rm:data field="stability" size="4" type="STABILITY-CODE">
+ stability version applies to
+ </rm:data>
+ <rm:data field="major" size="4" type="int">
+ major version number
+ </rm:data>
+ <rm:data field="minor" size="4" type="int">
+ minor version number
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="APINAME-DATA">
+ <rm:data field="api_name" size="varies" type="string<>">
+ API name
+ </rm:data>
+ <rm:data field="versions" size="varies" type="VERSION-DATA<>">
+ API versions by stability
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ An attribute consists of a name, stability, various flags, a type,
+ and separate, optional read and write error types.
+ </para>
+
+ <rm:proto name="ATTRIBUTE-TYPE">
+ <rm:data field="aname" size="varies" type="string<>">
+ attribute name
+ </rm:data>
+ <rm:data field="stability" size="4" type="STABILITY-CODE">
+ stability
+ </rm:data>
+ <rm:data field="readable" size="4" type="boolean">
+ is attribute readable?
+ </rm:data>
+ <rm:data field="writable" size="4" type="boolean">
+ is attribute writable?
+ </rm:data>
+ <rm:data field="optional" size="4" type="boolean">
+ is attribute optional?
+ </rm:data>
+ <rm:data field="type" size="varies" type="TYPEREF">
+ attribute type
+ </rm:data>
+ <rm:data field="read_error" size="varies" type="TYPEREF *">
+ error data on read, if applicable
+ </rm:data>
+ <rm:data field="write_error" size="varies" type="TYPEREF *">
+ error data on write, if applicable
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ A method looks a lot like an attribute. It has a name, stability,
+ a result type, only a single optional error type, and an array of
+ argument definitions.
+ </para>
+
+ <rm:proto name="ARGUMENT-TYPE">
+ <rm:data field="argname" size="varies" type="string<>">
+ argument name
+ </rm:data>
+ <rm:data field="optional" size="4" type="boolean">
+ is argument optional?
+ </rm:data>
+ <rm:data field="type" size="varies" type="TYPEREF">
+ argument type
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="METHOD-TYPE">
+ <rm:data field="mname" size="varies" type="string<>">
+ method name
+ </rm:data>
+ <rm:data field="stability" size="4" type="STABILITY-CODE">
+ stability
+ </rm:data>
+ <rm:data field="optional" size="4" type="boolean">
+ is result optional?
+ </rm:data>
+ <rm:data field="result_type" size="varies" type="TYPEREF">
+ result type
+ </rm:data>
+ <rm:data field="error" size="varies" type="TYPEREF *">
+ error data, if applicable
+ </rm:data>
+ <rm:data field="args" size="varies" type="ARGUMENT-TYPE<>">
+ arguments
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ An event consists only of a name, stability, and type.
+ </para>
+
+ <rm:proto name="EVENT-TYPE">
+ <rm:data field="ename" size="varies" type="string<>">
+ method name
+ </rm:data>
+ <rm:data field="stability" size="4" type="STABILITY-CODE">
+ stability
+ </rm:data>
+ <rm:data field="event_type" size="varies" type="TYPEREF">
+ event type
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ Finally, an API definition combines all the above elements.
+ </para>
+
+ <rm:proto name="API-TYPE">
+ <rm:data field="ifname" size="varies" type="string<>">
+ interface name (domain)
+ </rm:data>
+ <rm:data field="apis" size="varies" type="APINAME-DATA<>">
+ API names and versions implemented
+ </rm:data>
+ <rm:data field="types" size="varies" type="TYPESET<>">
+ Types used by API definition
+ </rm:data>
+ <rm:data field="attributes" size="varies" type="ATTRIBUTE-TYPE<>">
+ API attributes
+ </rm:data>
+ <rm:data field="methods" size="varies" type="METHOD-TYPE<>">
+ API methods
+ </rm:data>
+ <rm:data field="events" size="varies" type="EVENT-TYPE<>">
+ API events
+ </rm:data>
+ </rm:proto>
+
+ </section>
+
+</section>
+<section id="proto-handshake"><title>Connection Initialization</title>
+ <para>
+ Once a connection has been established between a client and server,
+ a short synchronous handshake initiates the rad protocol. The
+ server begins by sending a <literal>SERVER-HELLO</literal>
+ message. This message specifies the minimum and maximum protocol
+ versions (inclusive) recognized by the server.
+ </para>
+
+ <rm:proto name="SERVER-HELLO">
+ <rm:data field="protocol" size="3" type="string[3]">
+ <quote>RAD</quote>
+ </rm:data>
+ <rm:data field="min_ver" size="4" type="int">
+ minimum supported version
+ </rm:data>
+ <rm:data field="max_ver" size="4" type="int">
+ maximum supported version
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ The client then replies with a <literal>CLIENT-HELLO</literal>
+ message specifying the version it wishes to use. This version may
+ not be less than the server's minimum version or greater than the
+ server's maximum version.
+ </para>
+
+ <rm:proto name="CLIENT-HELLO">
+ <rm:data field="protocol" size="3" type="string[3]">
+ <quote>RAD</quote>
+ </rm:data>
+ <rm:data field="version" size="4" type="int">
+ client-selected version
+ </rm:data>
+ <rm:data field="locale" size="varies" type="string<256>">
+ client locale
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ Part of the <literal>rad</literal> protocol is the communication of
+ structured error data on request failures. For consistency with
+ the object-specific errors that server-side objects are permitted
+ to return, the errors returned by rad when requests fail for other
+ reasons are also defined using <acronym>ADR</acronym>. After the
+ server receives and accepts a <literal>CLIENT-HELLO</literal>
+ message, it replies with <literal>ERRORS</literal> to communicate
+ those type definitions:
+ </para>
+
+ <rm:proto name="ERRORS">
+ <rm:data field="error_space" size="varies" type="TYPESPACE">
+ typespace containing error types
+ </rm:data>
+ <rm:data field="errors" size="varies" type="TYPEREF<>">
+ errors types, starting with <literal>EC-NOMEM</literal>
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ The <literal>TYPEREF</literal>s refer to the types defined in the
+ <literal>error_space</literal> <literal>TYPESPACE</literal>. The
+ types define the first <literal>error_count</literal> errors,
+ starting from the first non object-specific error,
+ <literal>EC-NOMEM</literal>. Any errors for which types are not
+ defined have type <quote>void</quote>.
+ </para>
+
+ <!--
+ These errors are defined in ADR for convenience and for
+ architectural consistency. However, from a interface perspective
+ they should be part of the protocol and documented here.
+ -->
+
+ <para>
+ At this point, the handshake is complete and normal client-server
+ communication can occur.
+ </para>
+</section>
+
+
+<section><title>Messages</title>
+ <para>
+ Normal communication consists of an asynchronous exchange of
+ messages: <literal>REQUEST</literal>s from the client to the
+ server, <literal>RESPONSE</literal>s from the server to the client,
+ and <literal>EVENT</literal>s from the server to the client.
+ </para>
+
+ <para>
+ A <literal>REQUEST</literal> is the <literal>rad</literal>
+ equivalent of a low-level remote procedure call. It consists of a
+ client-selected, non-zero serial number, an operation code, and an
+ opaque, operation-specific, variable-length payload.
+ </para>
+
+ <rm:proto name="REQUEST">
+ <rm:data field="serial" size="8" type="hyper">
+ client-specified serial number
+ </rm:data>
+ <rm:data field="opcode" size="4" type="OP-CODE">
+ operation code (see <xref linkend="op-data-def" />)
+ </rm:data>
+ <rm:data field="payload" size="varies" type="opaque<>">
+ request payload
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ The server will respond to every <literal>REQUEST</literal> with a
+ <literal>RESPONSE</literal>. The structure of a
+ <literal>RESPONSE</literal> varies depending on whether the server
+ was successful in processing the client's request. A
+ <literal>RESPONSE</literal> consists of the serial number of the
+ corresponding <literal>REQUEST</literal>, a boolean indicating
+ whether the request was successful, and either an
+ operation-specific opaque payload (in the case of success), or an
+ error code and an error-specific error payload (in the case of
+ failure):
+ </para>
+
+ <rm:proto name="RESPONSE (successful)">
+ <rm:data field="serial" size="8" type="hyper">
+ serial number of REQUEST
+ </rm:data>
+ <rm:data field="success" size="4" type="boolean">
+ true
+ </rm:data>
+ <rm:data field="payload" size="varies" type="opaque<>">
+ response payload
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="RESPONSE (failure)">
+ <rm:data field="serial" size="8" type="hyper">
+ serial number of REQUEST
+ </rm:data>
+ <rm:data field="success" size="4" type="boolean">
+ false
+ </rm:data>
+ <rm:data field="error" size="4" type="ERROR-CODE">
+ error code (see <xref linkend="error-data-def" />)
+ </rm:data>
+ <rm:data field="payload" size="varies" type="opaque<>">
+ error payload
+ </rm:data>
+ </rm:proto>
+
+ <para>
+ The <literal>rad</literal> protocol doesn't require the client to
+ wait for a <literal>RESPONSE</literal> before sending another
+ <literal>REQUEST</literal>. However, the server implementation may
+ place limits on the number of outstanding requests that can be
+ handled simultaneously. A client with an outstanding
+ <literal>REQUEST</literal> must assume that a subsequent
+ <literal>REQUEST</literal> will block until the
+ <literal>RESPONSE</literal> from the outstanding
+ <literal>REQUEST</literal> is read.
+ </para>
+
+ <para>
+ Lastly, a client may (via a <literal>REQUEST</literal>) subscribe
+ to asynchronous event sources. When an event occurs, the server
+ will send an <literal>EVENT</literal> message to the client. An
+ <literal>EVENT</literal> message will include the object ID of the
+ source object (more later), the time of the event, the name of the
+ event, and an event-specific opaque payload. An
+ <literal>EVENT</literal> message is distinguished from a
+ <literal>RESPONSE</literal> by having a serial number of 0.
+ </para>
+
+ <rm:proto name="EVENT">
+ <rm:data field="serial" size="8" type="hyper">
+ 0
+ </rm:data>
+ <rm:data field="source" size="8" type="hyper">
+ id of generating object
+ </rm:data>
+ <rm:data field="sequence" size="8" type="hyper">
+ sequence number of event
+ </rm:data>
+ <rm:data field="timestamp" size="12" type="TIME-DATA">
+ time of event
+ </rm:data>
+ <rm:data field="name" size="varies" type="string<>">
+ event name
+ </rm:data>
+ <rm:data field="payload" size="varies" type="opaque<>">
+ event payload
+ </rm:data>
+ </rm:proto>
+
+</section>
+
+
+<section><title>Operations</title>
+ <para>
+ Each operation that a client can perform against a
+ <command>rad</command> server has its own request and response
+ payloads. To facilitate processing without needing to fully decode
+ the payload, they are communicated as variable-lengthed
+ <literal>opaque</literal> data in the <literal>REQUEST</literal>
+ and <literal>RESPONSE</literal>.
+ </para>
+
+ <para>
+ For consistency and flexibility, all <acronym>ADR</acronym> data
+ referenced by these payloads is communicated as
+ <literal>OPTIONAL-DATA</literal>, which in turn is wrapped as
+ <literal>opaque</literal> data.
+ </para>
+
+ <rm:proto name="PAYLOAD-DATA">
+ <rm:data field="data" size="varies" type="opaque<>">
+ encapsulated <literal>OPTIONAL-DATA</literal>
+ </rm:data>
+ </rm:proto>
+
+ <section><title>INVOKE</title>
+
+ <para>
+ INVOKE makes a method call against a <command>rad</command> object,
+ identified by its object ID.
+ </para>
+
+ <rm:proto name="INVOKE-REQUEST">
+ <rm:data field="objectid" size="8" type="hyper">
+ Object ID, returned by lookup
+ </rm:data>
+ <rm:data field="mname" size="varies" type="string<>">
+ the method to invoke
+ </rm:data>
+ <rm:data field="arguments" size="varies" type="PAYLOAD-DATA<>">
+ array of method arguments
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="INVOKE-RESPONSE">
+ <rm:data field="result" size="varies" type="PAYLOAD-DATA">
+ the return value of method call, if any
+ </rm:data>
+ </rm:proto>
+
+ <rm:errors op="INVOKE">
+ <rm:error code="EC-OBJECT">
+ The method call was made but failed for an object-specific
+ reason.
+ </rm:error>
+ <rm:error code="EC-NOTFOUND">
+ <literal>objectid</literal> isn't a known object id, or the
+ object doesn't have the method <literal>mname</literal>.
+ </rm:error>
+ <rm:error code="EC-MISMATCH">
+ The wrong number of arguments were provided, or a
+ non-optional argument was missing.
+ </rm:error>
+ <rm:error code="EC-NOMEM">
+ The server had insufficient resources to complete the
+ operation.
+ </rm:error>
+ <rm:error code="EC-SYSTEM">
+ An unexpected internal error occurred.
+ </rm:error>
+ </rm:errors>
+
+ </section>
+
+ <section><title>GETATTR</title>
+
+ <para>
+ GETATTR reads an attribute of a <command>rad</command> object,
+ identified by its object ID.
+ </para>
+
+ <rm:proto name="GETATTR-REQUEST">
+ <rm:data field="objectid" size="8" type="hyper">
+ Object ID, returned by lookup
+ </rm:data>
+ <rm:data field="aname" size="varies" type="string<>">
+ the attribute to read
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="GETATTR-RESPONSE">
+ <rm:data field="result" size="varies" type="PAYLOAD-DATA">
+ the value of the attribute
+ </rm:data>
+ </rm:proto>
+
+ <rm:errors op="GETATTR">
+ <rm:error code="EC-OBJECT">
+ An attempt to read the attribute was made, but failed for
+ an object-specific reason.
+ </rm:error>
+ <rm:error code="EC-NOTFOUND">
+ <literal>objectid</literal> isn't a known object id, or the
+ object doesn't have the attribute <literal>aname</literal>.
+ </rm:error>
+ <rm:error code="EC-ILLEGAL">
+ <literal>aname</literal> refers to a write-only attribute.
+ </rm:error>
+ <rm:error code="EC-NOMEM">
+ The server had insufficient resources to complete the
+ operation.
+ </rm:error>
+ <rm:error code="EC-SYSTEM">
+ An unexpected internal error occurred.
+ </rm:error>
+ </rm:errors>
+
+ </section>
+
+ <section><title>SETATTR</title>
+
+ <para>
+ SETATTR reads an attribute of a <command>rad</command> object,
+ identified by its object ID. The response payload for a SETATTR
+ request is empty.
+ </para>
+
+ <rm:proto name="SETATTR-REQUEST">
+ <rm:data field="objectid" size="8" type="hyper">
+ Object ID, returned by lookup
+ </rm:data>
+ <rm:data field="aname" size="varies" type="string<>">
+ the attribute to write
+ </rm:data>
+ <rm:data field="value" size="varies" type="PAYLOAD-DATA">
+ the new value of the attribute
+ </rm:data>
+ </rm:proto>
+
+ <rm:errors op="SETATTR">
+ <rm:error code="EC-OBJECT">
+ An attempt to write the attribute was made, but failed for
+ an object-specific reason.
+ </rm:error>
+ <rm:error code="EC-NOTFOUND">
+ <literal>objectid</literal> isn't a known object id, or the
+ object doesn't have the attribute <literal>aname</literal>.
+ </rm:error>
+ <rm:error code="EC-MISMATCH">
+ <literal>aname</literal> has a non-optional value and
+ <literal>value</literal> was NULL.
+ </rm:error>
+ <rm:error code="EC-ILLEGAL">
+ <literal>aname</literal> refers to a read-only attribute.
+ </rm:error>
+ <rm:error code="EC-NOMEM">
+ The server had insufficient resources to complete the
+ operation.
+ </rm:error>
+ <rm:error code="EC-SYSTEM">
+ An unexpected internal error occurred.
+ </rm:error>
+ </rm:errors>
+
+ </section>
+
+ <section><title>LOOKUP</title>
+
+ <para>
+ LOOKUP attempts to find the named object in the server's namespace,
+ returning the object and API IDs of the object if it exists. Since
+ an object isn't usable until its API has been DEFINEed, the client
+ may request the API definition be provided as part of the LOOKUP
+ response. For the same reason, the server may unilaterally decide
+ to provide the API definition if it believes the client hasn't seen
+ it yet.
+ </para>
+
+ <rm:proto name="LOOKUP-REQUEST">
+ <rm:data field="name" size="varies" type="NAME-DATA">
+ object name
+ </rm:data>
+ <rm:data field="define" size="4" type="boolean">
+ include object definition?
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="LOOKUP-RESPONSE">
+ <rm:data field="objectid" size="8" type="hyper">
+ ID of the object
+ </rm:data>
+ <rm:data field="apiid" size="8" type="hyper">
+ ID of the object's API
+ </rm:data>
+ <rm:data field="definition" size="varies" type="API-TYPE *">
+ the definition of the object's API
+ </rm:data>
+ </rm:proto>
+
+ <rm:errors op="LOOKUP">
+ <rm:error code="EC-NOTFOUND">
+ <literal>name</literal> doesn't exist.
+ </rm:error>
+ <rm:error code="EC-NOMEM">
+ The server had insufficient resources to complete the
+ operation.
+ </rm:error>
+ <rm:error code="EC-SYSTEM">
+ An unexpected internal error occurred.
+ </rm:error>
+ </rm:errors>
+
+ </section>
+
+ <section><title>DEFINE</title>
+
+ <para>
+ DEFINE requests a definition of the specified API ID.
+ </para>
+
+ <rm:proto name="DEFINE-REQUEST">
+ <rm:data field="apiid" size="8" type="hyper">
+ API ID
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="DEFINE-RESPONSE">
+ <rm:data field="definition" size="varies" type="API-TYPE">
+ the definition of the API
+ </rm:data>
+ </rm:proto>
+
+ <rm:errors op="DEFINE">
+ <rm:error code="EC-NOTFOUND">
+ <literal>apiid</literal> isn't a known
+ <acronym>API</acronym> ID.
+ </rm:error>
+ <rm:error code="EC-NOMEM">
+ The server had insufficient resources to complete the
+ operation.
+ </rm:error>
+ <rm:error code="EC-SYSTEM">
+ An unexpected internal error occurred.
+ </rm:error>
+ </rm:errors>
+
+ </section>
+
+ <section><title>LIST</title>
+
+ <para>
+ LIST requests an enumeration of all objects present in the server
+ that match the specified object name pattern. The empty string
+ matches all server objects.
+ </para>
+
+ <rm:proto name="LIST-REQUEST">
+ <rm:data field="pattern" size="varies" type="NAME-DATA">
+ object name pattern
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="LIST-RESPONSE">
+ <rm:data field="names" size="varies" type="NAME-DATA<>">
+ the definition of the API
+ </rm:data>
+ </rm:proto>
+
+ <rm:errors op="LIST">
+ <rm:error code="EC-NOMEM">
+ The server had insufficient resources to complete the
+ operation.
+ </rm:error>
+ <rm:error code="EC-SYSTEM">
+ An unexpected internal error occurred.
+ </rm:error>
+ </rm:errors>
+
+ </section>
+
+ <section><title>SUB and UNSUB</title>
+
+ <para>
+ SUB and UNSUB subscribe and unsubscribe, respectively, to the named
+ event of the specified object. The response payload for a
+ successful SUB or UNSUB is empty.
+ </para>
+
+ <para>
+ Note that it is possible to receive an <literal>EVENT</literal>
+ that has been UNSUBed after a successful UNSUB.
+ </para>
+
+ <rm:proto name="SUB-REQUEST">
+ <rm:data field="objectid" size="8" type="hyper">
+ ID of the object
+ </rm:data>
+ <rm:data field="event" size="varies" type="string<>">
+ event name
+ </rm:data>
+ </rm:proto>
+
+ <rm:proto name="UNSUB-RESPONSE">
+ <rm:data field="objectid" size="8" type="hyper">
+ ID of the object
+ </rm:data>
+ <rm:data field="event" size="varies" type="string<>">
+ event name
+ </rm:data>
+ </rm:proto>
+
+ <rm:errors op="SUB">
+ <rm:error code="EC-NOTFOUND">
+ <literal>objectid</literal> isn't a known object id, or the
+ object doesn't have the event <literal>event</literal>.
+ </rm:error>
+ <rm:error code="EC-EXISTS">
+ The client is already subscribed to <literal>event</literal>.
+ </rm:error>
+ <rm:error code="EC-NOMEM">
+ The server had insufficient resources to complete the
+ operation.
+ </rm:error>
+ <rm:error code="EC-SYSTEM">
+ An unexpected internal error occurred.
+ </rm:error>
+ </rm:errors>
+
+ <rm:errors op="UNSUB">
+ <rm:error code="EC-NOTFOUND">
+ <literal>objectid</literal> isn't a known object id, the
+ object doesn't have the event <literal>event</literal>, or
+ the client isn't subscribed to <literal>event</literal>.
+ </rm:error>
+ <rm:error code="EC-NOMEM">
+ The server had insufficient resources to complete the
+ operation.
+ </rm:error>
+ <rm:error code="EC-SYSTEM">
+ An unexpected internal error occurred.
+ </rm:error>
+ </rm:errors>
+
+ </section>
+
+</section>
+
+</appendix>
--- a/usr/src/doc/rad-dev/b-references.xml Mon Aug 01 14:12:59 2011 -0700
+++ b/usr/src/doc/rad-dev/b-references.xml Wed Aug 03 13:07:44 2011 -0700
@@ -1,19 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE bibliography PUBLIC "-//OASIS//DTD DocBook V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<!--
- PDL HEADER START
+ PDL HEADER START
- Public Documentation License Notice
+ Public Documentation License Notice
- The contents of this Documentation are subject to the Public
- Documentation License Version 1.01 (the "License"); you may only
- use this Documentation if you comply with the terms of this License.
- A copy of the License is available at
- http://www.opensolaris.org/os/community/documentation/license.
+ The contents of this Documentation are subject to the Public
+ Documentation License Version 1.01 (the "License"); you may only
+ use this Documentation if you comply with the terms of this License.
+ A copy of the License is available at
+ http://www.opensolaris.org/os/community/documentation/license.
- PDL HEADER END
+ PDL HEADER END
- Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
-->
<bibliography><title>References</title>
@@ -29,6 +29,19 @@
</biblioentry>
<biblioentry>
+<abbrev>RPC</abbrev>
+<copyright>
+ <year>1995</year>
+ <holder>The Internet Society</holder>
+</copyright>
+<editor>
+ <personname><firstname>R.</firstname><surname>Srinivasan</surname></personname>
+</editor>
+<title>RFC 1831</title>
+<subtitle>RPC: Remote Procedure Call Protocol Specification Version 2</subtitle>
+</biblioentry>
+
+<biblioentry>
<abbrev>XDR</abbrev>
<copyright>
<year>2006</year>
--- a/usr/src/doc/rad-dev/c-concepts-data.xml Mon Aug 01 14:12:59 2011 -0700
+++ b/usr/src/doc/rad-dev/c-concepts-data.xml Wed Aug 03 13:07:44 2011 -0700
@@ -189,14 +189,15 @@
<para>
In some situations, data may be declared as optional. Optional
data is nullable, that is it can take on a "non-value" (e.g.
- <symbol>NULL</symbol> in C, or <symbol>null</symbol> in Java).
- Inversely, non-optional data cannot be NULL. Only data of type
- <type>opaque</type>, <type>string</type>, <type>password</type>,
- <type>array</type>, or <type>structure</type> may be declared
- optional. Additionally, only <type>structure</type> fields and
- certain API (see below) types can be optional. Specifically,
- <type>array</type> data cannot be optional (the <type>array</type>
- type is actually more like a list than an array).
+ <literal>NULL</literal> in C, or <literal>null</literal> in Java).
+ Inversely, non-optional data cannot be <literal>NULL</literal>.
+ Only data of type <type>opaque</type>, <type>string</type>,
+ <type>password</type>, <type>array</type>, or
+ <type>structure</type> may be declared optional. Additionally,
+ only <type>structure</type> fields and certain API (see below)
+ types can be optional. Specifically, <type>array</type> data
+ cannot be optional (the <type>array</type> type is actually more
+ like a list than an array).
</para>
<para>
--- a/usr/src/doc/rad-dev/c-concepts-namespace.xml Mon Aug 01 14:12:59 2011 -0700
+++ b/usr/src/doc/rad-dev/c-concepts-namespace.xml Wed Aug 03 13:07:44 2011 -0700
@@ -1,19 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<!--
- PDL HEADER START
+ PDL HEADER START
- Public Documentation License Notice
+ Public Documentation License Notice
- The contents of this Documentation are subject to the Public
- Documentation License Version 1.01 (the "License"); you may only
- use this Documentation if you comply with the terms of this License.
- A copy of the License is available at
- http://www.opensolaris.org/os/community/documentation/license.
+ The contents of this Documentation are subject to the Public
+ Documentation License Version 1.01 (the "License"); you may only
+ use this Documentation if you comply with the terms of this License.
+ A copy of the License is available at
+ http://www.opensolaris.org/os/community/documentation/license.
- PDL HEADER END
+ PDL HEADER END
- Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
-->
<section><title>The <command>rad</command> Namespace</title>
@@ -173,11 +173,12 @@
<note>
<para>
- Though all the <command>rad</command> clients support an
- inconsistency in behavior between <literal>LIST</literal> and
- <literal>DESCRIBE</literal>, the <command>rad</command> server
- doesn't yet support publishing objects that aren't enumerated by
- <literal>LIST</literal>.
+ These operations represent the most basic set of operations one
+ needs to discuss communication with a <command>rad</command>
+ server. For efficiency, the <literal>rad</literal> protocol
+ further divides <literal>DESCRIBE</literal> into separate
+ <literal>LOOKUP</literal> and <literal>DEFINE</literal>
+ operations.
</para>
</note>
</section>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/doc/rad-dev/macros.xsl Wed Aug 03 13:07:44 2011 -0700
@@ -0,0 +1,118 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:rm="rad-macros">
+
+ <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ omit-xml-declaration="no"
+ doctype-public="-//OASIS//DTD DocBook V4.4//EN"
+ doctype-system="http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"
+ />
+
+ <!-- By default, pass everything through -->
+
+ <xsl:template match="node()|@*">
+ <xsl:copy>
+ <xsl:apply-templates select="node()|@*" />
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'" />
+ <xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
+
+ <!-- Creates a list of errors -->
+
+ <xsl:template match="rm:errors">
+ <para>
+ <xsl:value-of select="@op" />
+ <xsl:text> can fail for the following reasons:</xsl:text>
+ </para>
+ <variablelist>
+ <xsl:apply-templates select="rm:error" />
+ </variablelist>
+ </xsl:template>
+
+ <xsl:template match="rm:error">
+ <varlistentry>
+ <term><literal><xsl:value-of select="@code" /></literal></term>
+ <listitem><para><xsl:apply-templates /></para></listitem>
+ </varlistentry>
+ </xsl:template>
+
+ <!-- Creates a list of constants -->
+
+ <xsl:template match="rm:codedef">
+ <para><xsl:value-of select="@label" /><xsl:text> code:</xsl:text>
+ <variablelist spacing="compact">
+ <xsl:apply-templates select="rm:code" />
+ </variablelist></para>
+ </xsl:template>
+
+ <xsl:template match="rm:code">
+ <varlistentry>
+ <term><xsl:value-of select="@num" /></term>
+ <listitem><literal>
+ <xsl:value-of select="translate(../@prefix, $lower, $upper)"/>
+ <xsl:text>-</xsl:text>
+ <xsl:value-of select="translate(@name, $lower, $upper)" />
+ </literal></listitem>
+ </varlistentry>
+ </xsl:template>
+
+ <!-- Creates a table out of a simple protocol definition -->
+
+ <xsl:template match="rm:proto">
+ <table><title><xsl:value-of select="@name" /></title>
+ <tgroup cols='4'>
+ <colspec colnum="1" colwidth="2*" />
+ <colspec colnum="2" colwidth="1*" />
+ <colspec colnum="3" colwidth="2*" />
+ <colspec colnum="4" colwidth="4*" />
+ <thead>
+ <row>
+ <entry>Field Name</entry>
+ <entry>Length</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <xsl:apply-templates select="rm:data" />
+ </tbody>
+ </tgroup>
+ </table>
+ </xsl:template>
+
+ <xsl:template match="rm:data">
+ <row>
+ <entry><literal><xsl:value-of select="@field" /></literal></entry>
+ <entry><xsl:value-of select="@size" /></entry>
+ <entry><literal><xsl:value-of select="@type" /></literal></entry>
+ <entry><xsl:apply-templates /></entry>
+ </row>
+ </xsl:template>
+
+</xsl:stylesheet>
+
--- a/usr/src/doc/rad-dev/rad-devguide.xml Mon Aug 01 14:12:59 2011 -0700
+++ b/usr/src/doc/rad-dev/rad-devguide.xml Wed Aug 03 13:07:44 2011 -0700
@@ -1,19 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<!--
- PDL HEADER START
+ PDL HEADER START
- Public Documentation License Notice
+ Public Documentation License Notice
- The contents of this Documentation are subject to the Public
- Documentation License Version 1.01 (the "License"); you may only
- use this Documentation if you comply with the terms of this License.
- A copy of the License is available at
- http://www.opensolaris.org/os/community/documentation/license.
+ The contents of this Documentation are subject to the Public
+ Documentation License Version 1.01 (the "License"); you may only
+ use this Documentation if you comply with the terms of this License.
+ A copy of the License is available at
+ http://www.opensolaris.org/os/community/documentation/license.
- PDL HEADER END
+ PDL HEADER END
- Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
-->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
@@ -31,5 +31,7 @@
<xi:include href="a-logistics.xml" />
+ <xi:include href="a-protocol-proc.xml" />
+
<xi:include href="b-references.xml" />
</book>
--- a/usr/src/lib/libradproto/common/protocol.x Mon Aug 01 14:12:59 2011 -0700
+++ b/usr/src/lib/libradproto/common/protocol.x Wed Aug 03 13:07:44 2011 -0700
@@ -69,7 +69,7 @@
};
struct resp_invoke {
- argument *result;
+ argument result;
};