KArc - Ken's Archive Utility

  1. What it is
  2. Access and Security
  3. The Configuration File
  4. Karc, the Client Utility
  5. Karcd, the Server Dæmon
  6. Karct, the Transfer Agent
  7. Karcc, the Copy Dæmon
  8. Karcr, the Remote Helper
  9. Karcb, the Broker Dæmon
  10. Karcf, the Flusher Agent
  11. Karcm, the Maintenance Utility
  12. Karcx, the Exception Reporter
  13. The Karc API

What it is

Ken's Archive is a client/server setup that acts as the warehouse for Ken's Dump Utility. An archive dæmon runs on the server systems, accepting dump images and storing them on HPSS for later retrieval.

Each dump image in the warehouse consists of a name entry, a data file and an optional index file. The name entry is stored in Ken's Name Server, KNS, the data file is stored in HPSS and the index file is stored both in HPSS and possibly on a native disk that is NFS exported to trusted clients.

Access and Security

The archive system uses Jim Fox's Lightweight Secure Connection Library to control access to individual dump images. Each client connecting to the karc dæmon must specify a valid LSC key. LSC keys have a public portion and a private portion. The key names are in the form:

karX_group_member

which encodes the following information:
X: Security level
The security level is a hexidecimal digit from 0 to F. The higher the level, the more privileged the client.
0: Level zero is unprivileged and can do nothing.
2: Level two clients can only access and manipulate images that were created by the specified group and member.
3: Level three clients can read images that were created by the same group regardless of member.
4: Level four clients can erase or set attributes on images created by other members of the same group.
7: Level seven clients can add public keys (at level seven and below) for other members in their own group.
A: Level ten clients can add public keys (at level seven and below) regardless of group.
F: The servers run with level 15 keys.

group
The group is an arbitrary character string assigned by the administrator of the karc servers. This is used as a directory name in the HPSS and NFS filesystem hiearchy so should be a short name of all letters and possibly digits. Expected strings might be UCS, NDC and TSS.

member
The member is an arbitrary character string, but for practical purposes should be the host name of the computer owning the key.
The public keys for the servers are part of the installation materials that come with the karc client package. If these keys need to be changed, all clients need to be updated. The key pair for the clients are generated on each client computer independantly. The private portion is kept on that computer, accessible only by the superuser. The public portion is given to the local group administrator to be installed on the servers.

The Configuration File

The file /usr/local/lib/karc/conf on each host provides the karc utilities with their local configuration. The following parameters can be put into the configuration file:

Server host preference
There should be one server entry for each address of each server that this client should attempt to access in order to retrieve or store dump images. The preference field specifies an integer value indicating the initial base preference for a particular server. Each address listed is sent a query asking how busy it is. The response from this query is added to the base preference to get an overall preference value. The address with the highest overall value is the one used when establishing the control channel connection. All dumps will be sent to that server if that server is active. On a restore, if the server chosen doesn't have the requested image, it will forward requests to the proper server. The actual data will not make the extra hop to the chosen server, but activity on the control channel will.

COSId id
The COSId entry in the configuration file establishes the HPSS Class Of Service Identifier for all dump images data and index files. The COSId statement only needs to be on server hosts, this parameter is ignored by client utilities.

DATId id
The DATId entry specifies the class of service for the dump image data file. It only needs to be specified on servers where the index and data files are written with different class of service identifiers.

DSKId value
The DSKId entry specifies whether this server supports an extra disk copy of the index files. A value of 0 indicates no, non-zero indicates yes. An extra disk copy is only needed if access to the backend storage subsystem would be too slow.

Encrypt modes [ key ]
Specifies the default encryption mode for traffic between the kdump utility and the karcd servers. The modes parameter can be one or more comma delimited tokens as follows:

None: No encryption is performed. The data and index file are sent to the karcd dæmons in clear text. This option should be used only if you're comfortable that there are no network sniffers running or you don't care that people may see the contents of your files (including your karc and ssh private keys if you happen to dump the filesystem that those are stored on).
Private: Files that are protected with no world (others) read permission are encrypted when sent across the network. This includes files in directories that do not contain an execute permission (traverse permission) for others.
Public: All files, whether all users on the local system can read them or not, are encrypted when sent across the network.
Index: The index file is encrypted when sent across the network. If the index file is not encrypted, sniffers can discover the names of the files that are being dumped.
All: The All option is the same as public,index.

