summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2017-12-05 14:48:56 -0500
committerDamjan Marion <dmarion.lists@gmail.com>2017-12-06 10:43:19 +0000
commit55c79e9c7e14b501baa72bc8b415e0a66752ed01 (patch)
treefb8dce55a87d00fb412234168e229ba029c2ac11
parent9c2c243062dd53a420f156ac3948b464fff833df (diff)
make clib_maplog_update_header(...) globally accessible
clib_maplog_process(...): handle logs which weren't closed properly. It will happen. Change-Id: Ibcf9c9ea7a09991e6294050e7d2979a0d3f965cf Signed-off-by: Dave Barach <dave@barachs.net>
-rw-r--r--src/vppinfra/maplog.c63
-rw-r--r--src/vppinfra/maplog.h1
-rw-r--r--src/vppinfra/test_maplog.c14
3 files changed, 56 insertions, 22 deletions
diff --git a/src/vppinfra/maplog.c b/src/vppinfra/maplog.c
index 41ee0757897..3e08973bc8c 100644
--- a/src/vppinfra/maplog.c
+++ b/src/vppinfra/maplog.c
@@ -224,35 +224,20 @@ _clib_maplog_get_entry_slowpath (clib_maplog_main_t * mm, u64 my_record_index)
}
/**
- * @brief Close a mapped log, and update the log header file
+ * @brief Update a mapped log header file
*
- * Unmap the current log segments.
* Read the log header. Update the number of records, and number of files
- *
* @param[in/out] mm mapped log object
*/
void
-clib_maplog_close (clib_maplog_main_t * mm)
+clib_maplog_update_header (clib_maplog_main_t * mm)
{
- int i, rv;
- u64 file_size_in_bytes;
- int fd;
+ int fd, rv;
clib_maplog_header_t _h, *h = &_h;
if (!(mm->flags & CLIB_MAPLOG_FLAG_INIT))
return;
- file_size_in_bytes =
- mm->file_size_in_records * mm->record_size_in_cachelines *
- CLIB_CACHE_LINE_BYTES;
-
- /* unmap current + next segments */
- for (i = 0; i < 2; i++)
- {
- (void) munmap ((u8 *) mm->file_baseva[i], file_size_in_bytes);
- vec_free (mm->filenames[i]);
- }
-
/* Open the log header */
fd = open ((char *) mm->header_filename, O_RDWR, 0600);
if (fd < 0)
@@ -286,6 +271,37 @@ clib_maplog_close (clib_maplog_main_t * mm)
out:
if (fd >= 0)
(void) close (fd);
+}
+
+/**
+ * @brief Close a mapped log, and update the log header file
+ *
+ * Unmap the current log segments.
+ * Read the log header. Update the number of records, and number of files
+ *
+ * @param[in/out] mm mapped log object
+ */
+void
+clib_maplog_close (clib_maplog_main_t * mm)
+{
+ int i;
+ u64 file_size_in_bytes;
+
+ if (!(mm->flags & CLIB_MAPLOG_FLAG_INIT))
+ return;
+
+ clib_maplog_update_header (mm);
+
+ file_size_in_bytes =
+ mm->file_size_in_records * mm->record_size_in_cachelines *
+ CLIB_CACHE_LINE_BYTES;
+
+ /* unmap current + next segments */
+ for (i = 0; i < 2; i++)
+ {
+ (void) munmap ((u8 *) mm->file_baseva[i], file_size_in_bytes);
+ vec_free (mm->filenames[i]);
+ }
vec_free (mm->file_basename);
vec_free (mm->header_filename);
@@ -335,6 +351,14 @@ brief:
* Reads the maplog header. Map and process all log segments in order.
* Calls the callback function once per file with a record count.
*
+ * Note: if the file header isn't updated by calling
+ * clib_maplog_close(), it will appear to have an infinite
+ * number of records in an infinite number of files.
+ *
+ * So long as the callback function understands that possibility
+ * - by simply ignoring NULL records - the scheme still
+ * works...
+ *
* @param [in] file_basename Same basename supplied to clib_maplog_init
* @param [in] fp_arg Callback function pointer
*/
@@ -347,7 +371,7 @@ clib_maplog_process (char *file_basename, void *fp_arg)
u64 file_size_in_bytes;
u8 *header_filename, *this_filename = 0;
u8 *file_baseva;
- void (*fp) (clib_maplog_header_t *, void *data, u64 count);
+ int (*fp) (clib_maplog_header_t *, void *data, u64 count);
u64 records_this_file, records_left;
ASSERT (fp_arg);
@@ -384,7 +408,6 @@ clib_maplog_process (char *file_basename, void *fp_arg)
fd = open ((char *) this_filename, O_RDONLY, 0600);
if (fd < 0)
{
- clib_unix_warning ("open maplog file");
rv = -3;
goto out;
}
diff --git a/src/vppinfra/maplog.h b/src/vppinfra/maplog.h
index d1c23d20d29..9bc8596de1b 100644
--- a/src/vppinfra/maplog.h
+++ b/src/vppinfra/maplog.h
@@ -107,6 +107,7 @@ typedef struct
/* function prototypes */
int clib_maplog_init (clib_maplog_init_args_t * ap);
+void clib_maplog_update_header (clib_maplog_main_t * mm);
void clib_maplog_close (clib_maplog_main_t * mm);
int clib_maplog_process (char *file_basename, void *fp_arg);
diff --git a/src/vppinfra/test_maplog.c b/src/vppinfra/test_maplog.c
index c49ebd6885e..edb61bd84d0 100644
--- a/src/vppinfra/test_maplog.c
+++ b/src/vppinfra/test_maplog.c
@@ -38,6 +38,9 @@ process_maplog_records (clib_maplog_header_t * h,
while (records_this_file--)
{
+ /* Padding at the end of a damaged log? */
+ if (e->serial_number == 0ULL)
+ break;
fformat (stdout, "%4lld ", e->serial_number);
if (++i == 8)
{
@@ -57,6 +60,10 @@ test_maplog_main (unformat_input_t * input)
int rv;
int i;
test_entry_t *t;
+ int noclose = 0;
+
+ if (unformat (input, "noclose"))
+ noclose = 1;
memset (a, 0, sizeof (*a));
a->mm = mm;
@@ -79,10 +86,13 @@ test_maplog_main (unformat_input_t * input)
for (i = 0; i < 64 * 5; i++)
{
t = clib_maplog_get_entry (mm);
- t->serial_number = i;
+ t->serial_number = i + 1;
}
- clib_maplog_close (mm);
+ if (noclose)
+ memset (mm, 0, sizeof (*mm));
+ else
+ clib_maplog_close (mm);
clib_maplog_process ("/tmp/maplog_test", process_maplog_records);