svn commit: r44964 - head/en_US.ISO8859-1/articles/geom-class

Benedict Reuschling bcr at FreeBSD.org
Mon May 26 19:01:20 UTC 2014


Author: bcr
Date: Mon May 26 19:01:20 2014
New Revision: 44964
URL: http://svnweb.freebsd.org/changeset/doc/44964

Log:
  Big whitespace cleanup, so that igor does not complain anymore.
  Translators, you can ignore this.

Modified:
  head/en_US.ISO8859-1/articles/geom-class/article.xml

Modified: head/en_US.ISO8859-1/articles/geom-class/article.xml
==============================================================================
--- head/en_US.ISO8859-1/articles/geom-class/article.xml	Mon May 26 18:28:36 2014	(r44963)
+++ head/en_US.ISO8859-1/articles/geom-class/article.xml	Mon May 26 19:01:20 2014	(r44964)
@@ -1,15 +1,24 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
 	"http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd">
-<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en">
-  
-  <info><title>Writing a GEOM Class</title>
+<article xmlns="http://docbook.org/ns/docbook"
+  xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
+  xml:lang="en">
+  <info>
+    <title>Writing a GEOM Class</title>
 
     <authorgroup>
-      <author><personname><firstname>Ivan</firstname><surname>Voras</surname></personname><affiliation>
-          <address><email>ivoras at FreeBSD.org</email>
-          </address>
-        </affiliation></author>
+      <author>
+	<personname>
+	  <firstname>Ivan</firstname>
+	  <surname>Voras</surname>
+	</personname>
+	<affiliation>
+	  <address>
+	    <email>ivoras at FreeBSD.org</email>
+	  </address>
+	</affiliation>
+      </author>
     </authorgroup>
 
     <legalnotice xml:id="trademarks" role="trademarks">
@@ -23,65 +32,83 @@
     <releaseinfo>$FreeBSD$</releaseinfo>
 
     <abstract>
-
       <para>This text documents some starting points in developing
-      GEOM classes, and kernel modules in general. It is assumed
-      that the reader is familiar with C userland programming.</para>
-
+	GEOM classes, and kernel modules in general.  It is assumed
+	that the reader is familiar with C userland
+	programming.</para>
     </abstract>
-
   </info>
 
 <!-- Introduction -->
-<sect1 xml:id="intro">
-  <title>Introduction</title>
-
-  <sect2 xml:id="intro-docs">
-    <title>Documentation</title>
+  <sect1 xml:id="intro">
+    <title>Introduction</title>
 
-    <para>Documentation on kernel programming is scarce — it is one of
-      few areas where there is nearly nothing in the way of friendly
-      tutorials, and the phrase <quote>use the source!</quote> really
-      holds true. However, there are some bits and pieces (some of
-      them seriously outdated) floating around that should be studied
-      before beginning to code:</para>
-
-    <itemizedlist>
-
-      <listitem><para>The <link xlink:href="&url.books.developers-handbook;/index.html">FreeBSD
-        Developer's Handbook</link> — part of the documentation
-        project, it does not contain anything specific to kernel
-        programming, but rather some general useful information.</para></listitem>
-
-      <listitem><para>The <link xlink:href="&url.books.arch-handbook;/index.html">FreeBSD
-        Architecture Handbook</link> — also from the documentation
-        project, contains descriptions of several low-level facilities
-        and procedures.  The most important chapter is 13, <link xlink:href="&url.books.arch-handbook;/driverbasics.html">Writing
-        FreeBSD device drivers</link>.</para></listitem>
-
-      <listitem><para>The Blueprints section of <link xlink:href="http://www.freebsddiary.org">FreeBSD Diary</link> web
-        site — contains several interesting articles on kernel
-        facilities.</para></listitem>
-
-      <listitem><para>The man pages in section 9 — for important
-        documentation on kernel functions.</para></listitem>
-
-      <listitem><para>The &man.geom.4; man page and <link xlink:href="http://phk.freebsd.dk/pubs/">PHK's GEOM slides</link>
-        — for general introduction of the GEOM
-        subsystem.</para></listitem>
-
-      <listitem><para>Man pages &man.g.bio.9;, &man.g.event.9;, &man.g.data.9;,
-        &man.g.geom.9;, &man.g.provider.9; &man.g.consumer.9;, &man.g.access.9;
-        & others linked from those, for documentation on specific
-        functionalities.
-      </para></listitem>
-
-      <listitem><para>The &man.style.9; man page — for documentation on
-        the coding-style conventions which must be followed for any code
-        which is to be committed to the FreeBSD Subversion tree.</para></listitem>
-
-    </itemizedlist>
+    <sect2 xml:id="intro-docs">
+      <title>Documentation</title>
 
