<!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>