init: Add an selinux transition for snapuserd.

With compressed VAB updates, it is not possible to mount /system without
first running snapuserd, which is the userspace component to the dm-user
kernel module. This poses a problem because as soon as selinux
enforcement is enabled, snapuserd (running in a kernel context) does not
have access to read and decompress the underlying system partition.

To account for this, we split SelinuxInitialize into multiple steps:

First, sepolicy is read into an in-memory string.

Second, the device-mapper tables for all snapshots are rebuilt. This
flushes any pending reads and creates new dm-user devices. The original
kernel-privileged snapuserd is then killed.

Third, sepolicy is loaded from the in-memory string.

Fourth, we re-launch snapuserd and connect it to the newly created
dm-user devices. As part of this step we restorecon device-mapper
devices and /dev/block/by-name/super, since the new snapuserd is in a
limited context.

Finally, we set enforcing mode.

This sequence ensures that snapuserd has appropriate privileges with a
minimal number of permissive audits.

Bug: 173476209
Test: full OTA with VABC applies and boots
Change-Id: Ie4e0f5166b01c31a6f337afc26fc58b96217604e
diff --git a/init/init.cpp b/init/init.cpp
index d1998a5..d6753f5 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -79,6 +79,7 @@
 #include "service.h"
 #include "service_parser.h"
 #include "sigchld_handler.h"
+#include "snapuserd_transition.h"
 #include "subcontext.h"
 #include "system/core/init/property_service.pb.h"
 #include "util.h"
@@ -741,10 +742,15 @@
         return {};
     }
     svc->Start();
+    svc->SetShutdownCritical();
 
-    if (!sm->PerformSecondStageTransition()) {
+    if (!sm->PerformSecondStageInitTransition()) {
         LOG(FATAL) << "Failed to transition snapuserd to second-stage";
     }
+
+    if (auto pid = GetSnapuserdFirstStagePid()) {
+        KillFirstStageSnapuserd(pid.value());
+    }
     return {};
 }