Sophie

Sophie

distrib > Mandriva > 8.2 > i586 > media > contrib > by-pkgid > 211238da6d926d1ca4390483bb29f586 > files > 70

coda-doc-5.2.0-4mdk.noarch.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
 <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
 <TITLE>RVM: Recoverable Virtual Memory, Release 1.3: Library Functions</TITLE>
 <LINK HREF="rvm_manual-5.html" REL=next>
 <LINK HREF="rvm_manual-3.html" REL=previous>
 <LINK HREF="rvm_manual.html#toc4" REL=contents>
</HEAD>
<BODY>
<A HREF="rvm_manual-5.html">Next</A>
<A HREF="rvm_manual-3.html">Previous</A>
<A HREF="rvm_manual.html#toc4">Contents</A>
<HR>
<H2><A NAME="s4">4. Library Functions</A></H2>

<P>
<A NAME="rvmAPI"></A> 
In this and the next two chapters, funtions of the RVM runtime library
will be briefly presented in groups, and then the actual man pages of the
functions will be presented.
<P>
<H2><A NAME="ss4.1">4.1 Initialization, Options, and Mapping Functions</A>
</H2>

<P>
<P>There are five functions for this groups:
<DL>
<DT><B>rvm_initialize</B><DD><P>Initialization of RVM runtime library
<DT><B>rvm_set_options</B><DD><P>Changes RVM options after initialization
<DT><B>rvm_terminate</B><DD><P>Clean termination of RVM runtime library
<DT><B>rvm_map</B><DD><P>Mapping all or part of data segment to virtual memory
<DT><B>rvm_unmap</B><DD><P>Ummapping previouslly mapped segment
</DL>
<P><HR>
NAME 
<H3></H3>

<P>rvm_initialize - RVM initialization
<P>
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

typedef struct
    {
    char            *log_dev;
    long            truncate;
    rvm_length_t    recovery_buf_len;
    rvm_length_t    flush_buf_len;
    rvm_length_t    max_read_len;
    rvm_length_t    flags;
    }
rvm_options_t;

rvm_return_t rvm_initialize (version, options)
rvm_return_t RVM_INIT (options)

char          *version;   /* RVM library version */
rvm_options_t *options;   /* pointer to a RVM options record */
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_initialize must be called once to initialize the RVM library, and
must be called before any other RVM function.
Without successful initialization, any call to RVM functions except
rvm_initialize
will result in the error return RVM_EINIT.
Multiple calls to rvm_initialize are ignored.
However, rvm_initialize cannot be used to restart RVM after
rvm_terminate has been called.
<P>The version parameter is used to detect version skews.
The string constant RVM_VERSION from rvm.h is passed to
rvm_initialize, and compared with 
the value from the header file the library was compiled with.
If they are different, RVM_EVERSION_SKEW is returned and RVM will
not initialize. 
<P>RVM operation option choices are specified with the options parameter.
A options record created with typedef rvm_options_t must be used.
RVM_EOPTIONS will be returned if options does not point to a valid
record.
<P>The name of the log file must be specified in the options record.
If either the name is not provided, or the file cannot be opened and
initialized, RVM_ELOG will be returned.
If options other than the log file are not specified, defaults will
be assumed.
These can be changed later with rvm_set_options.
<P>rvm.h defines a macro, RVM_INIT, with a single parameter for
the options, that calls rvm_initialize and automatically passes
RVM_VERSION.
This is the best way to initialize RVM.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<P>
<DT><B>RVM_EVERSION_SKEW</B><DD><P>RVM library version skew
<DT><B>RVM_ELOG</B><DD><P>invalid log file
<DT><B>RVM_EIO</B><DD><P>I/O or kernel error, errno has code number
<DT><B>RVM_EOPTIONS</B><DD><P>invalid RVM options record or pointer
<DT><B>RVM_ENO_MEMORY</B><DD><P>heap exhausted
<DT><B>RVM_EINIT</B><DD><P>RVM previously terminated
<DT><B>RVM_EPORTABILITY</B><DD><P>internal portability problem, see system maintainer
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_terminate (3)</CODE>, <CODE>rvm_set_options (3)</CODE>, <CODE>rvm_query (3)</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>NAME 
<H3></H3>

<P>rvm_set_options - set RVM options
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

typedef struct
    {
    char            *log_dev;
    long            truncate;
    rvm_length_t    recovery_buf_len;
    rvm_length_t    flush_buf_len;
    rvm_length_t    max_read_len;
    rvm_length_t    flags;
    }
rvm_options_t;

rvm_return_t rvm_set_options (options)

rvm_options_t    *options;    /* pointer to a options records */
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_set_options allows RVM options to be changed after
initialization.
Only the options permitted to be selected after initialization will be considered.
Others can be present, but will be ignored.
Please refer to the RVM manual for detailed descriptions of the options.
<P>If the options parameter does not point to a valid descriptor,
RVM_EOPTIONS will be returned.
<P>At present, the only options that can be changed are the following:
truncation threshold and transaction optimization levels.
If the truncation threshold is lowered and the log filled beyond the
new threshold, a truncation is initiated if one is not in progress.
If a truncation must be initiated, it will run synchronously with the
calling thread.
<P>
<P>Transaction optimization levels can be changed at any time, but the
level in effect at the beginning of a transaction remains in effect
for that transaction until it is ended.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_EOPTIONS</B><DD><P>invalid options record or pointer
<DT><B>RVM_ENO_MEMORY</B><DD><P>heap exhausted
<DT><B>RVM_ELOG</B><DD><P>invalid log file
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_map (3)</CODE>, <CODE>rvm_unmap (3)</CODE>, and <CODE>rvm_query (3)</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>NAME 
<H3></H3>

