Merge "fsmgr: support multiple fs-types/mountpoint"
diff --git a/adb/adb.c b/adb/adb.c
index 6d3a71b..90bdbaa 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -1344,29 +1344,29 @@
           " unchanged.\n");
     }
 
+    /* add extra groups:
+    ** AID_ADB to access the USB driver
+    ** AID_LOG to read system logs (adb logcat)
+    ** AID_INPUT to diagnose input issues (getevent)
+    ** AID_INET to diagnose network issues (netcfg, ping)
+    ** AID_GRAPHICS to access the frame buffer
+    ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
+    ** AID_SDCARD_R to allow reading from the SD card
+    ** AID_SDCARD_RW to allow writing to the SD card
+    ** AID_NET_BW_STATS to read out qtaguid statistics
+    */
+    gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
+                       AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
+                       AID_NET_BW_STATS };
+    if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
+        exit(1);
+    }
+
     /* don't listen on a port (default 5037) if running in secure mode */
     /* don't run as root if we are running in secure mode */
     if (should_drop_privileges()) {
         drop_capabilities_bounding_set_if_needed();
 
-        /* add extra groups:
-        ** AID_ADB to access the USB driver
-        ** AID_LOG to read system logs (adb logcat)
-        ** AID_INPUT to diagnose input issues (getevent)
-        ** AID_INET to diagnose network issues (netcfg, ping)
-        ** AID_GRAPHICS to access the frame buffer
-        ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
-        ** AID_SDCARD_R to allow reading from the SD card
-        ** AID_SDCARD_RW to allow writing to the SD card
-        ** AID_NET_BW_STATS to read out qtaguid statistics
-        */
-        gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
-                           AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
-                           AID_NET_BW_STATS };
-        if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
-            exit(1);
-        }
-
         /* then switch user and group to "shell" */
         if (setgid(AID_SHELL) != 0) {
             exit(1);
diff --git a/logcat/tests/Android.mk b/logcat/tests/Android.mk
index 5d4d29e..015a23d 100644
--- a/logcat/tests/Android.mk
+++ b/logcat/tests/Android.mk
@@ -16,11 +16,7 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# -----------------------------------------------------------------------------
-# Unit tests.
-# -----------------------------------------------------------------------------
-
-test_module := logcat-unit-tests
+test_module_prefix := logcat-
 test_tags := tests
 
 test_c_flags := \
@@ -28,7 +24,29 @@
     -g \
     -Wall -Wextra \
     -Werror \
-    -fno-builtin
+    -fno-builtin \
+    -std=gnu++11
+
+# -----------------------------------------------------------------------------
+# Benchmarks (actually a gTest where the result code does not matter)
+# ----------------------------------------------------------------------------
+
+benchmark_src_files := \
+    logcat_benchmark.cpp
+
+# Build benchmarks for the device. Run with:
+#   adb shell /data/nativetest/logcat-benchmarks/logcat-benchmarks
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(test_module_prefix)benchmarks
+LOCAL_MODULE_TAGS := $(test_tags)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_CFLAGS += $(test_c_flags)
+LOCAL_SRC_FILES := $(benchmark_src_files)
+include $(BUILD_NATIVE_TEST)
+
+# -----------------------------------------------------------------------------
+# Unit tests.
+# -----------------------------------------------------------------------------
 
 test_src_files := \
     logcat_test.cpp \
@@ -36,7 +54,7 @@
 # Build tests for the device (with .so). Run with:
 #   adb shell /data/nativetest/logcat-unit-tests/logcat-unit-tests
 include $(CLEAR_VARS)
-LOCAL_MODULE := $(test_module)
+LOCAL_MODULE := $(test_module_prefix)unit-tests
 LOCAL_MODULE_TAGS := $(test_tags)
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_CFLAGS += $(test_c_flags)
diff --git a/logcat/tests/logcat_benchmark.cpp b/logcat/tests/logcat_benchmark.cpp
new file mode 100644
index 0000000..be815be
--- /dev/null
+++ b/logcat/tests/logcat_benchmark.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2013-2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtest/gtest.h>
+
+static const char begin[] = "--------- beginning of ";
+
+TEST(logcat, sorted_order) {
+    FILE *fp;
+
+    ASSERT_TRUE(NULL != (fp = popen(
+      "logcat -v time -b radio -b events -b system -b main -d 2>/dev/null",
+      "r")));
+
+    class timestamp {
+    private:
+        int month;
+        int day;
+        int hour;
+        int minute;
+        int second;
+        int millisecond;
+        bool ok;
+
+    public:
+        void init(const char *buffer)
+        {
+            ok = false;
+            if (buffer != NULL) {
+                ok = sscanf(buffer, "%d-%d %d:%d:%d.%d ",
+                    &month, &day, &hour, &minute, &second, &millisecond) == 6;
+            }
+        }
+
+        timestamp(const char *buffer)
+        {
+            init(buffer);
+        }
+
+        bool operator< (timestamp &T)
+        {
+            return !ok || !T.ok
+             || (month < T.month)
+             || ((month == T.month)
+              && ((day < T.day)
+               || ((day == T.day)
+                && ((hour < T.hour)
+                 || ((hour == T.hour)
+                  && ((minute < T.minute)
+                   || ((minute == T.minute)
+                    && ((second < T.second)
+                     || ((second == T.second)
+                      && (millisecond < T.millisecond))))))))));
+        }
+
+        bool valid(void)
+        {
+            return ok;
+        }
+    } last(NULL);
+
+    char *last_buffer = NULL;
+    char buffer[5120];
+
+    int count = 0;
+    int next_lt_last = 0;
+
+    while (fgets(buffer, sizeof(buffer), fp)) {
+        if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
+            continue;
+        }
+        if (!last.valid()) {
+            free(last_buffer);
+            last_buffer = strdup(buffer);
+            last.init(buffer);
+        }
+        timestamp next(buffer);
+        if (next < last) {
+            if (last_buffer) {
+                fprintf(stderr, "<%s", last_buffer);
+            }
+            fprintf(stderr, ">%s", buffer);
+            ++next_lt_last;
+        }
+        if (next.valid()) {
+            free(last_buffer);
+            last_buffer = strdup(buffer);
+            last.init(buffer);
+        }
+        ++count;
+    }
+    free(last_buffer);
+
+    pclose(fp);
+
+    static const int max_ok = 2;
+
+    // Allow few fails, happens with readers active
+    fprintf(stderr, "%s: %d/%d out of order entries\n",
+            (next_lt_last)
+                ? ((next_lt_last <= max_ok)
+                    ? "WARNING"
+                    : "ERROR")
+                : "INFO",
+            next_lt_last, count);
+
+    EXPECT_GE(max_ok, next_lt_last);
+
+    // sample statistically too small
+    EXPECT_LT(100, count);
+}
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index 2e8ae8b..9b316d1 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -17,6 +17,7 @@
 #include <ctype.h>
 #include <signal.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include <gtest/gtest.h>
