CommandListener.cpp revision bd3038df74ace540d46c530a11e3145f922e1b42
1f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat/*
2f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Copyright (C) 2008 The Android Open Source Project
3f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *
4f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Licensed under the Apache License, Version 2.0 (the "License");
5f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * you may not use this file except in compliance with the License.
6f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * You may obtain a copy of the License at
7f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *
8f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *      http://www.apache.org/licenses/LICENSE-2.0
9f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *
10f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Unless required by applicable law or agreed to in writing, software
11f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * distributed under the License is distributed on an "AS IS" BASIS,
12f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * See the License for the specific language governing permissions and
14f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * limitations under the License.
15f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat */
16f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
17f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <stdlib.h>
18f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <sys/socket.h>
19a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat#include <sys/types.h>
20f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <netinet/in.h>
21f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <arpa/inet.h>
22a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat#include <dirent.h>
23f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <errno.h>
242350c44ff39b4cb2940893964a05f778fc80a436San Mehat#include <fcntl.h>
257929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash#include <fs_mgr.h>
26d1104f75a736210a95ba890473d78e8dfc8b8915Yabin Cui#include <stdio.h>
2737dcda68d334f70e1f7f69a9817def65fe3ee717Olivier Bailly#include <string.h>
285a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#include <stdint.h>
295a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#include <inttypes.h>
30f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
31d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat#define LOG_TAG "VoldCmdListener"
325a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
335a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#include <base/stringprintf.h>
345a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#include <cutils/fs.h>
35f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <cutils/log.h>
36f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
37f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <sysutils/SocketClient.h>
383ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall#include <private/android_filesystem_config.h>
39f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
40f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "CommandListener.h"
41f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "VolumeManager.h"
4236801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey#include "VolumeBase.h"
43a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include "ResponseCode.h"
44586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat#include "Process.h"
45d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat#include "Loop.h"
46d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat#include "Devmapper.h"
478f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include "cryptfs.h"
48b87937cdea689594a293979b30b13054e7455deeKen Sumrall#include "fstrim.h"
491d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey#include "MoveTask.h"
50f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
513fd60b428202a0f5f324fccc67c0c0402b9131baDianne Hackborn#define DUMP_ARGS 0
523fd60b428202a0f5f324fccc67c0c0402b9131baDianne Hackborn
53f1b736bc5605e92e917ab27f5abf3ba839be2270San MehatCommandListener::CommandListener() :
54149aa3eb65a8cb878781206b1476aae110e0e1fdRobert Greenwalt                 FrameworkListener("vold", true) {
55d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    registerCmd(new DumpCmd());
56eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    registerCmd(new VolumeCmd());
57eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    registerCmd(new AsecCmd());
58508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root    registerCmd(new ObbCmd());
59586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    registerCmd(new StorageCmd());
60b87937cdea689594a293979b30b13054e7455deeKen Sumrall    registerCmd(new FstrimCmd());
61f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat}
62f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
633fd60b428202a0f5f324fccc67c0c0402b9131baDianne Hackborn#if DUMP_ARGS
643e971277db0d87652af5622c989233e7159ab909Mark Salyzynvoid CommandListener::dumpArgs(int argc, char **argv, int argObscure) {
65d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    char buffer[4096];
66d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    char *p = buffer;
67d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
68d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    memset(buffer, 0, sizeof(buffer));
69d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    int i;
70d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    for (i = 0; i < argc; i++) {
718f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall        unsigned int len = strlen(argv[i]) + 1; // Account for space
72d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        if (i == argObscure) {
73d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            len += 2; // Account for {}
74d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        }
75d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        if (((p - buffer) + len) < (sizeof(buffer)-1)) {
76d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            if (i == argObscure) {
77d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                *p++ = '{';
78d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                *p++ = '}';
79d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                *p++ = ' ';
80d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                continue;
81d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            }
82d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            strcpy(p, argv[i]);
83d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            p+= strlen(argv[i]);
84d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            if (i != (argc -1)) {
85d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                *p++ = ' ';
86d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            }
87d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        }
88d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    }
8997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat    SLOGD("%s", buffer);
90d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat}
913e971277db0d87652af5622c989233e7159ab909Mark Salyzyn#else
923e971277db0d87652af5622c989233e7159ab909Mark Salyzynvoid CommandListener::dumpArgs(int /*argc*/, char ** /*argv*/, int /*argObscure*/) { }
933e971277db0d87652af5622c989233e7159ab909Mark Salyzyn#endif
94d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
9536801cccf27152c9eca5aab6ba3527221525110fJeff Sharkeyint CommandListener::sendGenericOkFail(SocketClient *cli, int cond) {
9636801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey    if (!cond) {
9736801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        return cli->sendMsg(ResponseCode::CommandOkay, "Command succeeded", false);
9836801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey    } else {
9936801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        return cli->sendMsg(ResponseCode::OperationFailed, "Command failed", false);
10036801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey    }
10136801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey}
10236801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
103d9a4e358614a0c5f60cc76c0636ee4bb02004a32San MehatCommandListener::DumpCmd::DumpCmd() :
104d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                 VoldCommand("dump") {
105d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat}
106d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
107d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehatint CommandListener::DumpCmd::runCommand(SocketClient *cli,
1083e971277db0d87652af5622c989233e7159ab909Mark Salyzyn                                         int /*argc*/, char ** /*argv*/) {
109d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    cli->sendMsg(0, "Dumping loop status", false);
110d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    if (Loop::dumpState(cli)) {
111d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Loop dump failed", true);
112d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    }
113d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    cli->sendMsg(0, "Dumping DM status", false);
114d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    if (Devmapper::dumpState(cli)) {
115d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Devmapper dump failed", true);
116d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    }
11796597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat    cli->sendMsg(0, "Dumping mounted filesystems", false);
11896597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat    FILE *fp = fopen("/proc/mounts", "r");
11996597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat    if (fp) {
12096597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat        char line[1024];
12196597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat        while (fgets(line, sizeof(line), fp)) {
12296597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat            line[strlen(line)-1] = '\0';
12396597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat            cli->sendMsg(0, line, false);;
12496597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat        }
12596597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat        fclose(fp);
12696597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat    }
127d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
128d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    cli->sendMsg(ResponseCode::CommandOkay, "dump complete", false);
129d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    return 0;
130d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat}
131d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
132eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan MehatCommandListener::VolumeCmd::VolumeCmd() :
133eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                 VoldCommand("volume") {
134f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat}
135f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
136eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehatint CommandListener::VolumeCmd::runCommand(SocketClient *cli,
1377929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash                                           int argc, char **argv) {
138d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    dumpArgs(argc, argv, -1);
139d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
140eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (argc < 2) {
141eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
142eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        return 0;
143eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    }
144f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
145eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    VolumeManager *vm = VolumeManager::Instance();
146c8e04c5a8285de07d2c84bfbda8eda2c14a9457dJeff Sharkey    std::lock_guard<std::mutex> lock(vm->getLock());
147eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat
14836801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey    // TODO: tease out methods not directly related to volumes
14957df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat
15036801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey    std::string cmd(argv[1]);
15136801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey    if (cmd == "reset") {
15236801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        return sendGenericOkFail(cli, vm->reset());
15336801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
15436801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey    } else if (cmd == "shutdown") {
15536801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        return sendGenericOkFail(cli, vm->shutdown());
15636801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
157f1b996df6f8283aac6953b22bd9e2496d8c30c86Jeff Sharkey    } else if (cmd == "debug") {
158f1b996df6f8283aac6953b22bd9e2496d8c30c86Jeff Sharkey        return sendGenericOkFail(cli, vm->setDebug(true));
159f1b996df6f8283aac6953b22bd9e2496d8c30c86Jeff Sharkey
16036801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey    } else if (cmd == "partition" && argc > 3) {
16136801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        // partition [diskId] [public|private|mixed] [ratio]
16236801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        std::string id(argv[2]);
16336801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        auto disk = vm->findDisk(id);
16436801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        if (disk == nullptr) {
16536801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown disk", false);
1669caab76c6b5aefdeeb1715a3695491ca793b8c18Ken Sumrall        }
16736801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
16836801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        std::string type(argv[3]);
16936801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        if (type == "public") {
17036801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey            return sendGenericOkFail(cli, disk->partitionPublic());
17136801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        } else if (type == "private") {
17236801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey            return sendGenericOkFail(cli, disk->partitionPrivate());
17336801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        } else if (type == "mixed") {
17436801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey            if (argc < 4) {
17536801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey                return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);
17636801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey            }
17736801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey            int frac = atoi(argv[4]);
17836801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey            return sendGenericOkFail(cli, disk->partitionMixed(frac));
17936801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        } else {
18036801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey            return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);
18157df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        }
18236801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
18336801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey    } else if (cmd == "mkdirs" && argc > 2) {
18436801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        // mkdirs [path]
18536801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        return sendGenericOkFail(cli, vm->mkdirs(argv[2]));
18636801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
187bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey    } else if (cmd == "user_added" && argc > 3) {
188bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey        // user_added [user] [serial]
189bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey        return sendGenericOkFail(cli, vm->onUserAdded(atoi(argv[2]), atoi(argv[3])));
19036801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
191bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey    } else if (cmd == "user_removed" && argc > 2) {
192bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey        // user_removed [user]
193bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey        return sendGenericOkFail(cli, vm->onUserRemoved(atoi(argv[2])));
194bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey
195bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey    } else if (cmd == "user_started" && argc > 2) {
196bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey        // user_started [user]
197bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey        return sendGenericOkFail(cli, vm->onUserStarted(atoi(argv[2])));
198bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey
199bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey    } else if (cmd == "user_stopped" && argc > 2) {
200bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey        // user_stopped [user]
201bd3038df74ace540d46c530a11e3145f922e1b42Jeff Sharkey        return sendGenericOkFail(cli, vm->onUserStopped(atoi(argv[2])));
20236801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
20336801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey    } else if (cmd == "mount" && argc > 2) {
20436801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        // mount [volId] [flags] [user]
20536801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        std::string id(argv[2]);
20636801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        auto vol = vm->findVolume(id);
20736801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        if (vol == nullptr) {
20836801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);
20957df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        }
21036801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
211f1b996df6f8283aac6953b22bd9e2496d8c30c86Jeff Sharkey        int mountFlags = (argc > 3) ? atoi(argv[3]) : 0;
212f1b996df6f8283aac6953b22bd9e2496d8c30c86Jeff Sharkey        userid_t mountUserId = (argc > 4) ? atoi(argv[4]) : -1;
21336801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
214f1b996df6f8283aac6953b22bd9e2496d8c30c86Jeff Sharkey        vol->setMountFlags(mountFlags);
215f1b996df6f8283aac6953b22bd9e2496d8c30c86Jeff Sharkey        vol->setMountUserId(mountUserId);
21636801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
2171bfb375f77c093a8e16bef4ddeab2681ca126d56Jeff Sharkey        int res = vol->mount();
2181bfb375f77c093a8e16bef4ddeab2681ca126d56Jeff Sharkey        if (mountFlags & android::vold::VolumeBase::MountFlags::kPrimary) {
2191bfb375f77c093a8e16bef4ddeab2681ca126d56Jeff Sharkey            vm->setPrimary(vol);
2201bfb375f77c093a8e16bef4ddeab2681ca126d56Jeff Sharkey        }
2211bfb375f77c093a8e16bef4ddeab2681ca126d56Jeff Sharkey        return sendGenericOkFail(cli, res);
22236801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
22336801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey    } else if (cmd == "unmount" && argc > 2) {
22436801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        // unmount [volId]
22536801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        std::string id(argv[2]);
22636801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        auto vol = vm->findVolume(id);
22736801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        if (vol == nullptr) {
22836801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);
229eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
23036801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
23136801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        return sendGenericOkFail(cli, vol->unmount());
23236801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey
233d0640f6358041f7e2657167560b357078db73526Jeff Sharkey    } else if (cmd == "format" && argc > 3) {
234d0640f6358041f7e2657167560b357078db73526Jeff Sharkey        // format [volId] [fsType|auto]
23536801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        std::string id(argv[2]);
236d0640f6358041f7e2657167560b357078db73526Jeff Sharkey        std::string fsType(argv[3]);
23736801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        auto vol = vm->findVolume(id);
23836801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey        if (vol == nullptr) {
23936801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);
24071ebe154a5fbbb4b394a439ff0b6b9c84fbd04f5Jeff Sharkey        }
24149e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat
242d0640f6358041f7e2657167560b357078db73526Jeff Sharkey        return sendGenericOkFail(cli, vol->format(fsType));
2431d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey
2441d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey    } else if (cmd == "move_storage" && argc > 3) {
2451d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey        // move_storage [fromVolId] [toVolId]
2461d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey        auto fromVol = vm->findVolume(std::string(argv[2]));
2471d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey        auto toVol = vm->findVolume(std::string(argv[3]));
2481d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey        if (fromVol == nullptr || toVol == nullptr) {
2491d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);
2501d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey        }
2511d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey
2521d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey        (new android::vold::MoveTask(fromVol, toVol))->start();
2531d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey        return sendGenericOkFail(cli, 0);
2545a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
2555a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    } else if (cmd == "benchmark" && argc > 2) {
2565a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        // benchmark [volId]
2575a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        std::string id(argv[2]);
2585a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        nsecs_t res = vm->benchmarkVolume(id);
2595a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        return cli->sendMsg(ResponseCode::CommandOkay,
2605a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                android::base::StringPrintf("%" PRId64, res).c_str(), false);
261a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    }
262a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
26336801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey    return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);
264a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat}
265a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
266586536c60b773e3517531ad8a6cb0de6722c67fcSan MehatCommandListener::StorageCmd::StorageCmd() :
267586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                 VoldCommand("storage") {
268586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat}
269586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
270586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehatint CommandListener::StorageCmd::runCommand(SocketClient *cli,
271586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                                                      int argc, char **argv) {
2727929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash    /* Guarantied to be initialized by vold's main() before the CommandListener is active */
2737929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash    extern struct fstab *fstab;
2747929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash
275d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    dumpArgs(argc, argv, -1);
276d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
277586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    if (argc < 2) {
278586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
279586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        return 0;
280586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    }
281586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
2827929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash    if (!strcmp(argv[1], "mountall")) {
2837929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash        if (argc != 2) {
2847929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: mountall", false);
2857929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash            return 0;
2867929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash        }
2877929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash        fs_mgr_mount_all(fstab);
2887929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash        cli->sendMsg(ResponseCode::CommandOkay, "Mountall ran successfully", false);
2897929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash        return 0;
2907929aa73d0c1fa75e8e0fcd4272361ad0ea9b0e6Mohamad Ayyash    }
291586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    if (!strcmp(argv[1], "users")) {
292586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        DIR *dir;
293586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        struct dirent *de;
294586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
295edf7adf21e1c210e5954b1128efb61b62f6da274JP Abgrall        if (argc < 3) {
296edf7adf21e1c210e5954b1128efb61b62f6da274JP Abgrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument: user <mountpoint>", false);
297edf7adf21e1c210e5954b1128efb61b62f6da274JP Abgrall            return 0;
298edf7adf21e1c210e5954b1128efb61b62f6da274JP Abgrall        }
299586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        if (!(dir = opendir("/proc"))) {
300586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to open /proc", true);
301586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            return 0;
302586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        }
303586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
304586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        while ((de = readdir(dir))) {
305586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            int pid = Process::getPid(de->d_name);
306586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
307586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            if (pid < 0) {
308586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                continue;
309586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            }
310586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
311586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            char processName[255];
312586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            Process::getProcessName(pid, processName, sizeof(processName));
313586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
314586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            if (Process::checkFileDescriptorSymLinks(pid, argv[2]) ||
315586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                Process::checkFileMaps(pid, argv[2]) ||
316586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                Process::checkSymLink(pid, argv[2], "cwd") ||
317586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                Process::checkSymLink(pid, argv[2], "root") ||
318586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                Process::checkSymLink(pid, argv[2], "exe")) {
319586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
320586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                char msg[1024];
321586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                snprintf(msg, sizeof(msg), "%d %s", pid, processName);
322586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                cli->sendMsg(ResponseCode::StorageUsersListResult, msg, false);
323586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            }
324586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        }
325586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        closedir(dir);
326586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Storage user list complete", false);
327586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    } else {
328586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown storage cmd", false);
329586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    }
330586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    return 0;
331586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat}
332586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
333eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan MehatCommandListener::AsecCmd::AsecCmd() :
334eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                 VoldCommand("asec") {
335048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat}
336048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat
337344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Rootvoid CommandListener::AsecCmd::listAsecsInDirectory(SocketClient *cli, const char *directory) {
338344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    DIR *d = opendir(directory);
339344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
340344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    if (!d) {
341344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        cli->sendMsg(ResponseCode::OperationFailed, "Failed to open asec dir", true);
342344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        return;
343344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    }
344344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
345344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    size_t dirent_len = offsetof(struct dirent, d_name) +
3468c480f73eed963eeca9b7df3e4c4543c6e43b0d7Elliott Hughes            fpathconf(dirfd(d), _PC_NAME_MAX) + 1;
347344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
348344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    struct dirent *dent = (struct dirent *) malloc(dirent_len);
349344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    if (dent == NULL) {
350344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        cli->sendMsg(ResponseCode::OperationFailed, "Failed to allocate memory", true);
351344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        return;
352344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    }
353344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
354344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    struct dirent *result;
355344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
356344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    while (!readdir_r(d, dent, &result) && result != NULL) {
357344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        if (dent->d_name[0] == '.')
358344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            continue;
359344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        if (dent->d_type != DT_REG)
360344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            continue;
361344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        size_t name_len = strlen(dent->d_name);
362344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        if (name_len > 5 && name_len < 260 &&
363344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root                !strcmp(&dent->d_name[name_len - 5], ".asec")) {
364344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            char id[255];
365344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            memset(id, 0, sizeof(id));
3667b0bc8571465666d6cba79bda60b72a97f852c05Kenny Root            strlcpy(id, dent->d_name, name_len - 4);
367344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            cli->sendMsg(ResponseCode::AsecListResult, id, false);
368344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        }
369344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    }
370344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    closedir(d);
371344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
372344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    free(dent);
373344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root}
374344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
375eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehatint CommandListener::AsecCmd::runCommand(SocketClient *cli,
376eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                                                      int argc, char **argv) {
377eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (argc < 2) {
378eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
379048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat        return 0;
380048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat    }
381048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat
382eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    VolumeManager *vm = VolumeManager::Instance();
383eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    int rc = 0;
384a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
385eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (!strcmp(argv[1], "list")) {
386d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
387a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
3889f18fe7807a4e4089778243dbbd08d154ec15540Jeff Sharkey        listAsecsInDirectory(cli, VolumeManager::SEC_ASECDIR_EXT);
3899f18fe7807a4e4089778243dbbd08d154ec15540Jeff Sharkey        listAsecsInDirectory(cli, VolumeManager::SEC_ASECDIR_INT);
390eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "create")) {
391d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, 5);
392344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        if (argc != 8) {
393eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
394344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root                    "Usage: asec create <container-id> <size_mb> <fstype> <key> <ownerUid> "
395344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root                    "<isExternal>", false);
396eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
397a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        }
398a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
399eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        unsigned int numSectors = (atoi(argv[3]) * (1024 * 1024)) / 512;
400344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        const bool isExternal = (atoi(argv[7]) == 1);
401344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        rc = vm->createAsec(argv[2], numSectors, argv[4], argv[5], atoi(argv[6]), isExternal);
402fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg    } else if (!strcmp(argv[1], "resize")) {
403fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        dumpArgs(argc, argv, -1);
404fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        if (argc != 5) {
405fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec resize <container-id> <size_mb> <key>", false);
406fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg            return 0;
407fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        }
408fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        unsigned int numSectors = (atoi(argv[3]) * (1024 * 1024)) / 512;
409fcd34a0ddd45db83b7bc71ff47cba9b789089fddDaniel Rosenberg        rc = vm->resizeAsec(argv[2], numSectors, argv[4]);
410eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "finalize")) {
411d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
412eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (argc != 3) {
413eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec finalize <container-id>", false);
414eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
415eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
4168f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->finalizeAsec(argv[2]);
417344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    } else if (!strcmp(argv[1], "fixperms")) {
418344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        dumpArgs(argc, argv, -1);
419344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        if  (argc != 5) {
420344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec fixperms <container-id> <gid> <filename>", false);
421344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            return 0;
422344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        }
423344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
424344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        char *endptr;
425344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        gid_t gid = (gid_t) strtoul(argv[3], &endptr, 10);
426344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        if (*endptr != '\0') {
427344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec fixperms <container-id> <gid> <filename>", false);
428344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            return 0;
429344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        }
430344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
431344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        rc = vm->fixupAsecPermissions(argv[2], gid, argv[4]);
432eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "destroy")) {
433d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
4344ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc < 3) {
4354ba8948dc16463053e21cda5744f519a555080d0San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec destroy <container-id> [force]", false);
436eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
437eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
4384ba8948dc16463053e21cda5744f519a555080d0San Mehat        bool force = false;
4394ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc > 3 && !strcmp(argv[3], "force")) {
4404ba8948dc16463053e21cda5744f519a555080d0San Mehat            force = true;
4414ba8948dc16463053e21cda5744f519a555080d0San Mehat        }
4428f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->destroyAsec(argv[2], force);
443eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "mount")) {
444d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, 3);
44543ed123d3fc1a3edf3660cd0e2528e971abc399eJeff Sharkey        if (argc != 6) {
446eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
44743ed123d3fc1a3edf3660cd0e2528e971abc399eJeff Sharkey                    "Usage: asec mount <namespace-id> <key> <ownerUid> <ro|rw>", false);
448eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
449eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
45043ed123d3fc1a3edf3660cd0e2528e971abc399eJeff Sharkey        bool readOnly = true;
45143ed123d3fc1a3edf3660cd0e2528e971abc399eJeff Sharkey        if (!strcmp(argv[5], "rw")) {
45243ed123d3fc1a3edf3660cd0e2528e971abc399eJeff Sharkey            readOnly = false;
45343ed123d3fc1a3edf3660cd0e2528e971abc399eJeff Sharkey        }
45443ed123d3fc1a3edf3660cd0e2528e971abc399eJeff Sharkey        rc = vm->mountAsec(argv[2], argv[3], atoi(argv[4]), readOnly);
455eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "unmount")) {
456d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
4574ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc < 3) {
4584ba8948dc16463053e21cda5744f519a555080d0San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec unmount <container-id> [force]", false);
459eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
460eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
4614ba8948dc16463053e21cda5744f519a555080d0San Mehat        bool force = false;
4624ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc > 3 && !strcmp(argv[3], "force")) {
4634ba8948dc16463053e21cda5744f519a555080d0San Mehat            force = true;
4644ba8948dc16463053e21cda5744f519a555080d0San Mehat        }
4658f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->unmountAsec(argv[2], force);
466eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "rename")) {
467d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
468eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (argc != 4) {
469eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
470eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                    "Usage: asec rename <old_id> <new_id>", false);
471eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
472eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
4738f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->renameAsec(argv[2], argv[3]);
474eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "path")) {
475d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
476eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (argc != 3) {
477eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec path <container-id>", false);
478eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
479eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
480eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        char path[255];
481a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
48288ac2c06539485942bf414efda2d39647fa1a415San Mehat        if (!(rc = vm->getAsecMountPath(argv[2], path, sizeof(path)))) {
483eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::AsecPathResult, path, false);
48488ac2c06539485942bf414efda2d39647fa1a415San Mehat            return 0;
485eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
486736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn    } else if (!strcmp(argv[1], "fspath")) {
487736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn        dumpArgs(argc, argv, -1);
488736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn        if (argc != 3) {
489736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec fspath <container-id>", false);
490736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn            return 0;
491736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn        }
492736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn        char path[255];
493736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn
494736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn        if (!(rc = vm->getAsecFilesystemPath(argv[2], path, sizeof(path)))) {
495736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn            cli->sendMsg(ResponseCode::AsecPathResult, path, false);
496736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn            return 0;
497736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn        }
498a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    } else {
499d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
500eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown asec cmd", false);
501a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    }
502a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
5038f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat    if (!rc) {
5048f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "asec operation succeeded", false);
5058f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat    } else {
5068f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = ResponseCode::convertFromErrno();
5078f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        cli->sendMsg(rc, "asec operation failed", true);
5088f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat    }
5098f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat
510a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    return 0;
511a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
5122350c44ff39b4cb2940893964a05f778fc80a436San Mehat
513508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny RootCommandListener::ObbCmd::ObbCmd() :
514508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root                 VoldCommand("obb") {
515fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root}
516fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root
517508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Rootint CommandListener::ObbCmd::runCommand(SocketClient *cli,
518fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root                                                      int argc, char **argv) {
519fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    if (argc < 2) {
520fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
521fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        return 0;
522fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    }
523fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root
524fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    VolumeManager *vm = VolumeManager::Instance();
525fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    int rc = 0;
526fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root
527508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root    if (!strcmp(argv[1], "list")) {
528508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        dumpArgs(argc, argv, -1);
529508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root
530508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        rc = vm->listMountedObbs(cli);
531508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root    } else if (!strcmp(argv[1], "mount")) {
532fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root            dumpArgs(argc, argv, 3);
533fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root            if (argc != 5) {
534fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root                cli->sendMsg(ResponseCode::CommandSyntaxError,
5356947904a76b69a1db20a3ddd30c0bcd281922fdeJeff Sharkey                        "Usage: obb mount <filename> <key> <ownerGid>", false);
536fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root                return 0;
537fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root            }
538508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root            rc = vm->mountObb(argv[2], argv[3], atoi(argv[4]));
539fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    } else if (!strcmp(argv[1], "unmount")) {
540fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        dumpArgs(argc, argv, -1);
541fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        if (argc < 3) {
542508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: obb unmount <source file> [force]", false);
543fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root            return 0;
544fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        }
545fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        bool force = false;
546fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        if (argc > 3 && !strcmp(argv[3], "force")) {
547fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root            force = true;
548fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        }
549508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        rc = vm->unmountObb(argv[2], force);
550508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root    } else if (!strcmp(argv[1], "path")) {
551508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        dumpArgs(argc, argv, -1);
552508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        if (argc != 3) {
553508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: obb path <source file>", false);
554508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root            return 0;
555508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        }
556508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        char path[255];
557508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root
558508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        if (!(rc = vm->getObbMountPath(argv[2], path, sizeof(path)))) {
559508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root            cli->sendMsg(ResponseCode::AsecPathResult, path, false);
560508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root            return 0;
561508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        }
562fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    } else {
563fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        dumpArgs(argc, argv, -1);
564508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown obb cmd", false);
565fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    }
566fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root
567fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    if (!rc) {
568508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        cli->sendMsg(ResponseCode::CommandOkay, "obb operation succeeded", false);
569fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    } else {
570fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        rc = ResponseCode::convertFromErrno();
571508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        cli->sendMsg(rc, "obb operation failed", true);
572fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    }
573fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root
574fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    return 0;
575fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root}
576fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root
577b87937cdea689594a293979b30b13054e7455deeKen SumrallCommandListener::FstrimCmd::FstrimCmd() :
578b87937cdea689594a293979b30b13054e7455deeKen Sumrall                 VoldCommand("fstrim") {
579b87937cdea689594a293979b30b13054e7455deeKen Sumrall}
580b87937cdea689594a293979b30b13054e7455deeKen Sumrallint CommandListener::FstrimCmd::runCommand(SocketClient *cli,
581b87937cdea689594a293979b30b13054e7455deeKen Sumrall                                                      int argc, char **argv) {
582b87937cdea689594a293979b30b13054e7455deeKen Sumrall    if ((cli->getUid() != 0) && (cli->getUid() != AID_SYSTEM)) {
583b87937cdea689594a293979b30b13054e7455deeKen Sumrall        cli->sendMsg(ResponseCode::CommandNoPermission, "No permission to run fstrim commands", false);
584b87937cdea689594a293979b30b13054e7455deeKen Sumrall        return 0;
585b87937cdea689594a293979b30b13054e7455deeKen Sumrall    }
586b87937cdea689594a293979b30b13054e7455deeKen Sumrall
587b87937cdea689594a293979b30b13054e7455deeKen Sumrall    if (argc < 2) {
588b87937cdea689594a293979b30b13054e7455deeKen Sumrall        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
589b87937cdea689594a293979b30b13054e7455deeKen Sumrall        return 0;
590b87937cdea689594a293979b30b13054e7455deeKen Sumrall    }
591b87937cdea689594a293979b30b13054e7455deeKen Sumrall
592b87937cdea689594a293979b30b13054e7455deeKen Sumrall    int rc = 0;
593b87937cdea689594a293979b30b13054e7455deeKen Sumrall
594b87937cdea689594a293979b30b13054e7455deeKen Sumrall    if (!strcmp(argv[1], "dotrim")) {
595b87937cdea689594a293979b30b13054e7455deeKen Sumrall        if (argc != 2) {
596b87937cdea689594a293979b30b13054e7455deeKen Sumrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: fstrim dotrim", false);
597b87937cdea689594a293979b30b13054e7455deeKen Sumrall            return 0;
598b87937cdea689594a293979b30b13054e7455deeKen Sumrall        }
599b87937cdea689594a293979b30b13054e7455deeKen Sumrall        dumpArgs(argc, argv, -1);
600422bdb7e49b39475328f05d765b00f0ef96820b8JP Abgrall        rc = fstrim_filesystems(0);
601422bdb7e49b39475328f05d765b00f0ef96820b8JP Abgrall    } else if (!strcmp(argv[1], "dodtrim")) {
602422bdb7e49b39475328f05d765b00f0ef96820b8JP Abgrall        if (argc != 2) {
603422bdb7e49b39475328f05d765b00f0ef96820b8JP Abgrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: fstrim dodtrim", false);
604422bdb7e49b39475328f05d765b00f0ef96820b8JP Abgrall            return 0;
605422bdb7e49b39475328f05d765b00f0ef96820b8JP Abgrall        }
606422bdb7e49b39475328f05d765b00f0ef96820b8JP Abgrall        dumpArgs(argc, argv, -1);
607422bdb7e49b39475328f05d765b00f0ef96820b8JP Abgrall        rc = fstrim_filesystems(1);   /* Do Deep Discard trim */
608b87937cdea689594a293979b30b13054e7455deeKen Sumrall    } else {
609b87937cdea689594a293979b30b13054e7455deeKen Sumrall        dumpArgs(argc, argv, -1);
610b87937cdea689594a293979b30b13054e7455deeKen Sumrall        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown fstrim cmd", false);
611b87937cdea689594a293979b30b13054e7455deeKen Sumrall    }
612b87937cdea689594a293979b30b13054e7455deeKen Sumrall
613b87937cdea689594a293979b30b13054e7455deeKen Sumrall    // Always report that the command succeeded and return the error code.
614b87937cdea689594a293979b30b13054e7455deeKen Sumrall    // The caller will check the return value to see what the error was.
615b87937cdea689594a293979b30b13054e7455deeKen Sumrall    char msg[255];
616b87937cdea689594a293979b30b13054e7455deeKen Sumrall    snprintf(msg, sizeof(msg), "%d", rc);
617b87937cdea689594a293979b30b13054e7455deeKen Sumrall    cli->sendMsg(ResponseCode::CommandOkay, msg, false);
618b87937cdea689594a293979b30b13054e7455deeKen Sumrall
619b87937cdea689594a293979b30b13054e7455deeKen Sumrall    return 0;
620b87937cdea689594a293979b30b13054e7455deeKen Sumrall}
621