If private or public is specified, the encryption key must also be named for kdump. This key is stored in the dump_keys file or can be stored on the server for global keys that must be accessed by multiple hosts.

The configuration file just specifies the default for kdump and karc. These defaults can be overridden by options on the respective utility's command line.

NDXId id
The NDXId entry specifies the class of service for the dump image index file. It only needs to be specified on servers where the index and data files are written with different class of service identifiers.

Ordinal ordinal
The Ordinal entry is only used by the karcd server, it is ignored by other clients. Each karcd server has a unique ordinal from 0 to 2.

Port port
The Port entry specifies the server TCP/IP port number that the karcd server listens to.

Karc, the Client Utility

The karc utility allows the super user on the local system to create and manipulate dump images and client keys. This utility has the basic syntax:

karc -command arg [options]

Commands:

-commit name
Commits the specified dump image to permanency. The expected usage of the karc commit function is to pipe the output of the standard Berkeley dump utility into a karc -dump name command. If the dump and the karc utility complete successfully they'll have a zero exit status. If that's the case, the karc -commit name command can be used. Dump images that have not been committed will be deleted periodically.

-dump name
Write stdin to dump image data file. The dump image name is created and karc simply transfers whatever it finds on stdin to the data file for the dump image. The karc utility will not create an index file, the kdump utility creates that itself through the karc API.

A script that archives the contents of a subdirectory might do something like:

NAME=`date '+subdir.%Y.%m.%d.%H.%M'`
tar -cf - subdir | karc -dump $NAME -comment "dump of subdir"
case $? in
  0) karc -commit $NAME;;
  *) echo "Oh no, the tar piped to karc failed";;
esac

-erase name
Remove dump image. The data file, the index file and the name are permanently removed from existence.

-list pattern
Display dump image status. Existing dumps matching the specified pattern are displayed. The pattern consists of an ed(1) regular expression including an optional group and member in the syntax: group/member/name. If an alternate group or member is specified, the security level must be high enough to permit that or else karc will get a "No Authorization" error.

-newkey file
Establishes a new LSC key. The expected procedure for setting up a new client is:
	client% cd /usr/local/lib/karc
	client% lsc_keygen kar4_GRP_`hostname` priv_keys newkey

        admin% rcp client:/usr/local/lib/karc/newkey newkey
	admin% karc -key 7 -newkey newkey
The data encryption keys can also be stored on the server if desired. In this case, only the public half of the key is used, both for the encryption and decryption, so the private half may be discarded.

-read file
The read command reads additional requests from the named file or stdin if a single dash is specified. Directives on this input file look like complete karc commands that the shell would interpret. The benefit of using this option rather than submitting multiple commands is that karc will make one connection to the server which can greatly reduce the time required to, say, erase several dozen dump images.

-restore name
Read dump image data file to stdout. The expected usage of this function is to pipe a dump created with karc -dump into the Berkeley restore utility or a derivitive thereof. The karc utility will not access an index file. The krest utility accesses that directly through the karc API.

A session to retrieve a file from the subdir archive created above might look something like:

frodo% karc -list subdir
C-d-  subdir.2000.10.20.15.01    20.02   dump of subdir
frodo% karc -restore subdir.2000.10.20.15.01 | tar -xf - subdir/lost_file

-set name
Set new comment.
Options:
-comment 'text'
Specify dump image comment. This option can be used on the -dump or -set commands.

-format 'format'
Specify list format string. The list format string allows you to tailor the output of the -list command how you want it. The format string is not unlike a C language printf format with the following percent characters defined:

C Comment associated with dump image.
F File name. This is the full name of the dump image including the group and member fields.
G Group name. The group name that the dump image belongs to.
H Host name. The member name that the dump image was created under.
L Local file name. This is the image name without the group and member fields prepended.
S Status. This a four character field giving the status of the dump image. The first is C for committed, p for partial or i for initial. The second either e for erased or dash for not. You'll see erased files if not all copies of the file have been erased from all servers. The third is a d if there's a data file or dash if not. The fourth is an i if there is an index file or dash if not.
T Time. Creation time in seconds since the beginning of the epoch.
c Creation time in standard unix ctime(3) format.
d Size of the data file in floating point megabytes.
f Flags associated with dump as a hexidecimal number. The flag bits are defined as KAR_S_xxxx in the kar.h include file.
i Size of the index file in floating point megabytes.
m Modification time in ctime(3) format.
s Size of the data file plus the size of the index file in floating point megabytes.
t Creation time in ctime(3) format (same as 'c').