+      <para>Documentation on kernel programming is scarce — it
+	is one of few areas where there is nearly nothing in the way
+	of friendly tutorials, and the phrase <quote>use the
+	  source!</quote> really holds true.  However, there are some
+	bits and pieces (some of them seriously outdated) floating
+	around that should be studied before beginning to code:</para>
+
+      <itemizedlist>
+	<listitem>
+	  <para>The <link
+	      xlink:href="&url.books.developers-handbook;/index.html">FreeBSD
+	      Developer's Handbook</link> — part of the
+	    documentation project, it does not contain anything
+	    specific to kernel programming, but rather some general
+	    useful information.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The <link
+	      xlink:href="&url.books.arch-handbook;/index.html">FreeBSD
+	      Architecture Handbook</link> — also from the
+	    documentation project, contains descriptions of several
+	    low-level facilities and procedures.  The most important
+	    chapter is 13, <link
+	      xlink:href="&url.books.arch-handbook;/driverbasics.html">Writing
+	      FreeBSD device drivers</link>.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The Blueprints section of <link
+	      xlink:href="http://www.freebsddiary.org">FreeBSD
+	      Diary</link> web site — contains several
+	    interesting articles on kernel
+	    facilities.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The man pages in section 9 — for important
+	    documentation on kernel functions.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The &man.geom.4; man page and <link
+	      xlink:href="http://phk.freebsd.dk/pubs/">PHK's GEOM
+	      slides</link> — for general introduction of the
+	    GEOM subsystem.</para>
+	</listitem>
+
+	<listitem>
+	  <para>Man pages &man.g.bio.9;, &man.g.event.9;,
+	    &man.g.data.9;, &man.g.geom.9;, &man.g.provider.9;
+	    &man.g.consumer.9;, &man.g.access.9; & others linked
+	    from those, for documentation on specific
+	    functionalities.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The &man.style.9; man page — for documentation
+	    on the coding-style conventions which must be followed for
+	    any code which is to be committed to the FreeBSD
+	    Subversion tree.</para>
+	</listitem>
+      </itemizedlist>
     </sect2>
   </sect1>
 
@@ -89,75 +116,77 @@
     <title>Preliminaries</title>
 
     <para>The best way to do kernel development is to have (at least)
-      two separate computers. One of these would contain the
+      two separate computers.  One of these would contain the
       development environment and sources, and the other would be used
       to test the newly written code by network-booting and
       network-mounting filesystems from the first one.  This way if
       the new code contains bugs and crashes the machine, it will not
-      mess up the sources (and other <quote>live</quote> data). The
-      second system does not even require a proper display.  Instead, it
-      could be connected with a serial cable or KVM to the first
+      mess up the sources (and other <quote>live</quote> data).  The
+      second system does not even require a proper display.  Instead,
+      it could be connected with a serial cable or KVM to the first
       one.</para>
 
-    <para>But, since not everybody has two or more computers handy, there are
-      a few things that can be done to prepare an otherwise <quote>live</quote>
-      system for developing kernel code. This setup is also applicable
-      for developing in a <link xlink:href="http://www.vmware.com/">VMWare</link>
-      or <link xlink:href="http://www.qemu.org/">QEmu</link> virtual machine (the
-      next best thing after a dedicated development machine).</para>
+    <para>But, since not everybody has two or more computers handy,
+      there are a few things that can be done to prepare an otherwise
+      <quote>live</quote> system for developing kernel code.  This
+      setup is also applicable for developing in a <link
+	xlink:href="http://www.vmware.com/">VMWare</link> or <link
+	xlink:href="http://www.qemu.org/">QEmu</link> virtual machine
+      (the next best thing after a dedicated development
+      machine).</para>
 
     <sect2 xml:id="prelim-system">
       <title>Modifying a System for Development</title>
 
       <para>For any kernel programming a kernel with
-        <option>INVARIANTS</option> enabled is a must-have. So enter
-        these in your kernel configuration file:</para>
+	<option>INVARIANTS</option> enabled is a must-have.  So enter
+	these in your kernel configuration file:</para>
 
-       <programlisting>options INVARIANT_SUPPORT
+      <programlisting>options INVARIANT_SUPPORT
 options INVARIANTS</programlisting>
 
-      <para>For more debugging you should also include WITNESS support,
-        which will alert you of mistakes in locking:</para>
+      <para>For more debugging you should also include WITNESS
+	support, which will alert you of mistakes in locking:</para>
 
-       <programlisting>options WITNESS_SUPPORT
+      <programlisting>options WITNESS_SUPPORT
 options WITNESS</programlisting>
 
       <para>For debugging crash dumps, a kernel with debug symbols is
-        needed:</para>
+	needed:</para>
 
       <programlisting>  makeoptions    DEBUG=-g</programlisting>
 
       <para>With the usual way of installing the kernel (<command>make
-        installkernel</command>) the debug kernel will not be
-        automatically installed. It is called
-        <filename>kernel.debug</filename> and located in
-        <filename>/usr/obj/usr/src/sys/KERNELNAME/</filename>.  For
-        convenience it should be copied to
-        <filename>/boot/kernel/</filename>.</para>
+	  installkernel</command>) the debug kernel will not be
+	automatically installed.  It is called
+	<filename>kernel.debug</filename> and located in
+	<filename>/usr/obj/usr/src/sys/KERNELNAME/</filename>.  For
+	convenience it should be copied to
+	<filename>/boot/kernel/</filename>.</para>
 
       <para>Another convenience is enabling the kernel debugger so you
