MYNEWT-568 log - Increase index to uint32 (was:16)

For the most part, this change is backwards compatible. The new behavior
is:

    /* If   lo_ts == -1: Only access last log entry;
     * Elif lo_ts == 0:  Don't filter by timestamp;
     * Else:             Only access entries whose ts >= lo_ts.
     */
    int64_t lo_ts;

    /* Only access entries whose index >= lo_index. */
    uint32_t lo_index;

So, the timestamp is still used as the primary key if a nonzero value is
specified. If 0 is specified, only the index is used to filter entries.

There is one compatibility-breaking change: the "logs show" command
retrieves all entries whose index is greater than or equal to the
specified index value. Prior to this change, the command only retrieved
entries whose index is greater. This change was made so that there is a
reliable means of getting an entry with an index of 0.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/e9390801
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/e9390801
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/e9390801

Branch: refs/heads/develop
Commit: e93908011066eab5cd9e6f2c2102fc36f049c58b
Parents: 68ed333
Author: Christopher Collins <[email protected]>
Authored: Thu Jan 26 16:23:23 2017 -0800
Committer: Christopher Collins <[email protected]>
Committed: Thu Jan 26 17:51:43 2017 -0800

----------------------------------------------------------------------
 sys/log/full/include/log/log.h |  9 ++--
 sys/log/full/src/log.c         | 88 +++++++++++++++++++++++++++++++++----
 sys/log/full/src/log_fcb.c     |  2 +-
 sys/log/full/src/log_nmgr.c    | 25 ++++++++---
 4 files changed, 103 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e9390801/sys/log/full/include/log/log.h
