美文网首页
一个关机耗时时间久的问题处理

一个关机耗时时间久的问题处理

作者: Nothing_655f | 来源:发表于2020-09-11 18:25 被阅读0次

Android平台:Android7.1

先从shutdown thread 入手,出现两个时间比较久

看这份打印 “开机慢打印 serial_com5_2020-01-11_11-43-06.log”
从这行打印开始

 [2020/1/11 13:44:43] [  147.932572@3] input input1: key 116 up
01-01 08:02:31.332  4233  5219 I ShutdownThread: Sending shutdown broadcast...
01-01 08:02:32.024  4233  5219 I ShutdownThread: Shutting down activity manager...
01-01 08:02:32.185  4233  5219 I ShutdownThread: Shutting down package manager...
01-01 08:02:32.200  4233  5226 W ShutdownThread: Disabling Bluetooth...
01-01 08:02:32.200  4233  5226 I ShutdownThread: Waiting for NFC, Bluetooth and Radio...
01-01 08:02:35.711  4233  5226 I ShutdownThread: Bluetooth turned off.
01-01 08:02:35.711  4233  5226 I ShutdownThread: NFC, Radio and Bluetooth shutdown complete.
01-01 08:02:35.713  4233  5219 I ShutdownThread: Shutting down MountService
01-01 08:02:42.033  4233  4268 W ShutdownThread: Result code 0 from MountService.shutdown
01-01 . 08:02:42.539  4233  5219 I ShutdownThread: Performing low-level shutdown...

这里面两个时间比较异常,是蓝牙关闭和mount serveice关机时间

蓝牙关闭函数这个时间随便是开了个线程在跑,但其实是阻塞的,注释将其改为非阻塞

+        /* My Patch Start */
+        /*
         try {
             t.join(timeout);
         } catch (InterruptedException ex) {
@@ -661,6 +681,8 @@ public final class ShutdownThread extends Thread {
         if (!done[0]) {
             Log.w(TAG, "Timed out waiting for NFC, Radio and Bluetooth shutdown.");
         }
+        */
+        /* My Patch End */

这样子蓝牙关闭时间是和mountservice shutdown 并行的,然后在mountservice shutdown后判断蓝牙是否关闭完再看是否阻塞等待
在Shutdown Thread 中

@@ -517,6 +520,14 @@ public final class ShutdownThread extends Thread {
        // 在mountservice shutdown后判断蓝牙是否关闭完
+        /* My Patch Start */
+        int shutdownRadiosDelay = 0;
+        while (!mShutdownRadiosDone && shutdownRadiosDelay < MAX_RADIO_WAIT_TIME) {
+            SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
+            shutdownRadiosDelay += PHONE_STATE_POLL_SLEEP_MSEC;
+        }
+        /* My Patch End */
+
         if (mRebootHasProgressBar) {
             sInstance.setRebootProgress(MOUNT_SERVICE_STOP_PERCENT, null);
 
@@ -650,10 +661,19 @@ public final class ShutdownThread extends Thread {
 
                     delay = endTime - SystemClock.elapsedRealtime();
                 }
    //蓝牙是否关闭置位
+                /* My Patch Start */
+                /* while loop timeout to shutdown */
+                mShutdownRadiosDone = true;
+                if (!done[0]) {
+                    Log.w(TAG, "Timed out waiting for NFC, Radio and Bluetooth shutdown.");
+                }
+                /* My Patch End */
             }
         };

第二个时间是mountservice关闭时间比较久,通过flow trace 到 vold这边做unmount的时候耗时久,下面是加的一些打印 diff



    tmp log debug

