android sd 挂载流程_android sdcard挂载/卸载方法

vold有一个调试的功能,叫做vdc,对应源码中的vdc.c或vdc.cpp。

如果研究vdc的源码会发现安卓的变迁史。

Android 4.2-5.1

checkout分支jb-release。

vold支持的命令在CommandListener中定义。

CommandListener::VolumeCmd::VolumeCmd() :

VoldCommand("volume") {

}

int CommandListener::VolumeCmd::runCommand(SocketClient *cli,

int argc, char **argv) {

dumpArgs(argc, argv, -1);

if (argc < 2) {

cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);

return 0;

}

VolumeManager *vm = VolumeManager::Instance();

int rc = 0;

if (!strcmp(argv[1], "list")) {

return vm->listVolumes(cli);

} else if (!strcmp(argv[1], "debug")) {

if (argc != 3 || (argc == 3 && (strcmp(argv[2], "off") && strcmp(argv[2], "on")))) {

cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume debug ", false);

return 0;

}

vm->setDebug(!strcmp(argv[2], "on") ? true : false);

} else if (!strcmp(argv[1], "mount")) {

if (argc != 3) {

cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume mount ", false);

return 0;

}

rc = vm->mountVolume(argv[2]);

} else if (!strcmp(argv[1], "unmount")) {

if (argc < 3 || argc > 4 ||

((argc == 4 && strcmp(argv[3], "force")) &&

(argc == 4 && strcmp(argv[3], "force_and_revert")))) {

cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume unmount [force|force_and_revert]", false);

return 0;

}

bool force = false;

bool revert = false;

if (argc >= 4 && !strcmp(argv[3], "force")) {

force = true;

} else if (argc >= 4 && !strcmp(argv[3], "force_and_revert")) {

force = true;

revert = true;

}

rc = vm->unmountVolume(argv[2], force, revert);

//...省略一些无用的 } else {

cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume cmd", false);

}

if (!rc) {

cli->sendMsg(ResponseCode::CommandOkay, "volume operation succeeded", false);

} else {

int erno = errno;

rc = ResponseCode::convertFromErrno();

cli->sendMsg(rc, "volume operation failed", true);

}

return 0;

}

根据上面的代码可以整理vdc的存储命令方法:

1、vdc volume list

用于查看volume。

2、vdc volume mount sdcard

用于挂载sdcard,这里的sdcard是最难确定的。

3、vdc volume unmount sdcard force

用于卸载sdcard,这里的sdcard是最难确定的。

Android 6.0/7.0/8.0

git checkout marshmallow-release

根据commit来看,android 6.0对vold的volume命令进行了大幅重写,reset和shutdown都是这时候加入的。

CommandListener::VolumeCmd::VolumeCmd() :

VoldCommand("volume") {

}

int CommandListener::VolumeCmd::runCommand(SocketClient *cli,

int argc, char **argv) {

dumpArgs(argc, argv, -1);

if (argc < 2) {

cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);

return 0;

}

VolumeManager *vm = VolumeManager::Instance();

std::lock_guard<:mutex> lock(vm->getLock());

// TODO: tease out methods not directly related to volumes

std::string cmd(argv[1]);

if (cmd == "reset") {

return sendGenericOkFail(cli, vm->reset());

} else if (cmd == "shutdown") {

return sendGenericOkFail(cli, vm->shutdown());

} else if (cmd == "debug") {

return sendGenericOkFail(cli, vm->setDebug(true));

} else if (cmd == "partition" && argc > 3) {

// partition [diskId] [public|private|mixed] [ratio] std::string id(argv[2]);

auto disk = vm->findDisk(id);

if (disk == nullptr) {

return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown disk", false);

}

std::string type(argv[3]);

if (type == "public") {

return sendGenericOkFail(cli, disk->partitionPublic());

} else if (type == "private") {

return sendGenericOkFail(cli, disk->partitionPrivate());

} else if (type == "mixed") {

if (argc < 4) {

return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);

}

int frac = atoi(argv[4]);

return sendGenericOkFail(cli, disk->partitionMixed(frac));

} else {

return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);

}

} else if (cmd == "mkdirs" && argc > 2) {

// mkdirs [path] return sendGenericOkFail(cli, vm->mkdirs(argv[2]));

} else if (cmd == "user_added" && argc > 3) {

// user_added [user] [serial] return sendGenericOkFail(cli, vm->onUserAdded(atoi(argv[2]), atoi(argv[3])));

} else if (cmd == "user_removed" && argc > 2) {

// user_removed [user] return sendGenericOkFail(cli, vm->onUserRemoved(atoi(argv[2])));

} else if (cmd == "user_started" && argc > 2) {

// user_started [user] return sendGenericOkFail(cli, vm->onUserStarted(atoi(argv[2])));

} else if (cmd == "user_stopped" && argc > 2) {

// user_stopped [user] return sendGenericOkFail(cli, vm->onUserStopped(atoi(argv[2])));

} else if (cmd == "mount" && argc > 2) {

// mount [volId] [flags] [user] std::string id(argv[2]);

auto vol = vm->findVolume(id);

if (vol == nullptr) {

return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);

}