<P>rvm_terminate - terminate RVM
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

rvm_return_t rvm_terminate ()
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_terminate checks for uncommitted transactions and otherwise insures
a clean exit from RVM.
If an uncommitted transaction is found, RVM_EUNCOMMIT is returned,
and the application should call rvm_query to
discover such transactions.
If any are discovered, this is an indicator of likely program logic errors.
If there are no uncommitted transactions, the log is flushed, and all
regions unmapped.
<P>RVM cannot be reinitialized after termination.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_EUNCOMMIT</B><DD><P>uncommitted transaction(s) pending
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_initialize (3)</CODE>, and <CODE>rvm_query (3)</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>NAME 
<H3></H3>

<P>rvm_map - map segment region
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

typedef struct
    {
    char            *data_dev;
    rvm_offset_t    dev_length;
    rvm_offset_t    offset;
    char            *vmaddr;
    rvm_length_t    length;
    bool            no_copy;
    }
rvm_region_t;

typedef struct
    {
    char            *log_dev;
    long            truncate;
    rvm_length_t    recovery_buf_len;
    rvm_length_t    flush_buf_len;
    rvm_length_t    max_read_len;
    rvm_length_t    flags;
    }
rvm_options_t;

rvm_return_t rvm_map (region,options)

rvm_region_t    *region;  /* pointer to a region descriptor [in/out] */
rvm_options_t   *options; /* optional pointer to an options record */
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_map moves a copy of all or part of the data in a data file
to virtual memory.
Mapping is necessary before any transactions can be made on a segment.
Data can be mapped in any integer multiple of page size that Unix allows.
The only restriction is available space in virtual memory.
<P>To insure that the committed image of the data file is brought into
memory, rvm_map generally performs log truncation before mapping.
One advantage of this is that crash recovery is automatic with the first
mapping after the crash.
The application need do nothing to restore the state of recoverable
storage.
<P>rvm_map requires the name of the segment file to be specified in
the descriptor provided by the region parameter.
If the region parameter does not point to a legitimate descriptor, or
the segment file cannot be opened, RVM_EREGION is returned.
<P>The range to map is specified by the offset
and length fields of the region descriptor.
The offset is rounded down to a page boundary, and the unrounded
offset plus length is rounded up to a page boundary to determine the
exact region mapped.
The rounded offset plus length must
lie at least partially within the segment or RVM_EOFFSET is returned.
<P>For file segments, if length is zero, the number of bytes
remaining in the segment from the offset is assumed.
Setting the offset and length to zero maps the entire segment.
For raw partition segments, the length must be specified.
If the range cannot be mapped due to size, RVM_ERANGE will be returned.
The rounded offset and the length of the region actually mapped are returned
in the region descriptor, and should not be changed since the
region descriptor will be the applications record of the mapping and
will be required to unmap the region.
<P>The mapping buffer can be optionally specified with a virtual memory address
in the vmaddr field of the region descriptor, or set to zero.
If zero, RVM will allocate page aligned space for a buffer of the
requested length.
This space is not heap allocated and can not be returned via
free; the program can reuse it after it is unmapped.
When allocation is requested, no other threads should
also doing allocation, including using malloc.
In Unix, both RVM and malloc use the kernel call sbrk and cannot
be synchronized without RVM-specific modifications to the C library.
Interference between them can cause unreferenced virtual memory, but
the results are always correct.
To avoid such interference, try to do mapping allocations during
application initialization, or other times when concurrency is minimal.
Mach versions of RVM use vm_allocate and do not suffer from
conflicts with malloc.
<P>When a buffer is allocated, its address is returned in vmaddr.
If the buffer cannot be allocated due to space restrictions,
RVM_ENO_MEMORY will be returned.
<P>When vmaddr is non-zero, it must refer to a page aligned buffer;
the address specified is not rounded.
If  vmaddr specifies an invalid address, RVM_ERANGE will be returned.
<P>Mapping buffers must not overlap in virtual memory.
Neither can the same region of a segment be mapped twice by the same process.
In these cases, RVM_EVM_OVERLAP or RVM_EOVERLAP will be returned.
If an application splits objects across page boundaries, it must make
sure the pages are mapped so that such objects can be accessed.
<P>If any error is encountered, no buffer is allocated, no data mapped,
and no modifications are made to the region descriptor.
<P>An optional rvm_options record can be specified with the
options parameter.
If options is not zero, and points to a valid rvm_options record, the
options specified will be used in the mapping.
Please refer to the RVM manual (section RVM option descriptor) for
details for the available options.
Options that must be specified on the first mapping only will be ignored
on mappings of other regions of the same segment.
If options is not zero and does not point to a valid record,
RVM_EOPTIONS will be returned.
<P>If this is the first mapping of a segment and a Mach version of RVM is
running then the pager field of the options record is checked.
If it is not the null string,
rvm_map will attempt to load the file specified into a forked task as an
external pager and initialize it.
If either the load fails or the task cannot be properly initialized as
an external pager, RVM_EPAGER is returned.
Any task created will be destroyed if an error is reported.
If successful, rvm_map returns and pages will be copied on demand
by the external pager.
The external pager backs all mapped regions of the segment, and will be in
effect until the last region is unmapped.
Using an external pager can substantially improve performance, particularly if
references to the data in the region are sparse.
<P>If RVM is running on Unix, or the pager field is a
null pointer, the mapped region is copied into virtual memory in total.
If on Mach, the inheritance property of pages will be set to VM_INHERIT_NONE
and it recommended that this not be changed.
<P>If the no_copy field is set in the region record, the data
for the mapped region will not be copied to virtual memory.
This is true with or without the external pager.
This option can be used when it is known that the data will be
completely replaced.
<P>The virtual memory protection of mapped pages is initially read/write
in both Mach and Unix.
However, the application can change this if desired by making the
appropriate kernel calls.
<P>A disk transfer error can result in corrupting a buffer, so applications
must not assume anything about data in an existing buffer unless rvm_map
returns successfully.
If a transfer error occurs,RVM_EIO will be returned and length
will be set to zero, and errno will contain the error number
returned by the failing I/O call.
<P>Mapping requires allocation of internal structures.
If these cannot be allocated, RVM_ENO_MEMORY is returned and no
data mapped.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_EREGION</B><DD><P>invalid region descriptor or pointer
<DT><B>RVM_EOFFSET</B><DD><P>invalid offset
<DT><B>RVM_ERANGE</B><DD><P>invalid virtual memory range
<DT><B>RVM_EOVERLAP</B><DD><P>region overlaps existing segment mapping
<DT><B>RVM_EVM_OVERLAP</B><DD><P>region overlaps existing virtual memory mapping
<DT><B>RVM_EOPTIONS</B><DD><P>invalid options record or pointer
<DT><B>RVM_EIO</B><DD><P>transfer error or segment file cannot be opened, errno
has code number
<DT><B>RVM_EPAGER</B><DD><P>invalid external pager
<DT><B>RVM_ENO_MEMORY</B><DD><P>heap exhausted, or buffer cannot be allocated
<DT><B>RVM_ENOT_MAPPED</B><DD><P>file to be mapped has zero length
<DT><B>RVM_ELOG</B><DD><P>no log file has been specified or invalid file name
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_unmap (3)</CODE>, <CODE>rvm_set_options (3)</CODE>, <CODE>rvm_query (3)</CODE>,
<CODE>rvm_create_segment</CODE>, and <CODE>rvm_load_segment</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
BUGS
<H3></H3>

