Merge "libnetutils: Add synchronization per socket full operation"
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index b3e65cb..1b3893f 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -586,6 +586,7 @@
 
         /* mount(2) returned an error, handle the encryptable/formattable case */
         bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
+        bool crypt_footer = false;
         if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
             fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) {
             /* top_idx and attempted_idx point at the same partition, but sometimes
@@ -606,8 +607,11 @@
                     ERROR("%s(): %s wouldn't open (%s)\n", __func__,
                           fstab->recs[top_idx].key_loc, strerror(errno));
                 }
+            } else if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
+                !strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
+                crypt_footer = true;
             }
-            if (fs_mgr_do_format(&fstab->recs[top_idx]) == 0) {
+            if (fs_mgr_do_format(&fstab->recs[top_idx], crypt_footer) == 0) {
                 /* Let's replay the mount actions. */
                 i = top_idx - 1;
                 continue;
diff --git a/fs_mgr/fs_mgr_format.c b/fs_mgr/fs_mgr_format.c
index 6c5b1eb..5011b08 100644
--- a/fs_mgr/fs_mgr_format.c
+++ b/fs_mgr/fs_mgr_format.c
@@ -32,11 +32,12 @@
 #include "ext4.h"
 #include "make_ext4fs.h"
 #include "fs_mgr_priv.h"
+#include "cryptfs.h"
 
 extern struct fs_info info;     /* magic global from ext4_utils */
 extern void reset_ext4fs_info();
 
-static int format_ext4(char *fs_blkdev, char *fs_mnt_point)
+static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
 {
     uint64_t dev_sz;
     int fd, rc = 0;
@@ -63,6 +64,9 @@
     /* Format the partition using the calculated length */
     reset_ext4fs_info();
     info.len = (off64_t)dev_sz;
+    if (crypt_footer) {
+        info.len -= CRYPT_FOOTER_OFFSET;
+    }
 
     /* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */
     rc = make_ext4fs_internal(fd, NULL, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, sehandle, 0, 0, NULL);
@@ -118,7 +122,7 @@
     return rc;
 }
 
-int fs_mgr_do_format(struct fstab_rec *fstab)
+int fs_mgr_do_format(struct fstab_rec *fstab, bool crypt_footer)
 {
     int rc = -EINVAL;
 
@@ -127,7 +131,7 @@
     if (!strncmp(fstab->fs_type, "f2fs", 4)) {
         rc = format_f2fs(fstab->blk_device);
     } else if (!strncmp(fstab->fs_type, "ext4", 4)) {
-        rc = format_ext4(fstab->blk_device, fstab->mount_point);
+        rc = format_ext4(fstab->blk_device, fstab->mount_point, crypt_footer);
     } else {
         ERROR("File system type '%s' is not supported\n", fstab->fs_type);
     }
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index b498618..3c27ede 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -18,6 +18,7 @@
 #define __CORE_FS_MGR_H
 
 #include <stdint.h>
+#include <stdbool.h>
 #include <linux/dm-ioctl.h>
 
 // Magic number at start of verity metadata
@@ -108,7 +109,7 @@
 int fs_mgr_is_nofail(struct fstab_rec *fstab);
 int fs_mgr_swapon_all(struct fstab *fstab);
 
-int fs_mgr_do_format(struct fstab_rec *fstab);
+int fs_mgr_do_format(struct fstab_rec *fstab, bool reserve_footer);
 
 #ifdef __cplusplus
 }
diff --git a/init/Android.mk b/init/Android.mk
index e1a3638..7aa3c3f 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -52,7 +52,7 @@
     service.cpp \
     util.cpp \
 
-LOCAL_STATIC_LIBRARIES := libbase libselinux
+LOCAL_STATIC_LIBRARIES := libbase libselinux liblog libprocessgroup
 LOCAL_MODULE := libinit
 LOCAL_SANITIZE := integer
 LOCAL_CLANG := true
@@ -91,7 +91,6 @@
     libcutils \
     libbase \
     libext4_utils_static \
-    libutils \
     libc \
     libselinux \
     liblog \
@@ -100,7 +99,8 @@
     libc++_static \
     libdl \
     libsparse_static \
-    libz
+    libz \
+    libprocessgroup
 
 # Create symlinks
 LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \
diff --git a/init/service.cpp b/init/service.cpp
index f5b8b00..4175d05 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -30,6 +30,8 @@
 #include <cutils/android_reboot.h>
 #include <cutils/sockets.h>
 
+#include <processgroup/processgroup.h>
+
 #include "action.h"
 #include "init.h"
 #include "init_parser.h"
@@ -97,7 +99,7 @@
     if (!(flags_ & SVC_ONESHOT) || (flags_ & SVC_RESTART)) {
         NOTICE("Service '%s' (pid %d) killing any children in process group\n",
                name_.c_str(), pid_);
-        kill(-pid_, SIGKILL);
+        killProcessGroup(uid_, pid_, SIGKILL);
     }
 
     // Remove any sockets we may have created.
@@ -490,6 +492,7 @@
     time_started_ = gettime();
     pid_ = pid;
     flags_ |= SVC_RUNNING;
+    createProcessGroup(uid_, pid_);
 
     if ((flags_ & SVC_EXEC) != 0) {
         INFO("SVC_EXEC pid %d (uid %d gid %d+%zu context %s) started; waiting...\n",
@@ -532,7 +535,7 @@
     if (pid_) {
         NOTICE("Sending SIGTERM to service '%s' (pid %d)...\n", name_.c_str(),
                pid_);
-        kill(-pid_, SIGTERM);
+        killProcessGroup(uid_, pid_, SIGTERM);
         NotifyStateChange("stopping");
     }
 }
@@ -583,7 +586,7 @@
 
     if (pid_) {
         NOTICE("Service '%s' is being killed...\n", name_.c_str());
-        kill(-pid_, SIGKILL);
+        killProcessGroup(uid_, pid_, SIGKILL);
         NotifyStateChange("stopping");
     } else {
         NotifyStateChange("stopped");
diff --git a/init/util.cpp b/init/util.cpp
index 750e040..69f6566 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -489,6 +489,7 @@
      * - will accept $$ as a literal $.
      * - no nested property expansion, i.e. ${foo.${bar}} is not supported,
      *   bad things will happen
+     * - ${x.y:-default} will return default value if property empty.
      */
     while (*src_ptr) {
         const char* c;
@@ -511,6 +512,7 @@
         }
 
         std::string prop_name;
+        std::string def_val;
         if (*c == '{') {
             c++;
             const char* end = strchr(c, '}');
@@ -521,6 +523,11 @@
             }
             prop_name = std::string(c, end);
             c = end + 1;
+            size_t def = prop_name.find(":-");
+            if (def < prop_name.size()) {
+                def_val = prop_name.substr(def + 2);
+                prop_name = prop_name.substr(0, def);
+            }
         } else {
             prop_name = c;
             ERROR("using deprecated syntax for specifying property '%s', use ${name} instead\n",
@@ -535,9 +542,12 @@
 
         std::string prop_val = property_get(prop_name.c_str());
         if (prop_val.empty()) {
-            ERROR("property '%s' doesn't exist while expanding '%s'\n",
-                  prop_name.c_str(), src.c_str());
-            return false;
+            if (def_val.empty()) {
+                ERROR("property '%s' doesn't exist while expanding '%s'\n",
+                      prop_name.c_str(), src.c_str());
+                return false;
+            }
+            prop_val = def_val;
         }
 
         dst->append(prop_val);
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
index 01fb50f..1b66a56 100644
--- a/liblog/tests/liblog_benchmark.cpp
+++ b/liblog/tests/liblog_benchmark.cpp
@@ -205,7 +205,7 @@
         android_log_header_t header;
         android_log_event_int_t payload;
     };
-    char buf[sizeof(struct packet) + 8] __aligned(8);
+    alignas(8) char buf[sizeof(struct packet) + 8];
     memset(buf, 0, sizeof(buf));
     struct packet *buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7);
     if (((uintptr_t)&buffer->pmsg_header) & 7) {
@@ -281,7 +281,7 @@
         android_log_header_t header;
         android_log_event_int_t payload;
     };
-    char buf[sizeof(struct packet) + 8] __aligned(8);
+    alignas(8) char buf[sizeof(struct packet) + 8];
     memset(buf, 0, sizeof(buf));
     struct packet *buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1);
     if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) {
@@ -357,7 +357,7 @@
         android_log_header_t header;
         android_log_event_int_t payload;
     };