-        can examine a kernel panic when it happens. For this, enter
-        the following lines in your kernel configuration file:</para>
+	can examine a kernel panic when it happens.  For this, enter
+	the following lines in your kernel configuration file:</para>
 
       <programlisting>options KDB
 options DDB
 options KDB_TRACE</programlisting>
 
       <para>For this to work you might need to set a sysctl (if it is
-        not on by default):</para>
+	not on by default):</para>
 
       <programlisting>  debug.debugger_on_panic=1</programlisting>
 
       <para>Kernel panics will happen, so care should be taken with
-        the filesystem cache. In particular, having softupdates might
-        mean the latest file version could be lost if a panic occurs
-        before it is committed to storage.  Disabling softupdates
-        yields a great performance hit, and still does not guarantee
-        data consistency.  Mounting filesystem with the <quote>sync</quote> option
-        is needed for that.  For a compromise, the softupdates cache delays can
-        be shortened. There are three sysctl's that are useful for
-        this (best to be set in
-        <filename>/etc/sysctl.conf</filename>):</para>
+	the filesystem cache.  In particular, having softupdates might
+	mean the latest file version could be lost if a panic occurs
+	before it is committed to storage.  Disabling softupdates
+	yields a great performance hit, and still does not guarantee
+	data consistency.  Mounting filesystem with the
+	<quote>sync</quote> option is needed for that.  For a
+	compromise, the softupdates cache delays can be shortened.
+	There are three sysctl's that are useful for this (best to be
+	set in <filename>/etc/sysctl.conf</filename>):</para>
 
       <programlisting>kern.filedelay=5
 kern.dirdelay=4
@@ -166,76 +195,79 @@ kern.metadelay=3</programlisting>
       <para>The numbers represent seconds.</para>
 
       <para>For debugging kernel panics, kernel core dumps are
-        required. Since a kernel panic might make filesystems
-        unusable, this crash dump is first written to a raw
-        partition. Usually, this is the swap partition.  This partition must be at
-        least as large as the physical RAM in the machine. On the
-        next boot, the dump is copied to a regular file.
-        This happens after filesystems are checked and mounted, and
-        before swap is enabled.  This is controlled with two
-        <filename>/etc/rc.conf</filename> variables:</para>
+	required.  Since a kernel panic might make filesystems
+	unusable, this crash dump is first written to a raw partition.
+	Usually, this is the swap partition.  This partition must be
+	at least as large as the physical RAM in the machine.  On the
+	next boot, the dump is copied to a regular file.  This happens
+	after filesystems are checked and mounted, and before swap is
+	enabled.  This is controlled with two
+	<filename>/etc/rc.conf</filename> variables:</para>
 
       <programlisting>dumpdev="/dev/ad0s4b"
 dumpdir="/usr/core </programlisting>
 
       <para>The <varname>dumpdev</varname> variable specifies the swap
-        partition and <varname>dumpdir</varname> tells the system
-        where in the filesystem to relocate the core dump on reboot.</para>
+	partition and <varname>dumpdir</varname> tells the system
+	where in the filesystem to relocate the core dump on
+	reboot.</para>
 
       <para>Writing kernel core dumps is slow and takes a long time so
-        if you have lots of memory (>256M) and lots of panics it could
-        be frustrating to sit and wait while it is done (twice — first
-        to write it to swap, then to relocate it to filesystem). It is
-        convenient then to limit the amount of RAM the system will use
-        via a <filename>/boot/loader.conf</filename> tunable:</para>
+	if you have lots of memory (>256M) and lots of panics it
+	could be frustrating to sit and wait while it is done (twice
+	— first to write it to swap, then to relocate it to
+	filesystem).  It is convenient then to limit the amount of RAM
+	the system will use via a
+	<filename>/boot/loader.conf</filename> tunable:</para>
 
       <programlisting>  hw.physmem="256M"</programlisting>
 
       <para>If the panics are frequent and filesystems large (or you
-        simply do not trust softupdates+background fsck) it is advisable
-        to turn background fsck off via
-        <filename>/etc/rc.conf</filename> variable:</para>
+	simply do not trust softupdates+background fsck) it is
+	advisable to turn background fsck off via
+	<filename>/etc/rc.conf</filename> variable:</para>
 
       <programlisting>  background_fsck="NO"</programlisting>
 
       <para>This way, the filesystems will always get checked when
