make clib_maplog_update_header(...) globally accessible 34/9734/2
authorDave Barach <dave@barachs.net>
Tue, 5 Dec 2017 19:48:56 +0000 (14:48 -0500)
committerDamjan Marion <dmarion.lists@gmail.com>
Wed, 6 Dec 2017 10:43:19 +0000 (10:43 +0000)
clib_maplog_process(...): handle logs which weren't closed properly.
It will happen.

Change-Id: Ibcf9c9ea7a09991e6294050e7d2979a0d3f965cf
Signed-off-by: Dave Barach <dave@barachs.net>
src/vppinfra/maplog.c
src/vppinfra/maplog.h
src/vppinfra/test_maplog.c

index 41ee075..3e08973 100644 (file)
@@ -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;
        }
index d1c23d2..9bc8596 100644 (file)
@@ -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);
 
index c49ebd6..edb61bd 100644 (file)
@@ -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);