Merge "Fix selinux warning on tracefs systems"
diff --git a/libcutils/tests/sockets_test.cpp b/libcutils/tests/sockets_test.cpp
index 82961a4..adfbf4a 100644
--- a/libcutils/tests/sockets_test.cpp
+++ b/libcutils/tests/sockets_test.cpp
@@ -190,8 +190,16 @@
     EXPECT_EQ(-1, socket_send_buffers(INVALID_SOCKET, nullptr, 0));
 }
 
+#ifndef SOCK_NONBLOCK
+#define SOCK_NONBLOCK 0
+#endif
+
+#ifndef SOCK_CLOEXEC
+#define SOCK_CLOEXEC 0
+#endif
+
 TEST(SocketsTest, android_get_control_socket) {
-    static const char key[] = ANDROID_SOCKET_ENV_PREFIX "SocketsTest.android_get_control_socket";
+    static const char key[] = ANDROID_SOCKET_ENV_PREFIX "SocketsTest_android_get_control_socket";
     static const char* name = key + strlen(ANDROID_SOCKET_ENV_PREFIX);
 
     EXPECT_EQ(unsetenv(key), 0);
@@ -199,6 +207,11 @@
 
     int fd;
     ASSERT_GE(fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0), 0);
+#ifdef F_GETFL
+    int flags;
+    ASSERT_GE(flags = fcntl(fd, F_GETFL), 0);
+    ASSERT_GE(fcntl(fd, F_SETFL, flags | O_NONBLOCK), 0);
+#endif
     EXPECT_EQ(android_get_control_socket(name), -1);
 
     struct sockaddr_un addr;
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index d68bfee..d4b48ef 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -547,6 +547,7 @@
         }
         spaces += spaces_total;
     }
+    totalSize += sizeOf();
     if (spaces < 0) spaces = 0;
     output += android::base::StringPrintf("%*s%zu", spaces, "", totalSize);
 
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
index bfaafa4..1f598af 100644
--- a/logd/LogStatistics.h
+++ b/logd/LogStatistics.h
@@ -42,8 +42,32 @@
 
     std::unordered_map<TKey, TEntry> map;
 
+    size_t bucket_size() const {
+        size_t count = 0;
+        for (size_t idx = 0; idx < map.bucket_count(); ++idx) {
+            size_t bucket_size = map.bucket_size(idx);
+            if (bucket_size == 0) bucket_size = 1;
+            count += bucket_size;
+        }
+        float load_factor = map.max_load_factor();
+        if (load_factor < 1.0) return count;
+        return count * load_factor;
+    }
+
+    static const size_t unordered_map_per_entry_overhead = sizeof(void*);
+    static const size_t unordered_map_bucket_overhead = sizeof(void*);
+
 public:
 
+    size_t size() const { return map.size(); }
+
+    // Estimate unordered_map memory usage.
+    size_t sizeOf() const {
+        return sizeof(*this) +
+               (size() * (sizeof(TEntry) + unordered_map_per_entry_overhead)) +
+               (bucket_size() * sizeof(size_t) + unordered_map_bucket_overhead);
+    }
+
     typedef typename std::unordered_map<TKey, TEntry>::iterator iterator;
     typedef typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator;
 
@@ -155,6 +179,7 @@
         }
         return output;
     }
+
 };
 
 namespace EntryBaseConstants {
@@ -472,7 +497,30 @@
     // security tag list
     tagTable_t securityTagTable;
 
+    size_t sizeOf() const {
+        size_t size = sizeof(*this) + pidTable.sizeOf() + tidTable.sizeOf() +
+                      tagTable.sizeOf() + securityTagTable.sizeOf() +
+                      (pidTable.size() * sizeof(pidTable_t::iterator)) +
+                      (tagTable.size() * sizeof(tagTable_t::iterator));
+        for(auto it : pidTable) {
+            const char* name = it.second.getName();
+            if (name) size += strlen(name) + 1;
+        }
+        for(auto it : tidTable) {
+            const char* name = it.second.getName();
+            if (name) size += strlen(name) + 1;
+        }
+        log_id_for_each(id) {
+            size += uidTable[id].sizeOf();
+            size += uidTable[id].size() * sizeof(uidTable_t::iterator);
+            size += pidSystemTable[id].sizeOf();
+            size += pidSystemTable[id].size() * sizeof(pidSystemTable_t::iterator);
+        }
+        return size;
+    }
+
 public:
+
     LogStatistics();
 
     void enableStatistics() { enable = true; }