<P>There is no provision for extending a mapped region.
<P>
<P>
<HR>NAME 
<H3></H3>

<P>rvm_unmap - unmap segment region
<P>
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

typedef struct
    {
    char            *data_dev;
    rvm_offset_t    dev_length;
    rvm_offset_t    offset;
    char            *vmaddr;
    rvm_length_t    length;
    bool            no_copy;
    }
rvm_region_t;

rvm_return_t rvm_unmap (region)

rvm_region_t *region;   /* pointer to region descriptor */
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_unmap releases mapped buffers.
The virtual memory space is freed for other uses, but not returned to Unix.
This is true even if the space was allocated by rvm_map, in which
case attempts to deallocate it with free will result in error.
If the space was originally allocated from the heap by the
application, using free is permissible.
<P>If vmaddr is invalid, length is zero, or the
range is not within
valid virtual memory limits, RVM_ERANGE is returned.
The address range must represent a mapped region of a segment,
otherwise RVM_ENOT_MAPPED is returned.
The region unmapped must be the same as that mapped, or RVM_ERANGE
or RVM_ENOT_MAPPED, as appropriate, will be returned.
A region cannot be split by unmapping part of it.
Use of the region descriptor as returned by rvm_map for the region
is recommended.
<P>Before a region of a segment can be unmapped, there must be no uncommitted
transactions affecting that region.
RVM checks this and will return the code RVM_EUNCOMMIT if any exist.
The function rvm_query can be used to discover the uncommitted
transaction (s).
Discovery of an uncommitted transaction in a region to be unmapped is a
likely indicator of program logic errors.
<P>Invoking log truncation after unmapping modified regions will avoid
delay in mapping if those regions are expected to be remapped.
If several regions are unmapped, truncation after the last unmapped
will insure no mapping delay if any are remapped.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_EREGION</B><DD><P>invalid region descriptor or pointer
<DT><B>RVM_ERANGE</B><DD><P>virtual memory address range does not match mapped
region
<DT><B>RVM_EUNCOMMIT</B><DD><P>uncommitted transaction(s) pending
<DT><B>RVM_ENOT_MAPPED</B><DD><P>designated region not mapped
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_map (3)</CODE>, <CODE>rvm_set_options (3)</CODE>, and <CODE>rvm_query (3)</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>
<H2><A NAME="ss4.2">4.2 Transaction Functions</A>
</H2>