int mountFlags = (argc > 3) ? atoi(argv[3]) : 0;

userid_t mountUserId = (argc > 4) ? atoi(argv[4]) : -1;

vol->setMountFlags(mountFlags);

vol->setMountUserId(mountUserId);

int res = vol->mount();

if (mountFlags & android::vold::VolumeBase::MountFlags::kPrimary) {

vm->setPrimary(vol);

}

return sendGenericOkFail(cli, res);

} else if (cmd == "unmount" && argc > 2) {

// unmount [volId] std::string id(argv[2]);

auto vol = vm->findVolume(id);

if (vol == nullptr) {

return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);

}

return sendGenericOkFail(cli, vol->unmount());

} else if (cmd == "format" && argc > 3) {

// format [volId] [fsType|auto] std::string id(argv[2]);

std::string fsType(argv[3]);

auto vol = vm->findVolume(id);

if (vol == nullptr) {

return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);

}

return sendGenericOkFail(cli, vol->format(fsType));

} else if (cmd == "move_storage" && argc > 3) {

// move_storage [fromVolId] [toVolId] auto fromVol = vm->findVolume(std::string(argv[2]));

auto toVol = vm->findVolume(std::string(argv[3]));

if (fromVol == nullptr || toVol == nullptr) {

return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);

}

(new android::vold::MoveTask(fromVol, toVol))->start();

return sendGenericOkFail(cli, 0);

} else if (cmd == "benchmark" && argc > 2) {

// benchmark [volId] std::string id(argv[2]);

nsecs_t res = vm->benchmarkPrivate(id);

return cli->sendMsg(ResponseCode::CommandOkay,

android::base::StringPrintf("%" PRId64, res).c_str(), false);

} else if (cmd == "forget_partition" && argc > 2) {

// forget_partition [partGuid] std::string partGuid(argv[2]);

return sendGenericOkFail(cli, vm->forgetPartition(partGuid));

} else if (cmd == "remount_uid" && argc > 3) {

// remount_uid [uid] [none|default|read|write] uid_t uid = atoi(argv[2]);

std::string mode(argv[3]);

return sendGenericOkFail(cli, vm->remountUid(uid, mode));

}

return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);

}

可以发现list功能不见了,但是mount和unmount功能还是在的,其中unmount的功能还简化了,不需要force了。

但是测试vdc volume unmount sdcard却不行。

通过研究源码,发现sdcard现在用的标签名为emulated。

EmulatedVolume::EmulatedVolume(const std::string& rawPath) :

VolumeBase(Type::kEmulated), mFusePid(0) {

setId("emulated");

mRawPath = rawPath;

mLabel = "emulated";

}

用emulated尝试,可以。所以在Android 6.0中,挂载和卸载方法为:

挂载

vdc volume mount emulated

卸载

vdc volume unmount emulated

Android 9.0/10.0

取消了CommandListener,命令直接看vdc.cpp

} else if (args[0] == "volume" && args[1] == "shutdown") {

checkStatus(vold->shutdown());

额,只剩卸载sdcard命令了,挂载哪里去了。。

Android 11.0

在最新版中取消了CommandListener,命令直接看vdc.cpp

} else if (args[0] == "volume" && args[1] == "shutdown") {

checkStatus(args, vold->shutdown());

} else if (args[0] == "volume" && args[1] == "reset") {

checkStatus(args, vold->reset());

可以看出最新版只留了两个命令shutdown和reset了。相比9.0把reset加回来了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值