Each of these fields can be modified as "%[-]w.f+nX" where w is the minimum width of the field (leading minus sign for left justification), f is the maximum width for a string or the digits right of the decimal point for the floating point fields and n is an offset to the first displayed character of the resulting string. Thus %.12+4c will get the month, day of month, hours and minutes of the creation time without the leading day of the week or trailing colon, seconds and year. The default format string is: "%-5.5S %9.2s %-36L %C"

-key level
Specify alternate key level. By default the karc utility will use the most recently created key in the priv_keys file. An alternate key can be selected by specifying the single digit level with the -key option.

-port port
The karcd server runs on the port specified in the configuration file. The -port option can select a test server running on an alternate port.

-server host
The karc utility normally connects to the servers in the order specified in the configuration file. An alternate server can be selected with the -server option.

-sort field
Sort list by Creation, Name or NOne. Normally the list command sorts its output by creation time. This can be overridden with the -sort option. The NONE sort option yields an apparent random order (sorted by the KNS server's internal hashing function).

Karcd, the Server Dæmon

The karcd dæmon runs on each server host. Its main function is to accept incoming connections which it hands off to the Transfer Agent and to report on the current status of things to the Argus dæmon. The karcd dæmon is multi-threaded. One thread responds to Argus queries and a second thread processes status reports from the transfer agents while the main thread listens for new connections, starting individual threads which fork copies of the transfer agent and wait for them to complete. That's pretty much the whole story.

Karct, the Transfer Agent

The karct transfer agent does all of the work of the server. One transfer agent gets started for each dump or restore. The transfer agent processes individual commands that come from the clients. Each transfer agent can handle operations on ten simultaneous connection numbers or cns. Each cn is assigned to a particular dump image with the Create or Access commands then other commands operate on that dump image through by specifying the cn handle. The set of commands is:
Access cn[+] group/host/name
Assigns the existing name to the connection number. The plus following the cn requests control access -- otherwise it's a read-only access and no changes are allowed.

Close cn
Closes the current stream associated with the cn (see Open). The threads transfering the data are shut down and their status is and the total number of bytes transferred is returned.

Comment cn text
Sets the comment associated with the dump image to the specified text.

Commit cn
Sets the committed flag on the dump image.

Create cn group/host/name
Creates the specified name in the KNS name space and assigns the connection number to the new dump image.

Erase cn
Removes the dump image and deletes the name from the KNS name space.

List pattern
Retrieves entries matching the pattern from the KNS name space.

Open cn type
Establishes a pipeline to transfer the specified dump image data, type=d, or index, type=i, file across the network. Multiple threads are started to perform the transfer. One communicates with a network partner by opening a socket to which the client is instructed to connect. Another communicates with the data store. The reading thread fills buffers while the writing thread(s) flush them out until end of data.

Read cn start length
If the transfer is from the data store to the network client (a restore operation by the client), read instructions are necessary to tell the data store reading thread what portions of the data are required. The reading thread will seek to the appropriate place, fill the buffers with the data and then proceed to the next read instruction. The start and length values are in 64 bit values as hexidecimal strings high+low. An asterisk for the length field requests a read to end of data. An octothorpe (pound sign) for the start field indicates end of read requests. The buffers won't be flushed unless they're filled or the end of read request is encountered, so all read requests should be sent prior to blocking on reading the data socket or in a separate thread.

Report cn rate
The report request is used to provide the karcd dæmon with the transfer rates for the client's portion of the transfer. The transfer rate is used to identify bottlenecks in the system.

Karcc, the Copy Dæmon

The copy dæmon deals with making sure dump images are duplicated on the alternate Karc server(s). Karcc will start up N child processes to make sure copies are made of each file in the karc system. When a dump completes and is committed, a datagram message is sent to the karcc process on the alternate karc server system. Karcc will feed each of its children a filename to copy. The child process runs a karc command that connects to the local karcd. It issues a copy command to the local karct process that gets spawned off as a result of that connection. The local karct connects to the remote karcd where the file currently resides. The karct on the remote system receives a standard restore sequence to fetch the data which is collected by the local karct and stored locally.

When a copy completes, the next file in the stack is handed off to the idle child until the stack is empty. The requests are processed LIFO to increase the chances that the dump image is still in the local disk cache and doesn't need to be retrieved from tape.

Karcr, the Remote Helper

When karct gets a copy request, it invokes karcr to connect to the remote karcd server. Karcr acts as a karc client who passes commands and their responses between the local karct and the remote karct. Karcr gets around the fact that it's difficult to be a karc client and a karc server at the same time. Only the command stream goes through karcr, the actual data channel is between the karct processes themselves.

Karcb, the Broker Dæmon

Dec 2005
The broker dæmon controls the local disk cache used by the non-HPSS version of the karc dæmon. The broker maintains the name space of image chunks. Each chunk can be up to 4 gigabytes in length. The broker's database keeps track of what chunks exist and how long they are and whether they're currently on disk, on back end store or copied to alternate servers.

The broker dæmon processes the following commands:

Create group/host/name
Allocates a new location in the broker database. The create request is the first activity on a particular chunk. All flags are zeroed and the update/create time is set to the current clock. In 24 hours the entry will be recycled if not updated.

Delete group/host/name
Releases all information about the specified entry and recycles the space it used. This call should be made after all instances of the file have been removed from the disk cache and back end store.

Modify group/host/name +/-flags
Sets or clears the indicated flags for the particular chunk.

Commit group/host/name size
Signifies that the chunk is complete and is ready to be flushed to the back end server and/or remote servers. The size parameter indicates the final segment size. The broker will spawn off the karcf helper processes to deal with the flush requests.

Stage group/host/name [offset length]
Stages the specified chunk from the back end store into the disk cache. If the offset and length are specified, control returned after that portion has been staged in. The actual staging process is handled by karcf helper child processes.

Karcf, the Flusher Agent

Dec 2005
The flusher or File handler agent deals with copying the 4 gigabyte chunks back and forth between the disk cache and the back end store. It accepts commands on its stdin and reports its success or failure on stdout. It will chug through the following requests as they come in:
Flush prefix group/host/name length
Copies the specified chunk to TSM. The prefix describes which disk pool the segment currently resides in and the length is in bytes modulo 4GB.

List [pattern]
Generates a list of files in the broker's namespace that match the given pattern. By default all files are listed. This is used by the reconciliation utilities to align the broker's view with TSM's view and the current disk cache.

TBD group/host/name TBD
Copies the specified chunk to a remote server.

Stage prefix group/host/name [offset length]
Copies the entire chunk from TSM to the disk cache. The prefix describes the intended disk pool for the segment. When the optional indicated chunk is disk resident a partial reply is returned.

Karcm, the Maintenance Utility

The maintenance utility runs each day to verify that consistancy is maintained. It verifies that the list of files on the backing store agrees with the list in karc's own tables and it generates commands to clean up anomolies and purge out partial dump images that never completed. The karcm utility also figures out which dump images should be copied to this server from other servers -- copies that didn't ocmplete and fell through the cracks -- and feeds a list of files to the local karcc dæmon.

Karcx, the Expiration Reporter

The karcx utility runs each week to look for neglected dumps. It reports on dump images that exist in the database that appear to be orphaned because no new dumps have been created recently or no new entries exist with that particular key -- indicating a fileserver that has been decommissioned. Periodically these dump images need to be cleaned up by hand when they're no longer useful, but it's not the Karc system's place to make the decision as to when that should happen, he's only the messenger.

The Karc API

Communication with the karc servers is accomplished through the Karc Application Programming Interface. This library contains the following routines:
extern int   kar_errno;
extern char *kar_errmsg;

void  kar_add64(dfaddr_t *df, int n);
void  kar_add6464(dfaddr_t *d1, dfaddr_t *d2, dfaddr_t *d3);
int   kar_accept(int fd);
int   kar_access(int cn, int mode, char *name);
int   kar_cipher(int cn, max_size, LSC lsc);
int   kar_close(int cn, int fd);
int   kar_cmp64(dfaddr_t *d1, dfaddr_t *d2);
int   kar_cmd(char *msg);
int   kar_comment(int cn, char *comment);
int   kar_commit(int cn);
int   kar_conf(char *dir);
int   kar_connect(void);
int   kar_create(int cn, char *name);
void  kar_disconnect(void);
void  kar_disect(char *key);
void  kar_getkey(char *key);
void  kar_init(char *dir);
int   kar_open(int cn, int file, int *fd);
int   kar_rc(int rc);
int   kar_read(int cn, dfaddr_t *start, dfaddr_t *length);
void  kar_reply(int code, int seq, char *reason);
int   kar_report(int cn, char *rate, int n);
void  kar_setgrp(char *key, char *group, char *host, char *file);
int   kar_stat_dec(char *buf, kar_stat_t *ks, char **cmt);
char *kar_stat_enc(kar_stat_t *ks, char *cmt);
void  kar_sub64(dfaddr_t *df, int n);
void  kar_sub6464(dfaddr_t *d1, dfaddr_t *d2, dfaddr_t *d3);

General Basics

The normal sequence is to call kar_init with a null parameter to get connected to a server. This initializes the various global variables and calls the kar_conf routine to read the configuration file, /usr/local/lib/karc/conf, which defines the host and tcp/udp port for the karcd servers.

Once initialized, kar_create or kar_access will be called to assign a dump image to a cn. Kar_open will be called to set up a network connection, data will be transferred and then kar_close will be called to close the connection. These routines are all covers for the more basic kar_cmd which does all the work.

The kar_cmd routine is called with a textual command to be processed by the server. Kar_cmd will call kar_connect if necessary to establish an actual connection with the server. The reply from kar_cmd will indicate success or failure:

KAR_RETRY-2Didn't work, but may later
KAR_ERROR-1Unsuccessful return value
KAR_OKAY0Successful return value
KAR_MORE1More data available

In addition, the kar_errno variable will contain an extended error status as defined by the KAR_E_xxx constants in the kar.h include file and kar_errmsg will point to a suitable message to be displayed as part of an error message as well as any response from the server. Note that these two global variables (and others) indicate that the code is not officially "thread safe". Normally, it is expected that one thread will make the calls to the kar library while secondary threads may be acting upon the results (eg: writing to a data stream opened by the main thread). Two threads should not call kar_ routines without proper synchronization via mutexes, however.

64 bit arithmetic

Since the data file of the dump image can exceed 2 gigabytes in size, some routines are used to manipulate 64 bit addresses and offsets. The dfaddr_t structure contains two unsigned 32 bit integers, df_high and df_low, that are acted upon by the following routines:
void kar_add64(dfaddr_t *df, int n);
Adds a 32 bit value to a 64 value.

void kar_add6464(dfaddr_t *d1, dfaddr_t *d2, dfaddr_t *d3);
Adds d1+d2 and stores the result in d3. The result structure can be one (or both) of the source structures.

int kar_cmp64(dfaddr_t *d1, dfaddr_t *d2);
Compares two 64 bit values and returns the sign of d1-d2 as a plus or minus 1 or 0 if the two values are equal.

void kar_sub64(dfaddr_t *df, int n);
Subtracts a 32 bit value from a 64 bit value.

void kar_sub6464(dfaddr_t *d1, dfaddr_t *d2, dfaddr_t *d3);
Subtracts d1-d2 and stores the result in d3. The result structure can be one (or both) of the source structures.

Initialization and Connections

The following routines initialize variables and deal with the communication between the client and the server.
void kar_init(char *dir);
Initializes the global variables to a known state and calls kar_conf. This routine should be called by a client prior to calling any of the other routines in the library.

void kar_deinit(void);
The deinit routine is used to close the connection and reset global variables. This would be called by a client who wants to reread the configuration file after it changes. Not a useful feature, but here nonetheless since it was part of the general package on which the kar library was based.

int kar_conf(char *dir);
Reads the configuration file and sets global variables such as the addresses of the servers and the well known port. This routine is normally called by kar_init rather than directly by the client.

int kar_connect(void);
void kar_disconnect(void);
The kar_connect routine establishes a connection to the server and performs authentication to verify it is talking to a trusted server. This routine is normally called by kar_cmd rather than directly by the client. The kar_disconnect routine closes the connection to the server and is normally called by the de_init routine rather than directly by the client.

int kar_cmd(char *msg);
The kar_cmd routine is the main communication routine that the client uses to talk to the server. It assigns a sequence number to the specified message, transmits it to the server and waits for a response. If there is no response it will retry or time out. In most cases, the client will only reference higher level routines that call kar_cmd rather than calling it itself.

int kar_rc(int rc);
The kar_rc routine is used by the kar_cmd routine (and a few others) to set the kar_errno and kar_errmsg variables and return the actual reply code. It also throttles requests that result in "KAR_RETRY" responses to one every 10 seconds to reduce overhead. This routine is not intended to be called directly by the client.

Dump Image Controlling Routines

The client and server manage several concurrent dump images at the same time. Each dump image is assigned a separate connection number or cn. The following routines manipulate those dump images.
int kar_create(int cn, char *name);
Creates a dump image. The dump image name must not already exist. This routine simply adds the name to the name space and assigns the name to the cn.

int kar_access(int cn, int mode, char *name);
The kar_access routine simply assigns the specified dump image name to the cn. The mode field is either KAR_A_READ or KAR_A_WRITE to indicate whether the client intends to modify the entry (which requires a higher authorization level).

int kar_comment(int cn, char *comment);
Sets the comment field associated with the dump image.

int kar_commit(int cn);
Sets the committed flag associated with the dump image.

int kar_open(int cn, int file, int *fd);
Creates a separate TCP connection to the karcd server host (or its designee) for the stream associated with either the data file or the index file of the dump image. A prior kar_create or kar_access call for the cn is required to select the specific dump image. Whether the file descriptor is for reading or writing depends on whether this is a creation or an access. The file parameter is either KAR_A_DATA or KAR_A_INDEX to select the portion of the dump image is to be accessed or created.

int kar_close(int cn, int fd);
Closes a stream opened by kar_open. On success, kar_errno will contain the value KAR_E_COMPLETE and kar_errmsg will indicate the actual number of bytes transferred with the string xfer high+low where high and low are the two halves of the 64 bit byte count. This byte count can be used to verify that the server received all the bytes transferred or vice versa.

int kar_cipher(int cn, max_size, LSC lsc);
After opening an index or data stream, the kar_cipher routine can be used to indicate that the data will be block encrypted with the session key. An encrypted stream on the data channel is subdivided into smaller blocks. Each block is prefixed by a 5 byte header. This header consists of a 4 byte network order integer indicating the length of the encrypted block and a single byte flag code indicating the encryption method (0 for no encryption, 1 for session key encryption).

int kar_getkey(char *key);
The kar_getkey routine is used to retrieve an encryption key from the server. This routine first looks in the local dump_keys file for the key text. If not found it asks the server for the key and then appends it to the end of the dump_keys for next time. The dump_keys are used by kdump to encrypt private files on the dump image data file. These files can only be decrypted by systems that have the encryption key, so files that are to be restorable by multiple systems will need to share their encryption keys. They can be copied from system to system manually or they can stored on the server with the karc -newkey command where kdump will access them automatically.

int kar_read(int cn, dfaddr_t *start, dfaddr_t *length);
After opening an index or data stream for reading, a series of read instructions need to be issued. Specifying NULL for the length of the read will retrieve data to the end of file. Specifying NULL for a starting address indicates the end of the sequence. On success, kar_errno will contain the value KAR_E_READOK and kar_errmsg will indicate the actual length of the read with the string Read high+low. The actual length will differ from the requested length if the requested length is NULL (obviously) or if the requested length would have extended past the end of the file. Subsequent reads on the associated file descriptor are necessary to get the actual data.

Transfer Rates and Bottlenecks

int   kar_report(int cn, char *rate, int n);
The karcd server likes to report transfer rates so bottlenecks can be determined. The kar_report routine can be used by the client to tell the server the transfer rates of its end of the data pipeline. There are several macros that are used to compute the transfer rates.
   KAR_I_VARS
   KAR_I_INIT
   KAR_I_DVARS
   KAR_I_DINIT
   KAR_I_READ
   KAR_I_WRITE(CN, S, N)
   KAR_I_ENCODE(C)
   KAR_I_REPORT(CN, S, N)
The typical single-threaded client use of these is:
       char rate[2];
       KAR_I_VARS

       KAR_I_INIT

	...

       while (!end_of_data) {
         KAR_I_READ
         nbytes = read(...)

         KAR_I_WRITE(KAR_A_CN0, rate[0], 1)
         rc = write(...)
      }
The KAR_I_VARS macro allocates a set of instrumentation variables and the KAR_I_INIT macro initializes them. Each thread should use the KAR_I_READ macro to indicate that it is in the read phase of its operation and the KAR_I_WRITE macro to indicate that it's in its write phase. For multi-threaded operation, there would be one global rate string. The read thread uses the KAR_I_READ macro to indicate that it's collecting data and filling a buffer and KAR_I_WRITE(KAR_A_CN0, rate[0], 2) while waiting for a free buffer. The write thread uses KAR_I_READ prior to waiting for a filled buffer and then uses KAR_I_WRITE(KAR_A_CN0,macro rate[1], 0) while it is flushing the buffer. The KAR_I_WRITE macro with a non-zero third parameter (indicating the number of threads supported) periodically calls the kar_report() routine to report the accumulated instrumentation status to the dæmon.

The dæmon also uses the KAR_I_DVAR, KAR_I_DINIT and KAR_I_ENCODE macros to maintain the transfer rate indicator.

The dæmon reports the results of the instrumentation as part of its normal status display. The results are displayed as four characters representing the four possible threads in the transfer:

  1. The client data gathering thread.
  2. The client thread that flushes data to the network.
  3. The dæmon thread that reads data from the network.
  4. The dæmon thread that writes data to HPSS.
These four characters are coded to represent the percentage of time the thread has spent in its read phase versus its write phase. An @ represents 50% in each. Each lowercase letter a-y represents 2% more time spent in the read phase (a=52%, b=54%... y=100%) while each uppercase letter A-Z indicates 2% less time spent in the read phase (A=48%, B=56%... Y=0%).

After the four characters representing the time spent in each phase by the four threads is an indication of the throughput of the transfer. An uppercase letter indicates seconds per megabyte (A indicates 1-2 seconds, B indicates 2-3... Z indicates more than 26 seconds per megabyte) while a lowercase letter indicates megabytes per second (a indicates 1-2 megabytes, b is 2-3... z is more than 26 megabytes per second).

A typical status line may appear as:

 19460: Dump Active  423.00 PXyi/C  bp09.bp09.1999.03.18.09.1
Indicating that this dump is bottlenecked by the network at 3-4 seconds per megabyte. The dæmon network read thread is spending 100% of its time waiting for data from the network while the client network write thread is spending 98% of its time flushing buffers and the client thread gathering data from disk is spending 82% (P is the 16th letter of the alphabet, 82% = 50% + 2x16) of its time waiting for buffers to be flushed by the write thread. But is has managed to get 423 megabytes transfered so far.

Environment Manipulation

The following routines manipulate the environment in which the kar library operates:
void kar_disect(char *key);
Disects an LSC authentication key into its constituant parts kar_level, kar_group and kar_host. It is normally called by kar_conf when it determines the default key, but can also be used when a client wishes to select a different key to elevate its authority.

void kar_setgrp(char *key, char *group, char *host, char *file);
The kar_setgrp routine is used to select an alternate key, group or host other than the default as extracted from the authentication key. If the first character of a string is an asterisk, the default key, group or host will be used. The main intended purpose of this function is to allow the restore utility to select the alternate host name that created the dump when multiple hosts in the same group are allowed to access each other's dump images.

Dump Image Attributes

The list function retrieves status information about one or more dump images from the server. This information is encoded in a text string that is returned via the kar_errmsg string. The following routines are used to interpret those fields:
int kar_stat_dec(char *buf, kar_stat_t *ks, char **cmt);
char *kar_stat_enc(kar_stat_t *ks, char *cmt);
The kar_stat_dec routine extracts the information from the specified buffer (normally kar_errmsg) into a kar_stat_t structure and sets a pointer to the comment if one exists. The kar_stat_enc routine is what the server uses to encode that information into the KNS value that is also passed back to the client as a reply on a list request.

Server Routines

A few of the routines in the kar library are server side functions that are not meant to be called by the client routines. They are co-located in the library merely for convenience.
int kar_accept(int fd);
Dæmon end of the communication sequence. It accepts a connection, authenticates it and fills in the kar_level, kar_group, kar_host variables.

void kar_reply(int code, int seq, char *reason);
Sends a reply to the client.

Ken Lowe
Email -- ken@u.washington.edu
Web -- http://staff.washington.edu/krl/