system: vold2: Initial skeleton for vold2.
Let there be light. Signed-off-by: San Mehat <san@android.com>
This commit is contained in:
parent
8f8ba4d0c0
commit
f1b736bc56
20 changed files with 1332 additions and 0 deletions
43
Android.mk
Normal file
43
Android.mk
Normal file
|
@ -0,0 +1,43 @@
|
|||
BUILD_VOLD2 := false
|
||||
ifeq ($(BUILD_VOLD2),true)
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
main.cpp \
|
||||
VolumeManager.cpp \
|
||||
CommandListener.cpp \
|
||||
VoldCommand.cpp \
|
||||
NetlinkManager.cpp \
|
||||
NetlinkHandler.cpp \
|
||||
BlockDevice.cpp \
|
||||
Volume.cpp \
|
||||
DeviceVolume.cpp
|
||||
|
||||
LOCAL_MODULE:= vold
|
||||
|
||||
LOCAL_C_INCLUDES := $(KERNEL_HEADERS) -I../../frameworks/base/include/
|
||||
|
||||
LOCAL_CFLAGS :=
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libsysutils
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES:= \
|
||||
vdc.c \
|
||||
|
||||
LOCAL_MODULE:= vdc
|
||||
|
||||
LOCAL_C_INCLUDES := $(KERNEL_HEADERS)
|
||||
|
||||
LOCAL_CFLAGS :=
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libcutils
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
endif # ifeq ($(BUILD_VOLD,true)
|
36
BlockDevice.cpp
Normal file
36
BlockDevice.cpp
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LOG_TAG "Vold"
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include "BlockDevice.h"
|
||||
|
||||
BlockDevice::BlockDevice(const char *devpath, int major, int minor) {
|
||||
mDevpath = strdup(devpath);
|
||||
mMajor = major;
|
||||
mMinor = minor;
|
||||
}
|
||||
|
||||
BlockDevice::~BlockDevice() {
|
||||
free(mDevpath);
|
||||
}
|
||||
|
39
BlockDevice.h
Normal file
39
BlockDevice.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 _BLKDEVICE_H
|
||||
#define _BLKDEVICE_H
|
||||
|
||||
#include <utils/List.h>
|
||||
|
||||
class BlockDevice {
|
||||
|
||||
char *mDevpath;
|
||||
int mMajor;
|
||||
int mMinor;
|
||||
|
||||
public:
|
||||
BlockDevice(const char *devpath, int major, int minor);
|
||||
virtual ~BlockDevice();
|
||||
|
||||
const char *getDevpath() { return mDevpath; }
|
||||
int getMajor() { return mMajor; }
|
||||
int getMinor() { return mMinor; }
|
||||
};
|
||||
|
||||
typedef android::List<BlockDevice *> BlockDeviceCollection;
|
||||
|
||||
#endif
|
96
CommandListener.cpp
Normal file
96
CommandListener.cpp
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define LOG_TAG "CommandListener"
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <sysutils/SocketClient.h>
|
||||
|
||||
#include "CommandListener.h"
|
||||
#include "VolumeManager.h"
|
||||
#include "ErrorCode.h"
|
||||
|
||||
CommandListener::CommandListener() :
|
||||
FrameworkListener("vold") {
|
||||
registerCmd(new ListVolumesCmd());
|
||||
registerCmd(new MountVolumeCmd());
|
||||
registerCmd(new UnmountVolumeCmd());
|
||||
registerCmd(new ShareVolumeCmd());
|
||||
registerCmd(new UnshareVolumeCmd());
|
||||
}
|
||||
|
||||
CommandListener::ListVolumesCmd::ListVolumesCmd() :
|
||||
VoldCommand("list_volumes") {
|
||||
}
|
||||
|
||||
int CommandListener::ListVolumesCmd::runCommand(SocketClient *cli,
|
||||
int argc, char **argv) {
|
||||
return VolumeManager::Instance()->listVolumes(cli);
|
||||
}
|
||||
|
||||
CommandListener::MountVolumeCmd::MountVolumeCmd() :
|
||||
VoldCommand("mount_volume") {
|
||||
}
|
||||
|
||||
int CommandListener::MountVolumeCmd::runCommand(SocketClient *cli,
|
||||
int argc, char **argv) {
|
||||
VolumeManager *nm = VolumeManager::Instance();
|
||||
errno = ENOSYS;
|
||||
cli->sendMsg(ErrorCode::OperationFailed, "Failed to mount volume", true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CommandListener::UnmountVolumeCmd::UnmountVolumeCmd() :
|
||||
VoldCommand("unmount_volume") {
|
||||
}
|
||||
|
||||
int CommandListener::UnmountVolumeCmd::runCommand(SocketClient *cli,
|
||||
int argc, char **argv) {
|
||||
VolumeManager *nm = VolumeManager::Instance();
|
||||
errno = ENOSYS;
|
||||
cli->sendMsg(ErrorCode::OperationFailed, "Failed to unmount volume", true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CommandListener::ShareVolumeCmd::ShareVolumeCmd() :
|
||||
VoldCommand("share_volume") {
|
||||
}
|
||||
|
||||
int CommandListener::ShareVolumeCmd::runCommand(SocketClient *cli,
|
||||
int argc, char **argv) {
|
||||
VolumeManager *nm = VolumeManager::Instance();
|
||||
errno = ENOSYS;
|
||||
cli->sendMsg(ErrorCode::OperationFailed, "Failed to share volume", true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CommandListener::UnshareVolumeCmd::UnshareVolumeCmd() :
|
||||
VoldCommand("unshare_volume") {
|
||||
}
|
||||
|
||||
int CommandListener::UnshareVolumeCmd::runCommand(SocketClient *cli,
|
||||
int argc, char **argv) {
|
||||
VolumeManager *nm = VolumeManager::Instance();
|
||||
errno = ENOSYS;
|
||||
cli->sendMsg(ErrorCode::OperationFailed, "Failed to unshare volume", true);
|
||||
return 0;
|
||||
}
|
67
CommandListener.h
Normal file
67
CommandListener.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 _COMMANDLISTENER_H__
|
||||
#define _COMMANDLISTENER_H__
|
||||
|
||||
#include <sysutils/FrameworkListener.h>
|
||||
#include "VoldCommand.h"
|
||||
|
||||
class CommandListener : public FrameworkListener {
|
||||
public:
|
||||
CommandListener();
|
||||
virtual ~CommandListener() {}
|
||||
|
||||
private:
|
||||
|
||||
class ListVolumesCmd : public VoldCommand {
|
||||
public:
|
||||
ListVolumesCmd();
|
||||
virtual ~ListVolumesCmd() {}
|
||||
int runCommand(SocketClient *c, int argc, char ** argv);
|
||||
};
|
||||
|
||||
class MountVolumeCmd : public VoldCommand {
|
||||
public:
|
||||
MountVolumeCmd();
|
||||
virtual ~MountVolumeCmd() {}
|
||||
int runCommand(SocketClient *c, int argc, char ** argv);
|
||||
};
|
||||
|
||||
class UnmountVolumeCmd : public VoldCommand {
|
||||
public:
|
||||
UnmountVolumeCmd();
|
||||
virtual ~UnmountVolumeCmd() {}
|
||||
int runCommand(SocketClient *c, int argc, char ** argv);
|
||||
};
|
||||
|
||||
class ShareVolumeCmd : public VoldCommand {
|
||||
public:
|
||||
ShareVolumeCmd();
|
||||
virtual ~ShareVolumeCmd() {}
|
||||
int runCommand(SocketClient *c, int argc, char ** argv);
|
||||
};
|
||||
|
||||
class UnshareVolumeCmd : public VoldCommand {
|
||||
public:
|
||||
UnshareVolumeCmd();
|
||||
virtual ~UnshareVolumeCmd() {}
|
||||
int runCommand(SocketClient *c, int argc, char ** argv);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
73
DeviceVolume.cpp
Normal file
73
DeviceVolume.cpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LOG_TAG "Vold"
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include "DeviceVolume.h"
|
||||
|
||||
DeviceVolume::DeviceVolume(const char *label, const char *mount_point, int partIdx) :
|
||||
Volume(label, mount_point) {
|
||||
mPartIdx = partIdx;
|
||||
|
||||
mPaths = new PathCollection();
|
||||
}
|
||||
|
||||
DeviceVolume::~DeviceVolume() {
|
||||
PathCollection::iterator it;
|
||||
|
||||
for (it = mPaths->begin(); it != mPaths->end(); ++it)
|
||||
free(*it);
|
||||
delete mPaths;
|
||||
}
|
||||
|
||||
int DeviceVolume::addPath(const char *path) {
|
||||
mPaths->push_back(strdup(path));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DeviceVolume::handleDiskInsertion(const char *dp, int maj, int min,
|
||||
int nr_parts) {
|
||||
PathCollection::iterator it;
|
||||
|
||||
LOGD("Dv::diskInsertion - %s %d %d %d", dp, maj, min, nr_parts);
|
||||
for (it = mPaths->begin(); it != mPaths->end(); ++it) {
|
||||
LOGD("Dv::chk %s", *it);
|
||||
if (!strncmp(dp, *it, strlen(*it))) {
|
||||
/*
|
||||
* We can handle this disk. If there are no partitions then we're
|
||||
* good to go son!
|
||||
*/
|
||||
mDiskMaj = maj;
|
||||
mDiskNumParts = nr_parts;
|
||||
if (nr_parts == 0) {
|
||||
LOGD("Dv::diskIns - No partitions - good to go");
|
||||
setState(Volume::State_Idle);
|
||||
} else {
|
||||
LOGD("Dv::diskIns - waiting for %d partitions", nr_parts);
|
||||
setState(Volume::State_Pending);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
errno = ENODEV;
|
||||
return -1;
|
||||
}
|
44
DeviceVolume.h
Normal file
44
DeviceVolume.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 _DEVICEVOLUME_H
|
||||
#define _DEVICEVOLUME_H
|
||||
|
||||
#include <utils/List.h>
|
||||
|
||||
#include "Volume.h"
|
||||
|
||||
typedef android::List<char *> PathCollection;
|
||||
|
||||
class DeviceVolume : public Volume {
|
||||
protected:
|
||||
PathCollection *mPaths;
|
||||
int mPartIdx;
|
||||
int mDiskMaj;
|
||||
int mDiskNumParts;
|
||||
|
||||
public:
|
||||
DeviceVolume(const char *label, const char *mount_point, int partIdx);
|
||||
virtual ~DeviceVolume();
|
||||
|
||||
int addPath(const char *path);
|
||||
|
||||
int handleDiskInsertion(const char *dp, int maj, int min, int nr_parts);
|
||||
};
|
||||
|
||||
typedef android::List<DeviceVolume *> DeviceVolumeCollection;
|
||||
|
||||
#endif
|
43
ErrorCode.h
Normal file
43
ErrorCode.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 _ERRORCODE_H
|
||||
#define _ERRORCODE_H
|
||||
|
||||
class ErrorCode {
|
||||
public:
|
||||
// 100 series - Requestion action was initiated; expect another reply
|
||||
// before proceeding with a new command.
|
||||
static const int ActionInitiated = 100;
|
||||
|
||||
static const int VolumeListResult = 110;
|
||||
|
||||
// 200 series - Requested action has been successfully completed
|
||||
static const int CommandOkay = 200;
|
||||
|
||||
// 400 series - The command was accepted but the requested action
|
||||
// did not take place.
|
||||
static const int OperationFailed = 400;
|
||||
|
||||
// 500 series - The command was not accepted and the requested
|
||||
// action did not take place.
|
||||
static const int CommandSyntaxError = 500;
|
||||
static const int CommandParameterError = 501;
|
||||
|
||||
// 600 series - Unsolicited broadcasts
|
||||
static const int UnsolicitedInformational = 600;
|
||||
};
|
||||
#endif
|
91
NetlinkHandler.cpp
Normal file
91
NetlinkHandler.cpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define LOG_TAG "Vold"
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <sysutils/NetlinkEvent.h>
|
||||
#include "NetlinkHandler.h"
|
||||
#include "VolumeManager.h"
|
||||
|
||||
NetlinkHandler::NetlinkHandler(int listenerSocket) :
|
||||
NetlinkListener(listenerSocket) {
|
||||
}
|
||||
|
||||
NetlinkHandler::~NetlinkHandler() {
|
||||
}
|
||||
|
||||
int NetlinkHandler::start() {
|
||||
return this->startListener();
|
||||
}
|
||||
|
||||
int NetlinkHandler::stop() {
|
||||
return this->stopListener();
|
||||
}
|
||||
|
||||
void NetlinkHandler::onEvent(NetlinkEvent *evt) {
|
||||
VolumeManager *vm = VolumeManager::Instance();
|
||||
const char *subsys = evt->getSubsystem();
|
||||
int action = evt->getAction();
|
||||
|
||||
if (!subsys) {
|
||||
LOGW("No subsystem found in netlink event");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(subsys, "block")) {
|
||||
const char *devpath = evt->findParam("DEVPATH");
|
||||
const char *devtype = evt->findParam("DEVTYPE");
|
||||
int major = atoi(evt->findParam("MAJOR"));
|
||||
int minor = atoi(evt->findParam("MINOR"));
|
||||
|
||||
LOGI("Block event %d, type %s, %d:%d, path '%s'", action, devtype, major, minor, devpath);
|
||||
|
||||
if (!strcmp(devtype, "disk")) {
|
||||
const char *tmp = evt->findParam("NPARTS");
|
||||
|
||||
if (!tmp) {
|
||||
LOGE("Disk uevent missing 'NPARTS' parameter");
|
||||
return;
|
||||
}
|
||||
if (action == NetlinkEvent::NlActionAdd)
|
||||
vm->handleDiskInserted(devpath, major, minor, atoi(tmp));
|
||||
else if (action == NetlinkEvent::NlActionRemove)
|
||||
vm->handleDiskRemoved(major, minor);
|
||||
} else {
|
||||
const char *tmp = evt->findParam("PARTN");
|
||||
|
||||
if (!tmp) {
|
||||
LOGE("Partition uevent missing 'PARTN' parameter");
|
||||
return;
|
||||
}
|
||||
if (action == NetlinkEvent::NlActionAdd)
|
||||
vm->handlePartCreated(devpath, major, minor, atoi(tmp));
|
||||
else if (action == NetlinkEvent::NlActionRemove)
|
||||
vm->handlePartRemoved(major, minor);
|
||||
}
|
||||
LOGD("Block event handled");
|
||||
} else if (!strcmp(subsys, "battery")) {
|
||||
} else if (!strcmp(subsys, "power_supply")) {
|
||||
} else {
|
||||
LOGE("Dropping %s netlink event", subsys);
|
||||
}
|
||||
}
|
34
NetlinkHandler.h
Normal file
34
NetlinkHandler.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 _NETLINKHANDLER_H
|
||||
#define _NETLINKHANDLER_H
|
||||
|
||||
#include <sysutils/NetlinkListener.h>
|
||||
|
||||
class NetlinkHandler: public NetlinkListener {
|
||||
|
||||
public:
|
||||
NetlinkHandler(int listenerSocket);
|
||||
virtual ~NetlinkHandler();
|
||||
|
||||
int start(void);
|
||||
int stop(void);
|
||||
|
||||
protected:
|
||||
virtual void onEvent(NetlinkEvent *evt);
|
||||
};
|
||||
#endif
|
95
NetlinkManager.cpp
Normal file
95
NetlinkManager.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <linux/netlink.h>
|
||||
|
||||
#define LOG_TAG "Vold"
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include "NetlinkManager.h"
|
||||
#include "NetlinkHandler.h"
|
||||
|
||||
NetlinkManager *NetlinkManager::sInstance = NULL;
|
||||
|
||||
NetlinkManager *NetlinkManager::Instance() {
|
||||
if (!sInstance)
|
||||
sInstance = new NetlinkManager();
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
NetlinkManager::NetlinkManager() {
|
||||
mBroadcaster = NULL;
|
||||
}
|
||||
|
||||
NetlinkManager::~NetlinkManager() {
|
||||
}
|
||||
|
||||
int NetlinkManager::start() {
|
||||
struct sockaddr_nl nladdr;
|
||||
int sz = 64 * 1024;
|
||||
|
||||
memset(&nladdr, 0, sizeof(nladdr));
|
||||
nladdr.nl_family = AF_NETLINK;
|
||||
nladdr.nl_pid = getpid();
|
||||
nladdr.nl_groups = 0xffffffff;
|
||||
|
||||
if ((mSock = socket(PF_NETLINK,
|
||||
SOCK_DGRAM,NETLINK_KOBJECT_UEVENT)) < 0) {
|
||||
LOGE("Unable to create uevent socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) {
|
||||
LOGE("Unable to set uevent socket options: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {
|
||||
LOGE("Unable to bind uevent socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
mHandler = new NetlinkHandler(mSock);
|
||||
if (mHandler->start()) {
|
||||
LOGE("Unable to start NetlinkHandler: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NetlinkManager::stop() {
|
||||
if (mHandler->stop()) {
|
||||
LOGE("Unable to stop NetlinkHandler: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
delete mHandler;
|
||||
mHandler = NULL;
|
||||
|
||||
close(mSock);
|
||||
mSock = -1;
|
||||
|
||||
return 0;
|
||||
}
|
48
NetlinkManager.h
Normal file
48
NetlinkManager.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 _NETLINKMANAGER_H
|
||||
#define _NETLINKMANAGER_H
|
||||
|
||||
#include <sysutils/SocketListener.h>
|
||||
#include <sysutils/NetlinkListener.h>
|
||||
|
||||
class NetlinkHandler;
|
||||
|
||||
class NetlinkManager {
|
||||
private:
|
||||
static NetlinkManager *sInstance;
|
||||
|
||||
private:
|
||||
SocketListener *mBroadcaster;
|
||||
NetlinkHandler *mHandler;
|
||||
int mSock;
|
||||
|
||||
public:
|
||||
virtual ~NetlinkManager();
|
||||
|
||||
int start();
|
||||
int stop();
|
||||
|
||||
void setBroadcaster(SocketListener *sl) { mBroadcaster = sl; }
|
||||
SocketListener *getBroadcaster() { return mBroadcaster; }
|
||||
|
||||
static NetlinkManager *Instance();
|
||||
|
||||
private:
|
||||
NetlinkManager();
|
||||
};
|
||||
#endif
|
21
VoldCommand.cpp
Normal file
21
VoldCommand.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 "VoldCommand.h"
|
||||
|
||||
VoldCommand::VoldCommand(const char *cmd) :
|
||||
FrameworkCommand(cmd) {
|
||||
}
|
28
VoldCommand.h
Normal file
28
VoldCommand.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 _VOLD_COMMAND_H
|
||||
#define _VOLD_COMMAND_H
|
||||
|
||||
#include <sysutils/FrameworkCommand.h>
|
||||
|
||||
class VoldCommand : public FrameworkCommand {
|
||||
public:
|
||||
VoldCommand(const char *cmd);
|
||||
virtual ~VoldCommand() {}
|
||||
};
|
||||
|
||||
#endif
|
46
Volume.cpp
Normal file
46
Volume.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LOG_TAG "Vold"
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include "Volume.h"
|
||||
|
||||
Volume::Volume(const char *label, const char *mount_point) {
|
||||
mLabel = strdup(label);
|
||||
mMountpoint = strdup(mount_point);
|
||||
mState = Volume::State_Init;
|
||||
}
|
||||
|
||||
Volume::~Volume() {
|
||||
free(mLabel);
|
||||
free(mMountpoint);
|
||||
}
|
||||
|
||||
int Volume::handleDiskInsertion(const char *dp, int maj, int min, int nr_parts) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Volume::setState(int state) {
|
||||
LOGD("Volume %s state changing %d -> %d", mLabel, mState, state);
|
||||
mState = state;
|
||||
}
|
54
Volume.h
Normal file
54
Volume.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 _VOLUME_H
|
||||
#define _VOLUME_H
|
||||
|
||||
#include <utils/List.h>
|
||||
|
||||
class Volume {
|
||||
private:
|
||||
int mState;
|
||||
|
||||
public:
|
||||
static const int State_Init = -1;
|
||||
static const int State_Idle = 1;
|
||||
static const int State_Pending = 2;
|
||||
static const int State_Mounted = 3;
|
||||
static const int State_Checking = 4;
|
||||
static const int State_Formatting = 5;
|
||||
|
||||
protected:
|
||||
char *mLabel;
|
||||
char *mMountpoint;
|
||||
|
||||
public:
|
||||
Volume(const char *label, const char *mount_point);
|
||||
virtual ~Volume();
|
||||
|
||||
const char *getLabel() { return mLabel; }
|
||||
const char *getMountpoint() { return mMountpoint; }
|
||||
int getState() { return mState; }
|
||||
|
||||
virtual int handleDiskInsertion(const char *dp, int maj, int min, int nr_parts);
|
||||
|
||||
protected:
|
||||
void setState(int state);
|
||||
};
|
||||
|
||||
typedef android::List<Volume *> VolumeCollection;
|
||||
|
||||
#endif
|
103
VolumeManager.cpp
Normal file
103
VolumeManager.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define LOG_TAG "Vold"
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include "VolumeManager.h"
|
||||
#include "DeviceVolume.h"
|
||||
#include "ErrorCode.h"
|
||||
|
||||
VolumeManager *VolumeManager::sInstance = NULL;
|
||||
|
||||
VolumeManager *VolumeManager::Instance() {
|
||||
if (!sInstance)
|
||||
sInstance = new VolumeManager();
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
VolumeManager::VolumeManager() {
|
||||
mBlockDevices = new BlockDeviceCollection();
|
||||
mVolumes = new VolumeCollection();
|
||||
mBroadcaster = NULL;
|
||||
}
|
||||
|
||||
VolumeManager::~VolumeManager() {
|
||||
delete mBlockDevices;
|
||||
}
|
||||
|
||||
int VolumeManager::start() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VolumeManager::stop() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VolumeManager::addVolume(Volume *v) {
|
||||
mVolumes->push_back(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VolumeManager::handleDiskInserted(const char *devpath, int maj, int min,
|
||||
int nr_parts) {
|
||||
|
||||
/* Lookup possible candidate DeviceVolumes */
|
||||
VolumeCollection::iterator it;
|
||||
bool hit = false;
|
||||
for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {
|
||||
if (!(*it)->handleDiskInsertion(devpath, maj, min, nr_parts)) {
|
||||
hit = true;
|
||||
LOGD("Volume '%s' has handled disk insertion for '%s'",
|
||||
(*it)->getLabel(), devpath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hit) {
|
||||
LOGW("No volumes handled insertion of disk '%s'", devpath);
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeManager::handleDiskRemoved(int maj, int min) {
|
||||
}
|
||||
|
||||
void VolumeManager::handlePartCreated(const char *devpath, int maj, int min,
|
||||
int part_no) {
|
||||
}
|
||||
|
||||
void VolumeManager::handlePartRemoved(int maj, int min) {
|
||||
}
|
||||
|
||||
|
||||
int VolumeManager::listVolumes(SocketClient *cli) {
|
||||
VolumeCollection::iterator i;
|
||||
|
||||
for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
|
||||
char *buffer;
|
||||
asprintf(&buffer, "%s %s %d",
|
||||
(*i)->getLabel(), (*i)->getMountpoint(),
|
||||
(*i)->getState());
|
||||
cli->sendMsg(ErrorCode::VolumeListResult, buffer, false);
|
||||
free(buffer);
|
||||
}
|
||||
cli->sendMsg(ErrorCode::CommandOkay, "Volumes Listed", false);
|
||||
return 0;
|
||||
}
|
64
VolumeManager.h
Normal file
64
VolumeManager.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 _VOLUMEMANAGER_H
|
||||
#define _VOLUMEMANAGER_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <utils/List.h>
|
||||
#include <sysutils/SocketListener.h>
|
||||
|
||||
#include "BlockDevice.h"
|
||||
#include "Volume.h"
|
||||
|
||||
class VolumeManager {
|
||||
private:
|
||||
static VolumeManager *sInstance;
|
||||
|
||||
private:
|
||||
SocketListener *mBroadcaster;
|
||||
BlockDeviceCollection *mBlockDevices;
|
||||
|
||||
VolumeCollection *mVolumes;
|
||||
|
||||
public:
|
||||
virtual ~VolumeManager();
|
||||
|
||||
int start();
|
||||
int stop();
|
||||
|
||||
void handleDiskInserted(const char *devpath, int maj, int min,
|
||||
int nr_parts);
|
||||
void handleDiskRemoved(int maj, int min);
|
||||
|
||||
void handlePartCreated(const char *devpath, int maj, int min,
|
||||
int part_no);
|
||||
void handlePartRemoved(int maj, int min);
|
||||
|
||||
int addVolume(Volume *v);
|
||||
|
||||
int listVolumes(SocketClient *cli);
|
||||
|
||||
void setBroadcaster(SocketListener *sl) { mBroadcaster = sl; }
|
||||
SocketListener *getBroadcaster() { return mBroadcaster; }
|
||||
|
||||
static VolumeManager *Instance();
|
||||
|
||||
private:
|
||||
VolumeManager();
|
||||
};
|
||||
#endif
|
159
main.cpp
Normal file
159
main.cpp
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LOG_TAG "Vold"
|
||||
|
||||
#include "cutils/log.h"
|
||||
|
||||
#include "VolumeManager.h"
|
||||
#include "CommandListener.h"
|
||||
#include "NetlinkManager.h"
|
||||
#include "DeviceVolume.h"
|
||||
|
||||
static int process_config(VolumeManager *vm);
|
||||
|
||||
int main() {
|
||||
|
||||
VolumeManager *vm;
|
||||
CommandListener *cl;
|
||||
NetlinkManager *nm;
|
||||
|
||||
LOGI("Vold 2.0 firing up");
|
||||
|
||||
/* Create our singleton managers */
|
||||
if (!(vm = VolumeManager::Instance())) {
|
||||
LOGE("Unable to create VolumeManager");
|
||||
exit(1);
|
||||
};
|
||||
|
||||
if (!(nm = NetlinkManager::Instance())) {
|
||||
LOGE("Unable to create NetlinkManager");
|
||||
exit(1);
|
||||
};
|
||||
|
||||
cl = new CommandListener();
|
||||
vm->setBroadcaster((SocketListener *) cl);
|
||||
nm->setBroadcaster((SocketListener *) cl);
|
||||
|
||||
if (vm->start()) {
|
||||
LOGE("Unable to start VolumeManager (%s)", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (process_config(vm)) {
|
||||
LOGE("Error reading configuration (%s)", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (nm->start()) {
|
||||
LOGE("Unable to start NetlinkManager (%s)", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that we're up, we can respond to commands
|
||||
*/
|
||||
if (cl->startListener()) {
|
||||
LOGE("Unable to start CommandListener (%s)", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Eventually we'll become the monitoring thread
|
||||
while(1) {
|
||||
sleep(1000);
|
||||
}
|
||||
|
||||
LOGI("Vold exiting");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static int process_config(VolumeManager *vm) {
|
||||
FILE *fp;
|
||||
int n = 0;
|
||||
char line[255];
|
||||
|
||||
if (!(fp = fopen("/etc/vold.fstab", "r"))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(fgets(line, sizeof(line), fp)) {
|
||||
char *next = line;
|
||||
char *type, *label, *mount_point;
|
||||
|
||||
n++;
|
||||
line[strlen(line)-1] = '\0';
|
||||
|
||||
if (line[0] == '#' || line[0] == '\0')
|
||||
continue;
|
||||
|
||||
if (!(type = strsep(&next, " \t"))) {
|
||||
LOGE("Error parsing type");
|
||||
goto out_syntax;
|
||||
}
|
||||
if (!(label = strsep(&next, " \t"))) {
|
||||
LOGE("Error parsing label");
|
||||
goto out_syntax;
|
||||
}
|
||||
if (!(mount_point = strsep(&next, " \t"))) {
|
||||
LOGE("Error parsing mount point");
|
||||
goto out_syntax;
|
||||
}
|
||||
|
||||
if (!strcmp(type, "dev_mount")) {
|
||||
DeviceVolume *dv = NULL;
|
||||
char *part, *sysfs_path;
|
||||
|
||||
if (!(part = strsep(&next, " \t"))) {
|
||||
LOGE("Error parsing partition");
|
||||
goto out_syntax;
|
||||
}
|
||||
if (strcmp(part, "auto") && atoi(part) == 0) {
|
||||
LOGE("Partition must either be 'auto' or 1 based index instead of '%s'", part);
|
||||
goto out_syntax;
|
||||
}
|
||||
|
||||
dv = new DeviceVolume(label, mount_point, atoi(part));
|
||||
|
||||
while((sysfs_path = strsep(&next, " \t"))) {
|
||||
if (dv->addPath(sysfs_path)) {
|
||||
LOGE("Failed to add devpath %s to volume %s", sysfs_path,
|
||||
label);
|
||||
goto out_fail;
|
||||
}
|
||||
}
|
||||
vm->addVolume(dv);
|
||||
} else if (!strcmp(type, "map_mount")) {
|
||||
} else {
|
||||
LOGE("Unknown type '%s'", type);
|
||||
goto out_syntax;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
|
||||
out_syntax:
|
||||
LOGE("Syntax error on config line %d", n);
|
||||
errno = -EINVAL;
|
||||
out_fail:
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
148
vdc.c
Normal file
148
vdc.c
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <cutils/sockets.h>
|
||||
#include <private/android_filesystem_config.h>
|
||||
|
||||
static void usage(char *progname);
|
||||
static int do_monitor(int sock, int stop_after_cmd);
|
||||
static int do_cmd(int sock, int argc, char **argv);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int sock;
|
||||
|
||||
if (argc < 2)
|
||||
usage(argv[0]);
|
||||
|
||||
if ((sock = socket_local_client("vold",
|
||||
ANDROID_SOCKET_NAMESPACE_RESERVED,
|
||||
SOCK_STREAM)) < 0) {
|
||||
fprintf(stderr, "Error connecting (%s)\n", strerror(errno));
|
||||
exit(4);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "monitor"))
|
||||
exit(do_monitor(sock, 0));
|
||||
exit(do_cmd(sock, argc, argv));
|
||||
}
|
||||
|
||||
static int do_cmd(int sock, int argc, char **argv) {
|
||||
char final_cmd[255] = { '\0' };
|
||||
int i;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
char *cmp;
|
||||
|
||||
if (!index(argv[i], ' '))
|
||||
asprintf(&cmp, "%s%s", argv[i], (i == (argc -1)) ? "" : " ");
|
||||
else
|
||||
asprintf(&cmp, "\"%s\"%s", argv[i], (i == (argc -1)) ? "" : " ");
|
||||
|
||||
strcat(final_cmd, cmp);
|
||||
free(cmp);
|
||||
}
|
||||
|
||||
if (write(sock, final_cmd, strlen(final_cmd) + 1) < 0) {
|
||||
perror("write");
|
||||
return errno;
|
||||
}
|
||||
|
||||
return do_monitor(sock, 1);
|
||||
}
|
||||
|
||||
static int do_monitor(int sock, int stop_after_cmd) {
|
||||
char *buffer = malloc(4096);
|
||||
|
||||
if (!stop_after_cmd)
|
||||
printf("[Connected to Vold]\n");
|
||||
|
||||
while(1) {
|
||||
fd_set read_fds;
|
||||
struct timeval to;
|
||||
int rc = 0;
|
||||
|
||||
to.tv_sec = 10;
|
||||
to.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(sock, &read_fds);
|
||||
|
||||
if ((rc = select(sock +1, &read_fds, NULL, NULL, &to)) < 0) {
|
||||
fprintf(stderr, "Error in select (%s)\n", strerror(errno));
|
||||
free(buffer);
|
||||
return errno;
|
||||
} else if (!rc) {
|
||||
continue;
|
||||
fprintf(stderr, "[TIMEOUT]\n");
|
||||
return ETIMEDOUT;
|
||||
} else if (FD_ISSET(sock, &read_fds)) {
|
||||
memset(buffer, 0, 4096);
|
||||
if ((rc = read(sock, buffer, 4096)) <= 0) {
|
||||
if (rc == 0)
|
||||
fprintf(stderr, "Lost connection to Vold - did it crash?\n");
|
||||
else
|
||||
fprintf(stderr, "Error reading data (%s)\n", strerror(errno));
|
||||
free(buffer);
|
||||
if (rc == 0)
|
||||
return ECONNRESET;
|
||||
return errno;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < rc; i++) {
|
||||
if (buffer[i] == '\0') {
|
||||
int code;
|
||||
char tmp[4];
|
||||
|
||||
strncpy(tmp, buffer + offset, 3);
|
||||
tmp[3] = '\0';
|
||||
code = atoi(tmp);
|
||||
|
||||
printf("%s\n", buffer + offset);
|
||||
if (stop_after_cmd) {
|
||||
if (code >= 200 && code < 600)
|
||||
return 0;
|
||||
}
|
||||
offset = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usage(char *progname) {
|
||||
fprintf(stderr, "Usage: %s <monitor>|<cmd> [arg1] [arg2...]\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
Loading…
Reference in a new issue