<P>
<P>Transactions are used to change recoverable storage.  A single
transaction can modify any number of mapped regions.  Addresses used
in modifications to recoverable storage are virtual addresses and only
virtual memory is modified directly.  RVM will perform the translation
into segment offsets based on the mapped region descriptors.  The
modifications become permanent only when a transaction commits.
<P>To initiate a transaction, a transaction identifier record (rvm_tid_t)
is created and presented to rvm_start_transaction which will give the
transaction a unique identifier.  A pointer to the record becomes a
handle that must be used for all subsequent operations on the
transaction.  The record can be created with the rvm_malloc_tid
function (see section 
<A HREF="rvm_manual-3.html#AllocFuncs">of RVM structures</A>).
<P>The transaction identifier record has two time value fields that mark
the approximate time when the transaction was begun.  Because the Unix
kernel call gettimeofday underlying the timestamps is defined in
microseconds, but many machine clocks do not have that fine
resolution, the value can be no more precise than the machines clock.
Also, RVM may increment the lowest order bits to generate a unique
name without having to perform a kernel call.  The value can still be
presented to the time formatting routines available to extract a
printable time.  The fields, both integers, are contained in the
<CODE>struct timeval</CODE> field <CODE>uname</CODE>:
<DL>
<DT><B>tv_sec</B><DD><P>Seconds since Jan. 1, 1970.
<DT><B>tv_usec</B><DD><P>Microseconds since last second "tick."
</DL>
<P>RVM offers several options to control logging in transactions.
The intent in all cases is to take advantage of special situations that may
be known to the application and can be used to optimize the timing of,
or eliminate, log operations.
If a transaction cannot abort, using no_restore transactions will
enhance performance.
<P>The options supported are:
<DL>
<DT><B>restore</B><DD><P>Create old and new value log records for modifications;
restore virtual memory after an abort.
<DT><B>no_restore</B><DD><P>Do not create old value log records; virtual memory
not restored after an abort.
<DT><B>flush</B><DD><P>Flush log on commit.
<DT><B>no_flush</B><DD><P>Do not flush log on commit.
</DL>
<P>Note that options can be specified at transaction start and commit.
The restore, and no_restore options are valid only at the
beginning of a transaction.
The flush and no_flush options are valid only at transaction
end (commit).
At either transaction beginning or end, only one option can be specified.
<P>
<P><HR>
<P>
<P>
NAME 
<H3><A HREF="rvm_manual-3.html#AllocFuncs">of RVM structures</A></H3>

<P>rvm_begin_transaction - begin a transaction
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

rvm_return_t rvm_begin_transaction (tid,mode)

rvm_tid_t    *tid;    /* pointer to transaction identifier */
rvm_mode_t   mode;    /* transaction begin mode */
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_begin_transaction initiates a transaction.
A unique transaction identifier is assigned and returned in the record
specified by tid parameter.
If the pointer does not reference a valid rvm_tid_t record,
the RVM_ETID exception code is returned.
If the transaction cannot be started because of internal memory
limitations, RVM_ENO_MEMORY is returned.
<P>rvm_begin_transaction recognizes two transaction modes:
restore and no_restore.
Transactions begun with restore create old value records so that
the state of virtual memory can be restored if the transaction aborts.
If mode is not a legal option, RVM_EMODE is returned.
<P>The no_restore mode transactions do not create old value records.
Therefore, an abort does not restore the state of virtual memory.
They are offered as an additional performance enhancement for situations where
there is no possibility that the application will issue an abort for
the transaction.
<P>Once a transaction is begun, modifications to mapped regions
can be made with rvm_modify_bytes, or by the program in a range
specified by rvm_set_range.
The only restriction on modifications is that the modified regions must be mapped.
<P>Transactions are ended with rvm_end_transaction, or
rvm_abort_transaction, as appropriate.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_ETID</B><DD><P>invalid transaction identifier pointer
<DT><B>RVM_EMODE</B><DD><P>illegal transaction mode
<DT><B>RVM_ENO_MEMORY</B><DD><P>heap exhausted
<DT><B>RVM_ELOG</B><DD><P>no log file has been specified
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_set_range (3)</CODE>, <CODE>rvm_modify_bytes (3)</CODE>,
<CODE>rvm_end_transaction (3)</CODE>, and <CODE>rvm_abort_transaction (3)</CODE>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>NAME 
<H3></H3>

<P>rvm_set_range - define a modification range
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

rvm_return_t rvm_set_range (tid,dest,length)