-        needed.  Note that with background fsck, a new panic could happen while
-        it is checking the disks. Again, the safest way is not to have
-        many local filesystems by using another computer as an NFS
-        server.</para>
+	needed.  Note that with background fsck, a new panic could
+	happen while it is checking the disks.  Again, the safest way
+	is not to have many local filesystems by using another
+	computer as an NFS server.</para>
     </sect2>
 
     <sect2 xml:id="prelim-starting">
       <title>Starting the Project</title>
 
       <para>For the purpose of creating a new GEOM class, an empty
-        subdirectory has to be created under an arbitrary user-accessible
-        directory. You do not have to create the module directory under
-        <filename>/usr/src</filename>.</para>
+	subdirectory has to be created under an arbitrary
+	user-accessible directory.  You do not have to create the
+	module directory under <filename>/usr/src</filename>.</para>
     </sect2>
 
     <sect2 xml:id="prelim-makefile">
       <title>The Makefile</title>
 
       <para>It is good practice to create
-        <filename>Makefile</filename>s for every nontrivial coding
-        project, which of course includes kernel modules.</para>
+	<filename>Makefile</filename>s for every nontrivial coding
+	project, which of course includes kernel modules.</para>
 
       <para>Creating the <filename>Makefile</filename> is simple
-        thanks to an extensive set of helper routines provided by the
-        system. In short, here is how a minimal <filename>Makefile</filename>
-        looks for a kernel module:</para>
+	thanks to an extensive set of helper routines provided by the
+	system.  In short, here is how a minimal
+	<filename>Makefile</filename> looks for a kernel
+	module:</para>
 
       <programlisting>SRCS=g_journal.c
 KMOD=geom_journal
 
 .include <bsd.kmod.mk></programlisting>
 
-      <para>This <filename>Makefile</filename> (with changed filenames)
-        will do for any kernel module, and a GEOM class can reside in just
-        one kernel module. If more than one file is required, list it in the
-        <envar>SRCS</envar> variable, separated with whitespace from
-        other filenames.</para>
+      <para>This <filename>Makefile</filename> (with changed
+	filenames) will do for any kernel module, and a GEOM class can
+	reside in just one kernel module.  If more than one file is
+	required, list it in the <envar>SRCS</envar> variable,
+	separated with whitespace from other filenames.</para>
     </sect2>
   </sect1>
 
@@ -245,76 +277,77 @@ KMOD=geom_journal
     <sect2 xml:id="kernelprog-memalloc">
       <title>Memory Allocation</title>
 
-      <para>See &man.malloc.9;. Basic memory allocation is only
-        slightly different than its userland equivalent. Most
-        notably, <function>malloc</function>() and
-        <function>free</function>() accept additional parameters as is
-        described in the man page.</para>
+      <para>See &man.malloc.9;.  Basic memory allocation is only
+	slightly different than its userland equivalent.  Most
+	notably, <function>malloc</function>() and
+	<function>free</function>() accept additional parameters as is
+	described in the man page.</para>
 
       <para>A <quote>malloc type</quote> must be declared in the
-        declaration section of a source file, like this:</para>
+	declaration section of a source file, like this:</para>
 
       <programlisting>  static MALLOC_DEFINE(M_GJOURNAL, "gjournal data", "GEOM_JOURNAL Data");</programlisting>
 
       <para>To use this macro, <filename>sys/param.h</filename>,
-        <filename>sys/kernel.h</filename> and
-        <filename>sys/malloc.h</filename> headers must be
-        included.</para>
+	<filename>sys/kernel.h</filename> and
+	<filename>sys/malloc.h</filename> headers must be
+	included.</para>
 
       <para>There is another mechanism for allocating memory, the UMA
-        (Universal Memory Allocator). See &man.uma.9; for details, but
-        it is a special type of allocator mainly used for speedy
-        allocation of lists comprised of same-sized items (for
-        example, dynamic arrays of structs).</para>
+	(Universal Memory Allocator).  See &man.uma.9; for details,
+	but it is a special type of allocator mainly used for speedy
+	allocation of lists comprised of same-sized items (for
+	example, dynamic arrays of structs).</para>
     </sect2>
 
     <sect2 xml:id="kernelprog-lists">
       <title>Lists and Queues</title>
 
-      <para>See &man.queue.3;. There are a LOT of cases when a list of
-        things needs to be maintained. Fortunately, this data
-        structure is implemented (in several ways) by C macros
-        included in the system. The most used list type is TAILQ
-        because it is the most flexible. It is also the one with largest
-        memory requirements (its elements are doubly-linked) and
-        also the slowest (although the speed variation is on
-        the order of several CPU instructions more, so it should not be
-        taken seriously).</para>
+      <para>See &man.queue.3;.  There are a LOT of cases when a list
+	of things needs to be maintained.  Fortunately, this data
+	structure is implemented (in several ways) by C macros
+	included in the system.  The most used list type is TAILQ
+	because it is the most flexible.  It is also the one with
+	largest memory requirements (its elements are doubly-linked)
+	and also the slowest (although the speed variation is on the
+	order of several CPU instructions more, so it should not be
+	taken seriously).</para>
 
       <para>If data retrieval speed is very important, see
