blob: 374beb640db270a25afeb5f620f6487a1e4645b7 [file] [log] [blame]
// 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.
//! mmd is a native daemon managing memory task:
//!
//! * zram
mod properties;
mod service;
use std::time::Duration;
use binder::BinderFeatures;
use log::error;
use log::info;
use log::warn;
use log::LevelFilter;
use mmd::zram::recompression::is_zram_recompression_activated;
use mmd::zram::recompression::ZramRecompression;
use mmd::zram::stats::load_total_zram_size;
use mmd::zram::writeback::is_zram_writeback_activated;
use mmd::zram::writeback::ZramWriteback;
use mmd::zram::SysfsZramApiImpl;
use mmd_aidl_interface::aidl::android::os::IMmd::BnMmd;
use rustutils::system_properties;
use crate::properties::BoolProp;
// In Android zram writeback file is always "/data/per_boot/zram_swap".
const ZRAM_WRITEBACK_FILE_PATH: &str = "/data/per_boot/zram_swap";
fn main() {
// "mmd --set-property" command copies the AConfig flag to "mmd.enabled_aconfig" system
// property as either "true" or "false".
// This is the workaround for init language which does not support AConfig integration.
// TODO: b/380365026 - Remove "--set-property" command when init language supports AConfig
// integration.
if std::env::args().nth(1).map(|s| &s == "--set-property").unwrap_or(false) {
let value = if mmd_flags::mmd_enabled() { "true" } else { "false" };
system_properties::write("mmd.enabled_aconfig", value).expect("set system property");
return;
}
let _init_success = logger::init(
logger::Config::default().with_tag_on_device("mmd").with_max_level(LevelFilter::Trace),
);
if !mmd_flags::mmd_enabled() {
// It is mmd.rc responsibility to start mmd process only if AConfig flag is enabled.
// This is a safe guard to ensure that mmd runs only when AConfig flag is enabled.
warn!("mmd is disabled");
return;
}
// 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,
Err(e) => {
error!("failed to load total zram size: {e:?}");
std::process::exit(1);
}
};
let zram_writeback = if BoolProp::ZramWritebackEnabled.get(true) {
match load_zram_writeback_disk_size() {
Ok(Some(zram_writeback_disk_size)) => {
info!("zram writeback is activated");
Some(ZramWriteback::new(total_zram_size, zram_writeback_disk_size))
}
Ok(None) => {
info!("zram writeback is not activated");
None
}
Err(e) => {
error!("failed to load zram writeback file size: {e:?}");
None
}
}
} else {
info!("zram writeback is disabled");
None
};
let zram_recompression = if BoolProp::ZramRecompressionEnabled.get(true) {
match is_zram_recompression_activated::<SysfsZramApiImpl>() {
Ok(is_activated) => {
if is_activated {
info!("zram recompression is activated");
Some(ZramRecompression::new())
} else {
info!("zram recompression is not activated");
None
}
}
Err(e) => {
error!("failed to check zram recompression is activated: {e:?}");
None
}
}
} else {
info!("zram recompression is disabled");
None
};
let mmd_service = service::MmdService::new(zram_writeback, zram_recompression);
let mmd_service_binder = BnMmd::new_binder(mmd_service, BinderFeatures::default());
binder::add_service("mmd", mmd_service_binder.as_binder()).expect("register service");
info!("mmd started");
binder::ProcessState::join_thread_pool();
}
/// Loads the zram writeback disk size.
///
/// If zram writeback is not enabled, this returns `Ok(None)`.
pub fn load_zram_writeback_disk_size() -> std::io::Result<Option<u64>> {
if is_zram_writeback_activated::<SysfsZramApiImpl>()? {
Ok(Some(std::fs::metadata(ZRAM_WRITEBACK_FILE_PATH)?.len()))
} else {
Ok(None)
}
}