@@ -41,99 +42,6 @@
 
 static const char begin[] = "--------- beginning of ";
 
-TEST(logcat, sorted_order) {
-    FILE *fp;
-
-    ASSERT_TRUE(NULL != (fp = popen(
-      "logcat -v time -b radio -b events -b system -b main -d 2>/dev/null",
-      "r")));
-
-    class timestamp {
-    private:
-        int month;
-        int day;
-        int hour;
-        int minute;
-        int second;
-        int millisecond;
-        bool ok;
-
-    public:
-        void init(const char *buffer)
-        {
-            ok = false;
-            if (buffer != NULL) {
-                ok = sscanf(buffer, "%d-%d %d:%d:%d.%d ",
-                    &month, &day, &hour, &minute, &second, &millisecond) == 6;
-            }
-        }
-
-        timestamp(const char *buffer)
-        {
-            init(buffer);
-        }
-
-        bool operator< (timestamp &T)
-        {
-            return !ok || !T.ok
-             || (month < T.month)
-             || ((month == T.month)
-              && ((day < T.day)
-               || ((day == T.day)
-                && ((hour < T.hour)
-                 || ((hour == T.hour)
-                  && ((minute < T.minute)
-                   || ((minute == T.minute)
-                    && ((second < T.second)
-                     || ((second == T.second)
-                      && (millisecond < T.millisecond))))))))));
-        }
-
-        bool valid(void)
-        {
-            return ok;
-        }
-    } last(NULL);
-
-    char *last_buffer = NULL;
-    char buffer[5120];
-
-    int count = 0;
-    int next_lt_last = 0;
-
-    while (fgets(buffer, sizeof(buffer), fp)) {
-        if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
-            continue;
-        }
-        if (!last.valid()) {
-            free(last_buffer);
-            last_buffer = strdup(buffer);
-            last.init(buffer);
-        }
-        timestamp next(buffer);
-        if (next < last) {
-            if (last_buffer) {
-                fprintf(stderr, "<%s", last_buffer);
-            }
-            fprintf(stderr, ">%s", buffer);
-            ++next_lt_last;
-        }
-        if (next.valid()) {
-            free(last_buffer);
-            last_buffer = strdup(buffer);
-            last.init(buffer);
-        }
-        ++count;
-    }
-    free(last_buffer);
-
-    pclose(fp);
-
-    EXPECT_EQ(0, next_lt_last);
-
-    EXPECT_LT(100, count);
-}
-
 TEST(logcat, buckets) {
     FILE *fp;
 
@@ -362,9 +270,10 @@
     ASSERT_EQ(1, count);
 }
 