-        &man.tree.3; and &man.hashinit.9;.</para>
+	&man.tree.3; and &man.hashinit.9;.</para>
     </sect2>
 
     <sect2 xml:id="kernelprog-bios">
       <title>BIOs</title>
 
-      <para>Structure <varname remap="structname">bio</varname> is used for any and
-        all Input/Output operations concerning GEOM. It basically
-        contains information about what device ('provider') should
-        satisfy the request, request type, offset, length, pointer to
-        a buffer, and a bunch of <quote>user-specific</quote> flags
-        and fields that can help implement various hacks.</para>
-
-      <para>The important thing here is that <varname remap="structname">bio</varname>s
-        are handled asynchronously. That means that, in most parts of the code,
-        there is no analogue to userland's &man.read.2; and
-        &man.write.2; calls that do not return until a request is
-        done. Rather, a developer-supplied function is called as a
-        notification when the request gets completed (or results in
-        error).</para>
-
-      <para>The asynchronous programming model (also
-        called <quote>event-driven</quote>) is somewhat harder
-        than the much more used imperative one used in userland
-        (at least it takes a
-        while to get used to it). In some cases the helper routines
-        <function>g_write_data</function>() and
-        <function>g_read_data</function>() can be used, but <emphasis>not
-        always</emphasis>. In particular, they cannot be used when
-        a mutex is held; for example, the GEOM topology mutex or
-        the internal mutex held during the <function>.start</function>() and
-        <function>.stop</function>() functions.</para>
-
+      <para>Structure <varname remap="structname">bio</varname> is
+	used for any and all Input/Output operations concerning GEOM.
+	It basically contains information about what device
+	('provider') should satisfy the request, request type, offset,
+	length, pointer to a buffer, and a bunch of
+	<quote>user-specific</quote> flags and fields that can help
+	implement various hacks.</para>
+
+      <para>The important thing here is that <varname
+	  remap="structname">bio</varname>s are handled
+	asynchronously.  That means that, in most parts of the code,
+	there is no analogue to userland's &man.read.2; and
+	&man.write.2; calls that do not return until a request is
+	done.  Rather, a developer-supplied function is called as a
+	notification when the request gets completed (or results in
+	error).</para>
+
+      <para>The asynchronous programming model (also called
+	<quote>event-driven</quote>) is somewhat harder than the much
+	more used imperative one used in userland (at least it takes a
+	while to get used to it).  In some cases the helper routines
+	<function>g_write_data</function>() and
+	<function>g_read_data</function>() can be used, but
+	<emphasis>not always</emphasis>.  In particular, they cannot
+	be used when a mutex is held; for example, the GEOM topology
+	mutex or the internal mutex held during the
+	<function>.start</function>() and <function>.stop</function>()
+	functions.</para>
     </sect2>
   </sect1>
 
@@ -325,109 +358,131 @@ KMOD=geom_journal
       <title>Ggate</title>
 
       <para>If maximum performance is not needed, a much simpler way
-        of making a data transformation is to implement it in userland
-        via the ggate (GEOM gate) facility. Unfortunately, there is no
-        easy way to convert between, or even share code between the
-        two approaches.</para>
+	of making a data transformation is to implement it in userland
+	via the ggate (GEOM gate) facility.  Unfortunately, there is
+	no easy way to convert between, or even share code between the
+	two approaches.</para>
     </sect2>
 
     <sect2 xml:id="geom-class">
       <title>GEOM Class</title>
 
-      <para>GEOM classes are transformations on the data. These transformations
-        can be combined in a tree-like fashion. Instances of GEOM classes are
-        called <emphasis>geoms</emphasis>.</para>
-
-      <para>Each GEOM class has several <quote>class methods</quote> that get called
-        when there is no geom instance available (or they are simply not
-        bound to a single instance):</para>
-
-      <itemizedlist>
-
-        <listitem><para><function>.init</function> is called when GEOM
-          becomes aware of a GEOM class (when the kernel module
-          gets loaded.)</para></listitem>
-
-        <listitem><para><function>.fini</function> gets called when GEOM
-          abandons the class (when the module gets
-          unloaded)</para></listitem>
-
-        <listitem><para><function>.taste</function> is called next, once for
-          each provider the system has available.  If applicable, this
-          function will usually create and start a geom
-          instance.</para></listitem>
-
-        <listitem><para><function>.destroy_geom</function> is called when
-          the geom should be disbanded</para></listitem>
-
-        <listitem><para><function>.ctlconf</function> is called when user
-          requests reconfiguration of existing geom</para></listitem>
-
+      <para>GEOM classes are transformations on the data.  These
+	transformations can be combined in a tree-like fashion.
+	Instances of GEOM classes are called
+	<emphasis>geoms</emphasis>.</para>
+
+      <para>Each GEOM class has several <quote>class methods</quote>
+	that get called when there is no geom instance available (or
+	they are simply not bound to a single instance):</para>
+
+      <itemizedlist>
+	<listitem>
+	  <para><function>.init</function> is called when GEOM becomes
+	    aware of a GEOM class (when the kernel module gets
+	    loaded.)</para>
+	</listitem>
+
+	<listitem>
+	  <para><function>.fini</function> gets called when GEOM
+	    abandons the class (when the module gets
+	    unloaded)</para>
+	</listitem>
+
+	<listitem>
+	  <para><function>.taste</function> is called next, once for
+	    each provider the system has available.  If applicable,
+	    this function will usually create and start a geom
+	    instance.</para>
+	</listitem>
+
+	<listitem>
+	  <para><function>.destroy_geom</function> is called when the
+	    geom should be disbanded</para>
+	</listitem>
+
+	<listitem>
+	  <para><function>.ctlconf</function> is called when user
+	    requests reconfiguration of existing
+	    geom</para>
+	</listitem>
       </itemizedlist>
 
       <para>Also defined are the GEOM event functions, which will get