diff --git a/Disk.cpp b/Disk.cpp
index 7b0c149..d0cbe59 100644
--- a/Disk.cpp
+++ b/Disk.cpp
@@ -233,10 +233,13 @@ void Disk::createPrivateVolume(dev_t device, const std::string& partGuid) {
 }
 
 void Disk::destroyAllVolumes() {
+   LOG(ERROR) << "Horace Enter " << __FUNCTION__;
     for (auto vol : mVolumes) {
+       LOG(ERROR) << "Horace Enter " << __FUNCTION__ << vol;
         vol->destroy();
     }
     mVolumes.clear();
+   LOG(ERROR) << "Horace Leave " << __FUNCTION__;
 }
 
 status_t Disk::readMetadata() {
diff --git a/EmulatedVolume.cpp b/EmulatedVolume.cpp
index 581c322..34b5a29 100644
--- a/EmulatedVolume.cpp
+++ b/EmulatedVolume.cpp
@@ -111,7 +111,9 @@ status_t EmulatedVolume::doUnmount() {
     // the FUSE process first, most file system operations will return
     // ENOTCONN until the unmount completes. This is an exotic and unusual
     // error code and might cause broken behaviour in applications.
+    LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
     KillProcessesUsingPath(getPath());
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
     ForceUnmount(mFuseDefault);
     ForceUnmount(mFuseRead);
     ForceUnmount(mFuseWrite);
diff --git a/PrivateVolume.cpp b/PrivateVolume.cpp
index e5809fb..b9f7102 100644
--- a/PrivateVolume.cpp
+++ b/PrivateVolume.cpp
@@ -87,6 +87,7 @@ status_t PrivateVolume::doDestroy() {
     if (cryptfs_revert_ext_volume(getId().c_str())) {
         LOG(ERROR) << getId() << " failed to revert cryptfs";
     }
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
     return DestroyDeviceNode(mRawDevPath);
 }
 
@@ -163,11 +164,14 @@ status_t PrivateVolume::doMount() {
 }
 
 status_t PrivateVolume::doUnmount() {
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
     ForceUnmount(mPath);
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     if (TEMP_FAILURE_RETRY(rmdir(mPath.c_str()))) {
         PLOG(ERROR) << getId() << " failed to rmdir mount point " << mPath;
     }
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     return OK;
 }
diff --git a/PublicVolume.cpp b/PublicVolume.cpp
index d4dfc8c..0aa7168 100644
--- a/PublicVolume.cpp
+++ b/PublicVolume.cpp
@@ -114,6 +114,7 @@ status_t PublicVolume::doCreate() {
 
 status_t PublicVolume::doDestroy() {
     if (mJustPhysicalDev) return 0;
+   LOG(ERROR) << "Horace Enter " << __FUNCTION__ << __LINE__;
     return DestroyDeviceNode(mDevPath);
 }
 
@@ -329,6 +330,7 @@ status_t PublicVolume::doUnmount() {
     // ENOTCONN until the unmount completes. This is an exotic and unusual
     // error code and might cause broken behaviour in applications.
     KillProcessesUsingPath(getPath());
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
 #ifdef HAS_VIRTUAL_CDROM
     std::string stableName = getId();
@@ -346,22 +348,26 @@ status_t PublicVolume::doUnmount() {
     ForceUnmount(mFuseRead);
     ForceUnmount(mFuseWrite);
     ForceUnmount(mRawPath);
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     if (mFusePid > 0) {
         kill(mFusePid, SIGTERM);
         TEMP_FAILURE_RETRY(waitpid(mFusePid, nullptr, 0));
         mFusePid = 0;
     }
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     rmdir(mFuseDefault.c_str());
     rmdir(mFuseRead.c_str());
     rmdir(mFuseWrite.c_str());
     rmdir(mRawPath.c_str());
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     mFuseDefault.clear();
     mFuseRead.clear();
     mFuseWrite.clear();
     mRawPath.clear();
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     return OK;
 }
diff --git a/Utils.cpp b/Utils.cpp
index 260e77e..2c58d73 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -120,27 +120,33 @@ status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid)
 
 status_t ForceUnmount(const std::string& path) {
     const char* cpath = path.c_str();
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__ << path;
     if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
         return OK;
     }
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
     // Apps might still be handling eject request, so wait before
     // we start sending signals
     sleep(5);
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     Process::killProcessesWithOpenFiles(cpath, SIGINT);
     sleep(5);
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
     if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
         return OK;
     }
 
     Process::killProcessesWithOpenFiles(cpath, SIGTERM);
     sleep(5);
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
     if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
         return OK;
     }
 
     Process::killProcessesWithOpenFiles(cpath, SIGKILL);
     sleep(5);
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
     if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
         return OK;
     }