----------------------------------------------------------------------
diff --git a/sys/log/full/include/log/log.h b/sys/log/full/include/log/log.h
index 271312f..a55fa99 100644
--- a/sys/log/full/include/log/log.h
+++ b/sys/log/full/include/log/log.h
@@ -31,8 +31,7 @@ extern "C" {
 
 /* Global log info */
 struct log_info {
-    int64_t li_timestamp;
-    uint8_t li_index;
+    uint32_t li_next_index;
     uint8_t li_version;
 };
 #define LOG_VERSION_V2  2
@@ -72,7 +71,7 @@ struct log_handler {
 
 struct log_entry_hdr {
     int64_t ue_ts;
-    uint16_t ue_index;
+    uint32_t ue_index;
     uint8_t ue_module;
     uint8_t ue_level;
 }__attribute__((__packed__));
@@ -82,9 +81,9 @@ struct log_entry_hdr {
  * Encode request - packages log entry request and response
  */
 struct encode_off {
-    void *eo_encoder; /* typecast CborEncoder */
+    void *eo_arg; /* typecast CborEncoder */
     int64_t eo_ts;
-    uint8_t eo_index;
+    uint32_t eo_index;
     uint32_t rsp_len;
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e9390801/sys/log/full/src/log.c
----------------------------------------------------------------------
diff --git a/sys/log/full/src/log.c b/sys/log/full/src/log.c
index 89f2741..cc4c56a 100644
--- a/sys/log/full/src/log.c
+++ b/sys/log/full/src/log.c
@@ -36,6 +36,7 @@ struct log_info g_log_info;
 
 static STAILQ_HEAD(, log) g_log_list = STAILQ_HEAD_INITIALIZER(g_log_list);
 static uint8_t log_inited;
+static uint8_t log_written;
 
 #if MYNEWT_VAL(LOG_CLI)
 int shell_log_dump_all_cmd(int, char **);
@@ -59,10 +60,10 @@ log_init(void)
         return;
     }
     log_inited = 1;
+    log_written = 0;
 
     g_log_info.li_version = LOG_VERSION_V2;
-    g_log_info.li_index = 0;
-    g_log_info.li_timestamp = 0;
+    g_log_info.li_next_index = 0;
 
 #if MYNEWT_VAL(LOG_CLI)
     shell_cmd_register(&g_shell_log_cmd);
@@ -105,6 +106,47 @@ log_registered(struct log *log)
     return 0;
 }
 
+static int
+log_read_hdr_walk(struct log *log, void *arg, void *dptr, uint16_t len)
+{
+    struct encode_off *encode_off;
+    struct log_entry_hdr *hdr;
+    int rc;
+
+    encode_off = arg;
+    hdr = encode_off->eo_arg;
+
+    rc = log_read(log, dptr, hdr, 0, sizeof *hdr);
+    if (rc < sizeof *hdr) {
+        return -1;
+    }
+    return 0;
+}
+
+/**
+ * Reads the final log entry's header from the specified log.
+ *
+ * @param log                   The log to read from.
+ * @param out_hdr               On success, the last entry header gets written
+ *                                  here.
+ *
+ * @return                      0 on success; nonzero on failure.
+ */
+static int
+log_read_last_hdr(struct log *log, struct log_entry_hdr *out_hdr)
+{
+    struct encode_off encode_off;
+    int rc;
+
+    encode_off.eo_arg = out_hdr;
+    encode_off.eo_ts = -1;
+    encode_off.eo_index = 0;
+    encode_off.rsp_len = 0;
+
+    rc = log_walk(log, log_read_hdr_walk, &encode_off);
+    return rc;
+}
+
 /*
  * Associate an instantiation of a log with the logging infrastructure
  */
@@ -112,16 +154,36 @@ int
 log_register(char *name, struct log *log, const struct log_handler *lh,
              void *arg, uint8_t level)
 {
+    struct log_entry_hdr hdr;
+    int sr;
+    int rc;
+
+    assert(!log_written);
+
     log->l_name = name;
     log->l_log = (struct log_handler *)lh;
     log->l_arg = arg;
     log->l_level = level;
 
-    /*assert(!log_registered(log));*/
     if (!log_registered(log)) {
         STAILQ_INSERT_TAIL(&g_log_list, log, l_next);
     }
 
+    /* If this is a persisted log, read the index from its most recent entry.
+     * We need to ensure the index of all subseqently written entries is
+     * monotonically increasing.
+     */
+    if (log->l_log->log_type == LOG_TYPE_STORAGE) {
+        rc = log_read_last_hdr(log, &hdr);
+        if (rc == 0) {
+            OS_ENTER_CRITICAL(sr);
+            if (hdr.ue_index >= g_log_info.li_next_index) {
+                g_log_info.li_next_index = hdr.ue_index + 1;
+            }
+            OS_EXIT_CRITICAL(sr);
+        }
+    }
+
     return (0);
 }
 
@@ -131,7 +193,12 @@ log_append(struct log *log, uint16_t module, uint16_t 
level, void *data,
 {
     struct log_entry_hdr *ue;
     int rc;
+    int sr;
     struct os_timeval tv;
+    uint32_t idx;
+
+    /* Remember that a log entry has been written since boot. */
+    log_written = 1;
 
     if (log->l_name == NULL || log->l_log == NULL) {
         rc = -1;
@@ -149,8 +216,9 @@ log_append(struct log *log, uint16_t module, uint16_t 
level, void *data,
 
     ue = (struct log_entry_hdr *) data;
 
-    /* Could check for li_index wraparound here */
-    g_log_info.li_index++;
+    OS_ENTER_CRITICAL(sr);
+    idx = g_log_info.li_next_index++;
+    OS_EXIT_CRITICAL(sr);
 
     /* Try to get UTC Time */
     rc = os_gettimeofday(&tv, NULL);
@@ -160,10 +228,9 @@ log_append(struct log *log, uint16_t module, uint16_t 
level, void *data,
         ue->ue_ts = tv.tv_sec * 1000000 + tv.tv_usec;
     }
 
-    g_log_info.li_timestamp = ue->ue_ts;
     ue->ue_level = level;
     ue->ue_module = module;
-    ue->ue_index = g_log_info.li_index;
+    ue->ue_index = idx;
 
     rc = log->l_log->log_append(log, data, len + LOG_ENTRY_HDR_SIZE);
     if (rc != 0) {
@@ -207,6 +274,11 @@ err:
     return (rc);
 }
 
+/**
+ * Reads from the specified log.
+ *
+ * @return                      The number of bytes read; 0 on failure.
+ */
 int
 log_read(struct log *log, void *dptr, void *buf, uint16_t off,
         uint16_t len)
@@ -228,8 +300,6 @@ log_flush(struct log *log)
         goto err;
     }
 
-    g_log_info.li_index = 0;
-
     return (0);
 err:
     return (rc);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e9390801/sys/log/full/src/log_fcb.c
----------------------------------------------------------------------
diff --git a/sys/log/full/src/log_fcb.c b/sys/log/full/src/log_fcb.c
index 1db2d92..3353e41 100644
--- a/sys/log/full/src/log_fcb.c
+++ b/sys/log/full/src/log_fcb.c
@@ -113,7 +113,7 @@ log_fcb_walk(struct log *log, log_walk_func_t walk_func, 
void *arg)
     memset(&loc, 0, sizeof(loc));
 
     /*
-     * if timestamp for request is < 1, return last log entry
+     * if timestamp for request is < 0, return last log entry
      */
     if (encode_off->eo_ts < 0) {
         locp = &fcb->f_active;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e9390801/sys/log/full/src/log_nmgr.c
----------------------------------------------------------------------
diff --git a/sys/log/full/src/log_nmgr.c b/sys/log/full/src/log_nmgr.c
index cc55fae..bb45722 100644
--- a/sys/log/full/src/log_nmgr.c
+++ b/sys/log/full/src/log_nmgr.c
@@ -68,7 +68,7 @@ log_nmgr_encode_entry(struct log *log, void *arg, void *dptr, 
uint16_t len)
     int rc;
     int rsp_len;
     CborError g_err = CborNoError;
-    CborEncoder *penc = (CborEncoder*)encode_off->eo_encoder;
+    CborEncoder *penc = (CborEncoder*)encode_off->eo_arg;
     CborEncoder rsp;
     struct CborCntWriter cnt_writer;
     CborEncoder cnt_encoder;
@@ -80,10 +80,23 @@ log_nmgr_encode_entry(struct log *log, void *arg, void 
*dptr, uint16_t len)
     }
     rc = OS_OK;
 
-    /* Matching timestamps and indices for sending a log entry */
-    if (ueh.ue_ts < encode_off->eo_ts   ||
-        (ueh.ue_ts == encode_off->eo_ts &&
-         ueh.ue_index <= encode_off->eo_index)) {
+    /* If specified timestamp is nonzero, it is the primary criterion, and the
+     * specified index is the secondary criterion.  If specified timetsamp is
+     * zero, specified index is the only criterion.
+     *
+     * If specified timestamp == 0: encode entries whose index >=
+     *     specified index.
+     * Else: encode entries whose timestamp >= specified timestamp and whose
+     *      index >= specified index
+     */
+
+    if (encode_off->eo_ts == 0) {
+        if (encode_off->eo_index > ueh.ue_index) {
+            goto err;
+        }
+    } else if (ueh.ue_ts < encode_off->eo_ts   ||
+               (ueh.ue_ts == encode_off->eo_ts &&
+                ueh.ue_index < encode_off->eo_index)) {
         goto err;
     }
 
@@ -180,7 +193,7 @@ log_encode_entries(struct log *log, CborEncoder *cb,
     g_err |= cbor_encode_text_stringz(cb, "entries");
     g_err |= cbor_encoder_create_array(cb, &entries, CborIndefiniteLength);
 
-    encode_off.eo_encoder  = (void*)&entries;
+    encode_off.eo_arg  = (void*)&entries;
     encode_off.eo_index    = index;
     encode_off.eo_ts       = ts;
     encode_off.rsp_len = rsp_len;

Reply via email to