-        copied to the geom instance.</para>
+	copied to the geom instance.</para>
 
-      <para>Field <function>.geom</function> in the
-        <varname remap="structname">g_class</varname> structure is a LIST of geoms
-        instantiated from the class.</para>
-
-      <para>These functions are called from the g_event kernel thread.</para>
+      <para>Field <function>.geom</function> in the <varname
+	  remap="structname">g_class</varname> structure is a LIST of
+	geoms instantiated from the class.</para>
 
+      <para>These functions are called from the g_event kernel
+	thread.</para>
     </sect2>
 
     <sect2 xml:id="geom-softc">
       <title>Softc</title>
 
       <para>The name <quote>softc</quote> is a legacy term for
-        <quote>driver private data</quote>. The name most probably
-        comes from the archaic term <quote>software control block</quote>.
-        In GEOM, it is a structure (more precise: pointer to a
-        structure) that can be attached to a geom instance to hold
-        whatever data is private to the geom instance. Most GEOM classes
-        have the following members:</para>
-
-      <itemizedlist>
-        <listitem><para><varname>struct g_provider *provider</varname> : The
-        <quote>provider</quote> this geom instantiates</para></listitem>
-
-        <listitem><para><varname>uint16_t n_disks</varname> : Number of
-          consumer this geom consumes</para></listitem>
-
-        <listitem><para><varname>struct g_consumer **disks</varname> : Array
-          of <varname>struct g_consumer*</varname>. (It is not possible
-          to use just single indirection because struct g_consumer*
-          are created on our behalf by GEOM).</para></listitem>
-      </itemizedlist>
-
-      <para>The <varname remap="structname">softc</varname> structure contains all
-        the state of geom instance. Every geom instance has its own
-        softc.</para>
+	<quote>driver private data</quote>.  The name most probably
+	comes from the archaic term <quote>software control
+	  block</quote>.  In GEOM, it is a structure (more precise:
+	pointer to a structure) that can be attached to a geom
+	instance to hold whatever data is private to the geom
+	instance.  Most GEOM classes have the following
+	members:</para>
+
+      <itemizedlist>
+	<listitem>
+	  <para><varname>struct g_provider *provider</varname> : The
+	    <quote>provider</quote> this geom
+	    instantiates</para>
+	</listitem>
+
+	<listitem>
+	  <para><varname>uint16_t n_disks</varname> : Number of
+	    consumer this geom consumes</para>
+	</listitem>
+
+	<listitem>
+	  <para><varname>struct g_consumer **disks</varname> : Array
+	    of <varname>struct g_consumer*</varname>.  (It is not
+	    possible to use just single indirection because struct
+	    g_consumer* are created on our behalf by
+	    GEOM).</para>
+	</listitem>
+      </itemizedlist>
+
+      <para>The <varname remap="structname">softc</varname> structure
+	contains all the state of geom instance.  Every geom instance
+	has its own softc.</para>
     </sect2>
 
     <sect2 xml:id="geom-metadata">
       <title>Metadata</title>
 
       <para>Format of metadata is more-or-less class-dependent, but
-        MUST start with:</para>
+	MUST start with:</para>
 
       <itemizedlist>
+	<listitem>
+	  <para>16 byte buffer for null-terminated signature (usually
+	    the class name)</para>
+	</listitem>
 
-        <listitem><para>16 byte buffer for null-terminated signature
-          (usually the class name)</para></listitem>
-
-        <listitem><para>uint32 version ID</para></listitem>
-
+	<listitem>
+	  <para>uint32 version ID</para>
+	</listitem>
       </itemizedlist>
 
-      <para>It is assumed that geom classes know how to handle metadata
-        with version ID's lower than theirs.</para>
+      <para>It is assumed that geom classes know how to handle
+	metadata with version ID's lower than theirs.</para>
 
       <para>Metadata is located in the last sector of the provider