-    char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD] __aligned(8);
+    alignas(8) char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD];
     memset(buf, 0, sizeof(buf));
     struct packet *buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7);
     if (((uintptr_t)&buffer->pmsg_header) & 7) {
@@ -430,7 +430,7 @@
         android_log_header_t header;
         android_log_event_int_t payload;
     };
-    char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD] __aligned(8);
+    alignas(8) char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD];
     memset(buf, 0, sizeof(buf));
     struct packet *buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1);
     if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) {
diff --git a/libprocessgroup/Android.mk b/libprocessgroup/Android.mk
index ee6ba58..87985d4 100644
--- a/libprocessgroup/Android.mk
+++ b/libprocessgroup/Android.mk
@@ -3,7 +3,16 @@
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := processgroup.cpp
 LOCAL_MODULE := libprocessgroup
-LOCAL_SHARED_LIBRARIES := liblog libutils
+LOCAL_STATIC_LIBRARIES := liblog
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_CFLAGS := -Wall -Werror
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := processgroup.cpp
+LOCAL_MODULE := libprocessgroup
+LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_CFLAGS := -Wall -Werror
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index 00a0357..da4bb71 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -22,19 +22,18 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
-#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+
+#include <chrono>
 #include <memory>
 
 #include <log/log.h>
 #include <private/android_filesystem_config.h>
 
-#include <utils/SystemClock.h>
-
 #include <processgroup/processgroup.h>
 #include "processgroup_priv.h"
 
@@ -250,25 +249,26 @@
 
 int killProcessGroup(uid_t uid, int initialPid, int signal)
 {
-    int processes;
-    const int sleep_us = 5 * 1000;  // 5ms
-    int64_t startTime = android::uptimeMillis();
-    int retry = 40;
+    std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
 
+    int retry = 40;
+    int processes;
     while ((processes = killProcessGroupOnce(uid, initialPid, signal)) > 0) {
         SLOGV("killed %d processes for processgroup %d\n", processes, initialPid);
         if (retry > 0) {
-            usleep(sleep_us);
+            usleep(5 * 1000); // 5ms
             --retry;
         } else {
-            SLOGE("failed to kill %d processes for processgroup %d\n",
-                    processes, initialPid);
+            SLOGE("failed to kill %d processes for processgroup %d\n", processes, initialPid);
             break;
         }
     }
 
-    SLOGV("Killed process group uid %d pid %d in %" PRId64 "ms, %d procs remain", uid, initialPid,
-            android::uptimeMillis()-startTime, processes);
+    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
+
+    SLOGV("Killed process group uid %d pid %d in %dms, %d procs remain", uid, initialPid,
+          static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()),
+          processes);
 
     if (processes == 0) {
         return removeProcessGroup(uid, initialPid);
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
index 39dd227..61b7fd8 100644
--- a/logd/LogListener.cpp
+++ b/logd/LogListener.cpp
@@ -48,7 +48,7 @@
         + LOGGER_ENTRY_MAX_PAYLOAD];
     struct iovec iov = { buffer, sizeof(buffer) };
 
-    char control[CMSG_SPACE(sizeof(struct ucred))] __aligned(4);
+    alignas(4) char control[CMSG_SPACE(sizeof(struct ucred))];
     struct msghdr hdr = {
         NULL,
         0,