rvm_tid_t      *tid;   /* pointer to transaction identifier */
char           *dest;  /* base address of modification range */
unsigned long  length; /* length of range in bytes */
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_set_range defines a modification range within a transaction.
The transaction must have been begun with rvm_begin_transaction, or
the RVM_ETID exception code is returned.
<P>The range is specified with the dest and length parameters, and 
must be in valid virtual memory or RVM_ERANGE is returned.
The range must also be within a single mapped region
or RVM_ENOT_MAPPED is returned.
A range of zero length is ignored.
<P>Range modifications provide efficient logging for transactions modifying
memory in a specific range, and is ideal when modifications are not sparse.
The original values within the range are preserved for possible restoration upon
transaction abort.
eliminating the need for a modify operator to log changes as they are made
so normal assignment statements can be used.
Changes can be made anywhere in the range and need not be
sequential.
<P>A common programming error is to make modifications without doing a
rvm_set_range call to declare the modifications to RVM.
This results in changes that are not permanent: since RVM has not been
informed of the changes, it cannot log the new values and the changes
are lost when the region is unmapped or if a crash occurs.
<P>The declaration of a modification range should always be made <EM>before</EM> the
modifications are actually assigned.
This is absolutely required if the transaction was begun in
restore mode, since the old values cannot be recorded otherwise
and will not be available for restoration upon transaction abort.
In future versions, making modifications before calling
rvm_set_range may result in incorrect operation.
<P>rvm_set_range can be used as many times as necessary within a
transaction to define the ranges of modifications required.
rvm_set_range and rvm_modify_bytes are not mutually exclusive,
and can be used in the same transaction as is convenient to the programmer.
<P>If the transaction was begun with the no_restore mode, no old
value record will be created for the modification range, and
an abort will not restore the state of virtual memory.
If memory to create an old value record for the range cannot be allocated,
RVM_ENO_MEMORY is returned.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_ETID</B><DD><P>invalid transaction identifier or pointer
<DT><B>RVM_ERANGE</B><DD><P>invalide virtual memory range
<DT><B>RVM_ENOT_MAPPED</B><DD><P>virtual memory range not mapped
<DT><B>RVM_ENO_MEMORY</B><DD><P>heap exhausted
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_begin_transaction (3)</CODE>, <CODE>rvm_modify_bytes (3)</CODE>,
<CODE>rvm_end_transaction (3)</CODE>, and <CODE>rvm_abort_transaction (3)</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
BUGS
<H3></H3>

<P>A range cannot extend across a region boundary even if 
virtual memory is contiguously mapped.
<P>
<P>
<HR>NAME 
<H3></H3>

<P>rvm_modify_bytes - recoverable modifications to a segment
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

rvm_return_t rvm_modify_bytes (tid,dest,src,length)

rvm_tid_t     *tid;    /* pointer to transaction identifier */
char          *dest;   /* base address of modification range */
char          *src;    /* base address of source range */
unsigned long length;  /* number of bytes to modify */
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_modify_bytes is used to modify recoverable memory in a transaction.
The transaction must have been previously initiated with rvm_begin_transaction;
otherwise RVM_ETID is returned.
<P>The modification range is specified with the dest and length
parameters, and
must be in valid virtual memory or RVM_ERANGE is returned.
The source of new values is specified with src, and must be in
valid virtual memory or RVM_ESRC is returned.
The range must also be within a single mapped region specified by the
region parameter, or RVM_ENOT_MAPPED is returned.
A range of zero length is ignored.
<P>Modification of different mapped regions in successive
rvm_modify_bytes calls is permitted.
Modifications can also be made with rvm_set_range, and both can be
used in the same transaction as is convenient to the programmer.
The modifications in virtual memory are visible to the program when
the call returns.
<P>If the transaction was begun with the no_restore mode, no old
value records will be created for the modification range, and
an abort will not restore the state of virtual memory.
If memory to create an old value record for the range cannot be allocated,
RVM_ENO_MEMORY is returned.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_ETID</B><DD><P>invalid transaction identifier or pointer
<DT><B>RVM_ENOT_MAPPED</B><DD><P>virtual memory range not mapped
<DT><B>RVM_ESRC</B><DD><P>invalid addrss range for new values
<DT><B>RVM_ERANGE</B><DD><P>invalide virtual memory range
<DT><B>RVM_ENO_MEMORY</B><DD><P>heap exhausted
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_begin_transaction (3)</CODE>, <CODE>rvm_set_range (3)</CODE>,
<CODE>rvm_abort_transaction (3)</CODE>, and <CODE>rvm_end_transaction (3)</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>NAME 
<H3></H3>

<P>rvm_abort_transaction - abort specified transaction
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

rvm_return_t rvm_abort_transaction (tid)

rvm_tid_t    *tid;   /* pointer to transaction identifier */
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_abort_transaction aborts the specified transaction.
Transactions begun with any mode can be aborted with this function.
All modifications to segments made in the course of the transaction are
restored to their original values (unless the transaction was begun
with the no_restore) mode.
<P>The transaction identifier must refer to a previously initiated transaction
or RVM_ETID is returned.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_ETID</B><DD><P>invalid transaction identifier or pointer
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_begin_transaction (3)</CODE>, <CODE>rvm_end_transaction (3)</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>NAME 
<H3></H3>

<P>rvm_end_transaction - commit transaction
<P>
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

rvm_return_t rvm_end_transaction (tid,mode)

