diff --git a/garnet/go/src/amber/system_updater/BUILD.gn b/garnet/go/src/amber/system_updater/BUILD.gn index f32a68ac38456fc140516ea93a3ae045f1ea94dc..7c8bc0a85f8592b7d17c564eecf743f79cd741ff 100644 --- a/garnet/go/src/amber/system_updater/BUILD.gn +++ b/garnet/go/src/amber/system_updater/BUILD.gn @@ -18,6 +18,7 @@ go_library("lib") { "//sdk/fidl/fuchsia.amber($go_toolchain)", "//sdk/fidl/fuchsia.pkg($go_toolchain)", "//sdk/fidl/fuchsia.sys($go_toolchain)", + "//zircon/public/fidl/fuchsia-device-manager($go_toolchain)", "//zircon/public/fidl/fuchsia-io($go_toolchain)", ] } diff --git a/garnet/go/src/amber/system_updater/main.go b/garnet/go/src/amber/system_updater/main.go index 777e191aa508001763ec65f85d8ef17ea59bc08c..f281652b4379ed9a5ddd9363fa52223d8741f453 100644 --- a/garnet/go/src/amber/system_updater/main.go +++ b/garnet/go/src/amber/system_updater/main.go @@ -10,8 +10,12 @@ import ( "os" "path/filepath" "time" + "syscall/zx" + "syscall/zx/fdio" + "syscall/zx/fidl" "app/context" + devmgr "fidl/fuchsia/device/manager" "syslog/logger" "metrics" @@ -136,17 +140,32 @@ func run() (err error) { logger.Infof("system update complete, rebooting...") - dmctl, err := os.OpenFile("/dev/misc/dmctl", os.O_RDWR, os.ModePerm) + SendReboot() + + return nil +} + +func SendReboot() { + channel_local, channel_remote, err := zx.NewChannel(0) if err != nil { - logger.Errorf("error forcing restart: %s", err) + logger.Errorf("error creating channel: %s", err) + return } - defer dmctl.Close() - cmd := []byte("reboot") - if _, err := dmctl.Write(cmd); err != nil { - logger.Errorf("error writing to control socket: %s", err) + + err = fdio.ServiceConnect( + "/svc/fuchsia.device.manager.Administrator", zx.Handle(channel_remote)) + if err != nil { + logger.Errorf("error connecting to devmgr service: %s", err) + return } - return nil + var administrator = devmgr.AdministratorInterface( + fidl.ChannelProxy{Channel: zx.Channel(channel_local)}) + var status int32 + status, err = administrator.Suspend(devmgr.SuspendFlagReboot) + if err != nil || status != 0 { + logger.Errorf("error sending restart to Administrator: %s status: %d", err, status) + } } type InitiatorValue struct { diff --git a/garnet/go/src/amber/system_updater/meta/system_updater.cmx b/garnet/go/src/amber/system_updater/meta/system_updater.cmx index 4bf13785a5ba76a7102bf455e8c42924d87295eb..c5468d61cf9a469043063e8d741f75e6262d1e65 100644 --- a/garnet/go/src/amber/system_updater/meta/system_updater.cmx +++ b/garnet/go/src/amber/system_updater/meta/system_updater.cmx @@ -15,6 +15,7 @@ "services": [ "fuchsia.pkg.PackageResolver", "fuchsia.cobalt.LoggerFactory", + "fuchsia.device.manager.Administrator", "fuchsia.logger.LogSink", "fuchsia.process.Launcher" ] diff --git a/zircon/system/core/devmgr/devcoordinator/coordinator.cpp b/zircon/system/core/devmgr/devcoordinator/coordinator.cpp index 9072e297a196a5c711628b29b5f2859945d4745c..3c604115a191b23429a2621eacb533291100c35b 100644 --- a/zircon/system/core/devmgr/devcoordinator/coordinator.cpp +++ b/zircon/system/core/devmgr/devcoordinator/coordinator.cpp @@ -1649,6 +1649,9 @@ void Coordinator::InitOutgoingServices() { const auto& public_dir = outgoing_services_.public_dir(); const auto admin = [this](zx::channel request) { + static_assert(fuchsia_device_manager_SUSPEND_FLAG_REBOOT == DEVICE_SUSPEND_FLAG_REBOOT); + static_assert(fuchsia_device_manager_SUSPEND_FLAG_POWEROFF == DEVICE_SUSPEND_FLAG_POWEROFF); + static constexpr fuchsia_device_manager_Administrator_ops_t kOps = { .Suspend = [](void* ctx, uint32_t flags, fidl_txn_t* txn) { static_cast<Coordinator*>(ctx)->Suspend(flags); diff --git a/zircon/system/fidl/fuchsia-device-manager/administrator.fidl b/zircon/system/fidl/fuchsia-device-manager/administrator.fidl index 272f22e6718f5d3c795017f0801469a40f3a6206..e9c926d2239349220455e66318fadf508d4e5c95 100644 --- a/zircon/system/fidl/fuchsia-device-manager/administrator.fidl +++ b/zircon/system/fidl/fuchsia-device-manager/administrator.fidl @@ -6,6 +6,10 @@ library fuchsia.device.manager; using zx; +/// Check the DDK for all available flags. +const uint32 SUSPEND_FLAG_REBOOT = 0xdcdc0100; +const uint32 SUSPEND_FLAG_POWEROFF = 0xdcdc0200; + /// Provides administration services for the device manager service and the device tree it controls. [Discoverable, Layout = "Simple"] protocol Administrator {