blob: 1cfd0358d81afcbfa473d1f309ebfc5b1390c457 [file] [log] [blame]
Greg Kerr888f1ce2019-01-31 10:49:11 -08001// Copyright 2019 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "debugd/src/scheduler_configuration_tool.h"
6
7#include "debugd/src/error_utils.h"
Hardik Goyalb09d6b02019-08-13 16:15:50 -07008#include "debugd/src/helper_utils.h"
Greg Kerr888f1ce2019-01-31 10:49:11 -08009#include "debugd/src/process_with_output.h"
10#include "debugd/src/sandboxed_process.h"
11
12#include <string>
13
14#include <base/files/file_util.h>
15#include <base/logging.h>
16#include <base/strings/string_number_conversions.h>
17#include <base/strings/string_split.h>
18#include <base/strings/stringprintf.h>
19#include <brillo/errors/error_codes.h>
20#include <build/build_config.h>
21#include <build/buildflag.h>
22#include <chromeos/dbus/service_constants.h>
23
24namespace debugd {
25
26namespace {
27
28constexpr char kErrorPath[] =
29 "org.chromium.debugd.SchedulerConfigurationPolicyError";
30
Abhishek Bhardwaj08d907e2019-08-27 14:22:41 -070031const char kConservativePolicy[] = "conservative";
32
33const char kPerformancePolicy[] = "performance";
34
35bool IsValidSchedulerPolicy(const std::string& policy) {
36 return ((policy == kConservativePolicy) || (policy == kPerformancePolicy));
37}
38
Greg Kerr888f1ce2019-01-31 10:49:11 -080039constexpr bool IsX86_64() {
40#if defined(__x86_64__)
41 return true;
42#else
43 return false;
44#endif
45}
46
47// Executes a helper process with the expectation that any message printed to
48// stderr indicates a failure that should be passed back over D-Bus.
49// Returns false if any errors launching the process occur. Returns true
50// otherwise, and sets |exit_status| if it isn't null.
51bool RunHelper(const std::string& command,
52 const ProcessWithOutput::ArgList& arguments,
53 int* exit_status,
54 brillo::ErrorPtr* error) {
55 std::string helper_path;
Hardik Goyalb09d6b02019-08-13 16:15:50 -070056 if (!GetHelperPath(command, &helper_path)) {
Greg Kerr888f1ce2019-01-31 10:49:11 -080057 DEBUGD_ADD_ERROR(error, kErrorPath, "Path too long");
58 return false;
59 }
60
61 // Note: This runs the helper as root and without a sandbox only because the
62 // helper immediately drops privileges and enforces its own sandbox. debugd
63 // should not be used to launch unsandboxed executables.
64 std::string stderr;
65 int result = ProcessWithOutput::RunProcess(
66 helper_path, arguments, true /*requires_root*/,
67 true /* disable_sandbox */, nullptr, nullptr, &stderr, error);
68
69 if (!stderr.empty()) {
70 DEBUGD_ADD_ERROR(error, kErrorPath, stderr.c_str());
71 return false;
72 }
73
74 if (exit_status)
75 *exit_status = result;
76 return true;
77}
78
79} // namespace
80
81bool SchedulerConfigurationTool::SetPolicy(const std::string& policy,
Abhishek Bhardwaj08d907e2019-08-27 14:22:41 -070082 bool lock_policy,
Greg Kerr888f1ce2019-01-31 10:49:11 -080083 brillo::ErrorPtr* error) {
84 if (!IsX86_64()) {
85 DEBUGD_ADD_ERROR(error, kErrorPath, "Invalid architecture");
86 return false;
87 }
88
Abhishek Bhardwaj08d907e2019-08-27 14:22:41 -070089 if (!IsValidSchedulerPolicy(policy)) {
90 DEBUGD_ADD_ERROR(error, kErrorPath, "Invalid policy " + policy);
91 return false;
92 }
93 bool is_policy_conservative = (policy == kConservativePolicy);
94
95 if (policy_locked_conservative_) {
96 if (is_policy_conservative)
97 return true;
98
99 DEBUGD_ADD_ERROR(error, kErrorPath, "Policy locked to conservative");
100 return false;
101 }
102
103 if (lock_policy && !is_policy_conservative) {
104 DEBUGD_ADD_ERROR(error, kErrorPath, "Can't lock performance policy");
105 return false;
106 }
107
Greg Kerr888f1ce2019-01-31 10:49:11 -0800108 int exit_status;
109 bool result = RunHelper("scheduler_configuration_helper",
110 ProcessWithOutput::ArgList{"--policy=" + policy},
111 &exit_status, error);
Greg Kerre0d17fd2019-02-19 14:51:30 -0800112
113 bool status = result && (exit_status == 0);
114 if (!status) {
115 DEBUGD_ADD_ERROR(error, kErrorPath,
116 "scheduler_configuration_helper failed");
Abhishek Bhardwaj08d907e2019-08-27 14:22:41 -0700117 } else {
118 // The |policy_locked_conservative_| flag will only be set, if a
119 // "conservative" policy was successfully set when it was asked to be
120 // locked..
121 policy_locked_conservative_ = is_policy_conservative && lock_policy;
Greg Kerre0d17fd2019-02-19 14:51:30 -0800122 }
123
124 return status;
Greg Kerr888f1ce2019-01-31 10:49:11 -0800125}
126
127} // namespace debugd