rvm_tid_t         *tid;  /* pointer to transaction identifier */
rvm_trans_mode_t  mode;  /* transaction commit mode */
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_end_transaction commits the changes made since the transaction
began.
All transactions can be committed with this function, regardless of
the mode they were begun with.
The transaction identifier must refer to a previously initiated transaction
or RVM_ETID is returned.
<P>Two commit modes are recognized: flush and no_flush.
In a flush commit, the new value records for the transaction are
written (flushed) to the log file.
Permanence is then guaranteed upon successful return.
<P>A no_flush commit is faster than a commit with log flushing,
but provides a weaker guarantee of permanence.
The new value records are created, but not written to the log file.
Permanence is guaranteed only when they are flushed to the log
file.
This can be done either by a flush-mode commit of another transaction,
or by explicitly flushing the log with rvm_flush.
An application can enhance performance by delaying the log flush (and permanence of changes) until a sequence of related transactions has
been completed.
Note that aborting the last transaction of such a sequence <EM>will not</EM>
restore the original state of transactions previously committed with
the no_flush option.
RVM does not support nested transactions.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_ETID</B><DD><P>invalid transaction identifier or pointer
<DT><B>RVM_EMODE</B><DD><P>invalide transaction end mode
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_begin_transaction (3)</CODE>, <CODE>rvm_set_range (3)</CODE>, <CODE>rvm_modify_bytes (3)</CODE>, and
<CODE>rvm_flush (3)</CODE>
<P>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>
<H2><A NAME="ss4.3">4.3 Log Control Operations</A>
</H2>

<P>
<P>
<H3>Log Flush and Truncation</H3>

<P>If an application is scheduling log operations, it can explicitly
invoke the flush and truncate operations with the rvm_flush and
rvm_truncate functions.
Both of these functions are considered <EM>slow</EM> operations since they
require disk operations, and will lock out other RVM functions
requiring disk access, particularly rvm_end_transaction in flush mode.
If invoked by more than one thread, these operations will be
serialized in the order received by RVM.
<P>RVM will recognize when an operation is not needed because the log
is empty, and will return immediately.
<P>
<H3>Log Initialization</H3>

<P>
<P>The function rvm_create_log can be used to create log files,
<EM>provided</EM> that the file does not already exist.
This requirement is made to prevent applications that automatically
create a log file on startup from destroying the log records that are
necessary to recover from a crash.
<P>Either files or raw disk partitions can be initialized as logs with the
utility rvmutl. (Raw disk partitions can only be initialized by
rvmutl).
Details are found in Chapter 
<A HREF="rvm_manual-8.html#rvmutl">of rvmutl</A>.
<P><HR>
<P>
<P>
NAME 
<H3><A HREF="rvm_manual-8.html#rvmutl">of rvmutl</A></H3>

<P>rvm_flush - flush log records to log file
<P>
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

rvm_return_t rvm_flush ()
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_flush makes visible the log flush operation, which
moves transaction records
to the log file and insures the permanence of the changes
represented by those records.
It is normally done with a transaction commit,
but is available
to the application if it wishes to schedule the flush after a sequence of
no_flush transactions.
<P>rvm_flush is synchronous with the calling thread.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_ELOG</B><DD><P>no log file has been specified
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_end_transaction (3)</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>NAME 
<H3></H3>

<P>rvm_truncate - truncate the log
<P>
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

rvm_return_t rvm_truncate ()
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_truncate makes visible the log truncation operation.
When the log is truncated, records for committed changes are used to update the
committed images of modified segments.
After modified data files are successfully updated, the records can
be deleted and the log "truncated."
<P>Like log flushing, this operation is usually performed implicitly by RVM,
but is available to the application if it wishes to
schedule the operation itself.
rvm_truncate performs a flush before truncating, and is
synchronous with the calling thread.
<P>rvm_truncate requires virtual memory working space.
If this space cannot be allocated, RVM_ENO_MEMORY is returned, and
the truncation is aborted.
If possible, the application can deallocate as much memory as possible
and retry the truncation.
This can done as many times as necessary.
If no memory can be freed, this error should be considered fatal.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_ENO_MEMORY</B><DD><P>heap exhausted
<DT><B>RVM_EIO</B><DD><P>I/O or kernel error, errno has code number
<DT><B>RVM_ELOG</B><DD><P>no log file has been specified
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_flush (3)</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>NAME 
<H3></H3>

<P>rvm_create_log - RVM log file creation
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

rvm_return_t rvm_create_log (options, length, mode)

