diff --git a/health/storage/1.0/default/Android.bp b/health/storage/1.0/default/Android.bp new file mode 100644 index 0000000000..4723443cd7 --- /dev/null +++ b/health/storage/1.0/default/Android.bp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2018 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. + */ + +cc_binary { + name: "android.hardware.health.storage@1.0-service", + vendor: true, + defaults: ["hidl_defaults"], + relative_install_path: "hw", + init_rc: ["android.hardware.health.storage@1.0-service.rc"], + srcs: [ + "Storage.cpp", + "service.cpp", + ], + + cflags: [ + "-Wall", + "-Werror", + ], + + shared_libs: [ + "libbase", + "libhidlbase", + "libhidltransport", + "libutils", + "android.hardware.health.storage@1.0", + ], + + static_libs: [ + "libfstab", + ], + + vintf_fragments: [ + "manifest_android.hardware.health.storage@1.0.xml", + ], +} diff --git a/health/storage/1.0/default/Storage.cpp b/health/storage/1.0/default/Storage.cpp new file mode 100644 index 0000000000..2e53c50899 --- /dev/null +++ b/health/storage/1.0/default/Storage.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2018 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 "Storage.h" + +#include + +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace health { +namespace storage { +namespace V1_0 { +namespace implementation { + +using base::ReadFileToString; +using base::Timer; +using base::Trim; +using base::WriteStringToFd; +using base::WriteStringToFile; + +std::string getGarbageCollectPath() { + std::unique_ptr fstab(fs_mgr_read_fstab_default(), + fs_mgr_free_fstab); + struct fstab_rec* rec = NULL; + + for (int i = 0; i < fstab->num_entries; i++) { + if (fs_mgr_has_sysfs_path(&fstab->recs[i])) { + rec = &fstab->recs[i]; + break; + } + } + if (!rec) { + return ""; + } + + std::string path; + path.append(rec->sysfs_path); + path = path + "/manual_gc"; + + return path; +} + +Return Storage::garbageCollect(uint64_t timeoutSeconds, + const sp& cb) { + Result result = Result::SUCCESS; + std::string path = getGarbageCollectPath(); + + if (path.empty()) { + LOG(WARNING) << "Cannot find Dev GC path"; + result = Result::UNKNOWN_ERROR; + } else { + Timer timer; + LOG(INFO) << "Start Dev GC on " << path; + while (1) { + std::string require; + if (!ReadFileToString(path, &require)) { + PLOG(WARNING) << "Reading manual_gc failed in " << path; + result = Result::IO_ERROR; + break; + } + require = Trim(require); + if (require == "" || require == "off" || require == "disabled") { + LOG(DEBUG) << "No more to do Dev GC"; + break; + } + LOG(DEBUG) << "Trigger Dev GC on " << path; + if (!WriteStringToFile("1", path)) { + PLOG(WARNING) << "Start Dev GC failed on " << path; + result = Result::IO_ERROR; + break; + } + if (timer.duration() >= std::chrono::seconds(timeoutSeconds)) { + LOG(WARNING) << "Dev GC timeout"; + // Timeout is not treated as an error. Try next time. + break; + } + sleep(2); + } + LOG(INFO) << "Stop Dev GC on " << path; + if (!WriteStringToFile("0", path)) { + PLOG(WARNING) << "Stop Dev GC failed on " << path; + result = Result::IO_ERROR; + } + } + + if (cb != nullptr) { + auto ret = cb->onFinish(result); + if (!ret.isOk()) { + LOG(WARNING) << "Cannot return result to callback: " << ret.description(); + } + } + return Void(); +} + +Return Storage::debug(const hidl_handle& handle, const hidl_vec&) { + if (handle == nullptr || handle->numFds < 1) { + return Void(); + } + + int fd = handle->data[0]; + std::stringstream output; + + std::string path = getGarbageCollectPath(); + if (path.empty()) { + output << "Cannot find Dev GC path"; + } else { + std::string require; + + if (ReadFileToString(path, &require)) { + output << path << ":" << require << std::endl; + } + + if (WriteStringToFile("0", path)) { + output << "stop success" << std::endl; + } + } + + if (!WriteStringToFd(output.str(), fd)) { + PLOG(WARNING) << "debug: cannot write to fd"; + } + + fsync(fd); + + return Void(); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace storage +} // namespace health +} // namespace hardware +} // namespace android diff --git a/health/storage/1.0/default/Storage.h b/health/storage/1.0/default/Storage.h new file mode 100644 index 0000000000..8c57ddb776 --- /dev/null +++ b/health/storage/1.0/default/Storage.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2018 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. + */ + +#ifndef ANDROID_HARDWARE_HEALTH_FILESYSTEM_V1_0_FILESYSTEM_H +#define ANDROID_HARDWARE_HEALTH_FILESYSTEM_V1_0_FILESYSTEM_H + +#include +#include + +namespace android { +namespace hardware { +namespace health { +namespace storage { +namespace V1_0 { +namespace implementation { + +using ::android::sp; +using ::android::hardware::hidl_handle; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; + +struct Storage : public IStorage { + Return garbageCollect(uint64_t timeoutSeconds, + const sp& cb) override; + Return debug(const hidl_handle& handle, const hidl_vec&) override; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace storage +} // namespace health +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_HEALTH_FILESYSTEM_V1_0_FILESYSTEM_H diff --git a/health/storage/1.0/default/android.hardware.health.storage@1.0-service.rc b/health/storage/1.0/default/android.hardware.health.storage@1.0-service.rc new file mode 100644 index 0000000000..c6a142528b --- /dev/null +++ b/health/storage/1.0/default/android.hardware.health.storage@1.0-service.rc @@ -0,0 +1,5 @@ +service vendor.health-storage-hal-1-0 /vendor/bin/hw/android.hardware.health.storage@1.0-service + interface android.hardware.health.storage@1.0::IStorage default + class hal + user system + group system diff --git a/health/storage/1.0/default/manifest_android.hardware.health.storage@1.0.xml b/health/storage/1.0/default/manifest_android.hardware.health.storage@1.0.xml new file mode 100644 index 0000000000..ffe854eaef --- /dev/null +++ b/health/storage/1.0/default/manifest_android.hardware.health.storage@1.0.xml @@ -0,0 +1,11 @@ + + + android.hardware.health.storage + hwbinder + 1.0 + + IStorage + default + + + diff --git a/health/storage/1.0/default/service.cpp b/health/storage/1.0/default/service.cpp new file mode 100644 index 0000000000..a945033839 --- /dev/null +++ b/health/storage/1.0/default/service.cpp @@ -0,0 +1,41 @@ +/* + * Copyright 2018 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 +#include "Storage.h" + +using android::OK; +using android::sp; +using android::status_t; +using android::UNKNOWN_ERROR; +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using android::hardware::health::storage::V1_0::IStorage; +using android::hardware::health::storage::V1_0::implementation::Storage; + +int main() { + configureRpcThreadpool(1, true); + + sp service = new Storage(); + status_t result = service->registerAsService(); + + if (result != OK) { + return result; + } + + joinRpcThreadpool(); + return UNKNOWN_ERROR; +}