@@ -150,20 +156,24 @@ status_t ForceUnmount(const std::string& path) {
 
 status_t KillProcessesUsingPath(const std::string& path) {
     const char* cpath = path.c_str();
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__ << path;
     if (Process::killProcessesWithOpenFiles(cpath, SIGINT) == 0) {
         return OK;
     }
     sleep(5);
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     if (Process::killProcessesWithOpenFiles(cpath, SIGTERM) == 0) {
         return OK;
     }
     sleep(5);
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     if (Process::killProcessesWithOpenFiles(cpath, SIGKILL) == 0) {
         return OK;
     }
     sleep(5);
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     // Send SIGKILL a second time to determine if we've
     // actually killed everyone with open files
diff --git a/VolumeBase.cpp b/VolumeBase.cpp
index ea4d372..0bb99d6 100644
--- a/VolumeBase.cpp
+++ b/VolumeBase.cpp
@@ -177,13 +177,17 @@ status_t VolumeBase::doCreate() {
 
 status_t VolumeBase::destroy() {
     CHECK(mCreated);
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     if (mState == State::kMounted) {
+
+       LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
         unmount();
         setState(State::kBadRemoval);
     } else {
         setState(State::kRemoved);
     }
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     notifyEvent(ResponseCode::VolumeDestroyed);
     status_t res = doDestroy();
@@ -217,6 +221,7 @@ status_t VolumeBase::unmount() {
         LOG(WARNING) << getId() << " unmount requires state mounted";
         return -EBUSY;
     }
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     setState(State::kEjecting);
     for (auto vol : mVolumes) {
@@ -226,8 +231,10 @@ status_t VolumeBase::unmount() {
         }
     }
     mVolumes.clear();
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
 
     status_t res = doUnmount();
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
     setState(State::kUnmounted);
     return res;
 }
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 746551f..3948772 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -210,7 +210,7 @@ VolumeManager *VolumeManager::Instance() {
 }
 
 VolumeManager::VolumeManager() {
-    mDebug = false;
+    mDebug = true;
     mActiveContainers = new AsecIdCollection();
     mBroadcaster = NULL;
     mUmsSharingCount = 0;
@@ -648,11 +648,14 @@ int VolumeManager::reset() {
 }
 
 int VolumeManager::shutdown() {
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
     mInternalEmulated->destroy();
     for (auto disk : mDisks) {
+       LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
         disk->destroy();
     }
     mDisks.clear();
+   LOG(ERROR) << "Horace Enter " << __FILE__ << " " <<__FUNCTION__ << " " << __LINE__;
     return 0;
 }
 

在做unmount的时候有个sleep 5 s给应用做eject的延时,不过这个修改在An8 后有优化,这边是An7.1的代码,所以会有这个问题,从master上找对应修改导入过来即可

   - Various sleep(5) for vold shutdown can increase shutdown time a lot.
   - If it is shutting down, do not sleep at all. init will take care of
   active partitions if not unmounted.
   
   bug: 64143519
   Test: reboot and check logs from vold, check if "ShutdownThread: Shutdown wait timed out" happens.
   Change-Id: I7cb91427ad2205fe23a054d255caf7ffdfd9f6c3

diff --git a/Utils.cpp b/Utils.cpp
index 260e77e..6e1d4b8 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -17,6 +17,7 @@
#include "sehandle.h"
#include "Utils.h"
#include "Process.h"
+#include "VolumeManager.h"

#include <android-base/file.h>
#include <android-base/logging.h>
@@ -125,22 +126,22 @@ status_t ForceUnmount(const std::string& path) {
    }
    // Apps might still be handling eject request, so wait before
    // we start sending signals
-    sleep(5);
+    if (!VolumeManager::shutting_down) sleep(5);

    Process::killProcessesWithOpenFiles(cpath, SIGINT);
-    sleep(5);
+    if (!VolumeManager::shutting_down) sleep(5);
    if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
        return OK;
    }

    Process::killProcessesWithOpenFiles(cpath, SIGTERM);
-    sleep(5);
+    if (!VolumeManager::shutting_down) sleep(5);
    if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
        return OK;
    }

    Process::killProcessesWithOpenFiles(cpath, SIGKILL);
-    sleep(5);
+    if (!VolumeManager::shutting_down) sleep(5);
    if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
        return OK;
    }
@@ -153,18 +154,18 @@ status_t KillProcessesUsingPath(const std::string& path) {
    if (Process::killProcessesWithOpenFiles(cpath, SIGINT) == 0) {
        return OK;
    }
-    sleep(5);

+    if (!VolumeManager::shutting_down) sleep(5);
    if (Process::killProcessesWithOpenFiles(cpath, SIGTERM) == 0) {
        return OK;
    }
-    sleep(5);

+    if (!VolumeManager::shutting_down) sleep(5);
    if (Process::killProcessesWithOpenFiles(cpath, SIGKILL) == 0) {
        return OK;
    }
-    sleep(5);

+    if (!VolumeManager::shutting_down) sleep(5);
    // Send SIGKILL a second time to determine if we've
    // actually killed everyone with open files
    if (Process::killProcessesWithOpenFiles(cpath, SIGKILL) == 0) {
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 746551f..bb98e9a 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -94,6 +94,8 @@ const char *VolumeManager::ASECDIR           = "/mnt/asec";
 */
const char *VolumeManager::LOOPDIR           = "/mnt/obb";

+bool VolumeManager::shutting_down = false;
+
static const char* kUserMountPath = "/mnt/user";

static const unsigned int kMajorBlockMmc = 179;
@@ -648,11 +650,13 @@ int VolumeManager::reset() {
}

int VolumeManager::shutdown() {
+    shutting_down = true;
    mInternalEmulated->destroy();
    for (auto disk : mDisks) {
        disk->destroy();
    }
    mDisks.clear();
+    shutting_down = false;
    return 0;
}

diff --git a/VolumeManager.h b/VolumeManager.h
index 4f1e6cf..ffcb8d9 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -73,6 +73,9 @@ public:
    char *mLoopPath;
#endif

+    //TODO remove this with better solution, b/64143519
+    static bool shutting_down;
+
private:
    static VolumeManager *sInstance;

相关文章

  • 一个关机耗时时间久的问题处理

    Android平台:Android7.1 先从shutdown thread 入手,出现两个时间比较久 看这份打印...

  • centos在关机或开机时一直等待,提示A stop job i

    问题现象:在centos在关机或开机时一直等待,等待时间久,卡住时间久 解决方案一:通过systemd的设置项跳过...

  • 希望归来仍是少年

    手机这个这个东西太消耗时间了,决定以后5.之后关机,反正除了爸妈也没什么重要的电话

  • 奇妙的思维

    手机关机,每天只留一个小时处理工作。这听起来很舒服吧,事实上是带着恐慌的。关机的这段时间内你该如何分配时间,该去做...

  • Python-QApplication.processEvent

    作用是处理密集型耗时的事情,防止界面锁死 遇到的问题 要批量处理文件(大概几十个),界面处于长时间无相应的状态,但...

  • 一个尴尬的耗时处理

    文章来源:http://lexch.cn/2017/03/10/%E4%B8%80%E4%B8%AA%E5%B0%...

  • JAVA轻量级事件和任务调度框架EventTo

    很多时候在处理耗时问题的时候,我们不得不开一个线程来处理,但是在处理多个有序任务的时候,通常不能保证时序性。 因此...

  • day18

    一、线程 耗时操作放到主线程中的问题:耗时操作在主线程中,会阻塞线程多个耗时操作都放到一个线程里面,最终执行的时间...

  • day18-多线程

    一、线程 耗时操作放到主线程中的问题:耗时操作在主线程中,会阻塞线程多个耗时操作都放到一个线程里面,最终执行的时间...

  • 一种更简单的处理耗时任务的方式--IntentService

    开启处理耗时操作的方法--IntentService 一、概述 能解决的问题:当一个任务分为多个小任务,这些小任务...

网友评论

      本文标题:一个关机耗时时间久的问题处理

      本文链接:https://www.haomeiwen.com/subject/feubektx.html