-        (and thus must fit in it).</para>
+	(and thus must fit in it).</para>
 
       <para>(All this is implementation-dependent but all existing
-        code works like that, and it is supported by libraries.)</para>
+	code works like that, and it is supported by
+	libraries.)</para>
     </sect2>
 
     <sect2 xml:id="geom-creating">
@@ -436,271 +491,327 @@ KMOD=geom_journal
       <para>The sequence of events is:</para>
 
       <itemizedlist>
-
-        <listitem><para>user calls &man.geom.8; utility (or one of its
-          hardlinked friends)</para></listitem>
-
-        <listitem><para>the utility figures out which geom class it is
-          supposed to handle and searches for
-          <filename>geom_<replaceable>CLASSNAME</replaceable>.so</filename>
-          library (usually in
-          <filename>/lib/geom</filename>).</para></listitem>
-
-        <listitem><para>it &man.dlopen.3;-s the library, extracts the
-          definitions of command-line parameters and helper
-          functions.</para></listitem>
-
+	<listitem>
+	  <para>user calls &man.geom.8; utility (or one of its
+	    hardlinked friends)</para>
+	</listitem>
+
+	<listitem>
+	  <para>the utility figures out which geom class it is
+	    supposed to handle and searches for
+	    <filename>geom_<replaceable>CLASSNAME</replaceable>.so</filename>
+	    library (usually in
+	    <filename>/lib/geom</filename>).</para>
+	</listitem>
+
+	<listitem>
+	  <para>it &man.dlopen.3;-s the library, extracts the
+	    definitions of command-line parameters and helper
+	    functions.</para>
+	</listitem>
       </itemizedlist>
 
       <para>In the case of creating/labeling a new geom, this is what
-      happens:</para>
+	happens:</para>
 
       <itemizedlist>
-
-        <listitem><para>&man.geom.8; looks in the command-line argument
-          for the command (usually <option>label</option>), and calls a helper
-          function.</para></listitem>
-
-        <listitem><para>The helper function checks parameters and gathers
-          metadata, which it proceeds to write to all concerned
-          providers.</para></listitem>
-
-        <listitem><para>This <quote>spoils</quote> existing geoms (if any) and
-          initializes a new round of <quote>tasting</quote> of the providers. The
-          intended geom class recognizes the metadata and brings the
-          geom up.</para></listitem>
-
+	<listitem>
+	  <para>&man.geom.8; looks in the command-line argument for
+	    the command (usually <option>label</option>), and calls a
+	    helper function.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The helper function checks parameters and gathers
+	    metadata, which it proceeds to write to all concerned
+	    providers.</para>
+	</listitem>
+
+	<listitem>
+	  <para>This <quote>spoils</quote> existing geoms (if any) and
+	    initializes a new round of <quote>tasting</quote> of the
+	    providers.  The intended geom class recognizes the
+	    metadata and brings the geom up.</para>
+	</listitem>
       </itemizedlist>
 
       <para>(The above sequence of events is implementation-dependent
-        but all existing code works like that, and it is supported by
-        libraries.)</para>
-
+	but all existing code works like that, and it is supported by
+	libraries.)</para>
     </sect2>
 
     <sect2 xml:id="geom-command">
       <title>GEOM Command Structure</title>
 
       <para>The helper <filename>geom_CLASSNAME.so</filename> library
-        exports <varname remap="structname">class_commands</varname> structure,
-        which is an array of <varname remap="structname">struct g_command</varname>
-        elements. Commands are of uniform format and look like:</para>
+	exports <varname remap="structname">class_commands</varname>
+	structure, which is an array of <varname
+	  remap="structname">struct g_command</varname> elements.
+	Commands are of uniform format and look like:</para>
 
       <programlisting>  verb [-options] geomname [other]</programlisting>
 
       <para>Common verbs are:</para>
 
       <itemizedlist>
-
-        <listitem><para>label — to write metadata to devices so they can be
-          recognized at tasting and brought up in geoms</para></listitem>
-
-        <listitem><para>destroy — to destroy metadata, so the geoms get
-          destroyed</para></listitem>
-
+	<listitem>
+	  <para>label — to write metadata to devices so they can
+	    be recognized at tasting and brought up in
+	    geoms</para>
+	</listitem>
+
+	<listitem>
+	  <para>destroy — to destroy metadata, so the geoms get
+	    destroyed</para>
+	</listitem>
       </itemizedlist>
 
       <para>Common options are:</para>
 
       <itemizedlist>
-        <listitem><para><literal>-v</literal> : be verbose</para></listitem>
-        <listitem><para><literal>-f</literal> : force</para></listitem>
+	<listitem>
+	  <para><literal>-v</literal> : be verbose</para>
+	</listitem>
+
+	<listitem>
+	  <para><literal>-f</literal> : force</para>
+	</listitem>
       </itemizedlist>
 
       <para>Many actions, such as labeling and destroying metadata can
