- Emergency shutdown just marks the fs as clean while leaving fs
in the middle of any state. Do not use it anymore.
- Changed android_reboot to set sys.powerctl property so that
all shutdown can be done by init.
- Normal reboot sequence changed to
1. Terminate processes (give time to clean up). And wait for
completion based on ro.build.shutdown_timeout.
Default value (when not set) is changed to 3 secs. If it is 0, do not
terminate processes.
2. Kill all remaining services except critical services for shutdown.
3. Shutdown vold using "vdc volume shutdown"
4. umount all emulated partitions. If it fails, just detach.
Wait in step 5 can handle it.
5. Try umounting R/W block devices for up to max timeout.
If it fails, try DETACH.
If umount fails to complete before reboot, it can be detected when
system reboots.
6. Reboot
- Log shutdown time and umount stat to log so that it can be collected after reboot
- To umount emulated partitions, all pending writes inside kernel should
be completed.
- To umount /data partition, all emulated partitions on top of /data should
be umounted and all pending writes should be completed.
- umount retry will only wait up to timeout. If there are too many pending
writes, reboot will discard them and e2fsck after reboot will fix any file system
issues.
bug: 36004738
bug: 32246772
Test: many reboots combining reboot from UI and adb reboot. Check last_kmsg and
fs_stat after reboot.
Change-Id: I6e74d6c68a21e76e08cc0438573d1586fd9aaee2
83 lines
2.5 KiB
C++
83 lines
2.5 KiB
C++
/*
|
|
* Copyright (C) 2010 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 _INIT_UTIL_H_
|
|
#define _INIT_UTIL_H_
|
|
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
|
|
#include <chrono>
|
|
#include <functional>
|
|
#include <ostream>
|
|
#include <string>
|
|
|
|
#define COLDBOOT_DONE "/dev/.coldboot_done"
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
int create_socket(const char *name, int type, mode_t perm,
|
|
uid_t uid, gid_t gid, const char *socketcon);
|
|
|
|
bool read_file(const char* path, std::string* content);
|
|
bool write_file(const char* path, const char* content);
|
|
|
|
// A std::chrono clock based on CLOCK_BOOTTIME.
|
|
class boot_clock {
|
|
public:
|
|
typedef std::chrono::nanoseconds duration;
|
|
typedef std::chrono::time_point<boot_clock, duration> time_point;
|
|
static constexpr bool is_steady = true;
|
|
|
|
static time_point now();
|
|
};
|
|
|
|
class Timer {
|
|
public:
|
|
Timer() : start_(boot_clock::now()) {
|
|
}
|
|
|
|
double duration_s() const {
|
|
typedef std::chrono::duration<double> double_duration;
|
|
return std::chrono::duration_cast<double_duration>(boot_clock::now() - start_).count();
|
|
}
|
|
|
|
int64_t duration_ms() const {
|
|
return std::chrono::duration_cast<std::chrono::milliseconds>(boot_clock::now() - start_).count();
|
|
}
|
|
|
|
private:
|
|
boot_clock::time_point start_;
|
|
};
|
|
|
|
std::ostream& operator<<(std::ostream& os, const Timer& t);
|
|
|
|
unsigned int decode_uid(const char *s);
|
|
|
|
int mkdir_recursive(const char *pathname, mode_t mode);
|
|
void sanitize(char *p);
|
|
int wait_for_file(const char *filename, std::chrono::nanoseconds timeout);
|
|
void import_kernel_cmdline(bool in_qemu,
|
|
const std::function<void(const std::string&, const std::string&, bool)>&);
|
|
int make_dir(const char *path, mode_t mode);
|
|
int restorecon(const char *pathname, int flags = 0);
|
|
std::string bytes_to_hex(const uint8_t *bytes, size_t bytes_len);
|
|
bool is_dir(const char* pathname);
|
|
bool expand_props(const std::string& src, std::string* dst);
|
|
|
|
void panic() __attribute__((__noreturn__));
|
|
|
|
#endif
|