Merge changes from topics "dm-default-key-v2", "metadata_cipher"
* changes:
Set metadata cipher in fstab
Add support for v2 of dm-default-key
diff --git a/bootstat/Android.bp b/bootstat/Android.bp
index 5e2d171..edff26d 100644
--- a/bootstat/Android.bp
+++ b/bootstat/Android.bp
@@ -30,8 +30,8 @@
"libbase",
"libcutils",
"liblog",
- "libmetricslogger",
],
+ static_libs: ["libgtest_prod"],
}
// bootstat static library
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 6409db0..6b8a09a 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -44,7 +44,6 @@
#include <android/log.h>
#include <cutils/android_reboot.h>
#include <cutils/properties.h>
-#include <metricslogger/metrics_logger.h>
#include <statslog.h>
#include "boot_event_record_store.h"
@@ -57,9 +56,10 @@
BootEventRecordStore boot_event_store;
auto events = boot_event_store.GetAllBootEvents();
- for (auto i = events.cbegin(); i != events.cend(); ++i) {
- android::metricslogger::LogHistogram(i->first, i->second);
- }
+ // TODO(b/148575354): Replace with statsd.
+ // for (auto i = events.cbegin(); i != events.cend(); ++i) {
+ // android::metricslogger::LogHistogram(i->first, i->second);
+ // }
}
// Records the named boot |event| to the record store. If |value| is non-empty
@@ -1212,13 +1212,17 @@
const auto reason = android::base::GetProperty(bootloader_reboot_reason_property, "");
if (reason.empty()) {
+ // TODO(b/148575354): Replace with statsd.
// Log an empty boot reason value as '<EMPTY>' to ensure the value is intentional
// (and not corruption anywhere else in the reporting pipeline).
- android::metricslogger::LogMultiAction(android::metricslogger::ACTION_BOOT,
- android::metricslogger::FIELD_PLATFORM_REASON, "<EMPTY>");
+ // android::metricslogger::LogMultiAction(android::metricslogger::ACTION_BOOT,
+ // android::metricslogger::FIELD_PLATFORM_REASON,
+ // "<EMPTY>");
} else {
- android::metricslogger::LogMultiAction(android::metricslogger::ACTION_BOOT,
- android::metricslogger::FIELD_PLATFORM_REASON, reason);
+ // TODO(b/148575354): Replace with statsd.
+ // android::metricslogger::LogMultiAction(android::metricslogger::ACTION_BOOT,
+ // android::metricslogger::FIELD_PLATFORM_REASON,
+ // reason);
}
// Log the raw bootloader_boot_reason property value.
@@ -1246,9 +1250,10 @@
time_t current_time_utc = time(nullptr);
if (current_time_utc < 0) {
+ // TODO(b/148575354): Replace with statsd.
// UMA does not display negative values in buckets, so convert to positive.
- android::metricslogger::LogHistogram("factory_reset_current_time_failure",
- std::abs(current_time_utc));
+ // android::metricslogger::LogHistogram("factory_reset_current_time_failure",
+ // std::abs(current_time_utc));
// Logging via BootEventRecordStore to see if using android::metricslogger::LogHistogram
// is losing records somehow.
@@ -1256,7 +1261,8 @@
std::abs(current_time_utc));
return;
} else {
- android::metricslogger::LogHistogram("factory_reset_current_time", current_time_utc);
+ // TODO(b/148575354): Replace with statsd.
+ // android::metricslogger::LogHistogram("factory_reset_current_time", current_time_utc);
// Logging via BootEventRecordStore to see if using android::metricslogger::LogHistogram
// is losing records somehow.
@@ -1276,7 +1282,8 @@
// Calculate and record the difference in time between now and the
// factory_reset time.
time_t factory_reset_utc = record.second;
- android::metricslogger::LogHistogram("factory_reset_record_value", factory_reset_utc);
+ // TODO(b/148575354): Replace with statsd.
+ // android::metricslogger::LogHistogram("factory_reset_record_value", factory_reset_utc);
// Logging via BootEventRecordStore to see if using android::metricslogger::LogHistogram
// is losing records somehow.
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 88731df..785882a 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -1957,8 +1957,17 @@
auto current_super = device_->GetSuperDevice(current_slot);
auto current_metadata = MetadataBuilder::New(opener, current_super, current_slot);
+ if (current_metadata == nullptr) {
+ LOG(ERROR) << "Cannot create metadata builder.";
+ return Return::Error();
+ }
+
auto target_metadata =
MetadataBuilder::NewForUpdate(opener, current_super, current_slot, target_slot);
+ if (target_metadata == nullptr) {
+ LOG(ERROR) << "Cannot create target metadata builder.";
+ return Return::Error();
+ }
// Delete partitions with target suffix in |current_metadata|. Otherwise,
// partition_cow_creator recognizes these left-over partitions as used space.
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index 634e0b4..c49c49e 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -793,6 +793,7 @@
// Initialize source partition metadata using |manifest_|.
src_ = MetadataBuilder::New(*opener_, "super", 0);
+ ASSERT_NE(src_, nullptr);
ASSERT_TRUE(FillFakeMetadata(src_.get(), manifest_, "_a"));
// Add sys_b which is like system_other.
ASSERT_TRUE(src_->AddGroup("group_b", kGroupSize));
@@ -987,6 +988,7 @@
// Test that partitions prioritize using space in super.
auto tgt = MetadataBuilder::New(*opener_, "super", 1);
+ ASSERT_NE(tgt, nullptr);
ASSERT_NE(nullptr, tgt->FindPartition("sys_b-cow"));
ASSERT_NE(nullptr, tgt->FindPartition("vnd_b-cow"));
ASSERT_EQ(nullptr, tgt->FindPartition("prd_b-cow"));
@@ -1200,7 +1202,9 @@
// Check that the old COW space is reclaimed and does not occupy space of mapped partitions.
auto src = MetadataBuilder::New(*opener_, "super", 1);
+ ASSERT_NE(src, nullptr);
auto tgt = MetadataBuilder::New(*opener_, "super", 0);
+ ASSERT_NE(tgt, nullptr);
for (const auto& cow_part_name : {"sys_a-cow", "vnd_a-cow", "prd_a-cow"}) {
auto* cow_part = tgt->FindPartition(cow_part_name);
ASSERT_NE(nullptr, cow_part) << cow_part_name << " does not exist in target metadata";
@@ -1291,6 +1295,7 @@
SetSize(vnd_, 5_MiB);
SetSize(prd_, 5_MiB);
src_ = MetadataBuilder::New(*opener_, "super", 0);
+ ASSERT_NE(src_, nullptr);
src_->RemoveGroupAndPartitions(group_->name() + "_a");
src_->RemoveGroupAndPartitions(group_->name() + "_b");
ASSERT_TRUE(FillFakeMetadata(src_.get(), manifest_, "_a"));
@@ -1664,6 +1669,7 @@
// Simulate flashing |flashed_slot|. This clears the UPDATED flag.
auto flashed_builder = MetadataBuilder::New(*opener_, "super", flashed_slot);
+ ASSERT_NE(flashed_builder, nullptr);
flashed_builder->RemoveGroupAndPartitions(group_->name() + flashed_slot_suffix);
flashed_builder->RemoveGroupAndPartitions(kCowGroupName);
ASSERT_TRUE(FillFakeMetadata(flashed_builder.get(), manifest_, flashed_slot_suffix));
diff --git a/libcutils/trace-dev.cpp b/libcutils/trace-dev.cpp
index 2ee39d3..9ca1729 100644
--- a/libcutils/trace-dev.cpp
+++ b/libcutils/trace-dev.cpp
@@ -32,6 +32,10 @@
{
atrace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_WRONLY | O_CLOEXEC);
if (atrace_marker_fd == -1) {
+ atrace_marker_fd = open("/sys/kernel/tracing/trace_marker", O_WRONLY | O_CLOEXEC);
+ }
+
+ if (atrace_marker_fd == -1) {
ALOGE("Error opening trace file: %s (%d)", strerror(errno), errno);
atrace_enabled_tags = 0;
} else {
diff --git a/libmetricslogger/Android.bp b/libmetricslogger/Android.bp
deleted file mode 100644
index 7d7554b..0000000
--- a/libmetricslogger/Android.bp
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2017 The Android Open Source Project
-
-metricslogger_lib_src_files = [
- "metrics_logger.cpp",
-]
-
-cc_defaults {
- name: "metricslogger_defaults",
-
- host_supported: true,
-
- export_include_dirs: ["include"],
- local_include_dirs: ["include"],
- shared_libs: [
- "libbase",
- "liblog",
- "libstatssocket",
- ],
- whole_static_libs: ["libgtest_prod"],
-
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- ],
-}
-
-// metricslogger shared library
-// -----------------------------------------------------------------------------
-cc_library {
- name: "libmetricslogger",
- srcs: metricslogger_lib_src_files,
- defaults: ["metricslogger_defaults"],
- export_shared_lib_headers: ["libstatssocket"],
-}
-
-// metricslogger shared library, debug
-// -----------------------------------------------------------------------------
-cc_library_shared {
- name: "libmetricslogger_debug",
- srcs: metricslogger_lib_src_files,
- defaults: ["metricslogger_defaults"],
-
- target: {
- host: {
- cflags: ["-UNDEBUG"],
- },
- },
-}
-
-// Native tests
-// -----------------------------------------------------------------------------
-cc_test {
- name: "metricslogger_tests",
- isolated: true,
- defaults: ["metricslogger_defaults"],
- shared_libs: [
- "libbase",
- "libmetricslogger_debug",
- ],
- srcs: [
- "metrics_logger_test.cpp",
- ],
-}
diff --git a/libmetricslogger/OWNERS b/libmetricslogger/OWNERS
deleted file mode 100644
index 6a6fba2..0000000
--- a/libmetricslogger/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-cwren@google.com
-jhawkins@google.com
diff --git a/libmetricslogger/include/metricslogger/metrics_logger.h b/libmetricslogger/include/metricslogger/metrics_logger.h
deleted file mode 100644
index 71c04a6..0000000
--- a/libmetricslogger/include/metricslogger/metrics_logger.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <log/log_event_list.h>
-#include <stats_event_list.h>
-#include <cstdint>
-#include <string>
-
-namespace android {
-namespace metricslogger {
-
-// Logs a Tron histogram metric named |event| containing |data| to the Tron log
-// buffer.
-void LogHistogram(const std::string& event, int32_t data);
-
-// Logs a Tron counter metric named |name| containing |val| count to the Tron
-// log buffer.
-void LogCounter(const std::string& name, int32_t val);
-
-// Logs a Tron multi_action with category|category| containing the string
-// |value| in the field |field|.
-void LogMultiAction(int32_t category, int32_t field, const std::string& value);
-
-// Logs a Tron complex event.
-//
-// A complex event can include data in a structure not suppored by the other
-// log event types above.
-//
-// Note that instances of this class are single use. You must call Record()
-// to write the event to the event log.
-class ComplexEventLogger {
- private:
- android_log_event_list logger;
- stats_event_list stats_logger;
-
- public:
- // Create a complex event with category|category|.
- explicit ComplexEventLogger(int category);
- // Set the package name that this event originates from.
- void SetPackageName(const std::string& package_name);
- // Add tagged data to the event, with the given tag and integer value.
- void AddTaggedData(int tag, int32_t value);
- // Add tagged data to the event, with the given tag and string value.
- void AddTaggedData(int tag, const std::string& value);
- // Add tagged data to the event, with the given tag and integer value.
- void AddTaggedData(int tag, int64_t value);
- // Add tagged data to the event, with the given tag and float value.
- void AddTaggedData(int tag, float value);
- // Record this event. This method can only be used once per instance
- // of ComplexEventLogger. Do not made any subsequent calls to AddTaggedData
- // after recording an event.
- void Record();
-};
-
-// TODO: replace these with the metric_logger.proto definitions
-enum {
- LOGBUILDER_CATEGORY = 757,
- LOGBUILDER_TYPE = 758,
- LOGBUILDER_NAME = 799,
- LOGBUILDER_BUCKET = 801,
- LOGBUILDER_VALUE = 802,
- LOGBUILDER_COUNTER = 803,
- LOGBUILDER_HISTOGRAM = 804,
- LOGBUILDER_PACKAGENAME = 806,
-
- ACTION_BOOT = 1098,
- FIELD_PLATFORM_REASON = 1099,
-
- FIELD_DURATION_MILLIS = 1304,
-
- FIELD_END_BATTERY_PERCENT = 1308,
-
- ACTION_HIDDEN_API_ACCESSED = 1391,
- FIELD_HIDDEN_API_ACCESS_METHOD = 1392,
- FIELD_HIDDEN_API_ACCESS_DENIED = 1393,
- FIELD_HIDDEN_API_SIGNATURE = 1394,
-
- ACTION_USB_CONNECTOR_CONNECTED = 1422,
- ACTION_USB_CONNECTOR_DISCONNECTED = 1423,
- ACTION_USB_AUDIO_CONNECTED = 1424,
- FIELD_USB_AUDIO_VIDPID = 1425,
- ACTION_USB_AUDIO_DISCONNECTED = 1426,
- ACTION_HARDWARE_FAILED = 1427,
- FIELD_HARDWARE_TYPE = 1428,
- FIELD_HARDWARE_FAILURE_CODE = 1429,
- ACTION_PHYSICAL_DROP = 1430,
- FIELD_CONFIDENCE_PERCENT = 1431,
- FIELD_ACCEL_MILLI_G = 1432,
- ACTION_BATTERY_HEALTH = 1433,
- FIELD_BATTERY_HEALTH_SNAPSHOT_TYPE = 1434,
- FIELD_BATTERY_TEMPERATURE_DECI_C = 1435,
- FIELD_BATTERY_VOLTAGE_UV = 1436,
- FIELD_BATTERY_OPEN_CIRCUIT_VOLTAGE_UV = 1437,
- ACTION_BATTERY_CHARGE_CYCLES = 1438,
- FIELD_BATTERY_CHARGE_CYCLES = 1439,
-
- ACTION_SLOW_IO = 1442,
- FIELD_IO_OPERATION_TYPE = 1443,
- FIELD_IO_OPERATION_COUNT = 1444,
- ACTION_SPEAKER_IMPEDANCE = 1445,
- FIELD_SPEAKER_IMPEDANCE_MILLIOHMS = 1446,
- FIELD_SPEAKER_LOCATION = 1447,
- FIELD_BATTERY_RESISTANCE_UOHMS = 1448,
- FIELD_BATTERY_CURRENT_UA = 1449,
- FIELD_HARDWARE_LOCATION = 1450,
- ACTION_BATTERY_CAUSED_SHUTDOWN = 1451,
-};
-
-enum {
- TYPE_ACTION = 4,
-};
-
-enum {
- ACCESS_METHOD_NONE = 0,
- ACCESS_METHOD_REFLECTION = 1,
- ACCESS_METHOD_JNI = 2,
- ACCESS_METHOD_LINKING = 3,
-};
-
-enum HardwareType {
- HARDWARE_UNKNOWN = 0,
- HARDWARE_MICROPHONE = 1,
- HARDWARE_CODEC = 2,
- HARDWARE_SPEAKER = 3,
- HARDWARE_FINGERPRINT = 4,
-};
-
-enum HardwareFailureCode {
- HARDWARE_FAILURE_UNKNOWN = 0,
- HARDWARE_FAILURE_COMPLETE = 1,
- HARDWARE_FAILURE_SPEAKER_HIGH_Z = 2,
- HARDWARE_FAILURE_SPEAKER_SHORT = 3,
- HARDWARE_FAILURE_FINGERPRINT_SENSOR_BROKEN = 4,
- HARDWARE_FAILURE_FINGERPRINT_TOO_MANY_DEAD_PIXELS = 5,
-};
-
-enum IoOperation {
- IOOP_UNKNOWN = 0,
- IOOP_READ = 1,
- IOOP_WRITE = 2,
- IOOP_UNMAP = 3,
- IOOP_SYNC = 4,
-};
-
-} // namespace metricslogger
-} // namespace android
diff --git a/libmetricslogger/metrics_logger.cpp b/libmetricslogger/metrics_logger.cpp
deleted file mode 100644
index 2a1b137..0000000
--- a/libmetricslogger/metrics_logger.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "metricslogger/metrics_logger.h"
-
-#include <cstdlib>
-
-#include <android-base/chrono_utils.h>
-#include <log/event_tag_map.h>
-
-using namespace android;
-
-namespace {
-
-const static int kStatsEventTag = 1937006964;
-const static int kKeyValuePairAtomId = 83;
-#ifdef __ANDROID__
-EventTagMap* kEventTagMap = android_openEventTagMap(nullptr);
-const int kSysuiMultiActionTag = android_lookupEventTagNum(
- kEventTagMap, "sysui_multi_action", "(content|4)", ANDROID_LOG_UNKNOWN);
-#else
-// android_openEventTagMap does not work on host builds.
-const int kSysuiMultiActionTag = 0;
-#endif
-
-int64_t getElapsedTimeNanoSinceBoot() {
- return std::chrono::duration_cast<std::chrono::nanoseconds>(
- android::base::boot_clock::now().time_since_epoch())
- .count();
-}
-
-} // namespace
-
-namespace android {
-namespace metricslogger {
-
-// Mirror com.android.internal.logging.MetricsLogger#histogram().
-void LogHistogram(const std::string& event, int32_t data) {
- android_log_event_list log(kSysuiMultiActionTag);
- log << LOGBUILDER_CATEGORY << LOGBUILDER_HISTOGRAM << LOGBUILDER_NAME << event
- << LOGBUILDER_BUCKET << data << LOGBUILDER_VALUE << 1 << LOG_ID_EVENTS;
-
- stats_event_list stats_log(kStatsEventTag);
- stats_log << getElapsedTimeNanoSinceBoot() << kKeyValuePairAtomId << LOGBUILDER_CATEGORY
- << LOGBUILDER_HISTOGRAM << LOGBUILDER_NAME << event << LOGBUILDER_BUCKET << data
- << LOGBUILDER_VALUE << 1;
- stats_log.write(LOG_ID_STATS);
-}
-
-// Mirror com.android.internal.logging.MetricsLogger#count().
-void LogCounter(const std::string& name, int32_t val) {
- android_log_event_list log(kSysuiMultiActionTag);
- log << LOGBUILDER_CATEGORY << LOGBUILDER_COUNTER << LOGBUILDER_NAME << name << LOGBUILDER_VALUE
- << val << LOG_ID_EVENTS;
-
- stats_event_list stats_log(kStatsEventTag);
- stats_log << getElapsedTimeNanoSinceBoot() << kKeyValuePairAtomId << LOGBUILDER_CATEGORY
- << LOGBUILDER_COUNTER << LOGBUILDER_NAME << name << LOGBUILDER_VALUE << val;
- stats_log.write(LOG_ID_STATS);
-}
-
-// Mirror com.android.internal.logging.MetricsLogger#action().
-void LogMultiAction(int32_t category, int32_t field, const std::string& value) {
- android_log_event_list log(kSysuiMultiActionTag);
- log << LOGBUILDER_CATEGORY << category << LOGBUILDER_TYPE << TYPE_ACTION
- << field << value << LOG_ID_EVENTS;
-
- stats_event_list stats_log(kStatsEventTag);
- stats_log << getElapsedTimeNanoSinceBoot() << kKeyValuePairAtomId << LOGBUILDER_CATEGORY
- << category << LOGBUILDER_TYPE << TYPE_ACTION << field << value;
- stats_log.write(LOG_ID_STATS);
-}
-
-ComplexEventLogger::ComplexEventLogger(int category)
- : logger(kSysuiMultiActionTag), stats_logger(kStatsEventTag) {
- logger << LOGBUILDER_CATEGORY << category;
- stats_logger << getElapsedTimeNanoSinceBoot() << kKeyValuePairAtomId << LOGBUILDER_CATEGORY
- << category;
-}
-
-void ComplexEventLogger::SetPackageName(const std::string& package_name) {
- logger << LOGBUILDER_PACKAGENAME << package_name;
- stats_logger << LOGBUILDER_PACKAGENAME << package_name;
-}
-
-void ComplexEventLogger::AddTaggedData(int tag, int32_t value) {
- logger << tag << value;
- stats_logger << tag << value;
-}
-
-void ComplexEventLogger::AddTaggedData(int tag, const std::string& value) {
- logger << tag << value;
- stats_logger << tag << value;
-}
-
-void ComplexEventLogger::AddTaggedData(int tag, int64_t value) {
- logger << tag << value;
- stats_logger << tag << value;
-}
-
-void ComplexEventLogger::AddTaggedData(int tag, float value) {
- logger << tag << value;
- stats_logger << tag << value;
-}
-
-void ComplexEventLogger::Record() {
- logger << LOG_ID_EVENTS;
- stats_logger.write(LOG_ID_STATS);
-}
-
-} // namespace metricslogger
-} // namespace android
diff --git a/libmetricslogger/metrics_logger_test.cpp b/libmetricslogger/metrics_logger_test.cpp
deleted file mode 100644
index 440645c..0000000
--- a/libmetricslogger/metrics_logger_test.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "metricslogger/metrics_logger.h"
-
-#include <gtest/gtest.h>
-
-TEST(MetricsLoggerTest, AddSingleBootEvent) {
- android::metricslogger::LogHistogram("test_event", 42);
- // TODO(jhawkins): Verify the EventLog is updated.
-}
-
-TEST(MetricsLoggerTest, AddCounterVal) {
- android::metricslogger::LogCounter("test_count", 10);
-}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 12b9c20..20fb071 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -32,6 +32,10 @@
# cgroup for system_server and surfaceflinger
mkdir /dev/memcg/system 0550 system system
+ # symlink the Android specific /dev/tun to Linux expected /dev/net/tun
+ mkdir /dev/net 0755 root root
+ symlink ../tun /dev/net/tun
+
# set RLIMIT_NICE to allow priorities from 19 to -20
setrlimit nice 40 40