-TEST(logcat, get_) {
+TEST(logcat, get_size) {
     FILE *fp;
 
+    // NB: crash log only available in user space
     ASSERT_TRUE(NULL != (fp = popen(
       "logcat -b radio -b events -b system -b main -g 2>/dev/null",
       "r")));
@@ -375,13 +284,49 @@
 
     while (fgets(buffer, sizeof(buffer), fp)) {
         int size, consumed, max, payload;
+        char size_mult, consumed_mult;
+        long full_size, full_consumed;
 
         size = consumed = max = payload = 0;
-        if ((4 == sscanf(buffer, "%*s ring buffer is %dKb (%dKb consumed),"
-                                 " max entry is %db, max payload is %db",
-                                 &size, &consumed, &max, &payload))
-         && ((size * 3) >= consumed)
-         && ((size * 1024) > max)
+        // NB: crash log can be very small, not hit a Kb of consumed space
+        //     doubly lucky we are not including it.
+        if (6 != sscanf(buffer, "%*s ring buffer is %d%cb (%d%cb consumed),"
+                                " max entry is %db, max payload is %db",
+                                &size, &size_mult, &consumed, &consumed_mult,
+                                &max, &payload)) {
+            fprintf(stderr, "WARNING: Parse error: %s", buffer);
+            continue;
+        }
+        full_size = size;
+        switch(size_mult) {
+        case 'G':
+            full_size *= 1024;
+            /* FALLTHRU */
+        case 'M':
+            full_size *= 1024;
+            /* FALLTHRU */
+        case 'K':
+            full_size *= 1024;
+            break;
+        }
+        full_consumed = consumed;
+        switch(consumed_mult) {
+        case 'G':
+            full_consumed *= 1024;
+            /* FALLTHRU */
+        case 'M':
+            full_consumed *= 1024;
+            /* FALLTHRU */
+        case 'K':
+            full_consumed *= 1024;
+            break;
+        }
+        EXPECT_GT((full_size * 9) / 4, full_consumed);
+        EXPECT_GT(full_size, max);
+        EXPECT_GT(max, payload);
+
+        if ((((full_size * 9) / 4) >= full_consumed)
+         && (full_size > max)
          && (max > payload)) {
             ++count;
         }
@@ -649,7 +594,7 @@
 
     char buffer[5120];
 
-    snprintf(buffer, sizeof(buffer), "logcat -P '%s' 2>&1", list);
+    snprintf(buffer, sizeof(buffer), "logcat -P '%s' 2>&1", list ? list : "");
     fp = popen(buffer, "r");
     if (fp == NULL) {
         fprintf(stderr, "ERROR: %s\n", buffer);
@@ -662,10 +607,10 @@
             ++buf;
         }
         char *end = buf + strlen(buf);
-        while (isspace(*--end) && (end >= buf)) {
+        while ((end > buf) && isspace(*--end)) {
             *end = '\0';
         }
-        if (end < buf) {
+        if (end <= buf) {
             continue;
         }
         fprintf(stderr, "%s\n", buf);
@@ -679,7 +624,7 @@
     char *list = NULL;
     char *adjust = NULL;
 
-    ASSERT_EQ(true, get_white_black(&list));
+    get_white_black(&list);
 
     static const char adjustment[] = "~! 300/20 300/25 2000 ~1000/5 ~1000/30";
     ASSERT_EQ(true, set_white_black(adjustment));
@@ -696,8 +641,8 @@
     adjust = NULL;
 
     ASSERT_EQ(true, set_white_black(list));
-    ASSERT_EQ(true, get_white_black(&adjust));
-    EXPECT_STREQ(list, adjust);
+    get_white_black(&adjust);
+    EXPECT_STREQ(list ? list : "", adjust ? adjust : "");
     free(adjust);
     adjust = NULL;
 
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp
index 9d7d152..d7088b4 100644
--- a/logd/CommandListener.cpp
+++ b/logd/CommandListener.cpp
@@ -74,9 +74,9 @@
 int CommandListener::ClearCmd::runCommand(SocketClient *cli,
                                          int argc, char **argv) {
     setname();
-    if (!clientHasLogCredentials(cli)) {
-        cli->sendMsg("Permission Denied");
-        return 0;
+    uid_t uid = cli->getUid();
+    if (clientHasLogCredentials(cli)) {
+        uid = AID_ROOT;
     }
 
     if (argc < 2) {
@@ -90,7 +90,7 @@
         return 0;
     }
 
-    mBuf.clear((log_id_t) id);
+    mBuf.clear((log_id_t) id, uid);
     cli->sendMsg("success");
     return 0;
 }
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 0448afa..cd9ea20 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -232,7 +232,7 @@
 // prune "pruneRows" of type "id" from the buffer.
 //
 // mLogElementsLock must be held when this function is called.
-void LogBuffer::prune(log_id_t id, unsigned long pruneRows) {
+void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
     LogTimeEntry *oldest = NULL;
 
     LogTimeEntry::lock();
@@ -250,6 +250,38 @@
 
     LogBufferElementCollection::iterator it;
 
+    if (caller_uid != AID_ROOT) {
+        for(it = mLogElements.begin(); it != mLogElements.end();) {
+            LogBufferElement *e = *it;
+
+            if (oldest && (oldest->mStart <= e->getMonotonicTime())) {
+                break;
+            }
+
+            if (e->getLogId() != id) {
+                ++it;
+                continue;
+            }
+
+            uid_t uid = e->getUid();
+
+            if (uid == caller_uid) {
+                it = mLogElements.erase(it);
+                unsigned short len = e->getMsgLen();
+                stats.subtract(len, id, uid, e->getPid());
+                delete e;
+                pruneRows--;
+                if (pruneRows == 0) {
+                    break;
+                }
+            } else {
+                ++it;
+            }
+        }
+        LogTimeEntry::unlock();
+        return;
+    }
+
     // prune by worst offender by uid
     while (pruneRows > 0) {
         // recalculate the worst offender on every batched pass
@@ -375,9 +407,9 @@
 }
 
 // clear all rows of type "id" from the buffer.
-void LogBuffer::clear(log_id_t id) {
+void LogBuffer::clear(log_id_t id, uid_t uid) {
     pthread_mutex_lock(&mLogElementsLock);
-    prune(id, ULONG_MAX);
+    prune(id, ULONG_MAX, uid);
     pthread_mutex_unlock(&mLogElementsLock);
 }
 
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index b8a54b9..4b982a8 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -23,6 +23,8 @@
 #include <sysutils/SocketClient.h>
 #include <utils/List.h>
 
+#include <private/android_filesystem_config.h>
+
 #include "LogBufferElement.h"
 #include "LogTimes.h"
 #include "LogStatistics.h"
@@ -55,7 +57,7 @@
                      bool (*filter)(const LogBufferElement *element, void *arg) = NULL,
                      void *arg = NULL);
 
-    void clear(log_id_t id);
+    void clear(log_id_t id, uid_t uid = AID_ROOT);
     unsigned long getSize(log_id_t id);
     int setSize(log_id_t id, unsigned long size);
     unsigned long getSizeUsed(log_id_t id);
@@ -77,7 +79,7 @@
 
 private:
     void maybePrune(log_id_t id);
-    void prune(log_id_t id, unsigned long pruneRows);
+    void prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT);
 
 };
 
diff --git a/logd/tests/Android.mk b/logd/tests/Android.mk
index 123e317..f851288 100644
--- a/logd/tests/Android.mk
+++ b/logd/tests/Android.mk
@@ -34,7 +34,7 @@
     -Werror \
     -fno-builtin \
 
-ifeq ($(TARGET_USES_LOGD),true)
+ifneq ($(TARGET_USES_LOGD),false)
 test_c_flags += -DTARGET_USES_LOGD=1
 endif
 
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index 5b51b1f..957fdb5 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -568,10 +568,11 @@
 
     while (fgets(buffer, sizeof(buffer), fp)) {
         for (unsigned i = 0; i < sizeof(ns) / sizeof(ns[0]); ++i) {
-            if (strncmp(benchmarks[i], buffer, strlen(benchmarks[i]))) {
+            char *cp = strstr(buffer, benchmarks[i]);
+            if (!cp) {
                 continue;
             }
-            sscanf(buffer, "%*s %lu %lu", &ns[i], &ns[i]);
+            sscanf(cp, "%*s %lu %lu", &ns[i], &ns[i]);
             fprintf(stderr, "%-22s%8lu\n", benchmarks[i], ns[i]);
         }
     }
@@ -592,15 +593,15 @@
 #endif
 
 #ifdef TARGET_USES_LOGD
-    EXPECT_GE(25000UL, ns[log_maximum]); // 14055 user
+    EXPECT_GE(30000UL, ns[log_maximum]); // 27305 user
 #else
     EXPECT_GE(10000UL, ns[log_maximum]); // 5637 kernel
 #endif
 
-    EXPECT_GE(4000UL, ns[clock_overhead]); // 2008
+    EXPECT_GE(4096UL, ns[clock_overhead]); // 4095
 
 #ifdef TARGET_USES_LOGD
-    EXPECT_GE(250000UL, ns[log_overhead]); // 113219 user
+    EXPECT_GE(250000UL, ns[log_overhead]); // 121876 user
 #else
     EXPECT_GE(100000UL, ns[log_overhead]); // 50945 kernel
 #endif
@@ -612,7 +613,7 @@
 #endif
 
 #ifdef TARGET_USES_LOGD
-    EXPECT_GE(20000000UL, ns[log_delay]); // 9542541 user
+    EXPECT_GE(20000000UL, ns[log_delay]); // 10500289 user
 #else
     EXPECT_GE(55000UL, ns[log_delay]); // 27341 kernel
 #endif
@@ -642,36 +643,61 @@
     // 0/4225?     7454388/303656      31488/755
     //                                 ^-- benchmark_statistics_found
 
-    unsigned long nowSize = atol(benchmark_statistics_found);
+    unsigned long nowSpamSize = atol(benchmark_statistics_found);
 
     delete [] buf;
 
-    ASSERT_NE(0UL, nowSize);
+    ASSERT_NE(0UL, nowSpamSize);
 
+    // Determine if we have the spam filter enabled
     int sock = socket_local_client("logd",
                                    ANDROID_SOCKET_NAMESPACE_RESERVED,
                                    SOCK_STREAM);
+
+    ASSERT_TRUE(sock >= 0);
+
+    static const char getPruneList[] = "getPruneList";
+    if (write(sock, getPruneList, sizeof(getPruneList)) > 0) {
+        char buffer[80];
+        memset(buffer, 0, sizeof(buffer));
+        read(sock, buffer, sizeof(buffer));
+        char *cp = strchr(buffer, '\n');
+        if (!cp || (cp[1] != '~') || (cp[2] != '!')) {
+            close(sock);
+            fprintf(stderr,
+                    "WARNING: "
+                    "Logger has SPAM filtration turned off \"%s\"\n", buffer);
+            return;
+        }
+    } else {
+        int save_errno = errno;
+        close(sock);
+        FAIL() << "Can not send " << getPruneList << " to logger -- " << strerror(save_errno);
+    }
+
     static const unsigned long expected_absolute_minimum_log_size = 65536UL;
     unsigned long totalSize = expected_absolute_minimum_log_size;
-    if (sock >= 0) {
-        static const char getSize[] = {
-            'g', 'e', 't', 'L', 'o', 'g', 'S', 'i', 'z', 'e', ' ',
-            LOG_ID_MAIN + '0', '\0'
-        };
-        if (write(sock, getSize, sizeof(getSize)) > 0) {
-            char buffer[80];
-            memset(buffer, 0, sizeof(buffer));
-            read(sock, buffer, sizeof(buffer));
-            totalSize = atol(buffer);
-            if (totalSize < expected_absolute_minimum_log_size) {
-                totalSize = expected_absolute_minimum_log_size;
-            }
+    static const char getSize[] = {
+        'g', 'e', 't', 'L', 'o', 'g', 'S', 'i', 'z', 'e', ' ',
+        LOG_ID_MAIN + '0', '\0'
+    };
+    if (write(sock, getSize, sizeof(getSize)) > 0) {
+        char buffer[80];
+        memset(buffer, 0, sizeof(buffer));
+        read(sock, buffer, sizeof(buffer));
+        totalSize = atol(buffer);
+        if (totalSize < expected_absolute_minimum_log_size) {
+            fprintf(stderr,
+                    "WARNING: "
+                    "Logger had unexpected referenced size \"%s\"\n", buffer);
+            totalSize = expected_absolute_minimum_log_size;
         }
-        close(sock);
     }
+    close(sock);
+
     // logd allows excursions to 110% of total size
     totalSize = (totalSize * 11 ) / 10;
 
     // 50% threshold for SPAM filter (<20% typical, lots of engineering margin)
-    ASSERT_GT(totalSize, nowSize * 2);
+    ASSERT_GT(totalSize, nowSpamSize * 2);
 }