rvm_options   *options;  /* pointer to a RVM options record */
rvm_offset_t  *length;   /* length of log record area in file to be created */
long          mode;      /* protection mode of file to be created */
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_create_log provides a mechanism for creating a log file from
within an application.
It is intended to allow an application to be self-installing by
silently creating the log and other RVM structures it needs.
To provide some protection against an applications automatically
over-writing a log containing valid records, rvm_create_log can
be used to create logs in Unix files only, and only if the file does
not already exist.
Creating logs in raw partitions must be done with the utility
<CODE>rvmutl</CODE>.
<P>The name of the log file to be created must be specified in the options record.
An options record created with typedef rvm_options_t must be used.
RVM_EOPTIONS will be returned if options does not point to a valid
record.
If either the name is not provided, or the file cannot be created and
initialized, RVM_ELOG will be returned.
Also, the total length of the file to be created must be permitted by the
file system.
This includes the length specified for log records plus the overhead
necessary for the log status area, presently one sector.
Options other than the log file name are ignored.
<P>The mode parameter is the Unix file system protection mode and
must allow writing by the owner.  An i/o error will be returned if
the file cannot be created or written.
<P>rvm_create_log does not declare the created log file as the
operational log.  This must be done by specifying an options
descriptor to <CODE>rvm_set_options</CODE>, <CODE>rvm_initialize</CODE>, or <CODE>rvm_map</CODE>.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_ELOG</B><DD><P>no log file has been specified
<DT><B>RVM_EIO</B><DD><P>I/O or kernel error, errno has code number
<DT><B>RVM_EOPTIONS</B><DD><P>invalid RVM options record or pointer
<DT><B>RVM_ENO_MEMORY</B><DD><P>heap exhausted
<DT><B>RVM_ENAME_TOO_LONG</B><DD><P>file name longer than 1023 characters
<DT><B>RVM_ETOO_BIG</B><DD><P>file length requested greater than file system permits
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_set_options (3)</CODE>, <CODE>rvm_initialize (3)</CODE>, <CODE>rvm_map (3)</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>
<H2><A NAME="ss4.4">4.4 Query and Statistics Functions</A>
</H2>

<P>
<P>RVM allows the application to query the settings of options and some
internal state with <CODE>rvm_query</CODE>.  Access to the statistics
automatically collected by RVM is provided by <CODE>rvm_statistics</CODE>.
<P>The query and statistics functions require that the application
allocate records for the data to be returned.  In general, the
application is responsible for deallocation of these records, although
they can be used in multiple calls to their respective functions.
As with other records types in RVM, the <CODE>rvm_options_t</CODE> and
<CODE>rvm_statistics_t</CODE> records must be allocated or initialized with the
provided type-specific functions.
<P>Because <CODE>rvm_query</CODE> must return two variable length items, some
special allocation conventions must be observed.
If the name of the log file is to be returned, the caller must
allocate a buffer of <CODE>MAXPATHLEN+1</CODE> characters and place a pointer
to it in the <CODE>log_dev</CODE> field.
The file name will be copied into the buffer.
The buffer will not be deallocated by RVM.
The <CODE>log_dev</CODE> field should be null if the name of the log is not to
be returned.
<P>The tid_array vector is always returned if uncommitted
transactions are present.  Since the length isnt known before the
call, <CODE>rvm_query</CODE> must do the allocation.  This results in the
following deallocation conventions:
for option records allocated with <CODE>rvm_malloc_options</CODE>, the array
should not be deallocated by the application since this will be done by
<CODE>rvm_free_options</CODE>.
However, if the options record is allocated on the stack, the array
must be explicitly deallocated by the application, or space will be
lost.
<P>Deallocation of the array in statically allocated options records is
optional: repeated use of the record will cause the array to be
reallocated as necessary by <CODE>rvm_query</CODE> with no explicit action by
the application.  If you do deallocate the array, you <EM>must</EM> null the
pointer to avoid a possible internal error due the dangling pointer.
<P>No special deallocation conventions are required for
<CODE>rvm_statistics_t</CODE> records.
<P><HR>
<P>
<P>
NAME 
<H3></H3>

<P>rvm_query - query RVM options
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm.h"

rvm_return_t rvm_query (options,region)

rvm_options_t  *options;  /* pointer to a RVM options record */
rvm_region_t   *region;   /* optional pointer to a region descriptor */
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_query allows inspection of the RVM options currently set.
An options record, specified by options, is filled in with the
values currently in effect.
If this record is not valid, RVM_EOPTIONS will be returned.
Please refer to the RVM manual for the details of options.
<P>If the name of the log file is to be returned, the caller must
allocate a buffer of <CODE>MAXPATHLEN+1</CODE> characters and place a pointer
to it in the <CODE>log_dev</CODE> field.
The file name will be copied into the buffer.
The buffer will not be deallocated by RVM.
<P>If region is null, the options returned are those global to RVM,
otherwise the options will be for the specified region.
If the region does not point to a valid region descriptor,
RVM_EREGION will be returned.
<P>If only the segment file is specified in the region descriptor,
the options are those applicable to all mappings of the segment.
If the offset, length, and vmaddr
fields of the region descriptor are not zero, the options
returned will reflect those of that region.
If the region isnt mapped, RVM_ENOT_MAPPED is returned.
Certain options reflect the the global state of
RVM regardless of the region specified.
<P>The number of uncommitted transactions, if any, is returned in the
n_uncommit field of the options descriptor.
If uncommitted transactions exist, tid_array will contain a
pointer to a vector of length n_uncommit of identifiers for the
transactions.
If a valid region descriptor has been specified, the uncommitted
transaction descriptors returned will be only those modifying the
specified region.
Otherwise, all uncommitted transactions are returned.
<P>If a tid_array vector exists in the options record when
rvm_query is called, it will be replaced to reflect the current
status.
<P>For option records allocated with rvm_malloc_options, the array
should not be deallocated by the application since this will be done by
rvm_free_options.
However, if the options record is allocated on the stack, the array
must be explicitly deallocated by the application, or space will be
lost.
Deallocation of the array in statically allocated options records is
optional: repeated use of the record will cause the array to be
reallocated as necessary by rvm_query with no explicit action by
the application.  If you do deallocate the array, you <EM>must</EM> null the
pointer to avoid a possible internal error due the dangling pointer.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_EREGION</B><DD><P>invalide region descriptor or pointer
<DT><B>RVM_ENOT_MAPPED</B><DD><P>region not mapped
<DT><B>RVM_EOPTIONS</B><DD><P>invalid options record or pointer
<DT><B>RVM_ENO_MEMORY</B><DD><P>heap exhausted
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_map (3)</CODE>, <CODE>rvm_unmap (3)</CODE>, <CODE>rvm_set_options (3)</CODE>, <CODE>rvm_abort_transaction (3)</CODE>,
<CODE>rvm_end_transaction (3)</CODE>, and <CODE>rvm_terminate (3)</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>NAME 
<H3></H3>

