init: add a swapoff built-in command

Enables a method for swapping off certain block devices or files. This
will be used before hibernation occurs.

Bug: 339688542
Test: Manual, verified that calling swapoff from a init file swapsoff
location that is specified

Change-Id: I212a6f303a023c3e440b557caae82ad3904ac9c9
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 606ea8c..f743a30 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -36,6 +36,7 @@
 #include <sys/resource.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
+#include <sys/swap.h>
 #include <sys/syscall.h>
 #include <sys/system_properties.h>
 #include <sys/time.h>
@@ -1316,6 +1317,13 @@
     return {};
 }
 
+static Result<void> do_swapoff(const BuiltinArguments& args) {
+    if (!swapoff(args[1].c_str())) {
+        return ErrnoError() << "swapoff() failed";
+    }
+    return {};
+}
+
 // Builtin-function-map start
 const BuiltinFunctionMap& GetBuiltinFunctionMap() {
     constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
@@ -1372,6 +1380,7 @@
         {"start",                   {1,     1,    {false,  do_start}}},
         {"stop",                    {1,     1,    {false,  do_stop}}},
         {"swapon_all",              {0,     1,    {false,  do_swapon_all}}},
+        {"swapoff",                 {1,     1,    {false,  do_swapoff}}},
         {"enter_default_mount_ns",  {0,     0,    {false,  do_enter_default_mount_ns}}},
         {"symlink",                 {2,     2,    {true,   do_symlink}}},
         {"sysclktz",                {1,     1,    {false,  do_sysclktz}}},