[tools/peerindex] Improve resource management and error reporting
This commit is contained in:
parent
5b090d605e
commit
5e43edd273
|
@ -133,6 +133,15 @@ void Peerindex_DropFile(const char *fmt, ...)
|
||||||
Bgp_ClearMrt(&S.peerIndex);
|
Bgp_ClearMrt(&S.peerIndex);
|
||||||
S.hasPeerIndex = FALSE;
|
S.hasPeerIndex = FALSE;
|
||||||
|
|
||||||
|
// Drop any opened file and jump out
|
||||||
|
if (S.infOps) {
|
||||||
|
if (S.infOps->Close) S.infOps->Close(S.inf);
|
||||||
|
|
||||||
|
S.inf = NULL;
|
||||||
|
S.infOps = NULL;
|
||||||
|
}
|
||||||
|
S.filename = NULL;
|
||||||
|
|
||||||
longjmp(S.dropFileFrame, 1);
|
longjmp(S.dropFileFrame, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,36 +188,40 @@ static void Peerindex_Init(void)
|
||||||
S.rec.memOps = Mem_BgpBufOps;
|
S.rec.memOps = Mem_BgpBufOps;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const StmOps *Peerindex_OpenMrtDump(const char *filename, void **phn)
|
static void Peerindex_OpenMrtDump(const char *filename)
|
||||||
{
|
{
|
||||||
|
S.filename = filename;
|
||||||
|
if (strcmp(S.filename, "-") == 0) {
|
||||||
|
// Direct read from stdin, assume uncompressed
|
||||||
|
S.inf = STM_FILDES(CON_FILDES(STDIN));
|
||||||
|
S.infOps = Stm_NcFildesOps;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Fildes fh = Sys_Fopen(filename, FM_READ, FH_SEQ);
|
Fildes fh = Sys_Fopen(filename, FM_READ, FH_SEQ);
|
||||||
if (fh == FILDES_BAD)
|
if (fh == FILDES_BAD)
|
||||||
Peerindex_DropFile("Can't open file");
|
Peerindex_DropFile("Can't open file");
|
||||||
|
|
||||||
const char *ext = Sys_GetFileExtension(filename);
|
const char *ext = Sys_GetFileExtension(filename);
|
||||||
|
|
||||||
void *hn;
|
|
||||||
const StmOps *ops;
|
|
||||||
|
|
||||||
if (Df_stricmp(ext, ".bz2") == 0) {
|
if (Df_stricmp(ext, ".bz2") == 0) {
|
||||||
hn = Bzip2_OpenDecompress(STM_FILDES(fh), Stm_FildesOps, /*opts=*/NULL);
|
S.inf = Bzip2_OpenDecompress(STM_FILDES(fh), Stm_FildesOps, /*opts=*/NULL);
|
||||||
ops = Bzip2_StmOps;
|
S.infOps = Bzip2_StmOps;
|
||||||
|
|
||||||
Bzip2Ret err = Bzip2_GetErrStat();
|
Bzip2Ret err = Bzip2_GetErrStat();
|
||||||
if (err)
|
if (err)
|
||||||
Peerindex_DropFile("Can't read Bz2 archive: %s", Bzip2_ErrorString(err));
|
Peerindex_DropFile("Can't read Bz2 archive: %s", Bzip2_ErrorString(err));
|
||||||
|
|
||||||
} else if (Df_stricmp(ext, ".gz") == 0 || Df_stricmp(ext, ".z") == 0) {
|
} else if (Df_stricmp(ext, ".gz") == 0 || Df_stricmp(ext, ".z") == 0) {
|
||||||
hn = Zlib_InflateOpen(STM_FILDES(fh), Stm_FildesOps, /*opts=*/NULL);
|
S.inf = Zlib_InflateOpen(STM_FILDES(fh), Stm_FildesOps, /*opts=*/NULL);
|
||||||
ops = Zlib_StmOps;
|
S.infOps = Zlib_StmOps;
|
||||||
|
|
||||||
ZlibRet err = Zlib_GetErrStat();
|
ZlibRet err = Zlib_GetErrStat();
|
||||||
if (err)
|
if (err)
|
||||||
Peerindex_DropFile("Can't read Zlib archive: %s", Zlib_ErrorString(err));
|
Peerindex_DropFile("Can't read Zlib archive: %s", Zlib_ErrorString(err));
|
||||||
|
|
||||||
} else if (Df_stricmp(ext, ".xz") == 0) {
|
} else if (Df_stricmp(ext, ".xz") == 0) {
|
||||||
hn = Xz_OpenDecompress(STM_FILDES(fh), Stm_FildesOps, /*opts=*/NULL);
|
S.inf = Xz_OpenDecompress(STM_FILDES(fh), Stm_FildesOps, /*opts=*/NULL);
|
||||||
ops = Xz_StmOps;
|
S.infOps = Xz_StmOps;
|
||||||
|
|
||||||
XzRet err = Xz_GetErrStat();
|
XzRet err = Xz_GetErrStat();
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -216,12 +229,9 @@ static const StmOps *Peerindex_OpenMrtDump(const char *filename, void **phn)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Assume uncompressed file
|
// Assume uncompressed file
|
||||||
hn = STM_FILDES(fh);
|
S.inf = STM_FILDES(fh);
|
||||||
ops = Stm_FildesOps;
|
S.infOps = Stm_FildesOps;
|
||||||
}
|
}
|
||||||
|
|
||||||
*phn = hn;
|
|
||||||
return ops;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Peerindex_MarkPeerRefs(void)
|
static void Peerindex_MarkPeerRefs(void)
|
||||||
|
@ -242,7 +252,7 @@ static void Peerindex_MarkPeerRefs(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Peerindex_DumpPeerIndexTable(void)
|
static void Peerindex_FlushPeerIndexTable(void)
|
||||||
{
|
{
|
||||||
char buf[IPV6_STRLEN + 1];
|
char buf[IPV6_STRLEN + 1];
|
||||||
Stmbuf sb;
|
Stmbuf sb;
|
||||||
|
@ -278,28 +288,15 @@ static void Peerindex_DumpPeerIndexTable(void)
|
||||||
Bufio_Flush(&sb);
|
Bufio_Flush(&sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Peerindex_ProcessMrtDump(const char *filename)
|
static void Peerindex_ProcessRecord(void)
|
||||||
{
|
{
|
||||||
void *hn;
|
|
||||||
const StmOps *ops;
|
|
||||||
|
|
||||||
S.filename = filename; // NOTE: Only function that manipulates this
|
|
||||||
|
|
||||||
if (strcmp(filename, "-") == 0) {
|
|
||||||
hn = STM_FILDES(CON_FILDES(STDIN));
|
|
||||||
ops = Stm_NcFildesOps;
|
|
||||||
} else
|
|
||||||
ops = Peerindex_OpenMrtDump(filename, &hn);
|
|
||||||
|
|
||||||
setjmp(S.dropRecordFrame); // NOTE: The ONLY place where this is set
|
|
||||||
while (Bgp_ReadMrt(&S.rec, hn, ops) == OK) {
|
|
||||||
const Mrthdr *hdr = MRT_HDR(&S.rec);
|
const Mrthdr *hdr = MRT_HDR(&S.rec);
|
||||||
if (hdr->type != MRT_TABLE_DUMPV2)
|
if (hdr->type != MRT_TABLE_DUMPV2)
|
||||||
continue; // don't care for anything else
|
return; // don't care for anything else
|
||||||
|
|
||||||
if (hdr->subtype == TABLE_DUMPV2_PEER_INDEX_TABLE) {
|
if (hdr->subtype == TABLE_DUMPV2_PEER_INDEX_TABLE) {
|
||||||
// Dump peers seen so far, if any
|
// Dump peers seen so far, if any
|
||||||
Peerindex_DumpPeerIndexTable();
|
Peerindex_FlushPeerIndexTable();
|
||||||
// Clear previous PEER_INDEX_TABLE, if any
|
// Clear previous PEER_INDEX_TABLE, if any
|
||||||
Bgp_ClearMrt(&S.peerIndex);
|
Bgp_ClearMrt(&S.peerIndex);
|
||||||
// Clear reference table...
|
// Clear reference table...
|
||||||
|
@ -312,24 +309,43 @@ static void Peerindex_ProcessMrtDump(const char *filename)
|
||||||
Bgp_GetMrtPeerIndexPeers(&S.peerIndex, &npeers, /*nbytes=*/NULL);
|
Bgp_GetMrtPeerIndexPeers(&S.peerIndex, &npeers, /*nbytes=*/NULL);
|
||||||
S.npeers = npeers;
|
S.npeers = npeers;
|
||||||
S.hasPeerIndex = TRUE;
|
S.hasPeerIndex = TRUE;
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
if (!TABLE_DUMPV2_ISRIB(hdr->subtype))
|
|
||||||
continue; // don't care for anything but RIBs
|
|
||||||
|
|
||||||
if (!S.hasPeerIndex) {
|
if (!TABLE_DUMPV2_ISRIB(hdr->subtype))
|
||||||
Peerindex_Warning("SKIPPING");
|
return; // irrelevant to us
|
||||||
continue;
|
|
||||||
}
|
if (!S.hasPeerIndex)
|
||||||
|
Peerindex_DropRecord("SKIPPING TABLE_DUMPV2 RECORD - No PEER_INDEX_TABLE found yet");
|
||||||
|
|
||||||
Peerindex_MarkPeerRefs();
|
Peerindex_MarkPeerRefs();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Peerindex_ProcessMrtDump(const char *filename)
|
||||||
|
{
|
||||||
|
// NOTE: This call is responsible to set and clear:
|
||||||
|
// S.filename, S.inf, S.infOps.
|
||||||
|
// These must be cleared either here or within a file drop.
|
||||||
|
Peerindex_OpenMrtDump(filename);
|
||||||
|
|
||||||
|
setjmp(S.dropRecordFrame); // NOTE: The ONLY place where this is set
|
||||||
|
while (Bgp_ReadMrt(&S.rec, S.inf, S.infOps) == OK) {
|
||||||
|
Peerindex_ProcessRecord();
|
||||||
|
|
||||||
|
Bgp_ClearMrt(&S.rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
Peerindex_DumpPeerIndexTable(); // execute the very last dump
|
Peerindex_FlushPeerIndexTable(); // execute the very last dump
|
||||||
|
|
||||||
if (ops->Close)
|
// Don't need PEER_INDEX_TABLE anymore
|
||||||
ops->Close(hn);
|
Bgp_ClearMrt(&S.peerIndex);
|
||||||
|
S.hasPeerIndex = FALSE;
|
||||||
|
|
||||||
|
// Finally close file and call it a day
|
||||||
|
if (S.infOps->Close) S.infOps->Close(S.inf);
|
||||||
|
|
||||||
|
S.inf = NULL;
|
||||||
|
S.infOps = NULL;
|
||||||
S.filename = NULL;
|
S.filename = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,13 +386,8 @@ int main(int argc, char **argv)
|
||||||
volatile int i = 0;
|
volatile int i = 0;
|
||||||
|
|
||||||
setjmp(S.dropFileFrame); // NOTE: The ONLY place where this is set
|
setjmp(S.dropFileFrame); // NOTE: The ONLY place where this is set
|
||||||
while (i < argc) {
|
while (i < argc)
|
||||||
Peerindex_ProcessMrtDump(argv[i++]);
|
Peerindex_ProcessMrtDump(argv[i++]);
|
||||||
|
|
||||||
// Don't need PEER_INDEX_TABLE anymore
|
|
||||||
Bgp_ClearMrt(&S.peerIndex);
|
|
||||||
S.hasPeerIndex = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (S.nerrors > 0) ? EXIT_FAILURE : EXIT_SUCCESS;
|
return (S.nerrors > 0) ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,10 @@ FORCE_INLINE Boolean ISPEERINDEXREF(const PeerRefsTab tab, Uint16 idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *filename; // current file being processed
|
// MRT input file stream
|
||||||
|
const char *filename;
|
||||||
|
void *inf;
|
||||||
|
const StmOps *infOps;
|
||||||
|
|
||||||
// Miscellaneous global flags and data
|
// Miscellaneous global flags and data
|
||||||
Boolean8 hasPeerIndex;
|
Boolean8 hasPeerIndex;
|
||||||
|
|
Loading…
Reference in New Issue