<P>rvm_statistics - query collected statistics
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm_statistics.h"

typedef struct
    {
    /* see rvm_statistics.h for current fields */
    }
rvm_statistics_t;

rvm_return_t     rvm_statistics (version, statistics);
char             *version;    /* Statistics version string */
rvm_statistics_t *statistics; /* pointer to a statistics record */

rvm_return_t     RVM_STATISTICS (statistics);
rvm_statistics_t *statistics; /* pointer to a statistics record */
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P><CODE>rvm_statistics</CODE> copies the statistics collected by RVM to a record
provided by the application.  The contents of the record can then be
analyzed by the application, or formated by <CODE>rvm_print_statistics</CODE>.
<P>Note that the header <CODE>rvm_statistics.h</CODE> must be included to use the
statistics facility.  These declarations are not included in the
standard RVM library header since they are expected to change as RVM
is further developed.  Because of the expectation of change,
a version parameter is used to detect version skews between the
statistics record format of the application and the RVM library.
The string constant RVM_STATISTICS_VERSION from
rvm_statistics.h is passed to rvm_statistics, and compared with 
the value the library was compiled with.
If they are different, RVM_ESTAT_VERSION_SKEW is returned and no
data is copied to the statistics record.
<P>The macro <CODE>RVM_STATISTICS</CODE> will automatically pass the version
string to the function.
<P>The <CODE>statistics</CODE> parameter specifies the record to which the
statistics will be copied.
This record must be of type <CODE>rvm_statistics_t</CODE> and must
have been created by <CODE>rvm_malloc_statistics</CODE> or initialized with
<CODE>rvm_init_statistics</CODE>.
If the record is not properly formated by either of the above
functions, the error <CODE>RVM_ESTATISTICS</CODE> is returned.
<P>For detailed specification of the statistics currently collected,
consult the header file <CODE>rvm_statistics.h</CODE> which is also
included in the RVM manual.
<P>
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_ESTAT_VERSION_SKEW</B><DD><P>Statistics version skew
<DT><B>RVM_ESTATISTICS</B><DD><P>Invalid statistics record or pointer
<DT><B>RVM_ELOG</B><DD><P>no log file has been specified
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_print_statistics (3)</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>NAME 
<H3></H3>

<P>rvm_print_statistics - format and print statistics
<P>
SYNOPSIS
<H3></H3>

<P>
<PRE>
#include "rvm_statistics.h"

typedef struct
    {
    /* see rvm_statistics.h for current fields */
    }
rvm_statistics_t;]

rvm_return_t     rvm_print_statistics (statistics,out_stream);
rvm_statistics_t *statistics; /* pointer to a statistics record */
FILE             *out_stream; /* pointer to stdio stream */
</PRE>
<P>
DESCRIPTION
<H3></H3>

<P>rvm_print_statistics formats an rvm_statistics_t record
previously filled in by rvm_statistics.  The formated output is
set to the specified stream, which must first have been opened with
fopen.
<P>For detailed specification of the statistics currently collected,
consult the header file <CODE>rvm_statistics.h</CODE>, which is also
included in the RVM manual.
<P>This function can also be invoked from <CODE>rvmutl</CODE> with the
<CODE>statistics</CODE> command.
<P>
<P>
DIAGNOSTICS
<H3></H3>

<P>
<DL>
<DT><B>RVM_SUCCESS</B><DD><P>success
<DT><B>RVM_ESTATISTICS</B><DD><P>Invalid statistics record or pointer
<DT><B>RVM_EIO</B><DD><P>I/O or kernel error, errno has code number
<DT><B>RVM_ELOG</B><DD><P>no log file has been specified
<DT><B>RVM_EINIT</B><DD><P>RVM not initialized
</DL>
<P>
<P>
SEE ALSO
<H3></H3>

<P><CODE>rvm_statistics (3)</CODE>, <CODE>rvmutl-statistics (1)</CODE>
<P>
<P>
AUTHOR
<H3></H3>

<P>Hank Mashburn
<P>
<P>
<HR>
<HR>
<A HREF="rvm_manual-5.html">Next</A>
<A HREF="rvm_manual-3.html">Previous</A>
<A HREF="rvm_manual.html#toc4">Contents</A>
</BODY>
</HTML>