-        be performed in userland. For this, <varname remap="structname">struct
-        g_command</varname> provides field
-        <varname>gc_func</varname> that can be set to a function (in
-        the same <filename>.so</filename>) that will be called to
-        process a verb. If <varname>gc_func</varname> is NULL, the
-        command will be passed to kernel module, to
-        <function>.ctlreq</function> function of the geom
-        class.</para>
+	be performed in userland.  For this, <varname
+	  remap="structname">struct g_command</varname> provides field
+	<varname>gc_func</varname> that can be set to a function (in
+	the same <filename>.so</filename>) that will be called to
+	process a verb.  If <varname>gc_func</varname> is NULL, the
+	command will be passed to kernel module, to
+	<function>.ctlreq</function> function of the geom
+	class.</para>
     </sect2>
 
     <sect2 xml:id="geom-geoms">
       <title>Geoms</title>
 
-      <para>Geoms are instances of GEOM classes. They have internal
-        data (a softc structure) and some functions with which they
-        respond to external events.</para>
+      <para>Geoms are instances of GEOM classes.  They have internal
+	data (a softc structure) and some functions with which they
+	respond to external events.</para>
 
       <para>The event functions are:</para>
 
       <itemizedlist>
-        <listitem><para><function>.access</function> : calculates
-        permissions (read/write/exclusive)</para></listitem>
-
-        <listitem><para><function>.dumpconf</function> : returns
-        XML-formatted information about the geom</para></listitem>
-
-        <listitem><para><function>.orphan</function> : called when some
-        underlying provider gets disconnected</para></listitem>
-
-        <listitem><para><function>.spoiled</function> : called when some
-        underlying provider gets written to</para></listitem>
-
-        <listitem><para><function>.start</function> : handles I/O</para></listitem>
-      </itemizedlist>
-
-      <para>These functions are called from the <function>g_down</function>
-        kernel thread and there can be no sleeping in this context,
-        (see definition of sleeping elsewhere) which limits what can be done
-        quite a bit, but forces the handling to be fast.</para>
+	<listitem>
+	  <para><function>.access</function> : calculates permissions
+	    (read/write/exclusive)</para>
+	</listitem>
+
+	<listitem>
+	  <para><function>.dumpconf</function> : returns XML-formatted
+	    information about the geom</para>
+	</listitem>
+
+	<listitem>
+	  <para><function>.orphan</function> : called when some
+	    underlying provider gets disconnected</para>
+	</listitem>
+
+	<listitem>
+	  <para><function>.spoiled</function> : called when some
+	    underlying provider gets written to</para>
+	</listitem>
+
+	<listitem>
+	  <para><function>.start</function> : handles I/O</para>
+	</listitem>
+      </itemizedlist>
+
+      <para>These functions are called from the
+	<function>g_down</function> kernel thread and there can be no
+	sleeping in this context, (see definition of sleeping
+	elsewhere) which limits what can be done quite a bit, but
+	forces the handling to be fast.</para>
 
       <para>Of these, the most important function for doing actual
-        useful work is the <function>.start</function>() function,
-        which is called when a BIO request arrives for a provider
-        managed by a instance of geom class.</para>
+	useful work is the <function>.start</function>() function,
+	which is called when a BIO request arrives for a provider
+	managed by a instance of geom class.</para>
     </sect2>
 
     <sect2 xml:id="geom-threads">
       <title>GEOM Threads</title>
 
       <para>There are three kernel threads created and run by the GEOM
-      framework:</para>
+	framework:</para>
 
       <itemizedlist>
-        <listitem><para><literal>g_down</literal> : Handles requests coming
-          from high-level entities (such as a userland request) on the
-          way to physical devices</para></listitem>
-
-        <listitem><para><literal>g_up</literal> : Handles responses from
-          device drivers to requests made by higher-level
-          entities</para></listitem>
-
-        <listitem><para><literal>g_event</literal> : Handles all other
-          cases: creation of geom instances, access counting, <quote>spoil</quote>
-          events, etc.</para></listitem>
+	<listitem>
+	  <para><literal>g_down</literal> : Handles requests coming
+	    from high-level entities (such as a userland request) on
+	    the way to physical devices</para>
+	</listitem>
+
+	<listitem>
+	  <para><literal>g_up</literal> : Handles responses from
+	    device drivers to requests made by higher-level
+	    entities</para>
+	</listitem>
+
+	<listitem>
+	  <para><literal>g_event</literal> : Handles all other cases:
+	    creation of geom instances, access counting,
+	    <quote>spoil</quote> events, etc.</para>
+	</listitem>
       </itemizedlist>
 
       <para>When a user process issues <quote>read data X at offset Y
-        of a file</quote> request, this is what happens:</para>
+	  of a file</quote> request, this is what happens:</para>
 
       <itemizedlist>
-

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-doc-all mailing list