Revert "Implement basic mmd zram setup"
Revert submission 3365122-mmd_basic_zram_setup
Reason for revert: DroidMonitor created revert due to b/381372137. Will be verified through ABTD for standard investigation.
Reverted changes: /q/submissionid:3365122-mmd_basic_zram_setup
Change-Id: I703486e0d0842581b7fffe98e6b590688789543c
diff --git a/Android.bp b/Android.bp
index 098b802..369fbe4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -29,7 +29,6 @@
rustlibs: [
"liblibc",
"libmockall",
- "libnix",
"libthiserror",
],
}
diff --git a/mmd.rc b/mmd.rc
index ef33a05..ea764ce 100644
--- a/mmd.rc
+++ b/mmd.rc
@@ -8,13 +8,6 @@
disabled
on boot
- # Allow mmd to run mkswap on zram device
- chown root mmd /dev/block/zram0
- chmod 0664 /dev/block/zram0
- # Allow mmd to update zram disk size
- chown root mmd /sys/block/zram0/disksize
- chmod 0664 /sys/block/zram0/disksize
-
chown root mmd /sys/block/zram0/recompress
chmod 0220 /sys/block/zram0/recompress
chown root mmd /sys/block/zram0/writeback_limit
diff --git a/src/main.rs b/src/main.rs
index 859d5d7..374beb6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,6 +19,8 @@
mod properties;
mod service;
+use std::time::Duration;
+
use binder::BinderFeatures;
use log::error;
use log::info;
@@ -26,10 +28,6 @@
use log::LevelFilter;
use mmd::zram::recompression::is_zram_recompression_activated;
use mmd::zram::recompression::ZramRecompression;
-use mmd::zram::setup::activate_zram;
-use mmd::zram::setup::is_zram_swap_activated;
-use mmd::zram::setup::parse_zram_size_spec;
-use mmd::zram::setup::SetupApiImpl;
use mmd::zram::stats::load_total_zram_size;
use mmd::zram::writeback::is_zram_writeback_activated;
use mmd::zram::writeback::ZramWriteback;
@@ -38,24 +36,10 @@
use rustutils::system_properties;
use crate::properties::BoolProp;
-use crate::properties::StringProp;
// In Android zram writeback file is always "/data/per_boot/zram_swap".
const ZRAM_WRITEBACK_FILE_PATH: &str = "/data/per_boot/zram_swap";
-fn setup_zram() -> anyhow::Result<()> {
- let zram_activated = is_zram_swap_activated::<SetupApiImpl>()?;
- if zram_activated {
- info!("zram is already on, skipping zram setup");
- return Ok(());
- }
-
- let zram_size_spec = StringProp::ZramSize.get("50%");
- let zram_size = parse_zram_size_spec(&zram_size_spec)?;
- activate_zram::<SysfsZramApiImpl, SetupApiImpl>(zram_size)?;
- Ok(())
-}
-
fn main() {
// "mmd --set-property" command copies the AConfig flag to "mmd.enabled_aconfig" system
// property as either "true" or "false".
@@ -79,9 +63,9 @@
return;
}
- if BoolProp::ZramEnabled.get(false) {
- setup_zram().expect("zram setup");
- }
+ // TODO: This is to wait until swapon_all command sets up zram. Remove this when mmd sets up
+ // zram.
+ std::thread::sleep(Duration::from_secs(60));
let total_zram_size = match load_total_zram_size::<SysfsZramApiImpl>() {
Ok(v) => v,
diff --git a/src/os.rs b/src/os.rs
index 337692f..235fa83 100644
--- a/src/os.rs
+++ b/src/os.rs
@@ -16,9 +16,6 @@
use std::io;
-use nix::unistd::sysconf;
-use nix::unistd::SysconfVar;
-
const MEMINFO_PATH: &str = "/proc/meminfo";
/// [MeminfoApi] is a mockable interface for access to "/proc/meminfo".
@@ -50,10 +47,3 @@
// SAFETY: `sysconf` simply returns an integer.
unsafe { libc::sysconf(libc::_SC_PAGESIZE) as u64 }
}
-
-/// Returns the page count of the system.
-pub fn get_page_count() -> u64 {
- sysconf(SysconfVar::_PHYS_PAGES)
- .expect("PHYS_PAGES should be a valid sysconf variable")
- .expect("PHYS_PAGES variable should be supported") as u64
-}
diff --git a/src/properties.rs b/src/properties.rs
index 9169412..435b1b2 100644
--- a/src/properties.rs
+++ b/src/properties.rs
@@ -37,7 +37,6 @@
/// clippy::enum_variant_names is allowed because we may add more properties.
#[allow(clippy::enum_variant_names)]
pub enum BoolProp {
- ZramEnabled,
ZramWritebackEnabled,
ZramWritebackHugeIdleEnabled,
ZramWritebackIdleEnabled,
@@ -51,7 +50,6 @@
impl BoolProp {
fn flag_name(&self) -> &'static str {
match self {
- Self::ZramEnabled => "zram.enabled",
Self::ZramWritebackEnabled => "zram.writeback.enabled",
Self::ZramWritebackHugeIdleEnabled => "zram.writeback.huge_idle.enabled",
Self::ZramWritebackIdleEnabled => "zram.writeback.idle.enabled",
@@ -136,26 +134,6 @@
}
}
-/// String system properties for mmd.
-///
-/// clippy::enum_variant_names is allowed because we may add more properties.
-#[allow(clippy::enum_variant_names)]
-pub enum StringProp {
- ZramSize,
-}
-
-impl StringProp {
- fn flag_name(&self) -> &'static str {
- match self {
- Self::ZramSize => "zram.size",
- }
- }
-
- pub fn get(&self, default: &str) -> String {
- read(self.flag_name()).unwrap_or_else(|| default.to_string())
- }
-}
-
fn read<T: FromStr>(flag_name: &str) -> Option<T> {
let value = GetServerConfigurableFlag(SERVER_CONFIG_NAMESPACE, flag_name, "");
if !value.is_empty() {
diff --git a/src/zram.rs b/src/zram.rs
index 7aeb4a2..c22011c 100644
--- a/src/zram.rs
+++ b/src/zram.rs
@@ -16,7 +16,6 @@
pub mod idle;
pub mod recompression;
-pub mod setup;
pub mod stats;
pub mod writeback;
@@ -52,8 +51,6 @@
pub trait SysfsZramApi {
/// Read "/sys/block/zram0/disksize".
fn read_disksize() -> io::Result<String>;
- /// Write "/sys/block/zram0/disksize".
- fn write_disksize(contents: &str) -> io::Result<()>;
/// Read "/sys/block/zram0/mm_stat".
fn read_mm_stat() -> io::Result<String>;
@@ -85,10 +82,6 @@
std::fs::read_to_string(ZRAM_DISKSIZE_PATH)
}
- fn write_disksize(contents: &str) -> io::Result<()> {
- std::fs::write(ZRAM_DISKSIZE_PATH, contents)
- }
-
fn read_mm_stat() -> io::Result<String> {
std::fs::read_to_string(ZRAM_MM_STAT_PATH)
}
diff --git a/src/zram/setup.rs b/src/zram/setup.rs
deleted file mode 100644
index 6e78039..0000000
--- a/src/zram/setup.rs
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2024, 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.
-
-//! This module implements zram setup functionality.
-//!
-//! The setup implemented in this module assumes that the zram kernel module has been loaded early on init with only 1 zram device (`zram0`).
-//!
-//! zram kernel documentation https://docs.kernel.org/admin-guide/blockdev/zram.html
-
-#[cfg(test)]
-mod tests;
-
-use std::io;
-
-use crate::os::get_page_count;
-use crate::os::get_page_size;
-use crate::zram::SysfsZramApi;
-
-const MKSWAP_BIN_PATH: &str = "/system/bin/mkswap";
-const ZRAM_DEVICE_PATH: &str = "/dev/block/zram0";
-const PROC_SWAPS_PATH: &str = "/proc/swaps";
-
-const MAX_ZRAM_PERCENTAGE_ALLOWED: u64 = 500;
-
-/// [SetupApi] is the mockable interface for swap operations.
-#[cfg_attr(test, mockall::automock)]
-pub trait SetupApi {
- /// Set up zram swap device, returning whether the command succeeded and its output.
- fn mkswap(device_path: &str) -> io::Result<std::process::Output>;
- /// Specify the zram swap device.
- fn swapon(device_path: &std::ffi::CStr) -> io::Result<()>;
- /// Read swaps areas in use.
- fn read_swap_areas() -> io::Result<String>;
-}
-
-/// The implementation of [SetupApi].
-pub struct SetupApiImpl;
-
-impl SetupApi for SetupApiImpl {
- fn mkswap(device_path: &str) -> io::Result<std::process::Output> {
- std::process::Command::new(MKSWAP_BIN_PATH).arg(device_path).output()
- }
-
- fn swapon(device_path: &std::ffi::CStr) -> io::Result<()> {
- // SAFETY: device_path is a nul-terminated string.
- let res = unsafe { libc::swapon(device_path.as_ptr(), 0) };
- if res == 0 {
- Ok(())
- } else {
- Err(std::io::Error::last_os_error())
- }
- }
-
- fn read_swap_areas() -> io::Result<String> {
- std::fs::read_to_string(PROC_SWAPS_PATH)
- }
-}
-
-/// Whether or not zram is already set up on the device.
-pub fn is_zram_swap_activated<S: SetupApi>() -> io::Result<bool> {
- let swaps = S::read_swap_areas()?;
- // Skip the first line which is header.
- let swap_lines = swaps.lines().skip(1);
- // Swap is turned on if swap file contains entry with zram keyword.
- for line in swap_lines {
- if line.contains("zram") {
- return Ok(true);
- }
- }
- Ok(false)
-}
-
-/// Error from [parse_zram_size_spec].
-#[derive(Debug, thiserror::Error)]
-pub enum ZramSpecError {
- /// Zram size was not specified
- #[error("zram size is not specified")]
- EmptyZramSizeSpec,
- /// Zram size percentage needs to be between 1 and 500%
- #[error(
- "zram size percentage {0} is out of range (expected the between 1 and {})",
- MAX_ZRAM_PERCENTAGE_ALLOWED
- )]
- ZramPercentageOutOfRange(u64),
- /// Parsing zram size error
- #[error("zram size is not an int: {0}")]
- ParseZramSize(#[from] std::num::ParseIntError),
-}
-
-/// Parse zram size that can be specified by a percentage or an absolute value.
-pub fn parse_zram_size_spec(spec: &str) -> Result<u64, ZramSpecError> {
- parse_size_spec_with_page_info(spec, get_page_size(), get_page_count())
-}
-
-fn parse_size_spec_with_page_info(
- spec: &str,
- system_page_size: u64,
- system_page_count: u64,
-) -> Result<u64, ZramSpecError> {
- if spec.is_empty() {
- return Err(ZramSpecError::EmptyZramSizeSpec);
- }
-
- if let Some(percentage_str) = spec.strip_suffix('%') {
- let percentage = percentage_str.parse::<u64>()?;
- if percentage == 0 || percentage > MAX_ZRAM_PERCENTAGE_ALLOWED {
- return Err(ZramSpecError::ZramPercentageOutOfRange(percentage));
- }
- return Ok(system_page_count * percentage / 100 * system_page_size);
- }
-
- let zram_size = spec.parse::<u64>()?;
- Ok(zram_size)
-}
-
-/// Error from [activate].
-#[derive(Debug, thiserror::Error)]
-pub enum ZramActivationError {
- /// Failed to update zram disk size
- #[error("failed to write zram disk size: {0}")]
- UpdateZramDiskSize(std::io::Error),
- /// Failed to swapon
- #[error("swapon failed: {0}")]
- SwapOn(std::io::Error),
- /// Mkswap command failed
- #[error("failed to execute mkswap: {0}")]
- ExecuteMkSwap(std::io::Error),
- /// Mkswap command failed
- #[error("mkswap failed: {0:?}")]
- MkSwap(std::process::Output),
-}
-
-/// Set up a zram device with provided parameters.
-pub fn activate_zram<Z: SysfsZramApi, S: SetupApi>(
- zram_size: u64,
-) -> Result<(), ZramActivationError> {
- Z::write_disksize(&zram_size.to_string()).map_err(ZramActivationError::UpdateZramDiskSize)?;
-
- let output = S::mkswap(ZRAM_DEVICE_PATH).map_err(ZramActivationError::ExecuteMkSwap)?;
- if !output.status.success() {
- return Err(ZramActivationError::MkSwap(output));
- }
-
- let zram_device_path_cstring = std::ffi::CString::new(ZRAM_DEVICE_PATH)
- .expect("device path should have no nul characters");
- S::swapon(&zram_device_path_cstring).map_err(ZramActivationError::SwapOn)?;
-
- Ok(())
-}
diff --git a/src/zram/setup/tests.rs b/src/zram/setup/tests.rs
deleted file mode 100644
index 2f9c28f..0000000
--- a/src/zram/setup/tests.rs
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2024, 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.
-
-use super::*;
-use mockall::predicate::*;
-use mockall::Sequence;
-use std::os::unix::process::ExitStatusExt;
-use std::sync::LockResult;
-use std::sync::Mutex;
-use std::sync::MutexGuard;
-
-use crate::zram::MockSysfsZramApi;
-use crate::zram::ZRAM_API_MTX;
-
-const PROC_SWAP_HEADER: &str = "Filename Type Size Used Priority\n";
-const DEFAULT_PAGE_SIZE: u64 = 4096;
-const DEFAULT_PAGE_COUNT: u64 = 998875;
-const DEFAULT_ZRAM_SIZE: u64 = 1000000;
-
-fn success_command_output() -> std::process::Output {
- std::process::Output {
- status: std::process::ExitStatus::from_raw(0),
- stderr: "".to_owned().into_bytes(),
- stdout: "".to_owned().into_bytes(),
- }
-}
-
-fn failure_command_output() -> std::process::Output {
- std::process::Output {
- status: std::process::ExitStatus::from_raw(1),
- stderr: "".to_owned().into_bytes(),
- stdout: "".to_owned().into_bytes(),
- }
-}
-
-/// Mutex to synchronize tests using [MockSetupApi].
-///
-/// mockall for static functions requires synchronization.
-///
-/// https://docs.rs/mockall/latest/mockall/#static-methods
-pub static SETUP_API_MTX: Mutex<()> = Mutex::new(());
-
-struct MockContext<'a> {
- write_disksize: crate::zram::__mock_MockSysfsZramApi_SysfsZramApi::__write_disksize::Context,
- read_swap_areas: crate::zram::setup::__mock_MockSetupApi_SetupApi::__read_swap_areas::Context,
- mkswap: crate::zram::setup::__mock_MockSetupApi_SetupApi::__mkswap::Context,
- swapon: crate::zram::setup::__mock_MockSetupApi_SetupApi::__swapon::Context,
- // Lock will be released after mock contexts are dropped.
- _setup_lock: LockResult<MutexGuard<'a, ()>>,
- _zram_lock: LockResult<MutexGuard<'a, ()>>,
-}
-
-impl<'a> MockContext<'a> {
- fn new() -> Self {
- let _zram_lock = ZRAM_API_MTX.lock();
- let _setup_lock = SETUP_API_MTX.lock();
- Self {
- write_disksize: MockSysfsZramApi::write_disksize_context(),
- read_swap_areas: MockSetupApi::read_swap_areas_context(),
- mkswap: MockSetupApi::mkswap_context(),
- swapon: MockSetupApi::swapon_context(),
- _setup_lock,
- _zram_lock,
- }
- }
-}
-
-#[test]
-fn is_zram_swap_activated_zram_off() {
- let mock = MockContext::new();
- mock.read_swap_areas.expect().returning(|| Ok(PROC_SWAP_HEADER.to_string()));
-
- assert!(!is_zram_swap_activated::<MockSetupApi>().unwrap());
-}
-
-#[test]
-fn is_zram_swap_activated_zram_on() {
- let mock = MockContext::new();
- let zram_area = "/dev/block/zram0 partition 7990996 87040 -2\n";
- mock.read_swap_areas.expect().returning(|| Ok(PROC_SWAP_HEADER.to_owned() + zram_area));
-
- assert!(is_zram_swap_activated::<MockSetupApi>().unwrap());
-}
-
-#[test]
-fn parse_zram_spec_invalid() {
- assert!(parse_size_spec_with_page_info("", DEFAULT_PAGE_SIZE, DEFAULT_PAGE_COUNT).is_err());
- assert!(
- parse_size_spec_with_page_info("not_int%", DEFAULT_PAGE_SIZE, DEFAULT_PAGE_COUNT).is_err()
- );
- assert!(
- parse_size_spec_with_page_info("not_int", DEFAULT_PAGE_SIZE, DEFAULT_PAGE_COUNT).is_err()
- );
-}
-
-#[test]
-fn parse_zram_spec_percentage_out_of_range() {
- assert!(parse_size_spec_with_page_info("0%", DEFAULT_PAGE_SIZE, DEFAULT_PAGE_COUNT).is_err());
- assert!(parse_size_spec_with_page_info("501%", DEFAULT_PAGE_SIZE, DEFAULT_PAGE_COUNT).is_err());
-}
-
-#[test]
-fn parse_zram_spec_percentage() {
- assert_eq!(parse_size_spec_with_page_info("33%", 4096, 5).unwrap(), 4096);
- assert_eq!(parse_size_spec_with_page_info("50%", 4096, 5).unwrap(), 8192);
- assert_eq!(parse_size_spec_with_page_info("100%", 4096, 5).unwrap(), 20480);
- assert_eq!(parse_size_spec_with_page_info("200%", 4096, 5).unwrap(), 40960);
- assert_eq!(parse_size_spec_with_page_info("100%", 4096, 3995500).unwrap(), 16365568000);
-}
-
-#[test]
-fn parse_zram_spec_bytes() {
- assert_eq!(
- parse_size_spec_with_page_info("1234567", DEFAULT_PAGE_SIZE, DEFAULT_PAGE_COUNT).unwrap(),
- 1234567
- );
-}
-
-#[test]
-fn activate_success() {
- let mock = MockContext::new();
- let zram_size = 123456;
- let mut seq = Sequence::new();
- mock.write_disksize
- .expect()
- .with(eq("123456"))
- .times(1)
- .returning(|_| Ok(()))
- .in_sequence(&mut seq);
- mock.mkswap
- .expect()
- .with(eq(ZRAM_DEVICE_PATH))
- .times(1)
- .returning(|_| Ok(success_command_output()))
- .in_sequence(&mut seq);
- mock.swapon
- .expect()
- .with(eq(std::ffi::CString::new(ZRAM_DEVICE_PATH).unwrap()))
- .times(1)
- .returning(|_| Ok(()))
- .in_sequence(&mut seq);
-
- assert!(activate_zram::<MockSysfsZramApi, MockSetupApi>(zram_size).is_ok());
-}
-
-#[test]
-fn activate_failed_update_size() {
- let mock = MockContext::new();
- mock.write_disksize.expect().returning(|_| Err(std::io::Error::other("error")));
-
- assert!(matches!(
- activate_zram::<MockSysfsZramApi, MockSetupApi>(DEFAULT_ZRAM_SIZE),
- Err(ZramActivationError::UpdateZramDiskSize(_))
- ));
-}
-
-#[test]
-fn activate_failed_mkswap() {
- let mock = MockContext::new();
- mock.write_disksize.expect().returning(|_| Ok(()));
- mock.mkswap.expect().returning(|_| Ok(failure_command_output()));
-
- assert!(matches!(
- activate_zram::<MockSysfsZramApi, MockSetupApi>(DEFAULT_ZRAM_SIZE),
- Err(ZramActivationError::MkSwap(_))
- ));
-}
-
-#[test]
-fn activate_failed_swapon() {
- let mock = MockContext::new();
- mock.write_disksize.expect().returning(|_| Ok(()));
- mock.mkswap.expect().returning(|_| Ok(success_command_output()));
- mock.swapon.expect().returning(|_| Err(std::io::Error::other("error")));
-
- assert!(matches!(
- activate_zram::<MockSysfsZramApi, MockSetupApi>(DEFAULT_ZRAM_SIZE),
- Err(ZramActivationError::SwapOn(_))
- ));
-}