Пример #1
0
intgen_t
stobj_get_sessinfo ( inv_sestoken_t tok, invt_seshdr_t *hdr, 
		     invt_session_t *ses )
{
	int rval;
	int fd = tok->sd_invtok->d_stobj_fd; 

	/* get the session header first */
	if ( ( rval = GET_REC_NOLOCK( fd, hdr, sizeof( invt_seshdr_t ),
			     tok->sd_sesshdr_off ) ) > 0 ) {
		rval = GET_REC_NOLOCK( fd, ses, sizeof( invt_session_t ),
			     tok->sd_session_off );
	}
	
	return rval;
}
Пример #2
0
intgen_t
get_counters( int fd, void **cntpp, size_t cntsz )
{
	/* object must be locked at least SHARED by caller */
	u_int num;
	ASSERT( cntsz >= sizeof( invt_counter_t ) );

	*cntpp =  calloc( 1, cntsz);

	/* find the number of sessions and the max possible */
	if ( GET_REC_NOLOCK( fd, (void *) *cntpp, cntsz, (off64_t) 0 ) < 0 ) {
		free( *cntpp );
		*cntpp = NULL;
		return -1;
	}
	
	num = ((invt_counter_t *)(*cntpp))->ic_curnum;

	if ( ( (invt_counter_t *)(*cntpp))->ic_vernum != INV_VERSION ) {
		mlog( MLOG_NORMAL | MLOG_INV, 
		      "INV : Unknown version %d - Expected version %d \n",
		      (int) ( (invt_counter_t *)(*cntpp))->ic_vernum,
		      (int) INV_VERSION );
		ASSERT ( ((invt_counter_t *)(*cntpp))->ic_vernum ==
			INV_VERSION );
	} 

	return (intgen_t) num;
}
Пример #3
0
bool_t
stobj_getsession_bylabel(
	int fd, 
	invt_seshdr_t *hdr, 
	void *seslabel,
	void **buf )
{
	invt_session_t ses;

	/* retrieve the session */
	if ( GET_REC_NOLOCK( fd, &ses, sizeof( invt_session_t ),
			     hdr->sh_sess_off ) < 0 )
		return -1;

	/* now see if this is the one that caller is askin for */
	if (! STREQL(ses.s_label, (char *)seslabel)) {
		return BOOL_FALSE;	
	}

	/* yay. we found the session. so, make the session struct and 
	   put it in the buffer */
	stobj_copy_invsess(fd, hdr, &ses, (inv_session_t **)buf);

	return BOOL_TRUE;
	
}	
Пример #4
0
intgen_t
stobj_make_invsess( int fd, inv_session_t **buf, invt_seshdr_t *hdr )
{
	invt_session_t ses;

	/* load in the rest of the session, but not the streams */
	if ( GET_REC_NOLOCK( fd, &ses, sizeof(ses), hdr->sh_sess_off )
	    < 0 ) {
		return -1;
	}
	
	return stobj_copy_invsess(fd, hdr, &ses, buf);
}
Пример #5
0
intgen_t
get_headers( int fd, void **hdrs, size_t bufsz, size_t off )
{

	*hdrs = malloc( bufsz );
	if ( *hdrs == NULL ) {
		INV_PERROR( "get_headers() - malloc(seshdrs)\n" );
		return -1;
	}
	/* file must be locked at least SHARED by caller */

	/* get the array of hdrs */
	if ( GET_REC_NOLOCK( fd, (void *) *hdrs, bufsz, (off64_t)off ) < 0 ) {
		free ( *hdrs );
		*hdrs = NULL;
		return -1;
	}
	
	return 1;
}
Пример #6
0
intgen_t
stobj_sortheaders( int fd, u_int num )
{
	size_t sz = sizeof( invt_seshdr_t ) * num;
	invt_seshdr_t *hdrs;
#ifdef INVT_DEBUG
	int i;
#endif
	if ( num < 2 ) return 1;

	hdrs = malloc( sz );
	ASSERT( hdrs );

	if ( GET_REC_NOLOCK( fd, hdrs, sz, STOBJ_OFFSET( 0, 0 ) ) < 0 ) {
		free ( hdrs );
		return -1;
	}
#ifdef INVT_DEBUG
	printf("\nBEF\n" );
	for (i=0; i<(int)num; i++)
		printf("%ld\n", (long) hdrs[i].sh_time );
#endif	
	qsort( (void*) hdrs, (size_t) num, 
	      sizeof( invt_seshdr_t ), stobj_hdrcmp );

#ifdef INVT_DEBUG
	printf("\n\nAFT\n" );
	for (i=0; i<(int)num; i++)
		printf("%ld\n", (long) hdrs[i].sh_time );
#endif
	if ( PUT_REC_NOLOCK( fd, hdrs, sz, STOBJ_OFFSET( 0, 0 ) ) < 0 ) {
		free ( hdrs );
		return -1;
	}
	
	free ( hdrs );
	return 1;

}
Пример #7
0
/* ARGSUSED */
bool_t
stobj_delete_mobj(int fd, 
		  invt_seshdr_t *hdr, 
		  void *arg ,
		  void **buf )
{
	/* XXX fd needs to be locked EX, not SH */
	uuid_t *moid = *buf;
	invt_session_t ses;
	invt_stream_t  *strms;
	off64_t		off;
	invt_mediafile_t *mf, *mfiles;
	u_int 		nmfiles;
	u_int		i, j;
	bool_t 		dirty;

	if ( GET_REC_NOLOCK( fd, &ses, sizeof( invt_session_t ),
			     hdr->sh_sess_off ) < 0 )
		return -1;

	/* now get all the streams of this session */
	strms = calloc ( ses.s_cur_nstreams, sizeof( invt_stream_t ) );
	if ( GET_REC_NOLOCK( fd, strms, 
			     sizeof( invt_stream_t ) * ses.s_cur_nstreams, 
			     hdr->sh_streams_off ) < 0 ) {
		free ( strms );
		return BOOL_FALSE;
	}
	
	/* now look at all the mediafiles in all the streams */
	for ( i = 0; i < ses.s_cur_nstreams; i++ ) {
		off = strms[i].st_firstmfile;
		nmfiles = strms[i].st_nmediafiles;
		mfiles = mf = calloc( nmfiles, sizeof( invt_mediafile_t ) );
		for ( j = 0; j < nmfiles; 
		     j++, 
		     off = mf->mf_nextmf,
		     mf++ ) {
				
/*  The prob is that we need to keep track of where we got these mfiles from
    as we get them, or we wont know how to put them back if they are dirty.
*/
			ASSERT( off );
			if ( GET_REC_NOLOCK( fd, mf, 
					     sizeof( invt_mediafile_t ),
					     off ) <= 0 ) {
				free( strms );
				free( mfiles );
				return BOOL_FALSE;
			}
		}

		/* We have all the media files of this stream. Make another
		   pass, checking to see if we need to remove any mfiles */
 		dirty = BOOL_FALSE;

		for ( j = 0; j < nmfiles; j++ ) {
			mf = &mfiles[j];
			if ( !uuid_compare( mf->mf_moid, *moid ) ) {
#ifdef INVT_DEBUG
				printf(" found one\n" );
#endif

/*                                dirty = BOOL_TRUE;	

				if ( j == 0 )
				       strms[i].st_firstmfile = mf->mf_nextmf;
				else
				       mfiles[j-1].mf_nextmf = mf->mf_nextmf;

				if ( j == nmfiles - 1 )
				       strms[i].st_lastmfile = ;
*/
			}

		}
		free ( mfiles );
		if ( dirty );
	}

	free ( strms );

	return BOOL_FALSE; /* ret FALSE, or it'll stop iteration */
}
Пример #8
0
bool_t
stobj_pack_sessinfo( int fd, invt_session_t *ses, invt_seshdr_t *hdr,
		     void  **bufpp, size_t *bufszp )
{
	size_t	      	stmsz;
	u_int		i, j;
	size_t		sessz;
	invt_stream_t  *strms;
	char	       *sesbuf, *sesbufcp;
	off64_t		off;
	invt_mediafile_t mf;

	stmsz = sizeof( invt_stream_t ) * ses->s_cur_nstreams;

	/* the initial size without the mediafiles */
	sessz = strlen( INVTSESS_COOKIE ) * sizeof( char ) +
		sizeof( inv_version_t ) +
		sizeof( inv_version_t ) +  /* added to fix 64 bit alignment prob */
		sizeof( invt_session_t) + sizeof( invt_seshdr_t ) + stmsz;

	/* now get all the streams of this session */
	strms = calloc ( ses->s_cur_nstreams, sizeof( invt_stream_t ) );
	if ( GET_REC_NOLOCK( fd, strms, stmsz, hdr->sh_streams_off ) < 0 ) {
		free ( strms );
		return BOOL_FALSE;
	}
	
	for ( i = 0; i < ses->s_cur_nstreams; i++ )
		sessz += sizeof( invt_mediafile_t ) * 
			 (size_t) strms[i].st_nmediafiles;

	/* Now we know how big this entire thing is going to be */
	sesbufcp = sesbuf = calloc( 1, sessz );
	ASSERT( sesbuf );

	/* Copy everything. Note that we don't bother to adjust the offsets
	   either in the seshdr or in the mediafiles, because we don't need
	   those in order to restore this session ( since everything's 
	   contiguous ) */

	/* magic cookie that we put for sanity checking in case of an 
	   earthquake or something :) */
	strcpy( sesbuf, INVTSESS_COOKIE ); 
	sesbuf += (size_t)( strlen( INVTSESS_COOKIE ) * sizeof( char ) );
	
	/* This was originally INV_VERSION. Changed it to mean packed inventory 
	 * version number and added another inv_version_t to contain the INV_VERSION.
	 * The primary intent of this change was to make everything 64 bit aligned,
	 * but we also got the advantage of separating the packed inv version from
	 * the general inventory version
	 */
	*(inv_version_t *)sesbuf = INT_GET(PACKED_INV_VERSION, ARCH_CONVERT);
	sesbuf += sizeof( inv_version_t );

	/* This has the INV_VERSION */
	*(inv_version_t *)sesbuf = INT_GET(INV_VERSION, ARCH_CONVERT);
	sesbuf += sizeof( inv_version_t );

	xlate_invt_seshdr(hdr, (invt_seshdr_t *)sesbuf, 1);
	sesbuf += sizeof( invt_seshdr_t );

	xlate_invt_session( ses, (invt_session_t *)sesbuf, 1 );
	sesbuf += sizeof( invt_session_t );

	for ( i = 0; i < ses->s_cur_nstreams; i++ ) {
		xlate_invt_stream( strms, (invt_stream_t *)sesbuf, 1 );
		sesbuf += sizeof( invt_stream_t );
	}

	/* now append all the mediafiles */
	for ( i = 0; i < ses->s_cur_nstreams; i++ ) {
		off = strms[i].st_firstmfile;
		for ( j = 0; j < strms[i].st_nmediafiles; 
		     j++, 
		     off = mf.mf_nextmf ) {
			ASSERT( off );
			if ( GET_REC_NOLOCK( fd, &mf, 
					     sizeof( invt_mediafile_t ),
					     off ) <= 0 ) {
				free( strms );
				free( sesbuf );
				return BOOL_FALSE;
			}
			xlate_invt_mediafile(&mf, (invt_mediafile_t *)sesbuf, 1);
			sesbuf += sizeof( invt_mediafile_t );
		}
	}

	free( strms );
	*bufpp = sesbufcp;
	*bufszp = sessz;

	return BOOL_TRUE;
}
Пример #9
0
intgen_t
stobj_put_mediafile( inv_stmtoken_t tok, invt_mediafile_t *mf )
{
	int  rval;
	invt_sescounter_t *sescnt = NULL;
	invt_stream_t stream;
	inv_sestoken_t sestok = tok->md_sesstok;
	int fd =  sestok->sd_invtok->d_stobj_fd;
	off64_t pos;

	/* first we need to find out where the current write-position is.
	   so, we first read the sescounter that is at the top of this
	   storage object */
	if ( GET_SESCOUNTERS( fd, &sescnt ) < 0 )
		return -1;

	pos = sescnt->ic_eof;

	/* increment the pointer to give space for this media file */
	sescnt->ic_eof += (off64_t) sizeof( invt_mediafile_t );

	if ( PUT_SESCOUNTERS( fd, sescnt ) < 0 )
		return -1;

	/* get the stream information, and update number of mediafiles.
	   we also need to link the new mediafile into the linked-list of
	   media files of this stream */

	if ( GET_REC_NOLOCK( fd, &stream, sizeof( stream ), 
			     tok->md_stream_off ) < 0 )
		return -1;

	/* We need to update the last ino of this STREAM, which is now the
	   last ino of the new mediafile. If this is the first mediafile, we
	   have to update the startino as well. Note that ino is a <ino,off>
	   tuple */
	if ( ! ( mf->mf_flag & INVT_MFILE_INVDUMP )) {
		if ( stream.st_nmediafiles == 0 )
			stream.st_startino = mf->mf_startino;
		stream.st_endino = mf->mf_endino;
	}

	stream.st_nmediafiles++;
#ifdef INVT_DEBUG
	mlog (MLOG_VERBOSE, "#################### mediafile #%d "
	      "###################\n", stream.st_nmediafiles);
#endif	
	/* add the new mediafile at the tail of the list */
	
	mf->mf_nextmf = tok->md_stream_off; 
	mf->mf_prevmf = stream.st_lastmfile;

	
	if ( tok->md_lastmfile )
		tok->md_lastmfile->mf_nextmf = pos;	
	else {
		stream.st_firstmfile = pos;
	}

	stream.st_lastmfile = pos;

	
	/* write the stream to disk */
	if ( PUT_REC_NOLOCK( fd, &stream, sizeof( stream ), 
			     tok->md_stream_off ) < 0 )
		return -1;
	
	/* write the prev media file to disk too */
	if ( tok->md_lastmfile ) {
		rval = PUT_REC_NOLOCK( fd, tok->md_lastmfile, 
				       sizeof( invt_mediafile_t ), 
				       mf->mf_prevmf );
		free (  tok->md_lastmfile );
		if ( rval < 0 ) 
			return -1;
	}

	if ( ! ( mf->mf_flag & INVT_MFILE_INVDUMP )) {
		tok->md_lastmfile = mf;
	} else {
		tok->md_lastmfile = NULL;
	}

	/* at last, write the new media file to disk */
	rval = PUT_REC_NOLOCK( fd, mf, sizeof( invt_mediafile_t ), pos );
	if ( rval < 0 ) {
		return -1;
	}

	return rval;
}
Пример #10
0
/*----------------------------------------------------------------------*/
intgen_t
stobj_insert_session( invt_idxinfo_t *idx,
		      int fd, /* kept locked EX by caller */
		      invt_sessinfo_t *s )
{
	invt_sescounter_t *sescnt = NULL;
	
	if ( GET_SESCOUNTERS( fd, &sescnt ) < 0 ) {
		INVLOCK( fd, LOCK_UN );
		return -1;
	}

	/* Check the existing sessions to make sure that we're not
	   duplicating this session */
	if ( sescnt->ic_curnum > 0 ) {
		u_int i;
		invt_session_t	*sessions = calloc( sescnt->ic_curnum, 
				   sizeof( invt_session_t ) );
		if ( GET_REC_NOLOCK( fd, sessions, sescnt->ic_curnum *
				     sizeof( invt_session_t ), 
				     (off64_t) ( sizeof( *sescnt ) + 
         		sescnt->ic_maxnum * sizeof( invt_seshdr_t ))) < 0 ) {
			free ( sescnt );
			free ( sessions );
			return -1;
		}

		for( i = 0; i <  sescnt->ic_curnum; i++ ) {
			if ( uuid_compare( sessions[i].s_sesid, 
					   s->ses->s_sesid ) == 0 )
				break;

		}
		free ( sessions );
		if ( i < sescnt->ic_curnum ) {
			mlog( MLOG_DEBUG | MLOG_INV, 
			      "INV: attempt to insert an "
			      "existing session.\n"
			     );
			free ( sescnt );
			return 1;
		}

	}

	if ( sescnt->ic_curnum >= sescnt->ic_maxnum ) {
		if ( stobj_split( idx, fd, sescnt, s ) < 0 ) {
			free( sescnt );
			return -1;
		}
		free( sescnt );
		return 1;
		
	}
			
	if ( stobj_put_session( fd, sescnt, s->ses, s->seshdr, s->strms,
			        s->mfiles ) < 0 ){
		free ( sescnt);
		return -1;
	}
	
	free ( sescnt);
	return 1;
}
Пример #11
0
intgen_t
stobj_split( invt_idxinfo_t *idx, int fd, invt_sescounter_t *sescnt, 
	     invt_sessinfo_t *newsess )
{
	invt_seshdr_t 	*harr = NULL;
	u_int          	i, ix, ns = sescnt->ic_curnum;
	void        	*bufpp;
	size_t        	bufszp;
	invt_sessinfo_t sesinfo;
	invt_entry_t 	ient;

	if ( GET_SESHEADERS( fd, &harr, ns ) < 0 )
		return -1;
	
	ASSERT( harr != NULL );

	if ( ( ix = stobj_find_splitpoint( fd, harr, ns, 
				       newsess->seshdr->sh_time ) ) == 0 )
		return -1;
	
	if ( ix == ns ) {
		ient.ie_timeperiod.tp_start = ient.ie_timeperiod.tp_end = 
			 newsess->seshdr->sh_time;
	} else {
		ient.ie_timeperiod.tp_start = ient.ie_timeperiod.tp_end = 
		harr[ix].sh_time;
		if ( harr[ix - 1].sh_time >  newsess->seshdr->sh_time )
			idx->iarr[idx->index].ie_timeperiod.tp_end 
				= harr[ix - 1].sh_time;
		else
			idx->iarr[idx->index].ie_timeperiod.tp_end 
				= newsess->seshdr->sh_time;
	}

	/* Get the new stobj to put the 'spilling' sessinfo in. We know the
	   idx of the current stobj, and by definition, the new stobj
	   should come right afterwards. */
	newsess->stobjfd = idx_put_newentry( idx, &ient );
	if ( newsess->stobjfd < 0 )
		return -1;
	
	if ( ix == ns ) {
		invt_sescounter_t *scnt = NULL;
		off64_t rval;

		/* We dont need to split. So, just put the new session in
		   the new stobj, and rest in peace */
		idx->index++;
		
		if ( GET_SESCOUNTERS( newsess->stobjfd, &scnt ) < 0 )
			return -1;
		
		rval = stobj_put_session( newsess->stobjfd, scnt, 
				        newsess->ses,
				        newsess->seshdr, newsess->strms, 
				        newsess->mfiles );
		free( scnt );
		return (rval < 0)? -1: 1;
	}
		
	

	for ( i = ix; i < ns; i++ ) {
		invt_session_t session;
		bufpp = NULL;
		bufszp = 0;

		newsess->seshdr->sh_sess_off = harr[i].sh_sess_off;
		
		if ( GET_REC_NOLOCK( fd, &session, sizeof( invt_session_t ),
			     harr[i].sh_sess_off ) < 0 )
			return -1;
		if (! stobj_pack_sessinfo( fd, &session, &harr[i], &bufpp,
					   &bufszp ))
			return -1;
		/* Now we need to put this in the new StObj. So, first
		   unpack it. */
		if (! stobj_unpack_sessinfo( bufpp, bufszp, &sesinfo ) )
			return -1;

		/* There is no chance of a recursion here */
		if ( stobj_insert_session( idx, newsess->stobjfd, &sesinfo )
		     < 0 ) 
			return -1;
		
		/* Now delete that session from this StObj */
		if (! stobj_delete_sessinfo( fd, sescnt, &session, 
					     &harr[i] ) )
			return -1;
		free( bufpp );
	}
	/* Put the new session in the stobj that we just split. Make
	   sure that we use the updated sescnt and not the stale stuff
	   from disk. stobj_put_session() writes sescnt and sessinfo to
	   disk */ 
	if ( stobj_put_session( fd, sescnt, newsess->ses, newsess->seshdr, 
			        newsess->strms, newsess->mfiles ) < 0 ) {
		free ( sescnt);
		return -1;
	}	

	
	return 1;
}
Пример #12
0
intgen_t
stobj_copy_invsess(int fd,  
		   invt_seshdr_t *hdr,
		   invt_session_t *ses,
		   inv_session_t **buf)
{
	inv_session_t  *ises;
	invt_stream_t  *strms;
	int i;
	invt_mediafile_t mf;

	strms = calloc ( ses->s_cur_nstreams, sizeof( invt_stream_t ) ); 

	/* load in all the stream-headers */
	if ( GET_REC_NOLOCK( fd, strms, 
			     ses->s_cur_nstreams * sizeof( invt_stream_t ), 
			     hdr->sh_streams_off ) < 0 ) {
		free (strms);
		return -1;
	}

	ises = calloc( 1, sizeof( inv_session_t ) );
	stobj_convert_session(ises, ses, hdr);
	ises->s_streams = calloc(ses->s_cur_nstreams, sizeof( inv_stream_t ));
	
	/* fill in the stream structures too */
	i = (int) ses->s_cur_nstreams;
	while ( i-- ) {
		off64_t		 off;
		u_int            j, nmf;
		
		stobj_convert_strm(&ises->s_streams[i], &strms[i]);
		nmf = strms[i].st_nmediafiles;
		off = strms[i].st_firstmfile;

		if (nmf)
			ises->s_streams[i].st_mediafiles = calloc( nmf,
						    sizeof( inv_mediafile_t ) );
		ASSERT( !nmf || ises->s_streams[i].st_mediafiles );

		for ( j = 0; j < nmf; 
		      j++, 
		      off = mf.mf_nextmf ) {
			ASSERT( off );
			if ( GET_REC_NOLOCK( fd, &mf, 
					     sizeof( invt_mediafile_t ),
					     off ) <= 0 ) {
				INV_PERROR( "stobj::make_invsess\n" );
				free( strms );
				free( ises );
				return -1;
			}

			/* copy the mediafile into the exported structure */
			if (ises->s_streams[i].st_mediafiles) {
				stobj_convert_mfile( &ises->s_streams[i].st_mediafiles[j],
						&mf);
			} else {
				mlog(MLOG_ERROR, _(
					"Failed to get data from media file: "
					"possible file corruption\n") );
				mlog_exit_hint(RV_CORRUPT);
				return -1;
			}
		}
		
	}
	

	free( strms );
	*buf = ises;

	return 1;
}