The translation is temporarily closed for contributions due to maintenance, please come back later.

Source string Read only

(itstool) path: sect2/para
Context English State
Starting the Project
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>.
The Makefile
It is good practice to create <filename>Makefile</filename>s for every nontrivial coding project, which of course includes kernel modules.
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:

.include &lt;;
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.
On FreeBSD Kernel Programming
Memory Allocation
See <citerefentry><refentrytitle>malloc</refentrytitle><manvolnum>9</manvolnum></citerefentry>. 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.
A <quote>malloc type</quote> must be declared in the declaration section of a source file, like this:
static MALLOC_DEFINE(M_GJOURNAL, "gjournal data", "GEOM_JOURNAL Data");
To use this macro, <filename>sys/param.h</filename>, <filename>sys/kernel.h</filename> and <filename>sys/malloc.h</filename> headers must be included.
There is another mechanism for allocating memory, the UMA (Universal Memory Allocator). See <citerefentry><refentrytitle>uma</refentrytitle><manvolnum>9</manvolnum></citerefentry> 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).
Lists and Queues
See <citerefentry><refentrytitle>queue</refentrytitle><manvolnum>3</manvolnum></citerefentry>. 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).
If data retrieval speed is very important, see <citerefentry><refentrytitle>tree</refentrytitle><manvolnum>3</manvolnum></citerefentry> and <citerefentry><refentrytitle>hashinit</refentrytitle><manvolnum>9</manvolnum></citerefentry>.
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.
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 <citerefentry><refentrytitle>read</refentrytitle><manvolnum>2</manvolnum></citerefentry> and <citerefentry><refentrytitle>write</refentrytitle><manvolnum>2</manvolnum></citerefentry> 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).
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.
On GEOM Programming
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.
GEOM Class
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>.
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):
<function>.init</function> is called when GEOM becomes aware of a GEOM class (when the kernel module gets loaded.)
<function>.fini</function> gets called when GEOM abandons the class (when the module gets unloaded)
<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.
<function>.destroy_geom</function> is called when the geom should be disbanded


No matching activity found.

Browse all component changes

Source information

Source string comment
(itstool) path: sect2/para
Source string location
String age
a year ago
Source string age
a year ago
Translation file
articles/geom-class.pot, string 61