xfsrestore: fix fs uuid order check for incremental restores
PATCH 1/1 xfsrestore: fix fs uuid order check for incremental restores
Restoring an incremental level 1 dump will fail with the following error if the fs uuid of the most recent level 0 dump in the inventory does not match level 1 dump we are restoring.
xfsrestore: ERROR: selected dump not based on previously applied dump
This can happen when you have multiple filesystems and you are restoring a level 1 or greater dump of filesystem FS1 but the most recent level 0 dump in the inventory was filesystem FS2
The fix is to ensure the fs uuid of the inventory entry and the dump to be restored match.
--- dump/content.c | 8 ++- inventory/inv_api.c | 108 ++++++++++++++++++++++++++++++-------------------- inventory/inv_mgr.c | 32 ++++++++++---- inventory/inv_priv.h | 7 +-- inventory/inventory.h | 5 ++ restore/content.c | 17 +++++-- 6 files changed, 113 insertions(+), 64 deletions(-)
dump/content.c +5 -2
@@ -872,7 +872,7 @@ content_init( intgen_t argc, sameinterruptedpr =BOOL_FALSE ; interruptedpr =BOOL_FALSE ; - ok =inv_get_session_byuuid ( &baseuuid, &sessp ); + ok =inv_get_session_byuuid ( &fsid, &baseuuid, &sessp );if ( ! ok ) { mlog( MLOG_NORMAL | MLOG_ERROR, _( "could not find specified base dump (%s) "
@@ -983,7 +983,8 @@ content_init( intgen_t argc, "online inventory not available\n") );return BOOL_FALSE ; } - ok =inv_lastsession_level_lessthan ( inv_idbt, + ok =inv_lastsession_level_lessthan ( &fsid, + inv_idbt, (u_char_t )sc_level, &sessp );if ( ! ok ) {
@@ -1022,7 +1023,8 @@ content_init( intgen_t argc,if ( inv_idbt !=INV_TOKEN_NULL ) {/* REFERENCED */ bool_t ok1; - ok =inv_lastsession_level_equalto ( inv_idbt, + ok =inv_lastsession_level_equalto ( &fsid, + inv_idbt, (u_char_t )sc_level, &sessp ); ok1 =inv_close ( inv_idbt );
inventory/inv_api.c +0 -0
@@ -596,69 +596,78 @@ inv_free_session(
/*----------------------------------------------------------------------*/
-/* inventory_lasttime_level_lessthan */
-/* */
-/* Given a token that refers to a file system, and a level, this returns*/
-/* the last time when a session of a lesser level was done. */ -/* */ -/* returns -1 on error. */
+/* inv_lasttime_level_lessthan */
+/* */
+/* Given a file system uuid, token that refers to a file system, and a */
+/* level, tm is populated with last time when a session of a lesser */
+/* level was done. */
+/* */
+/* Returns TRUE on success. */
/*----------------------------------------------------------------------*/
bool_t
inv_lasttime_level_lessthan( - inv_idbtoken_t tok,
- u_char level,
- time32_t **tm )
+ uuid_t *fsidp,
+ inv_idbtoken_t tok,
+ u_char level,
+ time32_t **tm )
{
int rval;
if ( tok != INV_TOKEN_NULL ) {- rval = search_invt( tok->d_invindex_fd, &level, (void **) tm,
- (search_callback_t) tm_level_lessthan );
+ rval = search_invt(fsidp, tok->d_invindex_fd, &level,
+ (void **) tm,
+ (search_callback_t) tm_level_lessthan);
return ( rval < 0) ? BOOL_FALSE: BOOL_TRUE;
}- return invmgr_query_all_sessions((void *) &level, /* in */
- (void **) tm, /* out */
+ return invmgr_query_all_sessions(fsidp, /* fs uuid ptr*/
+ (void *) &level, /* in */
+ (void **) tm, /* out */
(search_callback_t) tm_level_lessthan); }
-
-
-
-
/*----------------------------------------------------------------------*/
-/* */ -/* */ -/* */
+/* inv_lastsession_level_lessthan */
+/* */
+/* Given a file system uuid, token that refers to a file system, and a */
+/* level, ses is populated with a session of lesser than the level */
+/* passed in. */
+/* */
+/* Returns FALSE on an error, TRUE if not. If (*ses) is NULL, then the */
+/* search failed. */
/*----------------------------------------------------------------------*/
bool_t
inv_lastsession_level_lessthan( - inv_idbtoken_t tok,
+ uuid_t *fsidp,
+ inv_idbtoken_t tok,
u_char level,
- inv_session_t **ses )
+ inv_session_t **ses )
{
int rval;
if ( tok != INV_TOKEN_NULL ) {
- rval = search_invt( tok->d_invindex_fd, &level, (void **) ses, - (search_callback_t) lastsess_level_lessthan );
+ rval = search_invt(fsidp, tok->d_invindex_fd, &level,
+ (void **) ses,
+ (search_callback_t) lastsess_level_lessthan);
return ( rval < 0) ? BOOL_FALSE: BOOL_TRUE;
}
- return invmgr_query_all_sessions((void *) &level, /* in */
+ return invmgr_query_all_sessions(fsidp, /* fs uuid */
+ (void *) &level, /* in */
(void **) ses, /* out */
(search_callback_t) lastsess_level_lessthan); }
-
-
-
/*----------------------------------------------------------------------*/
-/* */
-/* */
+/* inv_lastsession_level_equalto */
+/* */
+/* Given a file system uuid, token that refers to a file system, and a */
+/* level, this populates ses with last time when a session of a lesser */
+/* level was done. */
+/* */
/* Return FALSE on an error, TRUE if not. If (*ses) is NULL, then the */
/* search failed. */
/*----------------------------------------------------------------------*/
@@ -666,19 +675,22 @@ inv_lastsession_level_lessthan(
bool_t
inv_lastsession_level_equalto( + uuid_t *fsidp,
inv_idbtoken_t tok, u_char level,
inv_session_t **ses )
{
int rval;
if ( tok != INV_TOKEN_NULL ) {
- rval = search_invt( tok->d_invindex_fd, &level, (void **) ses, - (search_callback_t) lastsess_level_equalto );
+ rval = search_invt(fsidp, tok->d_invindex_fd, &level,
+ (void **) ses,
+ (search_callback_t) lastsess_level_equalto);
return ( rval < 0) ? BOOL_FALSE: BOOL_TRUE;
}- return invmgr_query_all_sessions((void *) &level, /* in */
+ return invmgr_query_all_sessions(fsidp, /* fs uuid */
+ (void *) &level, /* in */
(void **) ses, /* out */
(search_callback_t) lastsess_level_equalto); @@ -688,35 +700,45 @@ inv_lastsession_level_equalto( /*----------------------------------------------------------------------*/
/* inv_getsession_byuuid */
/* */
+/* Given a file system uuid and a session uuid , ses is populated with */
+/* the session that contains the matching system uuid. */
+/* */
+/* Returns FALSE on an error, TRUE if the session was found. */
/*----------------------------------------------------------------------*/
bool_t
inv_get_session_byuuid(
+ uuid_t *fsidp,
uuid_t *sesid,
inv_session_t **ses)
{
- return (invmgr_query_all_sessions((void *)sesid, /* in */
- (void **) ses, /* out */
- (search_callback_t) stobj_getsession_byuuid));
+ return invmgr_query_all_sessions(fsidp, /* fs uuid */
+ (void *) sesid, /* in */ + (void **) ses, /* out */
+ (search_callback_t) stobj_getsession_byuuid);
}
-
-
/*----------------------------------------------------------------------*/
-/* inv_getsession_byuuid */
+/* inv_getsession_bylabel */
/* */
+/* Given a file system uuid and a session uuid, ses is populated with */
+/* the session that contains the matching system label. */
+/* */
+/* Returns FALSE on an error, TRUE if the session was found. */
/*----------------------------------------------------------------------*/
bool_t
inv_get_session_bylabel(
+ uuid_t *fsidp,
char *session_label,
inv_session_t **ses)
{
- return (invmgr_query_all_sessions((void *)session_label, /* in */
- (void **) ses, /* out */
- (search_callback_t) stobj_getsession_bylabel));
+ return invmgr_query_all_sessions(fsidp, /* fs uuid */
+ (void *) session_label, /* in */
+ (void **) ses, /* out */
+ (search_callback_t) stobj_getsession_bylabel);
}
@@ -786,7 +808,7 @@ inv_delete_mediaobj( uuid_t *moid )
return BOOL_FALSE;
}
- if ( search_invt( invfd, NULL, (void **)&moid, + if ( search_invt( &arr[i].ft_uuid, invfd, NULL, (void **)&moid,
(search_callback_t) stobj_delete_mobj )
< 0 )
return BOOL_FALSE;inventory/inv_mgr.c +0 -0
@@ -134,6 +134,7 @@ get_sesstoken( inv_idbtoken_t tok )
/*---------------------------------------------------------------------------*/
bool_t
invmgr_query_all_sessions (
+ uuid_t *fsidp,
void *inarg,
void **outarg,
search_callback_t func)
@@ -169,7 +170,7 @@ invmgr_query_all_sessions (
mlog( MLOG_NORMAL | MLOG_INV, _(
"INV: Cant get inv-name for uuid\n")
);
- return BOOL_FALSE;
+ continue;
}
strcat( fname, INV_INVINDEX_PREFIX );
invfd = open( fname, INV_OFLAG(forwhat) );@@ -178,9 +179,9 @@ invmgr_query_all_sessions (
"INV: Open failed on %s\n"),
fname
);
- return BOOL_FALSE;
+ continue;
}
- result = search_invt( invfd, inarg, &objectfound, func );
+ result = search_invt(fsidp, invfd, inarg, &objectfound, func);
close(invfd);
/* if error return BOOL_FALSE */@@ -213,6 +214,7 @@ invmgr_query_all_sessions (
intgen_t
search_invt( + uuid_t *fsidp,
int invfd,
void *arg, void **buf,
@@ -247,7 +249,7 @@ search_invt(
/* we need to get all the invindex headers and seshdrs in reverse
order */
for (i = nindices - 1; i >= 0; i--) {
- int nsess;
+ int nsess, j;
invt_sescounter_t *scnt = NULL;
invt_seshdr_t *harr = NULL;
bool_t found;
@@ -272,19 +274,31 @@ search_invt(
}
free ( scnt ); - while ( nsess ) {
+ for (j = nsess - 1; j >= 0; j--) {
+ invt_session_t ses;
+
/* fd is kept locked until we return from the callback routine */
/* Check to see if this session has been pruned * by xfsinvutil before checking it. */
- if ( harr[nsess - 1].sh_pruned ) {
- --nsess;
+ if (harr[j].sh_pruned) {
continue;
}- found = (* do_chkcriteria ) ( fd, &harr[ --nsess ],
- arg, buf );
+
+ /* if we need to check the fs uuid's and they don't
+ * match or we fail to get the session record,
+ * then keep looking
+ */
+ if (fsidp &&
+ (GET_REC_NOLOCK(fd, &ses, sizeof(invt_session_t),
+ harr[j].sh_sess_off) ==
+ sizeof(invt_session_t)) &&
+ uuid_compare(ses.s_fsid, *fsidp))
+ continue ;
+
+ found = (* do_chkcriteria ) (fd, &harr[j], arg, buf);
if (! found ) continue;
/* we found what we need; just return */inventory/inv_priv.h +4 -2
@@ -548,11 +548,12 @@ get_headerinfo( int fd, void **hdrs, voi size_t hdrsz, size_t cntsz, bool_t doblock );bool_t -invmgr_query_all_sessions (void *inarg,void **outarg,search_callback_t func); +invmgr_query_all_sessions (uuid_t *fsidp,void *inarg,void **outarg, +search_callback_t func);intgen_t -search_invt( int invfd, void *arg, void **buf, - search_callback_t do_chkcriteria ); +search_invt (uuid_t *fsidp,int invfd,void *arg,void **buf, +search_callback_t do_chkcriteria);intgen_t invmgr_inv_print (int invfd,invt_pr_ctx_t *prctx); Index: b/inventory/inventory.h
===================================================================
inventory/inventory.h +2 -0
@@ -247,18 +247,21 @@ inv_put_mediafile(*/ extern bool_t inv_lasttime_level_lessthan( + uuid_t *fsidp,inv_idbtoken_t tok,u_char level,time32_t **time );/* out */ extern bool_t inv_lastsession_level_lessthan( + uuid_t *fsidp,inv_idbtoken_t tok,u_char level,inv_session_t **ses );/* out */ extern bool_t inv_lastsession_level_equalto( + uuid_t *fsidp,inv_idbtoken_t tok,u_char level,inv_session_t **ses );/* out */
@@ -266,11 +269,13 @@ inv_lastsession_level_equalto(/* Given a uuid of a session, return the session structure.*/ extern bool_t inv_get_session_byuuid ( +uuid_t *fsidp,uuid_t *sesid,inv_session_t **ses);extern bool_t inv_get_session_bylabel ( +uuid_t *fsidp,char *session_label,inv_session_t **ses); Index: b/restore/content.c
===================================================================
restore/content.c +11 -6
@@ -2179,8 +2179,9 @@ content_stream_restore( ix_t thrdix )if ( ! drivep->d_isnamedpipepr && ! drivep->d_isunnamedpipepr ) { - ok =inv_get_session_byuuid ( &grhdrp->gh_dumpid, - &sessp ); + ok =inv_get_session_byuuid ((uuid_t *)0 , + &grhdrp->gh_dumpid, + &sessp);if ( ok && sessp ) {mlog (MLOG_VERBOSE ,_ ("using online session inventory\n" ) );
@@ -3736,9 +3737,11 @@ Inv_validate_cmdline( void ) ok =BOOL_FALSE ; sessp =0 ;if ( tranp->t_reqdumpidvalpr ) { - ok =inv_get_session_byuuid ( &tranp->t_reqdumpid, &sessp ); + ok =inv_get_session_byuuid ((uuid_t *)0 , &tranp->t_reqdumpid, + &sessp ); }else if ( tranp->t_reqdumplabvalpr ) { - ok =inv_get_session_bylabel ( tranp->t_reqdumplab, &sessp ); + ok =inv_get_session_bylabel ((uuid_t *)0 , tranp->t_reqdumplab, + &sessp ); } rok =BOOL_FALSE ;if ( ok && sessp ) {
@@ -6812,11 +6815,13 @@ askinvforbaseof( uuid_t baseid, inv_sess/* get the base session */ if ( resumedpr ) { - ok =inv_lastsession_level_equalto ( invtok, + ok =inv_lastsession_level_equalto ( &sessp->s_fsid, + invtok, (u_char_t )level, &basesessp ); }else { - ok =inv_lastsession_level_lessthan ( invtok, + ok =inv_lastsession_level_lessthan ( &sessp->s_fsid, + invtok, (u_char_t )level, &basesessp ); }
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 28 lines · Rich Johnston
Restoring an incremental level 1 dump will fail with the following error if the fs uuid of the most recent level 0 dump in the inventory does not match level 1 dump we are restoring.
xfsrestore: ERROR: selected dump not based on previously applied dump
This can happen when you have multiple filesystems and you are restoring a level 1 or greater dump of filesystem FS1 but the most recent level 0 dump in the inventory was filesystem FS2
The fix is to ensure the fs uuid of the inventory entry and the dump to be restored match.
Signed-off-by Rich Johnston <[email protected]>--- dump/content.c | 8 ++- inventory/inv_api.c | 108 ++++++++++++++++++++++++++++++-------------------- inventory/inv_mgr.c | 32 ++++++++++---- inventory/inv_priv.h | 7 +-- inventory/inventory.h | 5 ++ restore/content.c | 17 +++++-- 6 files changed, 113 insertions(+), 64 deletions(-)Index:
b/dump/content.c
===================================================================
dump/content.c content_init( intgen_t argc, · line 878
Quoted 7 lines
dump/content.c +1
-0@@ -872,7 +872,7 @@ content_init( intgen_t argc, sameinterruptedpr =BOOL_FALSE ; interruptedpr =BOOL_FALSE ; - ok =inv_get_session_byuuid ( &baseuuid, &sessp ); + ok =inv_get_session_byuuid ( &fsid, &baseuuid, &sessp );if ( ! ok ) { mlog( MLOG_NORMAL | MLOG_ERROR, _( "could not find specified base dump (%s) "
This patch has whitespace problems all through it (bad indenting, all tabs converted to spaces, etc) and so it won't apply. Please fix and resend.
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 1/1 xfsrestore: fix fs uuid order check for incremental restores
In reply to Rich JohnstonRestoring an incremental level 1 dump will fail with the following error if the fs uuid of the most recent level 0 dump in the inventory does not match level 1 dump we are restoring.
xfsrestore: ERROR: selected dump not based on previously applied dump
This can happen when you have multiple filesystems and you are restoring a level 1 or greater dump of filesystem FS1 but the most recent level 0 dump in the inventory was filesystem FS2
The fix is to ensure the fs uuid of the inventory entry and the dump to be restored match.
--- dump/content.c | 8 ++- inventory/inv_api.c | 108 ++++++++++++++++++++++++++++++-------------------- inventory/inv_mgr.c | 32 ++++++++++---- inventory/inv_priv.h | 7 +-- inventory/inventory.h | 5 ++ restore/content.c | 17 +++++-- 6 files changed, 113 insertions(+), 64 deletions(-)
dump/content.c +5 -3
@@ -872,7 +872,7 @@ content_init( intgen_t argc, sameinterruptedpr =BOOL_FALSE ; interruptedpr =BOOL_FALSE ; - ok =inv_get_session_byuuid ( &baseuuid, &sessp ); + ok =inv_get_session_byuuid ( &fsid, &baseuuid, &sessp );if ( ! ok ) { mlog( MLOG_NORMAL | MLOG_ERROR, _( "could not find specified base dump (%s) "
@@ -983,7 +983,8 @@ content_init( intgen_t argc, "online inventory not available\n") );return BOOL_FALSE ; } - ok =inv_lastsession_level_lessthan ( inv_idbt, + ok =inv_lastsession_level_lessthan ( &fsid, + inv_idbt, (u_char_t )sc_level, &sessp );if ( ! ok ) {
@@ -1022,7 +1023,8 @@ content_init( intgen_t argc,if ( inv_idbt !=INV_TOKEN_NULL ) {/* REFERENCED */ bool_t ok1; - ok =inv_lastsession_level_equalto ( inv_idbt, + ok =inv_lastsession_level_equalto ( &fsid, + inv_idbt, (u_char_t )sc_level, &sessp ); ok1 =inv_close ( inv_idbt );
inventory/inv_api.c +65 -43
195 lines not on this page · raw message
inventory/inv_mgr.c +23 -9
@@ -134,6 +134,7 @@ get_sesstoken( inv_idbtoken_t tok )/*---------------------------------------------------------------------------*/ bool_t invmgr_query_all_sessions ( +uuid_t *fsidp,void *inarg,void **outarg,search_callback_t func)
@@ -169,7 +170,7 @@ invmgr_query_all_sessions (mlog (MLOG_NORMAL |MLOG_INV ,_ ("INV: Cant get inv-name for uuid\n" ) ); -return BOOL_FALSE ; +continue ; }strcat ( fname,INV_INVINDEX_PREFIX ); invfd =open ( fname,INV_OFLAG (forwhat) );
@@ -178,9 +179,9 @@ invmgr_query_all_sessions ( "INV: Open failed on %s\n"), fname ); -return BOOL_FALSE ; +continue ; } - result =search_invt ( invfd, inarg, &objectfound, func ); + result =search_invt (fsidp, invfd, inarg, &objectfound, func);close (invfd);/* if error return BOOL_FALSE */
@@ -213,6 +214,7 @@ invmgr_query_all_sessions ( intgen_t search_invt( + uuid_t *fsidp, int invfd, void *arg, void **buf,
@@ -247,7 +249,7 @@ search_invt(/* we need to get all the invindex headers and seshdrs in reverse order */ for (i = nindices -1 ; i >=0 ; i--) { -int nsess; +int nsess, j;invt_sescounter_t *scnt =NULL ;invt_seshdr_t *harr =NULL ;bool_t found;
@@ -272,19 +274,31 @@ search_invt( }free ( scnt ); -while ( nsess ) { +for (j = nsess -1 ; j >=0 ; j--) { +invt_session_t ses; +/* fd is kept locked until we return from the callback routine */ /* Check to see if this session has been pruned * by xfsinvutil before checking it. */ -if ( harr[nsess -1 ].sh_pruned ) { - --nsess; +if (harr[j].sh_pruned) {continue ; } - found = (* do_chkcriteria ) ( fd, &harr[ --nsess ], - arg, buf ); + +/* if we need to check the fs uuid's and they don't +* match or we fail to get the session record, +* then keep looking +*/ +if (fsidp && + (GET_REC_NOLOCK (fd, &ses,sizeof (invt_session_t), + harr[j].sh_sess_off) == +sizeof (invt_session_t)) && +uuid_compare (ses.s_fsid, *fsidp)) +continue ; + + found = (* do_chkcriteria ) (fd, &harr[j], arg, buf);if (! found )continue ;/* we found what we need; just return */
inventory/inv_priv.h +4 -3
@@ -548,11 +548,12 @@ get_headerinfo( int fd, void **hdrs, voi size_t hdrsz, size_t cntsz, bool_t doblock );bool_t -invmgr_query_all_sessions (void *inarg,void **outarg,search_callback_t func); +invmgr_query_all_sessions (uuid_t *fsidp,void *inarg,void **outarg, +search_callback_t func);intgen_t -search_invt (int invfd,void *arg,void **buf, -search_callback_t do_chkcriteria ); +search_invt (uuid_t *fsidp,int invfd,void *arg,void **buf, +search_callback_t do_chkcriteria);intgen_t invmgr_inv_print (int invfd,invt_pr_ctx_t *prctx);
inventory/inventory.h +5 -0
@@ -247,18 +247,21 @@ inv_put_mediafile(*/ extern bool_t inv_lasttime_level_lessthan ( +uuid_t *fsidp,inv_idbtoken_t tok,u_char level,time32_t **time );/* out */ extern bool_t inv_lastsession_level_lessthan ( +uuid_t *fsidp,inv_idbtoken_t tok,u_char level,inv_session_t **ses );/* out */ extern bool_t inv_lastsession_level_equalto ( +uuid_t *fsidp,inv_idbtoken_t tok,u_char level,inv_session_t **ses );/* out */
@@ -266,11 +269,13 @@ inv_lastsession_level_equalto(/* Given a uuid of a session, return the session structure.*/ extern bool_t inv_get_session_byuuid ( +uuid_t *fsidp,uuid_t *sesid,inv_session_t **ses);extern bool_t inv_get_session_bylabel ( +uuid_t *fsidp,char *session_label,inv_session_t **ses);
restore/content.c +11 -6
@@ -2179,8 +2179,9 @@ content_stream_restore( ix_t thrdix )if ( ! drivep->d_isnamedpipepr && ! drivep->d_isunnamedpipepr ) { - ok =inv_get_session_byuuid ( &grhdrp->gh_dumpid, - &sessp ); + ok =inv_get_session_byuuid ((uuid_t *)0 , + &grhdrp->gh_dumpid, + &sessp);if ( ok && sessp ) {mlog (MLOG_VERBOSE ,_ ("using online session inventory\n" ) );
@@ -3736,9 +3737,11 @@ Inv_validate_cmdline( void ) ok =BOOL_FALSE ; sessp =0 ;if ( tranp->t_reqdumpidvalpr ) { - ok =inv_get_session_byuuid ( &tranp->t_reqdumpid, &sessp ); + ok =inv_get_session_byuuid ((uuid_t *)0 , &tranp->t_reqdumpid, + &sessp ); }else if ( tranp->t_reqdumplabvalpr ) { - ok =inv_get_session_bylabel ( tranp->t_reqdumplab, &sessp ); + ok =inv_get_session_bylabel ((uuid_t *)0 , tranp->t_reqdumplab, + &sessp ); } rok =BOOL_FALSE ;if ( ok && sessp ) {
@@ -6812,11 +6815,13 @@ askinvforbaseof( uuid_t baseid, inv_sess/* get the base session */ if ( resumedpr ) { - ok =inv_lastsession_level_equalto ( invtok, + ok =inv_lastsession_level_equalto ( &sessp->s_fsid, + invtok, (u_char_t )level, &basesessp ); }else { - ok =inv_lastsession_level_lessthan ( invtok, + ok =inv_lastsession_level_lessthan ( &sessp->s_fsid, + invtok, (u_char_t )level, &basesessp ); }
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
ping, Does anyone have time to review this please?
Thanks
--Rich
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 10 lines · Rich Johnston
Restoring an incremental level 1 dump will fail with the following error if the fs uuid of the most recent level 0 dump in the inventory does not match level 1 dump we are restoring.
xfsrestore: ERROR: selected dump not based on previously applied dump
This can happen when you have multiple filesystems and you are restoring a level 1 or greater dump of filesystem FS1 but the most recent level 0 dump in the inventory was filesystem FS2
Quoted 5 lines
The fix is to ensure the fs uuid of the inventory entry and the dump to be restored match.
Signed-off-by Rich Johnston <[email protected]>---
I'm not really familiar with xfsdump, but a few comments below...
Quoted 8 lines
dump/content.c | 8 ++- inventory/inv_api.c | 108 ++++++++++++++++++++++++++++++-------------------- inventory/inv_mgr.c | 32 ++++++++++---- inventory/inv_priv.h | 7 +-- inventory/inventory.h | 5 ++ restore/content.c | 17 +++++-- 6 files changed, 113 insertions(+), 64 deletions(-)
...
Quoted 22 lines
Index:
b/inventory/inv_mgr.c
===================================================================inventory/inv_mgr.c +2
-1@@ -134,6 +134,7 @@ get_sesstoken( inv_idbtoken_t tok )/*---------------------------------------------------------------------------*/ bool_t invmgr_query_all_sessions ( +uuid_t *fsidp,void *inarg,void **outarg,search_callback_t func)@@ -169,7 +170,7 @@ invmgr_query_all_sessions (mlog (MLOG_NORMAL |MLOG_INV ,_ ("INV: Cant get inv-name for uuid\n" ) ); -return BOOL_FALSE ; +continue ; }strcat ( fname,INV_INVINDEX_PREFIX ); invfd =open ( fname,INV_OFLAG (forwhat) );
inventory/inv_mgr.c invmgr_query_all_sessions ( · line 183
Quoted 6 lines
inventory/inv_mgr.c +1
-1@@ -178,9 +179,9 @@ invmgr_query_all_sessions ( "INV: Open failed on %s\n"), fname ); -return BOOL_FALSE ; +continue ; }
Now that the above two cases don't return false, we can end up returning true if these error cases persist throughout the loop. Perhaps we should define 'bool ret = false,' return that variable everywhere and only set it true when appropriate.
Quoted 5 lines
inventory/inv_mgr.c +1
-1- result =search_invt ( invfd, inarg, &objectfound, func ); + result =search_invt (fsidp, invfd, inarg, &objectfound, func);close (invfd);/* if error return BOOL_FALSE */
...
Quoted 23 lines
inventory/inv_mgr.c +6
-5@@ -272,19 +274,31 @@ search_invt( }free ( scnt ); -while ( nsess ) { +for (j = nsess -1 ; j >=0 ; j--) { +invt_session_t ses; +/* fd is kept locked until we return from the callback routine */ /* Check to see if this session has been pruned * by xfsinvutil before checking it. */ -if ( harr[nsess -1 ].sh_pruned ) { - --nsess; +if (harr[j].sh_pruned) {continue ; } - found = (* do_chkcriteria ) ( fd, &harr[ --nsess ], - arg, buf ); + +/* if we need to check the fs uuid's and they don't
inventory/inv_mgr.c search_invt( · line 300
Quoted 10 lines
inventory/inv_mgr.c +10
-0+* match or we fail to get the session record, +* then keep looking +*/ +if (fsidp && + (GET_REC_NOLOCK (fd, &ses,sizeof (invt_session_t), + harr[j].sh_sess_off) == +sizeof (invt_session_t)) && +uuid_compare (ses.s_fsid, *fsidp)) +continue ; +
This seems like kind of a loaded check. GET_REC_NOLOCK() looks like it returns -1 if the read doesn't return the exact size of the buffer, so we probably don't need to check that here. It also seems like we should return an error if an error occurs rather than just continue on. How about something like this?
...
if (fsidp) {
ret = GET_REC_NOLOCK(fd, &ses,
sizeof(invt_session_t),
harr[j].sh_sess_off);
if (ret < 0) {
/* XXX: clean up here */
return ret;
}
ret = uuid_compare(ses.s_fsid, *fsidp);
if (ret)
continue;
}Quoted 4 lines
inventory/inv_mgr.c +1
-0+ found = (* do_chkcriteria ) (fd, &harr[j], arg, buf);if (! found )continue ;/* we found what we need; just return */
...
Quoted 17 lines
Index:
b/restore/content.c
===================================================================restore/content.c +3
-2@@ -2179,8 +2179,9 @@ content_stream_restore( ix_t thrdix )if ( ! drivep->d_isnamedpipepr && ! drivep->d_isunnamedpipepr ) { - ok =inv_get_session_byuuid ( &grhdrp->gh_dumpid, - &sessp ); + ok =inv_get_session_byuuid ((uuid_t *)0 , + &grhdrp->gh_dumpid, + &sessp);if ( ok && sessp ) {mlog (MLOG_VERBOSE ,_ ("using online session inventory\n" ) );
restore/content.c Inv_validate_cmdline( void ) · line 3744
Quoted 10 lines
restore/content.c +4
-2@@ -3736,9 +3737,11 @@ Inv_validate_cmdline( void ) ok =BOOL_FALSE ; sessp =0 ;if ( tranp->t_reqdumpidvalpr ) { - ok =inv_get_session_byuuid ( &tranp->t_reqdumpid, &sessp ); + ok =inv_get_session_byuuid ((uuid_t *)0 , &tranp->t_reqdumpid, + &sessp ); }else if ( tranp->t_reqdumplabvalpr ) { - ok =inv_get_session_bylabel ( tranp->t_reqdumplab, &sessp ); + ok =inv_get_session_bylabel ((uuid_t *)0 , tranp->t_reqdumplab, + &sessp );
Can we use NULL instead of 0 in these cases? Not sure the cast is really necessary either..?.
Brian
Quoted 20 lines
restore/content.c +4
-2} rok =BOOL_FALSE ;if ( ok && sessp ) {@@ -6812,11 +6815,13 @@ askinvforbaseof( uuid_t baseid, inv_sess/* get the base session */ if ( resumedpr ) { - ok =inv_lastsession_level_equalto ( invtok, + ok =inv_lastsession_level_equalto ( &sessp->s_fsid, + invtok, (u_char_t )level, &basesessp ); }else { - ok =inv_lastsession_level_lessthan ( invtok, + ok =inv_lastsession_level_lessthan ( &sessp->s_fsid, + invtok, (u_char_t )level, &basesessp ); }
Quoted 4 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 51 lines · Brian Foster
Quoted 10 lines · Rich Johnston
Restoring an incremental level 1 dump will fail with the following error if the fs uuid of the most recent level 0 dump in the inventory does not match level 1 dump we are restoring.
xfsrestore: ERROR: selected dump not based on previously applied dump
This can happen when you have multiple filesystems and you are restoring a level 1 or greater dump of filesystem FS1 but the most recent level 0 dump in the inventory was filesystem FS2
Quoted 5 lines
The fix is to ensure the fs uuid of the inventory entry and the dump to be restored match.
Signed-off-by Rich Johnston <[email protected]>---
I'm not really familiar with xfsdump, but a few comments below...
Quoted 8 lines
dump/content.c | 8 ++- inventory/inv_api.c | 108 ++++++++++++++++++++++++++++++-------------------- inventory/inv_mgr.c | 32 ++++++++++---- inventory/inv_priv.h | 7 +-- inventory/inventory.h | 5 ++ restore/content.c | 17 +++++-- 6 files changed, 113 insertions(+), 64 deletions(-)...
Quoted 23 lines
Index:
b/inventory/inv_mgr.c
===================================================================inventory/inv_mgr.c +2
-1@@ -134,6 +134,7 @@ get_sesstoken( inv_idbtoken_t tok )/*---------------------------------------------------------------------------*/ bool_t invmgr_query_all_sessions ( +uuid_t *fsidp,void *inarg,void **outarg,search_callback_t func)@@ -169,7 +170,7 @@ invmgr_query_all_sessions (mlog (MLOG_NORMAL |MLOG_INV ,_ ("INV: Cant get inv-name for uuid\n" ) ); -return BOOL_FALSE ; +continue ; }strcat ( fname,INV_INVINDEX_PREFIX ); invfd =open ( fname,INV_OFLAG (forwhat) );@@ -178,9 +179,9 @@ invmgr_query_all_sessions ( "INV: Open failed on %s\n"),
Quoted 8 lines
inventory/inv_mgr.c invmgr_query_all_sessions ( · line 183
Quoted 5 lines
inventory/inv_mgr.c +1
-1fname ); -return BOOL_FALSE ; +continue ; }Now that the above two cases don't return false, we can end up returning true if these error cases persist throughout the loop.
Yes I missed that case.
Quoted 3 lines
Perhaps we should
define 'bool ret = false,' return that variable everywhere and only set it true when appropriate.
Good suggestion.
Quoted 38 lines
Quoted 6 lines
inventory/inv_mgr.c +1
-1- result =search_invt ( invfd, inarg, &objectfound, func ); + result =search_invt (fsidp, invfd, inarg, &objectfound, func);close (invfd);/* if error return BOOL_FALSE */ ...
Quoted 31 lines
inventory/inv_mgr.c +14
-5@@ -272,19 +274,31 @@ search_invt( }free ( scnt ); -while ( nsess ) { +for (j = nsess -1 ; j >=0 ; j--) { +invt_session_t ses; +/* fd is kept locked until we return from the callback routine */ /* Check to see if this session has been pruned * by xfsinvutil before checking it. */ -if ( harr[nsess -1 ].sh_pruned ) { - --nsess; +if (harr[j].sh_pruned) {continue ; } - found = (* do_chkcriteria ) ( fd, &harr[ --nsess ], - arg, buf ); + +/* if we need to check the fs uuid's and they don't +* match or we fail to get the session record, +* then keep looking +*/ +if (fsidp && + (GET_REC_NOLOCK (fd, &ses,sizeof (invt_session_t), + harr[j].sh_sess_off) == +sizeof (invt_session_t)) && +uuid_compare (ses.s_fsid, *fsidp))
Quoted 8 lines
inventory/inv_mgr.c search_invt( · line 300
Quoted 2 lines
inventory/inv_mgr.c +2
-0+continue ; +This seems like kind of a loaded check.
GET_REC_NOLOCK()looks like it returns -1 if the read doesn't return the exact size of the buffer, so we probably don't need to check that here. It also seems like we should return an error if an error occurs rather than just continue on. How about something like this?
Sounds reasonable, would be more readable.
Quoted 42 lines
... if (fsidp) { ret = GET_REC_NOLOCK(fd, &ses, sizeof(invt_session_t), harr[j].sh_sess_off); if (ret < 0) { /* XXX: clean up here */ return ret; } ret = uuid_compare(ses.s_fsid, *fsidp); if (ret) continue; }Quoted 4 lines
inventory/inv_mgr.c +1
-0+ found = (* do_chkcriteria ) (fd, &harr[j], arg, buf);if (! found )continue ;/* we found what we need; just return */ ...
Quoted 22 lines
Index:
b/restore/content.c
===================================================================restore/content.c +4
-3@@ -2179,8 +2179,9 @@ content_stream_restore( ix_t thrdix )if ( ! drivep->d_isnamedpipepr && ! drivep->d_isunnamedpipepr ) { - ok =inv_get_session_byuuid ( &grhdrp->gh_dumpid, - &sessp ); + ok =inv_get_session_byuuid ((uuid_t *)0 , + &grhdrp->gh_dumpid, + &sessp);if ( ok && sessp ) {mlog (MLOG_VERBOSE ,_ ("using online session inventory\n" ) );@@ -3736,9 +3737,11 @@ Inv_validate_cmdline( void ) ok =BOOL_FALSE ; sessp =0 ;if ( tranp->t_reqdumpidvalpr ) { - ok =inv_get_session_byuuid ( &tranp->t_reqdumpid, &sessp ); + ok = inv_get_session_byuuid((uuid_t *)0, &tranp->t_reqdumpid,
Quoted 8 lines
restore/content.c Inv_validate_cmdline( void ) · line 3744
Quoted 5 lines
restore/content.c +3
-1+ &sessp ); }else if ( tranp->t_reqdumplabvalpr ) { - ok =inv_get_session_bylabel ( tranp->t_reqdumplab, &sessp ); + ok =inv_get_session_bylabel ((uuid_t *)0 , tranp->t_reqdumplab, + &sessp );Can we use NULL instead of 0 in these cases? Not sure the cast is really necessary either..?.
I will check that out, if NULL works I will make that change.
Thanks for your time
--Rich
Quoted 23 lines
Brian
Quoted 20 lines
restore/content.c +4
-2} rok =BOOL_FALSE ;if ( ok && sessp ) {@@ -6812,11 +6815,13 @@ askinvforbaseof( uuid_t baseid, inv_sess/* get the base session */ if ( resumedpr ) { - ok =inv_lastsession_level_equalto ( invtok, + ok =inv_lastsession_level_equalto ( &sessp->s_fsid, + invtok, (u_char_t )level, &basesessp ); }else { - ok =inv_lastsession_level_lessthan ( invtok, + ok =inv_lastsession_level_lessthan ( &sessp->s_fsid, + invtok, (u_char_t )level, &basesessp ); }
Quoted 4 lines
Quoted 4 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH v2 1/1 xfsrestore: fix fs uuid order check for incremental restores
In reply to Brian FosterRestoring an incremental level 1 dump will fail with the following error if the fs uuid of the most recent level 0 dump in the inventory does not match level 1 dump we are restoring.
xfsrestore: ERROR: selected dump not based on previously applied dump
To: <[email protected]>
BCC: Rich Johnston <[email protected]>
This can happen when you have multiple filesystems and you are restoring a level 1 or greater dump of filesystem FS1 but the most recent level 0 dump in the inventory was filesystem FS2
The fix is to ensure the fs uuid of the inventory entry and the dump to be restored match.
--- dump/content.c | 8 ++- inventory/inv_api.c | 108 ++++++++++++++++++++++++++++++-------------------- inventory/inv_mgr.c | 48 +++++++++++++++------- inventory/inv_priv.h | 7 +-- inventory/inventory.h | 5 ++ restore/content.c | 17 +++++-- 6 files changed, 124 insertions(+), 69 deletions(-)
dump/content.c +5 -2
@@ -872,7 +872,7 @@ content_init( intgen_t argc, sameinterruptedpr =BOOL_FALSE ; interruptedpr =BOOL_FALSE ; - ok =inv_get_session_byuuid ( &baseuuid, &sessp ); + ok =inv_get_session_byuuid ( &fsid, &baseuuid, &sessp );if ( ! ok ) { mlog( MLOG_NORMAL | MLOG_ERROR, _( "could not find specified base dump (%s) "
@@ -983,7 +983,8 @@ content_init( intgen_t argc, "online inventory not available\n") );return BOOL_FALSE ; } - ok =inv_lastsession_level_lessthan ( inv_idbt, + ok =inv_lastsession_level_lessthan ( &fsid, + inv_idbt, (u_char_t )sc_level, &sessp );if ( ! ok ) {
@@ -1022,7 +1023,8 @@ content_init( intgen_t argc,if ( inv_idbt !=INV_TOKEN_NULL ) {/* REFERENCED */ bool_t ok1; - ok =inv_lastsession_level_equalto ( inv_idbt, + ok =inv_lastsession_level_equalto ( &fsid, + inv_idbt, (u_char_t )sc_level, &sessp ); ok1 =inv_close ( inv_idbt );
inventory/inv_api.c +0 -0
@@ -596,69 +596,78 @@ inv_free_session(
/*----------------------------------------------------------------------*/
-/* inventory_lasttime_level_lessthan */
-/* */
-/* Given a token that refers to a file system, and a level, this returns*/
-/* the last time when a session of a lesser level was done. */ -/* */ -/* returns -1 on error. */
+/* inv_lasttime_level_lessthan */
+/* */
+/* Given a file system uuid, token that refers to a file system, and a */
+/* level, tm is populated with last time when a session of a lesser */
+/* level was done. */
+/* */
+/* Returns TRUE on success. */
/*----------------------------------------------------------------------*/
bool_t
inv_lasttime_level_lessthan( - inv_idbtoken_t tok,
- u_char level,
- time32_t **tm )
+ uuid_t *fsidp,
+ inv_idbtoken_t tok,
+ u_char level,
+ time32_t **tm )
{
int rval;
if ( tok != INV_TOKEN_NULL ) {
- rval = search_invt( tok->d_invindex_fd, &level, (void **) tm,
- (search_callback_t) tm_level_lessthan );
+ rval = search_invt(fsidp, tok->d_invindex_fd, &level,
+ (void **) tm,
+ (search_callback_t) tm_level_lessthan);
return ( rval < 0) ? BOOL_FALSE: BOOL_TRUE;
}
- return invmgr_query_all_sessions((void *) &level, /* in */
- (void **) tm, /* out */
+ return invmgr_query_all_sessions(fsidp, /* fs uuid ptr*/
+ (void *) &level, /* in */
+ (void **) tm, /* out */
(search_callback_t) tm_level_lessthan); }
-
-
-
-
/*----------------------------------------------------------------------*/
-/* */ -/* */ -/* */
+/* inv_lastsession_level_lessthan */
+/* */
+/* Given a file system uuid, token that refers to a file system, and a */
+/* level, ses is populated with a session of lesser than the level */
+/* passed in. */
+/* */
+/* Returns FALSE on an error, TRUE if not. If (*ses) is NULL, then the */
+/* search failed. */
/*----------------------------------------------------------------------*/
bool_t
inv_lastsession_level_lessthan( - inv_idbtoken_t tok,
+ uuid_t *fsidp,
+ inv_idbtoken_t tok,
u_char level,
- inv_session_t **ses )
+ inv_session_t **ses )
{
int rval;
if ( tok != INV_TOKEN_NULL ) {
- rval = search_invt( tok->d_invindex_fd, &level, (void **) ses, -
(search_callback_t) lastsess_level_lessthan );
+ rval = search_invt(fsidp, tok->d_invindex_fd, &level,
+ (void **) ses,
+ (search_callback_t) lastsess_level_lessthan);
return ( rval < 0) ? BOOL_FALSE: BOOL_TRUE;
}
- return invmgr_query_all_sessions((void *) &level, /* in */
+ return invmgr_query_all_sessions(fsidp, /* fs uuid */
+ (void *) &level, /* in */
(void **) ses, /* out */
(search_callback_t) lastsess_level_lessthan);
}
-
-
-
/*----------------------------------------------------------------------*/
-/* */
-/* */
+/* inv_lastsession_level_equalto */
+/* */
+/* Given a file system uuid, token that refers to a file system, and a */
+/* level, this populates ses with last time when a session of a lesser */
+/* level was done. */
+/* */
/* Return FALSE on an error, TRUE if not. If (*ses) is NULL, then the */
/* search failed. */
/*----------------------------------------------------------------------*/
@@ -666,19 +675,22 @@ inv_lastsession_level_lessthan(
bool_t
inv_lastsession_level_equalto( + uuid_t *fsidp,
inv_idbtoken_t tok, u_char level,
inv_session_t **ses )
{
int rval;
if ( tok != INV_TOKEN_NULL ) {
- rval = search_invt( tok->d_invindex_fd, &level, (void **) ses, -
(search_callback_t) lastsess_level_equalto );
+ rval = search_invt(fsidp, tok->d_invindex_fd, &level,
+ (void **) ses,
+ (search_callback_t) lastsess_level_equalto);
return ( rval < 0) ? BOOL_FALSE: BOOL_TRUE;
}
- return invmgr_query_all_sessions((void *) &level, /* in */
+ return invmgr_query_all_sessions(fsidp, /* fs uuid */
+ (void *) &level, /* in */
(void **) ses, /* out */
(search_callback_t) lastsess_level_equalto);
@@ -688,35 +700,45 @@ inv_lastsession_level_equalto( /*----------------------------------------------------------------------*/
/* inv_getsession_byuuid */
/* */
+/* Given a file system uuid and a session uuid , ses is populated with */
+/* the session that contains the matching system uuid. */
+/* */
+/* Returns FALSE on an error, TRUE if the session was found. */
/*----------------------------------------------------------------------*/
bool_t
inv_get_session_byuuid(
+ uuid_t *fsidp,
uuid_t *sesid,
inv_session_t **ses)
{
- return (invmgr_query_all_sessions((void *)sesid, /* in */
- (void **) ses, /* out */
- (search_callback_t) stobj_getsession_byuuid));
+ return invmgr_query_all_sessions(fsidp, /* fs uuid */
+ (void *) sesid, /* in */
+ (void **) ses, /* out */
+ (search_callback_t) stobj_getsession_byuuid);
}
-
-
/*----------------------------------------------------------------------*/
-/* inv_getsession_byuuid */
+/* inv_getsession_bylabel */
/* */
+/* Given a file system uuid and a session uuid, ses is populated with */
+/* the session that contains the matching system label. */
+/* */
+/* Returns FALSE on an error, TRUE if the session was found. */
/*----------------------------------------------------------------------*/
bool_t
inv_get_session_bylabel(
+ uuid_t *fsidp,
char *session_label,
inv_session_t **ses)
{
- return (invmgr_query_all_sessions((void *)session_label, /* in */
- (void **) ses, /* out */
- (search_callback_t) stobj_getsession_bylabel));
+ return invmgr_query_all_sessions(fsidp, /* fs uuid */
+ (void *) session_label, /* in */
+ (void **) ses, /* out */
+ (search_callback_t) stobj_getsession_bylabel);
}
@@ -786,7 +808,7 @@ inv_delete_mediaobj( uuid_t *moid )
return BOOL_FALSE;
}
- if ( search_invt( invfd, NULL, (void **)&moid, + if ( search_invt(
&arr[i].ft_uuid, invfd, NULL, (void **)&moid,
(search_callback_t) stobj_delete_mobj )
< 0 )
return BOOL_FALSE;
inventory/inv_mgr.c +0 -0
@@ -134,6 +134,7 @@ get_sesstoken( inv_idbtoken_t tok )
/*---------------------------------------------------------------------------*/
bool_t
invmgr_query_all_sessions (
+ uuid_t *fsidp,
void *inarg,
void **outarg,
search_callback_t func)
@@ -145,6 +146,7 @@ invmgr_query_all_sessions (
int result;
inv_oflag_t forwhat = INV_SEARCH_ONLY;
void *objectfound;
+ bool ret = false;
/* if on return, this is still null, the search failed */ *outarg = NULL; @@ -153,11 +155,11 @@ invmgr_query_all_sessions ( fd = fstab_getall( &arr, &cnt, &numfs, forwhat );
/* special case missing file: ok, outarg says zero */
if ( fd < 0 && errno == ENOENT ) {
- return BOOL_TRUE;
+ return true;
}
if ( fd < 0 || numfs <= 0 ) {
mlog( MLOG_NORMAL | MLOG_INV, _("INV: Error in fstab\n") );
- return BOOL_FALSE;
+ return ret;
}
close( fd );
@@ -169,7 +171,7 @@ invmgr_query_all_sessions (
mlog( MLOG_NORMAL | MLOG_INV, _(
"INV: Cant get inv-name for uuid\n") );
- return BOOL_FALSE;
+ continue;
}
strcat( fname, INV_INVINDEX_PREFIX );
invfd = open( fname, INV_OFLAG(forwhat) );
@@ -178,26 +180,27 @@ invmgr_query_all_sessions (
"INV: Open failed on %s\n"), fname
);
- return BOOL_FALSE;
+ continue;
}
- result = search_invt( invfd, inarg, &objectfound, func );
+ result = search_invt(fsidp, invfd, inarg, &objectfound, func);
close(invfd);
/* if error return BOOL_FALSE */
if (result < 0) {
- return BOOL_FALSE;
+ return ret;
} else if ((result == 1) && *outarg) {
/* multiple entries found, more info needed */ *outarg = NULL;
- return BOOL_TRUE;
+ return true;
} else if (result == 1) {
*outarg = objectfound;
+ ret = true;
}
}
/* return val indicates if there was an error or not. *buf
says whether the search was successful */
- return BOOL_TRUE;
+ return ret;
}
@@ -213,6 +216,7 @@ invmgr_query_all_sessions (
intgen_t
search_invt( + uuid_t *fsidp,
int invfd,
void *arg, void **buf,
@@ -247,7 +251,7 @@ search_invt(
/* we need to get all the invindex headers and seshdrs in reverse
order */
for (i = nindices - 1; i >= 0; i--) {
- int nsess;
+ int nsess, j;
invt_sescounter_t *scnt = NULL;
invt_seshdr_t *harr = NULL;
bool_t found;
@@ -272,19 +276,35 @@ search_invt(
}
free ( scnt );
- while ( nsess ) {
+ for (j = nsess - 1; j >= 0; j--) {
+ invt_session_t ses;
+
/* fd is kept locked until we return from the callback
routine */
/* Check to see if this session has been pruned * by
xfsinvutil before checking it. */
- if ( harr[nsess - 1].sh_pruned ) {
- --nsess;
+ if (harr[j].sh_pruned) {
continue;
}
- found = (* do_chkcriteria ) ( fd, &harr[ --nsess ],
- arg, buf );
+
+ /* if we need to check the fs uuid's and they don't
+ * match or we fail to get the session record,
+ * then keep looking
+ */
+ if (fsidp) {
+ int ret = GET_REC_NOLOCK(fd, &ses,
+ sizeof(invt_session_t),
+ harr[j].sh_sess_off);
+ if (ret < 0)
+ return ret;
+
+ if (uuid_compare(ses.s_fsid, *fsidp))
+ continue;
+ }
+
+ found = (* do_chkcriteria ) (fd, &harr[j], arg, buf);
if (! found ) continue;
/* we found what we need; just return */
inventory/inv_priv.h +4 -2
@@ -548,11 +548,12 @@ get_headerinfo( int fd, void **hdrs, voi size_t hdrsz, size_t cntsz, bool_t doblock );bool_t -invmgr_query_all_sessions (void *inarg,void **outarg,search_callback_t func); +invmgr_query_all_sessions (uuid_t *fsidp,void *inarg,void **outarg, +search_callback_t func);intgen_t -search_invt( int invfd, void *arg, void **buf, - search_callback_t do_chkcriteria ); +search_invt (uuid_t *fsidp,int invfd,void *arg,void **buf, +search_callback_t do_chkcriteria);intgen_t invmgr_inv_print (int invfd,invt_pr_ctx_t *prctx); Index: b/inventory/inventory.h
===================================================================
inventory/inventory.h +2 -0
@@ -247,18 +247,21 @@ inv_put_mediafile(*/ extern bool_t inv_lasttime_level_lessthan( + uuid_t *fsidp,inv_idbtoken_t tok,u_char level,time32_t **time );/* out */ extern bool_t inv_lastsession_level_lessthan( + uuid_t *fsidp,inv_idbtoken_t tok,u_char level,inv_session_t **ses );/* out */ extern bool_t inv_lastsession_level_equalto( + uuid_t *fsidp,inv_idbtoken_t tok,u_char level,inv_session_t **ses );/* out */
@@ -266,11 +269,13 @@ inv_lastsession_level_equalto(/* Given a uuid of a session, return the session structure.*/ extern bool_t inv_get_session_byuuid ( +uuid_t *fsidp,uuid_t *sesid,inv_session_t **ses);extern bool_t inv_get_session_bylabel ( +uuid_t *fsidp,char *session_label,inv_session_t **ses); Index: b/restore/content.c
===================================================================
restore/content.c +11 -6
@@ -2179,8 +2179,9 @@ content_stream_restore( ix_t thrdix )if ( ! drivep->d_isnamedpipepr && ! drivep->d_isunnamedpipepr ) { - ok =inv_get_session_byuuid ( &grhdrp->gh_dumpid, - &sessp ); + ok =inv_get_session_byuuid (NULL , + &grhdrp->gh_dumpid, + &sessp);if ( ok && sessp ) {mlog (MLOG_VERBOSE ,_ ("using online session inventory\n" ) );
@@ -3736,9 +3737,11 @@ Inv_validate_cmdline( void ) ok =BOOL_FALSE ; sessp =0 ;if ( tranp->t_reqdumpidvalpr ) { - ok =inv_get_session_byuuid ( &tranp->t_reqdumpid, &sessp ); + ok =inv_get_session_byuuid (NULL , &tranp->t_reqdumpid, + &sessp ); }else if ( tranp->t_reqdumplabvalpr ) { - ok =inv_get_session_bylabel ( tranp->t_reqdumplab, &sessp ); + ok =inv_get_session_bylabel (NULL , tranp->t_reqdumplab, + &sessp ); } rok =BOOL_FALSE ;if ( ok && sessp ) {
@@ -6812,11 +6815,13 @@ askinvforbaseof( uuid_t baseid, inv_sess/* get the base session */ if ( resumedpr ) { - ok =inv_lastsession_level_equalto ( invtok, + ok =inv_lastsession_level_equalto ( &sessp->s_fsid, + invtok, (u_char_t )level, &basesessp ); }else { - ok =inv_lastsession_level_lessthan ( invtok, + ok =inv_lastsession_level_lessthan ( &sessp->s_fsid, + invtok, (u_char_t )level, &basesessp ); }
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Please disregard, not what I meat to send.
--Rich
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH v3 1/1 xfsrestore: fix fs uuid order check for incremental restores
In reply to Brian FosterRestoring an incremental level 1 dump will fail with the following error if the fs uuid of the most recent level 0 dump in the inventory does not match level 1 dump we are restoring.
xfsrestore: ERROR: selected dump not based on previously applied dump
This can happen when you have multiple filesystems and you are restoring a level 1 or greater dump of filesystem FS1 but the most recent level 0 dump in the inventory was filesystem FS2
The fix is to ensure the fs uuid of the inventory entry and the dump to be restored match.
---
Changelog
V2 wrong file sent
V3
Address review comments from Brian:
fix invmgr_query_all_sessions() returning true if these error cases persist throughout the loop
make if check more readable and less overloaded in search_inv() and return an error if GET_REC_NOLOCK() fails
use NULL instead of (uuid_t *)0 in Inv_validate_cmdline()
remove any spaces around braces of code that was changed
dump/content.c | 16 +++--- inventory/inv_api.c | 130 +++++++++++++++++++++++++++++--------------------- inventory/inv_mgr.c | 55 ++++++++++++++------- inventory/inv_priv.h | 7 +- inventory/inventory.h | 21 +++++--- restore/content.c | 23 +++++--- 6 files changed, 152 insertions(+), 100 deletions(-)
dump/content.c +9 -7
@@ -872,7 +872,7 @@ content_init( intgen_t argc, sameinterruptedpr =BOOL_FALSE ; interruptedpr =BOOL_FALSE ; - ok =inv_get_session_byuuid ( &baseuuid, &sessp ); + ok =inv_get_session_byuuid (&fsid, &baseuuid, &sessp);if ( ! ok ) { mlog( MLOG_NORMAL | MLOG_ERROR, _( "could not find specified base dump (%s) "
@@ -983,9 +983,10 @@ content_init( intgen_t argc, "online inventory not available\n") );return BOOL_FALSE ; } - ok =inv_lastsession_level_lessthan ( inv_idbt, - (u_char_t )sc_level, - &sessp ); + ok =inv_lastsession_level_lessthan (&fsid, + inv_idbt, + (u_char_t )sc_level, + &sessp);if ( ! ok ) { sessp =0 ; }
@@ -1022,9 +1023,10 @@ content_init( intgen_t argc,if ( inv_idbt !=INV_TOKEN_NULL ) {/* REFERENCED */ bool_t ok1; - ok =inv_lastsession_level_equalto ( inv_idbt, - (u_char_t )sc_level, - &sessp ); + ok =inv_lastsession_level_equalto (&fsid, + inv_idbt, + (u_char_t )sc_level, + &sessp); ok1 =inv_close ( inv_idbt );ASSERT ( ok1 );if ( ! ok ) {
inventory/inv_api.c +76 -54
209 lines not on this page · raw message
inventory/inv_mgr.c +37 -18
127 lines not on this page · raw message
inventory/inv_priv.h +4 -3
@@ -548,11 +548,12 @@ get_headerinfo( int fd, void **hdrs, voi size_t hdrsz, size_t cntsz, bool_t doblock );bool_t -invmgr_query_all_sessions (void *inarg,void **outarg,search_callback_t func); +invmgr_query_all_sessions (uuid_t *fsidp,void *inarg,void **outarg, +search_callback_t func);intgen_t -search_invt (int invfd,void *arg,void **buf, -search_callback_t do_chkcriteria ); +search_invt (uuid_t *fsidp,int invfd,void *arg,void **buf, +search_callback_t do_chkcriteria);intgen_t invmgr_inv_print (int invfd,invt_pr_ctx_t *prctx);
inventory/inventory.h +13 -8
@@ -247,32 +247,37 @@ inv_put_mediafile(*/ extern bool_t inv_lasttime_level_lessthan ( +uuid_t *fsidp,inv_idbtoken_t tok, -u_char level, -time32_t **time );/* out */ +u_char level, +time32_t **time);/* out */ extern bool_t inv_lastsession_level_lessthan ( +uuid_t *fsidp,inv_idbtoken_t tok,u_char level, -inv_session_t **ses );/* out */ +inv_session_t **ses);/* out */ extern bool_t inv_lastsession_level_equalto ( +uuid_t *fsidp,inv_idbtoken_t tok,u_char level, -inv_session_t **ses );/* out */ +inv_session_t **ses);/* out */ /* Given a uuid of a session, return the session structure.*/ extern bool_t inv_get_session_byuuid ( -uuid_t *sesid, -inv_session_t **ses); +uuid_t *fsidp, +uuid_t *sesid, +inv_session_t **ses);extern bool_t inv_get_session_bylabel ( -char *session_label, -inv_session_t **ses); +uuid_t *fsidp, +char *session_label, +inv_session_t **ses);/* on return, *ses is NULL */
restore/content.c +13 -10
@@ -2179,8 +2179,9 @@ content_stream_restore( ix_t thrdix )if ( ! drivep->d_isnamedpipepr && ! drivep->d_isunnamedpipepr ) { - ok =inv_get_session_byuuid ( &grhdrp->gh_dumpid, - &sessp ); + ok =inv_get_session_byuuid (NULL , + &grhdrp->gh_dumpid, + &sessp);if ( ok && sessp ) {mlog (MLOG_VERBOSE ,_ ("using online session inventory\n" ) );
@@ -3736,9 +3737,9 @@ Inv_validate_cmdline( void ) ok =BOOL_FALSE ; sessp =0 ;if ( tranp->t_reqdumpidvalpr ) { - ok =inv_get_session_byuuid ( &tranp->t_reqdumpid, &sessp ); + ok =inv_get_session_byuuid (NULL , &tranp->t_reqdumpid, &sessp); }else if ( tranp->t_reqdumplabvalpr ) { - ok =inv_get_session_bylabel ( tranp->t_reqdumplab, &sessp ); + ok =inv_get_session_bylabel (NULL , tranp->t_reqdumplab, &sessp); } rok =BOOL_FALSE ;if ( ok && sessp ) {
@@ -6812,13 +6813,15 @@ askinvforbaseof( uuid_t baseid, inv_sess/* get the base session */ if ( resumedpr ) { - ok =inv_lastsession_level_equalto ( invtok, - (u_char_t )level, - &basesessp ); + ok =inv_lastsession_level_equalto (&sessp->s_fsid, + invtok, + (u_char_t )level, + &basesessp); }else { - ok =inv_lastsession_level_lessthan ( invtok, - (u_char_t )level, - &basesessp ); + ok =inv_lastsession_level_lessthan (&sessp->s_fsid, + invtok, + (u_char_t )level, + &basesessp); }if ( ! ok ) { mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_MEDIA, _(
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 166 lines · Rich Johnston
Restoring an incremental level 1 dump will fail with the following error if the fs uuid of the most recent level 0 dump in the inventory does not match level 1 dump we are restoring.
xfsrestore: ERROR: selected dump not based on previously applied dump
This can happen when you have multiple filesystems and you are restoring a level 1 or greater dump of filesystem FS1 but the most recent level 0 dump in the inventory was filesystem FS2
The fix is to ensure the fs uuid of the inventory entry and the dump to be restored match.
Signed-off-by Rich Johnston <[email protected]>---
Changelog
V2 wrong file sentV3
Address review comments from Brian:fix
invmgr_query_all_sessions()returning true if these error cases persist throughout the loopmake if check more readable and less overloaded in
search_inv()and return an error ifGET_REC_NOLOCK()failsuse NULL instead of (
uuid_t*)0 inInv_validate_cmdline()remove any spaces around braces of code that was changed
dump/content.c | 16 +++--- inventory/inv_api.c | 130 +++++++++++++++++++++++++++++--------------------- inventory/inv_mgr.c | 55 ++++++++++++++------- inventory/inv_priv.h | 7 +- inventory/inventory.h | 21 +++++--- restore/content.c | 23 +++++--- 6 files changed, 152 insertions(+), 100 deletions(-)Index:
b/dump/content.c
===================================================================dump/content.c +9
-7@@ -872,7 +872,7 @@ content_init( intgen_t argc, sameinterruptedpr =BOOL_FALSE ; interruptedpr =BOOL_FALSE ; - ok =inv_get_session_byuuid ( &baseuuid, &sessp ); + ok =inv_get_session_byuuid (&fsid, &baseuuid, &sessp);if ( ! ok ) { mlog( MLOG_NORMAL | MLOG_ERROR, _( "could not find specified base dump (%s) "@@ -983,9 +983,10 @@ content_init( intgen_t argc, "online inventory not available\n") );return BOOL_FALSE ; } - ok =inv_lastsession_level_lessthan ( inv_idbt, - (u_char_t )sc_level, - &sessp ); + ok =inv_lastsession_level_lessthan (&fsid, + inv_idbt, + (u_char_t )sc_level, + &sessp);if ( ! ok ) { sessp =0 ; }@@ -1022,9 +1023,10 @@ content_init( intgen_t argc,if ( inv_idbt !=INV_TOKEN_NULL ) {/* REFERENCED */ bool_t ok1; - ok =inv_lastsession_level_equalto ( inv_idbt, - (u_char_t )sc_level, - &sessp ); + ok =inv_lastsession_level_equalto (&fsid, + inv_idbt, + (u_char_t )sc_level, + &sessp); ok1 =inv_close ( inv_idbt );ASSERT ( ok1 );if ( ! ok ) {Index:
b/inventory/inv_api.c
===================================================================inventory/inv_api.c +30
-25@@ -596,69 +596,78 @@ inv_free_session(/*----------------------------------------------------------------------*/ -/* inventory_lasttime_level_lessthan */ -/* */ -/* Given a token that refers to a file system, and a level, this returns*/ -/* the last time when a session of a lesser level was done. */ -/* */ -/* returns -1 on error. */ +/* inv_lasttime_level_lessthan */ +/* */ +/* Given a file system uuid, token that refers to a file system, and a */ +/* level, tm is populated with last time when a session of a lesser */ +/* level was done. */ +/* */ +/* Returns TRUE on success. */ /*----------------------------------------------------------------------*/ bool_t inv_lasttime_level_lessthan ( -inv_idbtoken_t tok, -u_char level, -time32_t **tm ) +uuid_t *fsidp, +inv_idbtoken_t tok, +u_char level, +time32_t **tm) {int rval;if ( tok !=INV_TOKEN_NULL ) { - rval =search_invt ( tok->d_invindex_fd, &level, (void **) tm, - (search_callback_t ) tm_level_lessthan ); + rval =search_invt (fsidp, tok->d_invindex_fd, &level, + (void **)tm, + (search_callback_t )tm_level_lessthan);return ( rval <0 ) ?BOOL_FALSE :BOOL_TRUE ; } -return invmgr_query_all_sessions ((void *) &level,/* in */ - (void **) tm,/* out */ - (search_callback_t ) tm_level_lessthan); +return invmgr_query_all_sessions (fsidp,/* fs uuid ptr */ + (void *)&level,/* in */ + (void **)tm,/* out */ + (search_callback_t )tm_level_lessthan); } - - - -/*----------------------------------------------------------------------*/ -/* */ -/* */ -/* */ +/* inv_lastsession_level_lessthan */ +/* */ +/* Given a file system uuid, token that refers to a file system, and a */ +/* level, ses is populated with a session of lesser than the level */ +/* passed in. */ +/* */ +/* Returns FALSE on an error, TRUE if not. If (*ses) is NULL, then the */ +/* search failed. */ /*----------------------------------------------------------------------*/ bool_t inv_lastsession_level_lessthan ( -inv_idbtoken_t tok, +uuid_t *fsidp, +inv_idbtoken_t tok,u_char level, -inv_session_t **ses ) +inv_session_t **ses) {int rval;if ( tok !=INV_TOKEN_NULL ) { - rval =search_invt ( tok->d_invindex_fd, &level, (void **) ses, - (search_callback_t ) lastsess_level_lessthan ); + rval = search_invt(fsidp, tok->d_invindex_fd, &level,
inventory/inv_api.c inv_free_session( · line 657
Quoted 10 lines
inventory/inv_api.c +3
-3+ (void **)ses, + (search_callback_t)lastsess_level_lessthan);return ( rval <0 ) ?BOOL_FALSE :BOOL_TRUE ; } -return invmgr_query_all_sessions ((void *) &level,/* in */ - (void **) ses,/* out */ - (search_callback_t ) lastsess_level_lessthan); + return invmgr_query_all_sessions(fsidp /* fs uuid */
This doesn't compile because of a missing comma after fsidp above.
Quoted 169 lines
inventory/inv_api.c +43
-26+ (void *)&level,/* in */ + (void **)ses,/* out */ + (search_callback_t)lastsess_level_lessthan); } - - -/*----------------------------------------------------------------------*/ -/* */ -/* */ +/* inv_lastsession_level_equalto */ +/* */ +/* Given a file system uuid, token that refers to a file system, and a */ +/* level, this populates ses with last time when a session of a lesser */ +/* level was done. */ +/* */ /* Return FALSE on an error, TRUE if not. If (*ses) is NULL, then the */ /* search failed. */ /*----------------------------------------------------------------------*/ @@ -666,21 +675,24 @@ inv_lastsession_level_lessthan(bool_t inv_lastsession_level_equalto ( -inv_idbtoken_t tok, +uuid_t *fsidp, +inv_idbtoken_t tok,u_char level,inv_session_t **ses ) {int rval;if ( tok !=INV_TOKEN_NULL ) { - rval =search_invt ( tok->d_invindex_fd, &level, (void **) ses, - (search_callback_t ) lastsess_level_equalto ); + rval =search_invt (fsidp, tok->d_invindex_fd, &level, + (void **)ses, + (search_callback_t )lastsess_level_equalto);return ( rval <0 ) ?BOOL_FALSE :BOOL_TRUE ; } -return invmgr_query_all_sessions ((void *) &level,/* in */ - (void **) ses,/* out */ - (search_callback_t ) lastsess_level_equalto); +return invmgr_query_all_sessions (fsidp,/* fs uuid */ + (void *)&level,/* in */ + (void **)ses,/* out */ + (search_callback_t )lastsess_level_equalto); }@@ -688,35 +700,45 @@ inv_lastsession_level_equalto(/*----------------------------------------------------------------------*/ /* inv_getsession_byuuid */ /* */ +/* Given a file system uuid and a session uuid , ses is populated with */ +/* the session that contains the matching system uuid. */ +/* */ +/* Returns FALSE on an error, TRUE if the session was found. */ /*----------------------------------------------------------------------*/ bool_t inv_get_session_byuuid ( -uuid_t *sesid, -inv_session_t **ses) +uuid_t *fsidp, +uuid_t *sesid, +inv_session_t **ses) { -return (invmgr_query_all_sessions ((void *)sesid,/* in */ - (void **) ses,/* out */ - (search_callback_t ) stobj_getsession_byuuid)); +return invmgr_query_all_sessions (fsidp,/* fs uuid */ + (void *)sesid,/* in */ + (void **)ses,/* out */ + (search_callback_t )stobj_getsession_byuuid); } - -/*----------------------------------------------------------------------*/ -/* inv_getsession_byuuid */ +/* inv_getsession_bylabel */ /* */ +/* Given a file system uuid and a session uuid, ses is populated with */ +/* the session that contains the matching system label. */ +/* */ +/* Returns FALSE on an error, TRUE if the session was found. */ /*----------------------------------------------------------------------*/ bool_t inv_get_session_bylabel ( -char *session_label, -inv_session_t **ses) +uuid_t *fsidp, +char *session_label, +inv_session_t **ses) { -return (invmgr_query_all_sessions ((void *)session_label,/* in */ - (void **) ses,/* out */ - (search_callback_t ) stobj_getsession_bylabel)); +return invmgr_query_all_sessions (fsidp,/* fs uuid */ + (void *)session_label,/* in */ + (void **)ses,/* out */ + (search_callback_t )stobj_getsession_bylabel); }@@ -786,8 +808,8 @@ inv_delete_mediaobj( uuid_t *moid )return BOOL_FALSE ; } -if (search_invt ( invfd,NULL , (void **)&moid, - (search_callback_t ) stobj_delete_mobj ) +if (search_invt (&arr[i].ft_uuid, invfd,NULL , (void **)&moid, + (search_callback_t )stobj_delete_mobj) <0 )return BOOL_FALSE ;/* we have to delete the session, etc */ Index:
b/inventory/inv_mgr.c
===================================================================inventory/inv_mgr.c +6
-5@@ -134,8 +134,9 @@ get_sesstoken( inv_idbtoken_t tok )/*---------------------------------------------------------------------------*/ bool_t invmgr_query_all_sessions ( -void *inarg, -void **outarg, +uuid_t *fsidp, +void *inarg, +void **outarg,search_callback_t func) {invt_counter_t *cnt;@@ -145,6 +146,7 @@ invmgr_query_all_sessions (int result;inv_oflag_t forwhat =INV_SEARCH_ONLY ;void *objectfound; +bool_t ret =BOOL_FALSE ;/* if on return, this is still null, the search failed */ *outarg =NULL ;@@ -157,7 +159,7 @@ invmgr_query_all_sessions ( }if ( fd <0 || numfs <=0 ) {mlog (MLOG_NORMAL |MLOG_INV ,_ ("INV: Error in fstab\n" ) ); -return BOOL_FALSE ; +return ret; }close ( fd );@@ -169,7 +171,7 @@ invmgr_query_all_sessions (mlog (MLOG_NORMAL |MLOG_INV ,_ ("INV: Cant get inv-name for uuid\n" ) ); -return BOOL_FALSE ; +continue ; }strcat ( fname,INV_INVINDEX_PREFIX ); invfd =open ( fname,INV_OFLAG (forwhat) );@@ -178,26 +180,27 @@ invmgr_query_all_sessions ( "INV: Open failed on %s\n"), fname ); -return BOOL_FALSE ;
inventory/inv_mgr.c invmgr_query_all_sessions ( · line 190
Quoted 10 lines
inventory/inv_mgr.c +3
-2+continue ; } - result =search_invt ( invfd, inarg, &objectfound, func ); + result =search_invt (fsidp, invfd, inarg, &objectfound, func);close (invfd);/* if error return BOOL_FALSE */ if (result <0 ) { -return BOOL_FALSE ; +return ret;
Should this always return false? It's now possible to return true if an error occurs after we've found one object.
The rest seems Ok to me.
Brian
Quoted 203 lines
inventory/inv_mgr.c +28
-11}else if ((result ==1 ) && *outarg) {/* multiple entries found, more info needed */ *outarg =NULL ;return BOOL_TRUE ; }else if (result ==1 ) { *outarg = objectfound; + ret =BOOL_TRUE ; } }/* return val indicates if there was an error or not. *buf says whether the search was successful */ -return BOOL_TRUE ; +return ret; }@@ -213,10 +216,11 @@ invmgr_query_all_sessions (intgen_t search_invt ( -int invfd, -void *arg, -void **buf, -search_callback_t do_chkcriteria ) +uuid_t *fsidp, +int invfd, +void *arg, +void **buf, +search_callback_t do_chkcriteria) {int fd, i;@@ -247,7 +251,7 @@ search_invt(/* we need to get all the invindex headers and seshdrs in reverse order */ for (i = nindices -1 ; i >=0 ; i--) { -int nsess; +int nsess, j;invt_sescounter_t *scnt =NULL ;invt_seshdr_t *harr =NULL ;bool_t found;@@ -272,19 +276,34 @@ search_invt( }free ( scnt ); -while ( nsess ) { +for (j = nsess -1 ; j >=0 ; j--) { +invt_session_t ses; +/* fd is kept locked until we return from the callback routine */ /* Check to see if this session has been pruned * by xfsinvutil before checking it. */ -if ( harr[nsess -1 ].sh_pruned ) { - --nsess; +if (harr[j].sh_pruned) {continue ; } - found = (* do_chkcriteria ) ( fd, &harr[ --nsess ], - arg, buf ); + +/* if we need to check the fs uuid's and they don't +* match or we fail to get the session record, +* then keep looking +*/ +if (fsidp) { +int ret =GET_REC_NOLOCK (fd, &ses, +sizeof (invt_session_t), + harr[j].sh_sess_off); +if (ret <0 ) +return ret; +if (uuid_compare (ses.s_fsid, *fsidp)) +continue ; + } + + found = (* do_chkcriteria)(fd, &harr[j], arg, buf);if (! found )continue ;/* we found what we need; just return */ Index:
b/inventory/inv_priv.h
===================================================================inventory/inv_priv.h +4
-3@@ -548,11 +548,12 @@ get_headerinfo( int fd, void **hdrs, voi size_t hdrsz, size_t cntsz, bool_t doblock );bool_t -invmgr_query_all_sessions (void *inarg,void **outarg,search_callback_t func); +invmgr_query_all_sessions (uuid_t *fsidp,void *inarg,void **outarg, +search_callback_t func);intgen_t -search_invt (int invfd,void *arg,void **buf, -search_callback_t do_chkcriteria ); +search_invt (uuid_t *fsidp,int invfd,void *arg,void **buf, +search_callback_t do_chkcriteria);intgen_t invmgr_inv_print (int invfd,invt_pr_ctx_t *prctx);Index:
b/inventory/inventory.h
===================================================================inventory/inventory.h +13
-8@@ -247,32 +247,37 @@ inv_put_mediafile(*/ extern bool_t inv_lasttime_level_lessthan ( +uuid_t *fsidp,inv_idbtoken_t tok, -u_char level, -time32_t **time );/* out */ +u_char level, +time32_t **time);/* out */ extern bool_t inv_lastsession_level_lessthan ( +uuid_t *fsidp,inv_idbtoken_t tok,u_char level, -inv_session_t **ses );/* out */ +inv_session_t **ses);/* out */ extern bool_t inv_lastsession_level_equalto ( +uuid_t *fsidp,inv_idbtoken_t tok,u_char level, -inv_session_t **ses );/* out */ +inv_session_t **ses);/* out */ /* Given a uuid of a session, return the session structure.*/ extern bool_t inv_get_session_byuuid ( -uuid_t *sesid, -inv_session_t **ses); +uuid_t *fsidp, +uuid_t *sesid, +inv_session_t **ses);extern bool_t inv_get_session_bylabel ( -char *session_label, -inv_session_t **ses); +uuid_t *fsidp, +char *session_label, +inv_session_t **ses);/* on return, *ses is NULL */ Index:
b/restore/content.c
===================================================================restore/content.c +13
-10@@ -2179,8 +2179,9 @@ content_stream_restore( ix_t thrdix )if ( ! drivep->d_isnamedpipepr && ! drivep->d_isunnamedpipepr ) { - ok =inv_get_session_byuuid ( &grhdrp->gh_dumpid, - &sessp ); + ok =inv_get_session_byuuid (NULL , + &grhdrp->gh_dumpid, + &sessp);if ( ok && sessp ) {mlog (MLOG_VERBOSE ,_ ("using online session inventory\n" ) );@@ -3736,9 +3737,9 @@ Inv_validate_cmdline( void ) ok =BOOL_FALSE ; sessp =0 ;if ( tranp->t_reqdumpidvalpr ) { - ok =inv_get_session_byuuid ( &tranp->t_reqdumpid, &sessp ); + ok =inv_get_session_byuuid (NULL , &tranp->t_reqdumpid, &sessp); }else if ( tranp->t_reqdumplabvalpr ) { - ok =inv_get_session_bylabel ( tranp->t_reqdumplab, &sessp ); + ok =inv_get_session_bylabel (NULL , tranp->t_reqdumplab, &sessp); } rok =BOOL_FALSE ;if ( ok && sessp ) {@@ -6812,13 +6813,15 @@ askinvforbaseof( uuid_t baseid, inv_sess/* get the base session */ if ( resumedpr ) { - ok =inv_lastsession_level_equalto ( invtok, - (u_char_t )level, - &basesessp ); + ok =inv_lastsession_level_equalto (&sessp->s_fsid, + invtok, + (u_char_t )level, + &basesessp); }else { - ok =inv_lastsession_level_lessthan ( invtok, - (u_char_t )level, - &basesessp ); + ok =inv_lastsession_level_lessthan (&sessp->s_fsid, + invtok, + (u_char_t )level, + &basesessp); }if ( ! ok ) { mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_MEDIA, _(
Quoted 4 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 4 lines · Brian Foster
Quoted 3 lines · Rich Johnston
Restoring an incremental level 1 dump will fail with the following error if the fs uuid of the most recent level 0 dump in the inventory does not match level 1 dump we are restoring.
...
Quoted 5 lines
Quoted 5 lines
Index:
b/inventory/inv_api.c
===================================================================inventory/inv_api.c +0
-0@@ -596,69 +596,78 @@ inv_free_session(
...
Quoted 8 lines
inventory/inv_api.c inv_free_session( · line 657
Quoted 5 lines
inventory/inv_api.c +1
-3-return invmgr_query_all_sessions ((void *) &level,/* in */ - (void **) ses,/* out */ - (search_callback_t ) lastsess_level_lessthan); + return invmgr_query_all_sessions(fsidp /* fs uuid */This doesn't compile because of a missing comma after fsidp above.
My mistake, happened while cleaning up whitespace.
...
Quoted 4 lines
Quoted 4 lines
Index:
b/inventory/inv_mgr.c
===================================================================inventory/inv_mgr.c +0
-0
...
Quoted 11 lines
Quoted 11 lines
inventory/inv_mgr.c +2
-2@@ -178,26 +180,27 @@ invmgr_query_all_sessions ( "INV: Open failed on %s\n"), fname ); -return BOOL_FALSE ; +continue ; } - result =search_invt ( invfd, inarg, &objectfound, func ); + result =search_invt (fsidp, invfd, inarg, &objectfound, func);close (invfd);
Quoted 7 lines
inventory/inv_mgr.c invmgr_query_all_sessions ( · line 190
Quoted 4 lines
inventory/inv_mgr.c +1
-1/* if error return BOOL_FALSE */ if (result <0 ) { -return BOOL_FALSE ; +return ret;Should this always return false? It's now possible to return true if an error occurs after we've found one object.
*nod* Thanks I missed that one.
I'll have a V4 out shortly.
--Rich
Quoted 5 lines
The rest seems Ok to me.
Brian
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH v4 1/1 xfsrestore: fix fs uuid order check for incremental restores
In reply to Brian FosterRestoring an incremental level 1 dump will fail with the following error if the fs uuid of the most recent level 0 dump in the inventory does not match level 1 dump we are restoring.
xfsrestore: ERROR: selected dump not based on previously applied dump
This can happen when you have multiple filesystems and you are restoring a level 1 or greater dump of filesystem FS1 but the most recent level 0 dump in the inventory was filesystem FS2
The fix is to ensure the fs uuid of the inventory entry and the dump to be restored match.
---
Changelog
V2 wrong file sent
V3
Address review comments from Brian:
fix invmgr_query_all_sessions() returning true if these error cases persist throughout the loop
make if check more readable and less overloaded in search_inv() and return an error if GET_REC_NOLOCK() fails
use NULL instead of (uuid_t *)0 in Inv_validate_cmdline()
remove any spaces around braces of code that was changed
V4
fix compile error introduced when I removed any spaces around braces of code that was changed and cleaning up whitespace.
we should be returning BOOL_FALSE on any errors. I missed one.
dump/content.c | 16 +++--- inventory/inv_api.c | 130 +++++++++++++++++++++++++++++--------------------- inventory/inv_mgr.c | 53 +++++++++++++------- inventory/inv_priv.h | 7 +- inventory/inventory.h | 21 +++++--- restore/content.c | 23 +++++--- 6 files changed, 151 insertions(+), 99 deletions(-)
dump/content.c +9 -7
@@ -872,7 +872,7 @@ content_init( intgen_t argc, sameinterruptedpr =BOOL_FALSE ; interruptedpr =BOOL_FALSE ; - ok =inv_get_session_byuuid ( &baseuuid, &sessp ); + ok =inv_get_session_byuuid (&fsid, &baseuuid, &sessp);if ( ! ok ) { mlog( MLOG_NORMAL | MLOG_ERROR, _( "could not find specified base dump (%s) "
@@ -983,9 +983,10 @@ content_init( intgen_t argc, "online inventory not available\n") );return BOOL_FALSE ; } - ok =inv_lastsession_level_lessthan ( inv_idbt, - (u_char_t )sc_level, - &sessp ); + ok =inv_lastsession_level_lessthan (&fsid, + inv_idbt, + (u_char_t )sc_level, + &sessp);if ( ! ok ) { sessp =0 ; }
@@ -1022,9 +1023,10 @@ content_init( intgen_t argc,if ( inv_idbt !=INV_TOKEN_NULL ) {/* REFERENCED */ bool_t ok1; - ok =inv_lastsession_level_equalto ( inv_idbt, - (u_char_t )sc_level, - &sessp ); + ok =inv_lastsession_level_equalto (&fsid, + inv_idbt, + (u_char_t )sc_level, + &sessp); ok1 =inv_close ( inv_idbt );ASSERT ( ok1 );if ( ! ok ) {
inventory/inv_api.c +76 -54
209 lines not on this page · raw message
inventory/inv_mgr.c +36 -17
121 lines not on this page · raw message
inventory/inv_priv.h +4 -3
@@ -548,11 +548,12 @@ get_headerinfo( int fd, void **hdrs, voi size_t hdrsz, size_t cntsz, bool_t doblock );bool_t -invmgr_query_all_sessions (void *inarg,void **outarg,search_callback_t func); +invmgr_query_all_sessions (uuid_t *fsidp,void *inarg,void **outarg, +search_callback_t func);intgen_t -search_invt (int invfd,void *arg,void **buf, -search_callback_t do_chkcriteria ); +search_invt (uuid_t *fsidp,int invfd,void *arg,void **buf, +search_callback_t do_chkcriteria);intgen_t invmgr_inv_print (int invfd,invt_pr_ctx_t *prctx);
inventory/inventory.h +13 -8
@@ -247,32 +247,37 @@ inv_put_mediafile(*/ extern bool_t inv_lasttime_level_lessthan ( +uuid_t *fsidp,inv_idbtoken_t tok, -u_char level, -time32_t **time );/* out */ +u_char level, +time32_t **time);/* out */ extern bool_t inv_lastsession_level_lessthan ( +uuid_t *fsidp,inv_idbtoken_t tok,u_char level, -inv_session_t **ses );/* out */ +inv_session_t **ses);/* out */ extern bool_t inv_lastsession_level_equalto ( +uuid_t *fsidp,inv_idbtoken_t tok,u_char level, -inv_session_t **ses );/* out */ +inv_session_t **ses);/* out */ /* Given a uuid of a session, return the session structure.*/ extern bool_t inv_get_session_byuuid ( -uuid_t *sesid, -inv_session_t **ses); +uuid_t *fsidp, +uuid_t *sesid, +inv_session_t **ses);extern bool_t inv_get_session_bylabel ( -char *session_label, -inv_session_t **ses); +uuid_t *fsidp, +char *session_label, +inv_session_t **ses);/* on return, *ses is NULL */
restore/content.c +13 -10
@@ -2179,8 +2179,9 @@ content_stream_restore( ix_t thrdix )if ( ! drivep->d_isnamedpipepr && ! drivep->d_isunnamedpipepr ) { - ok =inv_get_session_byuuid ( &grhdrp->gh_dumpid, - &sessp ); + ok =inv_get_session_byuuid (NULL , + &grhdrp->gh_dumpid, + &sessp);if ( ok && sessp ) {mlog (MLOG_VERBOSE ,_ ("using online session inventory\n" ) );
@@ -3736,9 +3737,9 @@ Inv_validate_cmdline( void ) ok =BOOL_FALSE ; sessp =0 ;if ( tranp->t_reqdumpidvalpr ) { - ok =inv_get_session_byuuid ( &tranp->t_reqdumpid, &sessp ); + ok =inv_get_session_byuuid (NULL , &tranp->t_reqdumpid, &sessp); }else if ( tranp->t_reqdumplabvalpr ) { - ok =inv_get_session_bylabel ( tranp->t_reqdumplab, &sessp ); + ok =inv_get_session_bylabel (NULL , tranp->t_reqdumplab, &sessp); } rok =BOOL_FALSE ;if ( ok && sessp ) {
@@ -6812,13 +6813,15 @@ askinvforbaseof( uuid_t baseid, inv_sess/* get the base session */ if ( resumedpr ) { - ok =inv_lastsession_level_equalto ( invtok, - (u_char_t )level, - &basesessp ); + ok =inv_lastsession_level_equalto (&sessp->s_fsid, + invtok, + (u_char_t )level, + &basesessp); }else { - ok =inv_lastsession_level_lessthan ( invtok, - (u_char_t )level, - &basesessp ); + ok =inv_lastsession_level_lessthan (&sessp->s_fsid, + invtok, + (u_char_t )level, + &basesessp); }if ( ! ok ) { mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_MEDIA, _(
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 10 lines · Rich Johnston
Restoring an incremental level 1 dump will fail with the following error if the fs uuid of the most recent level 0 dump in the inventory does not match level 1 dump we are restoring.
xfsrestore: ERROR: selected dump not based on previously applied dump
This can happen when you have multiple filesystems and you are restoring a level 1 or greater dump of filesystem FS1 but the most recent level 0 dump in the inventory was filesystem FS2
Quoted 5 lines
The fix is to ensure the fs uuid of the inventory entry and the dump to be restored match.
Signed-off-by Rich Johnston <[email protected]>---
Looks fine to me:
Quoted 544 lines
Changelog
V2 wrong file sentV3
Address review comments from Brian:fix
invmgr_query_all_sessions()returning true if these error cases persist throughout the loopmake if check more readable and less overloaded in
search_inv()and return an error ifGET_REC_NOLOCK()failsuse NULL instead of (
uuid_t*)0 inInv_validate_cmdline()remove any spaces around braces of code that was changed
V4
fix compile error introduced when I removed any spaces around braces of code that was changed and cleaning up whitespace.we should be returning
BOOL_FALSEon any errors. I missed one.dump/content.c | 16 +++--- inventory/inv_api.c | 130 +++++++++++++++++++++++++++++--------------------- inventory/inv_mgr.c | 53 +++++++++++++------- inventory/inv_priv.h | 7 +- inventory/inventory.h | 21 +++++--- restore/content.c | 23 +++++--- 6 files changed, 151 insertions(+), 99 deletions(-)Index:
b/dump/content.c
===================================================================dump/content.c +9
-7@@ -872,7 +872,7 @@ content_init( intgen_t argc, sameinterruptedpr =BOOL_FALSE ; interruptedpr =BOOL_FALSE ; - ok =inv_get_session_byuuid ( &baseuuid, &sessp ); + ok =inv_get_session_byuuid (&fsid, &baseuuid, &sessp);if ( ! ok ) { mlog( MLOG_NORMAL | MLOG_ERROR, _( "could not find specified base dump (%s) "@@ -983,9 +983,10 @@ content_init( intgen_t argc, "online inventory not available\n") );return BOOL_FALSE ; } - ok =inv_lastsession_level_lessthan ( inv_idbt, - (u_char_t )sc_level, - &sessp ); + ok =inv_lastsession_level_lessthan (&fsid, + inv_idbt, + (u_char_t )sc_level, + &sessp);if ( ! ok ) { sessp =0 ; }@@ -1022,9 +1023,10 @@ content_init( intgen_t argc,if ( inv_idbt !=INV_TOKEN_NULL ) {/* REFERENCED */ bool_t ok1; - ok =inv_lastsession_level_equalto ( inv_idbt, - (u_char_t )sc_level, - &sessp ); + ok =inv_lastsession_level_equalto (&fsid, + inv_idbt, + (u_char_t )sc_level, + &sessp); ok1 =inv_close ( inv_idbt );ASSERT ( ok1 );if ( ! ok ) {Index:
b/inventory/inv_api.c
===================================================================inventory/inv_api.c +76
-54@@ -596,69 +596,78 @@ inv_free_session(/*----------------------------------------------------------------------*/ -/* inventory_lasttime_level_lessthan */ -/* */ -/* Given a token that refers to a file system, and a level, this returns*/ -/* the last time when a session of a lesser level was done. */ -/* */ -/* returns -1 on error. */ +/* inv_lasttime_level_lessthan */ +/* */ +/* Given a file system uuid, token that refers to a file system, and a */ +/* level, tm is populated with last time when a session of a lesser */ +/* level was done. */ +/* */ +/* Returns TRUE on success. */ /*----------------------------------------------------------------------*/ bool_t inv_lasttime_level_lessthan ( -inv_idbtoken_t tok, -u_char level, -time32_t **tm ) +uuid_t *fsidp, +inv_idbtoken_t tok, +u_char level, +time32_t **tm) {int rval;if ( tok !=INV_TOKEN_NULL ) { - rval =search_invt ( tok->d_invindex_fd, &level, (void **) tm, - (search_callback_t ) tm_level_lessthan ); + rval =search_invt (fsidp, tok->d_invindex_fd, &level, + (void **)tm, + (search_callback_t )tm_level_lessthan);return ( rval <0 ) ?BOOL_FALSE :BOOL_TRUE ; } -return invmgr_query_all_sessions ((void *) &level,/* in */ - (void **) tm,/* out */ - (search_callback_t ) tm_level_lessthan); +return invmgr_query_all_sessions (fsidp,/* fs uuid ptr */ + (void *)&level,/* in */ + (void **)tm,/* out */ + (search_callback_t )tm_level_lessthan); } - - - -/*----------------------------------------------------------------------*/ -/* */ -/* */ -/* */ +/* inv_lastsession_level_lessthan */ +/* */ +/* Given a file system uuid, token that refers to a file system, and a */ +/* level, ses is populated with a session of lesser than the level */ +/* passed in. */ +/* */ +/* Returns FALSE on an error, TRUE if not. If (*ses) is NULL, then the */ +/* search failed. */ /*----------------------------------------------------------------------*/ bool_t inv_lastsession_level_lessthan ( -inv_idbtoken_t tok, +uuid_t *fsidp, +inv_idbtoken_t tok,u_char level, -inv_session_t **ses ) +inv_session_t **ses) {int rval;if ( tok !=INV_TOKEN_NULL ) { - rval =search_invt ( tok->d_invindex_fd, &level, (void **) ses, - (search_callback_t ) lastsess_level_lessthan ); + rval =search_invt (fsidp, tok->d_invindex_fd, &level, + (void **)ses, + (search_callback_t )lastsess_level_lessthan);return ( rval <0 ) ?BOOL_FALSE :BOOL_TRUE ; } -return invmgr_query_all_sessions ((void *) &level,/* in */ - (void **) ses,/* out */ - (search_callback_t ) lastsess_level_lessthan); +return invmgr_query_all_sessions (fsidp,/* fs uuid */ + (void *)&level,/* in */ + (void **)ses,/* out */ + (search_callback_t )lastsess_level_lessthan); } - - -/*----------------------------------------------------------------------*/ -/* */ -/* */ +/* inv_lastsession_level_equalto */ +/* */ +/* Given a file system uuid, token that refers to a file system, and a */ +/* level, this populates ses with last time when a session of a lesser */ +/* level was done. */ +/* */ /* Return FALSE on an error, TRUE if not. If (*ses) is NULL, then the */ /* search failed. */ /*----------------------------------------------------------------------*/ @@ -666,21 +675,24 @@ inv_lastsession_level_lessthan(bool_t inv_lastsession_level_equalto ( -inv_idbtoken_t tok, +uuid_t *fsidp, +inv_idbtoken_t tok,u_char level,inv_session_t **ses ) {int rval;if ( tok !=INV_TOKEN_NULL ) { - rval =search_invt ( tok->d_invindex_fd, &level, (void **) ses, - (search_callback_t ) lastsess_level_equalto ); + rval =search_invt (fsidp, tok->d_invindex_fd, &level, + (void **)ses, + (search_callback_t )lastsess_level_equalto);return ( rval <0 ) ?BOOL_FALSE :BOOL_TRUE ; } -return invmgr_query_all_sessions ((void *) &level,/* in */ - (void **) ses,/* out */ - (search_callback_t ) lastsess_level_equalto); +return invmgr_query_all_sessions (fsidp,/* fs uuid */ + (void *)&level,/* in */ + (void **)ses,/* out */ + (search_callback_t )lastsess_level_equalto); }@@ -688,35 +700,45 @@ inv_lastsession_level_equalto(/*----------------------------------------------------------------------*/ /* inv_getsession_byuuid */ /* */ +/* Given a file system uuid and a session uuid , ses is populated with */ +/* the session that contains the matching system uuid. */ +/* */ +/* Returns FALSE on an error, TRUE if the session was found. */ /*----------------------------------------------------------------------*/ bool_t inv_get_session_byuuid ( -uuid_t *sesid, -inv_session_t **ses) +uuid_t *fsidp, +uuid_t *sesid, +inv_session_t **ses) { -return (invmgr_query_all_sessions ((void *)sesid,/* in */ - (void **) ses,/* out */ - (search_callback_t ) stobj_getsession_byuuid)); +return invmgr_query_all_sessions (fsidp,/* fs uuid */ + (void *)sesid,/* in */ + (void **)ses,/* out */ + (search_callback_t )stobj_getsession_byuuid); } - -/*----------------------------------------------------------------------*/ -/* inv_getsession_byuuid */ +/* inv_getsession_bylabel */ /* */ +/* Given a file system uuid and a session uuid, ses is populated with */ +/* the session that contains the matching system label. */ +/* */ +/* Returns FALSE on an error, TRUE if the session was found. */ /*----------------------------------------------------------------------*/ bool_t inv_get_session_bylabel ( -char *session_label, -inv_session_t **ses) +uuid_t *fsidp, +char *session_label, +inv_session_t **ses) { -return (invmgr_query_all_sessions ((void *)session_label,/* in */ - (void **) ses,/* out */ - (search_callback_t ) stobj_getsession_bylabel)); +return invmgr_query_all_sessions (fsidp,/* fs uuid */ + (void *)session_label,/* in */ + (void **)ses,/* out */ + (search_callback_t )stobj_getsession_bylabel); }@@ -786,8 +808,8 @@ inv_delete_mediaobj( uuid_t *moid )return BOOL_FALSE ; } -if (search_invt ( invfd,NULL , (void **)&moid, - (search_callback_t ) stobj_delete_mobj ) +if (search_invt (&arr[i].ft_uuid, invfd,NULL , (void **)&moid, + (search_callback_t )stobj_delete_mobj) <0 )return BOOL_FALSE ;/* we have to delete the session, etc */ Index:
b/inventory/inv_mgr.c
===================================================================inventory/inv_mgr.c +36
-17@@ -134,8 +134,9 @@ get_sesstoken( inv_idbtoken_t tok )/*---------------------------------------------------------------------------*/ bool_t invmgr_query_all_sessions ( -void *inarg, -void **outarg, +uuid_t *fsidp, +void *inarg, +void **outarg,search_callback_t func) {invt_counter_t *cnt;@@ -145,6 +146,7 @@ invmgr_query_all_sessions (int result;inv_oflag_t forwhat =INV_SEARCH_ONLY ;void *objectfound; +bool_t ret =BOOL_FALSE ;/* if on return, this is still null, the search failed */ *outarg =NULL ;@@ -157,7 +159,7 @@ invmgr_query_all_sessions ( }if ( fd <0 || numfs <=0 ) {mlog (MLOG_NORMAL |MLOG_INV ,_ ("INV: Error in fstab\n" ) ); -return BOOL_FALSE ; +return ret; }close ( fd );@@ -169,7 +171,7 @@ invmgr_query_all_sessions (mlog (MLOG_NORMAL |MLOG_INV ,_ ("INV: Cant get inv-name for uuid\n" ) ); -return BOOL_FALSE ; +continue ; }strcat ( fname,INV_INVINDEX_PREFIX ); invfd =open ( fname,INV_OFLAG (forwhat) );@@ -178,9 +180,9 @@ invmgr_query_all_sessions ( "INV: Open failed on %s\n"), fname ); -return BOOL_FALSE ; +continue ; } - result =search_invt ( invfd, inarg, &objectfound, func ); + result =search_invt (fsidp, invfd, inarg, &objectfound, func);close (invfd);/* if error return BOOL_FALSE */ @@ -192,12 +194,13 @@ invmgr_query_all_sessions (return BOOL_TRUE ; }else if (result ==1 ) { *outarg = objectfound; + ret =BOOL_TRUE ; } }/* return val indicates if there was an error or not. *buf says whether the search was successful */ -return BOOL_TRUE ; +return ret; }@@ -213,10 +216,11 @@ invmgr_query_all_sessions (intgen_t search_invt ( -int invfd, -void *arg, -void **buf, -search_callback_t do_chkcriteria ) +uuid_t *fsidp, +int invfd, +void *arg, +void **buf, +search_callback_t do_chkcriteria) {int fd, i;@@ -247,7 +251,7 @@ search_invt(/* we need to get all the invindex headers and seshdrs in reverse order */ for (i = nindices -1 ; i >=0 ; i--) { -int nsess; +int nsess, j;invt_sescounter_t *scnt =NULL ;invt_seshdr_t *harr =NULL ;bool_t found;@@ -272,19 +276,34 @@ search_invt( }free ( scnt ); -while ( nsess ) { +for (j = nsess -1 ; j >=0 ; j--) { +invt_session_t ses; +/* fd is kept locked until we return from the callback routine */ /* Check to see if this session has been pruned * by xfsinvutil before checking it. */ -if ( harr[nsess -1 ].sh_pruned ) { - --nsess; +if (harr[j].sh_pruned) {continue ; } - found = (* do_chkcriteria ) ( fd, &harr[ --nsess ], - arg, buf ); + +/* if we need to check the fs uuid's and they don't +* match or we fail to get the session record, +* then keep looking +*/ +if (fsidp) { +int ret =GET_REC_NOLOCK (fd, &ses, +sizeof (invt_session_t), + harr[j].sh_sess_off); +if (ret <0 ) +return ret; +if (uuid_compare (ses.s_fsid, *fsidp)) +continue ; + } + + found = (* do_chkcriteria)(fd, &harr[j], arg, buf);if (! found )continue ;/* we found what we need; just return */ Index:
b/inventory/inv_priv.h
===================================================================inventory/inv_priv.h +4
-3@@ -548,11 +548,12 @@ get_headerinfo( int fd, void **hdrs, voi size_t hdrsz, size_t cntsz, bool_t doblock );bool_t -invmgr_query_all_sessions (void *inarg,void **outarg,search_callback_t func); +invmgr_query_all_sessions (uuid_t *fsidp,void *inarg,void **outarg, +search_callback_t func);intgen_t -search_invt (int invfd,void *arg,void **buf, -search_callback_t do_chkcriteria ); +search_invt (uuid_t *fsidp,int invfd,void *arg,void **buf, +search_callback_t do_chkcriteria);intgen_t invmgr_inv_print (int invfd,invt_pr_ctx_t *prctx);Index:
b/inventory/inventory.h
===================================================================inventory/inventory.h +13
-8@@ -247,32 +247,37 @@ inv_put_mediafile(*/ extern bool_t inv_lasttime_level_lessthan ( +uuid_t *fsidp,inv_idbtoken_t tok, -u_char level, -time32_t **time );/* out */ +u_char level, +time32_t **time);/* out */ extern bool_t inv_lastsession_level_lessthan ( +uuid_t *fsidp,inv_idbtoken_t tok,u_char level, -inv_session_t **ses );/* out */ +inv_session_t **ses);/* out */ extern bool_t inv_lastsession_level_equalto ( +uuid_t *fsidp,inv_idbtoken_t tok,u_char level, -inv_session_t **ses );/* out */ +inv_session_t **ses);/* out */ /* Given a uuid of a session, return the session structure.*/ extern bool_t inv_get_session_byuuid ( -uuid_t *sesid, -inv_session_t **ses); +uuid_t *fsidp, +uuid_t *sesid, +inv_session_t **ses);extern bool_t inv_get_session_bylabel ( -char *session_label, -inv_session_t **ses); +uuid_t *fsidp, +char *session_label, +inv_session_t **ses);/* on return, *ses is NULL */ Index:
b/restore/content.c
===================================================================restore/content.c +13
-10@@ -2179,8 +2179,9 @@ content_stream_restore( ix_t thrdix )if ( ! drivep->d_isnamedpipepr && ! drivep->d_isunnamedpipepr ) { - ok =inv_get_session_byuuid ( &grhdrp->gh_dumpid, - &sessp ); + ok =inv_get_session_byuuid (NULL , + &grhdrp->gh_dumpid, + &sessp);if ( ok && sessp ) {mlog (MLOG_VERBOSE ,_ ("using online session inventory\n" ) );@@ -3736,9 +3737,9 @@ Inv_validate_cmdline( void ) ok =BOOL_FALSE ; sessp =0 ;if ( tranp->t_reqdumpidvalpr ) { - ok =inv_get_session_byuuid ( &tranp->t_reqdumpid, &sessp ); + ok =inv_get_session_byuuid (NULL , &tranp->t_reqdumpid, &sessp); }else if ( tranp->t_reqdumplabvalpr ) { - ok =inv_get_session_bylabel ( tranp->t_reqdumplab, &sessp ); + ok =inv_get_session_bylabel (NULL , tranp->t_reqdumplab, &sessp); } rok =BOOL_FALSE ;if ( ok && sessp ) {@@ -6812,13 +6813,15 @@ askinvforbaseof( uuid_t baseid, inv_sess/* get the base session */ if ( resumedpr ) { - ok =inv_lastsession_level_equalto ( invtok, - (u_char_t )level, - &basesessp ); + ok =inv_lastsession_level_equalto (&sessp->s_fsid, + invtok, + (u_char_t )level, + &basesessp); }else { - ok =inv_lastsession_level_lessthan ( invtok, - (u_char_t )level, - &basesessp ); + ok =inv_lastsession_level_lessthan (&sessp->s_fsid, + invtok, + (u_char_t )level, + &basesessp); }if ( ! ok ) { mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_MEDIA, _(
Quoted 4 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs