| /* |
| * Copyright (c) 2000-2001 Silicon Graphics, Inc. |
| * All Rights Reserved. |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License as |
| * published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it would be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| #ifndef _INV_PRIV_H_ |
| #define _INV_PRIV_H_ |
| |
| #include <sys/file.h> /* for flock */ |
| #include "global.h" |
| #include "inventory.h" |
| #include "mlog.h" |
| |
| |
| /*----------------------------------------------------------------------*/ |
| /* The Inventory stores its data in a hierarchical manner. */ |
| /* */ |
| /* At the first level is the Fstab, which maintains a table of unique */ |
| /* file system ids for all file systems that it knows of. From this fsid*/ |
| /* we can derive the Inventory Index for that file system. */ |
| /* */ |
| /* Inventory Index contains references to all the Storage Objects that */ |
| /* carry data associated with (its) file system. The Storage Objects, */ |
| /* the third level (of indirection) are reserved for certain (variable) */ |
| /* time periods, and the inv-index keeps track of those timeperiods */ |
| /* in its table. In other words, for a given time, there is a unique */ |
| /* stobj that exists to contain a session that occured at that time.. */ |
| /* */ |
| /*----------------------------------------------------------------------*/ |
| |
| #define INV_LOCKFILE inv_lockfile() |
| #define INVTSESS_COOKIE "idbsess0" |
| #define INVT_STOBJ_MAXSESSIONS 5 |
| #define INVT_MAX_INVINDICES -1 /* unlimited */ |
| #define FSTAB_UPDATED 1 |
| #define NEW_INVINDEX 2 |
| |
| /* session flags ( seshdr.sh_flag ) */ |
| #define INVT_PARTIAL (u_int)0x0001 |
| #define INVT_RESUMED (u_int)0x0002 |
| |
| /* media file flags ( mfile.mf_flag ) */ |
| #define INVT_MFILE_GOOD (u_char)0x01 |
| #define INVT_MFILE_INVDUMP (u_char)0x02 |
| |
| #define INVT_ENDTIME BOOL_FALSE |
| #define INVT_STARTTIME BOOL_TRUE |
| #define INVT_DOLOCK BOOL_TRUE |
| #define INVT_DONTLOCK BOOL_FALSE |
| |
| #define INVLOCK( fd, m ) flock( fd, m ) |
| |
| /* return values */ |
| #define INV_OK (intgen_t) 1 |
| #define INV_ERR (intgen_t) -1 |
| |
| #define I_DONE (int) -1 |
| #define I_EMPTYINV (int) -2 |
| |
| /* flags to oref_resolve_new_stobj() */ |
| #define IS_EMPTY BOOL_TRUE |
| #define IS_NOT_EMPTY BOOL_FALSE |
| |
| #define INV_PERMS S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH |
| |
| #define IS_WITHIN(ttpe, tm) ( tm >= (ttpe)->tp_start && \ |
| tm <= (ttpe)->tp_end ) |
| #define IDX_HDR_OFFSET(n) (off64_t) ( sizeof( invt_entry_t ) * \ |
| (size_t) (n)\ |
| + sizeof( invt_counter_t ) ) |
| #define STOBJ_OFFSET( nhdrs, nsess ) (off64_t) ( \ |
| sizeof( invt_sescounter_t ) + \ |
| (size_t) nhdrs * sizeof( invt_seshdr_t ) + \ |
| (size_t) nsess * sizeof( invt_session_t ) ) |
| |
| #define STREQL( n,m ) ( strcmp((n),(m)) == 0 ) |
| #define UUID_EQL( n,m,t ) ( uuid_compare( n, m, t ) == 0 ) |
| #define IS_PARTIAL_SESSION( h ) ( (h)->sh_flag & INVT_PARTIAL ) |
| #define IS_RESUMED_SESSION( h ) ( (h)->sh_flag & INVT_RESUMED ) |
| #define SC_EOF_INITIAL_POS (off64_t) (sizeof( invt_sescounter_t ) + \ |
| INVT_STOBJ_MAXSESSIONS * \ |
| ( sizeof( invt_seshdr_t ) + \ |
| sizeof( invt_session_t ) ) ) |
| |
| #define INV_PERROR(s) mlog( MLOG_NORMAL,"INV: %s %s\n", s,strerror(errno) ) |
| #define INV_OFLAG(f) ( f == INV_SEARCH_ONLY ) ? O_RDONLY: O_RDWR |
| |
| /*----------------------------------------------------------------------*/ |
| /* On Disk Data Structures */ |
| /* */ |
| /*----------------------------------------------------------------------*/ |
| |
| typedef struct invt_session { |
| uuid_t s_sesid; /* this session's id: 16 bytes*/ |
| uuid_t s_fsid; /* file system id */ |
| char s_label[INV_STRLEN]; /* session label */ |
| char s_mountpt[INV_STRLEN];/* path to the mount point */ |
| char s_devpath[INV_STRLEN];/* path to the device */ |
| u_int s_cur_nstreams;/* number of streams created under |
| this session so far */ |
| u_int s_max_nstreams;/* number of media streams in |
| the session */ |
| char s_padding[16]; |
| } invt_session_t; |
| |
| typedef struct invt_seshdr { |
| off64_t sh_sess_off; /* offset to rest of the sessioninfo */ |
| off64_t sh_streams_off; /* offset to start of the set of |
| stream hdrs */ |
| time32_t sh_time; /* time of the dump */ |
| __uint32_t sh_flag; /* for misc flags */ |
| u_char sh_level; /* dump level */ |
| u_char sh_pruned; /* pruned by invutil flag */ |
| char sh_padding[22]; |
| } invt_seshdr_t; |
| |
| |
| /* Each session consists of a number of media streams. While it is given that |
| there won't be multiple writesessions (ie. dumpsessions) concurrently, |
| there can be multiple media streams operating on a single file system, |
| each writing media files within its own stream. Hence, we have a linked |
| list of media files, that the stream keeps track of. */ |
| |
| |
| typedef struct invt_breakpt { |
| xfs_ino_t ino; /* the 64bit inumber */ |
| off64_t offset; /* offset into the file */ |
| } invt_breakpt_t; |
| |
| typedef struct invt_stream { |
| /* duplicate info from mediafiles for speed */ |
| invt_breakpt_t st_startino; /* the starting pt */ |
| invt_breakpt_t st_endino; /* where we actually ended up. this |
| means we've written upto but not |
| including this breakpoint. */ |
| off64_t st_firstmfile; /*offsets to the start and end of*/ |
| off64_t st_lastmfile; /* .. linked list of mediafiles */ |
| char st_cmdarg[INV_STRLEN]; /* drive path */ |
| u_int st_nmediafiles; /* number of mediafiles */ |
| bool_t st_interrupted; /* was this stream interrupted ? */ |
| char st_padding[16]; |
| } invt_stream_t; |
| |
| |
| |
| typedef struct invt_mediafile { |
| uuid_t mf_moid; /* media object id */ |
| char mf_label[INV_STRLEN]; /* media file label */ |
| invt_breakpt_t mf_startino; /* file that we started out with */ |
| invt_breakpt_t mf_endino; /* the dump file we ended this |
| media file with */ |
| off64_t mf_nextmf; /* links to other mfiles */ |
| off64_t mf_prevmf; |
| u_int mf_mfileidx; /* index within the media object */ |
| u_char mf_flag; /* Currently MFILE_GOOD, INVDUMP */ |
| off64_t mf_size; /* size of the media file */ |
| char mf_padding[15]; |
| } invt_mediafile_t; |
| |
| |
| |
| typedef struct invt_timeperiod { |
| time32_t tp_start; |
| time32_t tp_end; |
| } invt_timeperiod_t; |
| |
| typedef struct invt_entry { |
| invt_timeperiod_t ie_timeperiod; |
| char ie_filename[INV_STRLEN]; |
| char ie_padding[16]; |
| } invt_entry_t; |
| |
| /* Cheap Inheritance, and an attempt to avoid a nested type */ |
| #define INVT_COUNTER_FIELDS \ |
| __uint32_t ic_vernum;/* on disk version number for posterity */\ |
| u_int ic_curnum;/* number of sessions/invindices recorded \ |
| so far */ \ |
| u_int ic_maxnum;/* maximum number of sessions/inv_indices \ |
| that we can record on this stobj */ |
| #define INVT_COUNTER_FIELDS_SIZE 0xc |
| |
| typedef struct invt_counter { |
| INVT_COUNTER_FIELDS |
| char ic_padding[0x20 - INVT_COUNTER_FIELDS_SIZE]; |
| } invt_counter_t; |
| |
| typedef struct invt_sescounter { |
| INVT_COUNTER_FIELDS |
| off64_t ic_eof; /* current end of the file, where the next |
| media file or stream will be written to */ |
| char ic_padding[0x20 - ( INVT_COUNTER_FIELDS_SIZE + |
| sizeof( off64_t) )]; |
| } invt_sescounter_t; |
| |
| |
| typedef struct invt_fstab { |
| uuid_t ft_uuid; |
| char ft_mountpt[INV_STRLEN]; |
| char ft_devpath[INV_STRLEN]; |
| char ft_padding[16]; |
| } invt_fstab_t; |
| |
| |
| |
| /*----------------------------------------------------------------------*/ |
| /* The Tokens */ |
| /* */ |
| /*----------------------------------------------------------------------*/ |
| typedef struct invt_desc_entry { |
| int d_invindex_fd; /* open file descriptor of inv index */ |
| int d_stobj_fd; /* fd of storage object */ |
| u_char d_update_flag; /* indicates whether fstab was updated with |
| this file system or not and also if |
| we had to create a new invindex file */ |
| inv_oflag_t d_oflag; /* the open mode (SEARCH_ONLY, SEARCH_N_MOD) */ |
| off64_t d_invindex_off; /* for every session, we need a reference |
| to its invindex entry, so that when we |
| close a session, we know which one */ |
| } invt_desc_entry_t; |
| |
| |
| typedef struct invt_sesdesc_entry { |
| invt_desc_entry_t *sd_invtok; /* generic inventory token */ |
| off64_t sd_session_off; |
| off64_t sd_sesshdr_off; |
| time32_t sd_sesstime; /* time that session started. |
| needed for closing the session */ |
| } invt_sesdesc_entry_t; |
| |
| struct invt_mediafile; |
| |
| typedef struct invt_strdesc_entry { |
| invt_sesdesc_entry_t *md_sesstok; /* the session token */ |
| off64_t md_stream_off;/* offset to the media stream |
| header */ |
| struct invt_mediafile *md_lastmfile; /* just so that we dont have |
| to get it back from disk |
| when we add the next mfile |
| to the linked list */ |
| |
| } invt_strdesc_entry_t; |
| |
| |
| |
| |
| /*----------------------------------------------------------------------*/ |
| /* Info Structures - simple logical containers for sessions and indices */ |
| /* */ |
| /*----------------------------------------------------------------------*/ |
| |
| typedef struct invt_sessinfo { |
| int stobjfd; |
| invt_seshdr_t *seshdr; |
| invt_session_t *ses; |
| invt_stream_t *strms; |
| invt_mediafile_t *mfiles; |
| } invt_sessinfo_t; |
| |
| typedef struct invt_idxinfo { |
| int invfd; |
| invt_counter_t *icnt; |
| invt_entry_t *iarr; |
| u_int index; |
| }invt_idxinfo_t; |
| |
| #define INVT_MOID 1 |
| #define INVT_LABEL 2 |
| #define INVT_NULLTYPE -1 |
| typedef struct invt_mobjinfo { |
| int type; |
| void *value; |
| } invt_mobjinfo_t; |
| |
| |
| typedef struct invt_pr_ctx { |
| int index; |
| int depth; |
| bool_t fstab; |
| bool_t invidx; |
| bool_t invcheck; |
| invt_mobjinfo_t mobj; |
| u_char level; |
| } invt_pr_ctx_t; |
| |
| typedef bool_t (*search_callback_t) (int, invt_seshdr_t *, void *, void *); |
| |
| |
| #define GET_REC( fd, buf, sz, off ) \ |
| get_invtrecord( fd, buf, sz, off, SEEK_SET, INVT_DOLOCK ) |
| |
| #define GET_REC_NOLOCK( fd, buf, sz, off ) \ |
| get_invtrecord( fd, buf, sz, off, SEEK_SET, INVT_DONTLOCK ) |
| |
| #define GET_REC_SEEKCUR( fd, buf, sz, off ) \ |
| get_invtrecord( fd, buf, sz, off, SEEK_CUR, INVT_DOLOCK ) |
| |
| #define GET_ALLHDRS_N_CNTS( fd, h, c, hsz, csz ) \ |
| get_headerinfo( fd, h, c, hsz, csz, INVT_DOLOCK ) |
| |
| #define GET_ALLHDRS_N_CNTS_NOLOCK( fd, h, c, hsz, csz ) \ |
| get_headerinfo( fd, h, c, hsz, csz, INVT_DONTLOCK ) |
| |
| #define PUT_REC( fd, buf, sz, off ) \ |
| put_invtrecord( fd, buf, sz, off, SEEK_SET, INVT_DOLOCK ) |
| |
| #define PUT_REC_NOLOCK( fd, buf, sz, off ) \ |
| put_invtrecord( fd, buf, sz, off, SEEK_SET, INVT_DONTLOCK ) |
| |
| #define PUT_REC_SEEKCUR( fd, buf, sz, off ) \ |
| put_invtrecord( fd, buf, sz, off, SEEK_CUR, INVT_DOLOCK ) |
| |
| #define PUT_REC_NOLOCK_SEEKCUR( fd, buf, sz, off ) \ |
| put_invtrecord( fd, buf, sz, off, SEEK_CUR, INVT_DONTLOCK ) |
| |
| |
| #define GET_COUNTERS( fd, cnt ) get_counters( fd, (void **)(cnt), \ |
| sizeof(invt_counter_t) ) |
| #define GET_SESCOUNTERS( fd, cnt ) get_counters( fd, (void **)(cnt), \ |
| sizeof(invt_sescounter_t) ) |
| |
| #define PUT_COUNTERS( fd, cnt ) PUT_REC_NOLOCK( fd, (void *)(cnt), \ |
| sizeof( invt_counter_t ), \ |
| (off64_t) 0 ) |
| |
| #define PUT_SESCOUNTERS( fd, cnt ) PUT_REC_NOLOCK( fd, (void *)(cnt), \ |
| sizeof( invt_sescounter_t ), \ |
| (off64_t) 0 ) |
| |
| #define GET_SESHEADERS( fd, hdrs, n ) get_headers( fd, (void**)(hdrs), \ |
| (size_t) ( n * sizeof(invt_seshdr_t ) ),\ |
| sizeof( invt_sescounter_t ) ) |
| |
| #define GET_ENTRIES(fd, hdrs, n, sz) get_headers(fd, (void**)(hdrs), \ |
| (size_t) (n * sz), sizeof(invt_counter_t)) |
| |
| /*----------------------------------------------------------------------*/ |
| /* Function Prototypes */ |
| /* */ |
| /* */ |
| /*----------------------------------------------------------------------*/ |
| |
| |
| /*----------------------------------------------------------------------*/ |
| inv_idbtoken_t |
| idx_create( char *fname, inv_oflag_t forwhat ); |
| |
| intgen_t |
| idx_create_entry( inv_idbtoken_t *tok, int invfd, bool_t firstentry ); |
| |
| intgen_t |
| idx_put_sesstime( inv_sestoken_t tok, bool_t whichtime); |
| |
| |
| int |
| idx_find_stobj( invt_idxinfo_t *idx, time32_t tm ); |
| |
| u_int |
| idx_insert_newentry( int fd, int *stobjfd, invt_entry_t *iarr, |
| invt_counter_t *icnt, |
| time32_t tm ); |
| intgen_t |
| idx_put_newentry( invt_idxinfo_t *idx, invt_entry_t *ient ); |
| |
| int |
| idx_get_stobj( int invfd, inv_oflag_t forwhat, int *index ); |
| |
| intgen_t |
| idx_recons_time( time32_t tm, invt_idxinfo_t *idx ); |
| |
| intgen_t |
| idx_DEBUG_printinvindices( invt_entry_t *iarr, u_int num ); |
| |
| intgen_t |
| idx_DEBUG_print ( int fd ); |
| |
| /*----------------------------------------------------------------------*/ |
| |
| int |
| stobj_create( char *fname ); |
| |
| intgen_t |
| stobj_create_session( inv_sestoken_t tok, int fd, invt_sescounter_t *sescnt, |
| invt_session_t *ses, invt_seshdr_t *hdr ); |
| |
| intgen_t |
| stobj_put_mediafile( inv_stmtoken_t tok, invt_mediafile_t *mf ); |
| |
| off64_t |
| stobj_put_session( |
| int fd, |
| invt_sescounter_t *sescnt, |
| invt_session_t *ses, |
| invt_seshdr_t *hdr, |
| invt_stream_t *strms, |
| invt_mediafile_t *mfiles ); |
| |
| intgen_t |
| stobj_put_streams( int fd, invt_seshdr_t *hdr, invt_session_t *ses, |
| invt_stream_t *strms, |
| invt_mediafile_t *mfiles ); |
| |
| int |
| stobj_hdrcmp( const void *h1, const void *h2 ); |
| |
| intgen_t |
| stobj_sortheaders( int fd, u_int num ); |
| |
| u_int |
| stobj_find_splitpoint( int fd, invt_seshdr_t *harr, u_int ns, time32_t tm ); |
| |
| intgen_t |
| stobj_split( invt_idxinfo_t *idx, int fd, invt_sescounter_t *sescnt, |
| invt_sessinfo_t *newsess ); |
| bool_t |
| stobj_replace_session( int fd, invt_sescounter_t *sescnt, invt_session_t *ses, |
| invt_seshdr_t *hdr, invt_sessinfo_t *newsess ); |
| |
| intgen_t |
| stobj_delete_mfile( int fd, inv_stream_t *strm, invt_mediafile_t *mf, |
| off64_t mfileoff ); |
| |
| bool_t |
| stobj_pack_sessinfo( int fd, invt_session_t *ses, invt_seshdr_t *hdr, |
| void **bufpp, size_t *bufszp ); |
| |
| bool_t |
| stobj_unpack_sessinfo( |
| void *bufp, |
| size_t bufsz, |
| invt_sessinfo_t *s ); |
| |
| bool_t |
| stobj_delete_sessinfo( int fd, invt_sescounter_t *sescnt, |
| invt_session_t *ses, invt_seshdr_t *hdr ); |
| |
| bool_t |
| stobj_delete_mobj( int fd, invt_seshdr_t *hdr, void *arg, |
| void **buf ); |
| |
| intgen_t |
| stobj_get_sessinfo ( inv_sestoken_t tok, invt_seshdr_t *hdr, invt_session_t *ses ); |
| |
| void |
| stobj_makefname( char *fname ); |
| |
| intgen_t |
| stobj_insert_session( invt_idxinfo_t *idx, int fd, |
| invt_sessinfo_t *s ); |
| |
| intgen_t |
| stobj_make_invsess( int fd, inv_session_t **buf, invt_seshdr_t *hdr ); |
| |
| intgen_t |
| stobj_copy_invsess( int fd, invt_seshdr_t *hdr, invt_session_t *ses, |
| inv_session_t **buf); |
| |
| void |
| DEBUG_sessionprint( inv_session_t *ses, u_int ref, invt_pr_ctx_t *prctx); |
| |
| void |
| DEBUG_sessprint( invt_session_t *ses ); |
| |
| bool_t |
| stobj_getsession_byuuid(int fd, invt_seshdr_t *hdr, void *sesid, void **buf); |
| |
| bool_t |
| stobj_getsession_bylabel(int fd, invt_seshdr_t *hdr, void *label, void **buf); |
| |
| |
| void |
| stobj_convert_session(inv_session_t *ises, invt_session_t *ses, |
| invt_seshdr_t *hdr); |
| |
| void |
| stobj_convert_strm(inv_stream_t *expstrm, invt_stream_t *strm); |
| |
| void |
| stobj_convert_mfile(inv_mediafile_t *expmf, invt_mediafile_t *mf); |
| |
| void |
| stobj_convert_sessinfo(inv_session_t **buf, invt_sessinfo_t *sinfo); |
| |
| /*----------------------------------------------------------------------*/ |
| |
| intgen_t |
| fstab_get_fname( void *pred, char *fname, inv_predicate_t bywhat, |
| inv_oflag_t forwhat ); |
| |
| intgen_t |
| fstab_put_entry( uuid_t *fsidp, char *mntpt, char *dev, inv_oflag_t forwhat ); |
| |
| intgen_t |
| fstab_getall( invt_fstab_t **arr, invt_counter_t **cnt, int *numfs, |
| inv_oflag_t forwhat ); |
| |
| void |
| fstab_DEBUG_print( invt_fstab_t *arr, int num ); |
| |
| |
| /*----------------------------------------------------------------------*/ |
| |
| intgen_t |
| get_invtentry( char *fname, time32_t tm, invt_entry_t *buf, size_t bufsz ); |
| |
| intgen_t |
| get_invtrecord( int fd, void *buf, size_t bufsz, off64_t off, int, bool_t dolock ); |
| |
| intgen_t |
| put_invtrecord( int fd, void *buf, size_t bufsz, off64_t off, int, bool_t dolock ); |
| |
| inv_idbtoken_t |
| get_token( int fd, int objfd ); |
| |
| void |
| destroy_token( inv_idbtoken_t tok ); |
| |
| |
| intgen_t |
| get_headers( int fd, void **hdrs, size_t bufsz, size_t cntsz ); |
| |
| intgen_t |
| get_counters( int fd, void **cntpp, size_t sz ); |
| |
| intgen_t |
| get_sescounters( int fd, invt_sescounter_t **cntpp ); |
| |
| intgen_t |
| get_lastheader( int fd, void **ent, size_t hdrsz, size_t cntsz ); |
| |
| |
| inv_sestoken_t |
| get_sesstoken( inv_idbtoken_t tok ); |
| |
| intgen_t |
| get_headerinfo( int fd, void **hdrs, void **cnt, |
| size_t hdrsz, size_t cntsz, bool_t doblock ); |
| |
| bool_t |
| invmgr_query_all_sessions (void *inarg, void **outarg, search_callback_t func); |
| |
| intgen_t |
| search_invt( int invfd, void *arg, void **buf, |
| search_callback_t do_chkcriteria ); |
| intgen_t |
| invmgr_inv_print( int invfd, invt_pr_ctx_t *prctx); |
| |
| intgen_t |
| invmgr_inv_check( int invfd ); |
| |
| bool_t |
| tm_level_lessthan( int fd, invt_seshdr_t *hdr, void *arg, |
| void **tm ); |
| |
| bool_t |
| lastsess_level_lessthan( int fd, invt_seshdr_t *hdr, void *arg, |
| void **buf ); |
| |
| bool_t |
| lastsess_level_equalto( int fd, invt_seshdr_t *hdr, void *arg, void **buf ); |
| |
| intgen_t |
| DEBUG_displayallsessions( int fd, invt_seshdr_t *hdr, u_int ref, |
| invt_pr_ctx_t *prctx); |
| |
| intgen_t |
| make_invdirectory( inv_oflag_t forwhat ); |
| |
| bool_t |
| init_idb( void *pred, inv_predicate_t bywhat, inv_oflag_t forwhat, |
| inv_idbtoken_t *tok ); |
| |
| intgen_t |
| inv_getopt( int argc, char **argv, invt_pr_ctx_t *prctx); |
| |
| bool_t |
| insert_session( invt_sessinfo_t *s); |
| |
| /* To reconstruct a complete inventory from dumped inventories */ |
| extern bool_t |
| inv_put_sessioninfo( invt_sessinfo_t *s ); |
| |
| |
| #endif |