vold2: Refactor the netlink event handling and better define how partitions/disks are handled

Signed-off-by: San Mehat <san@android.com>
This commit is contained in:
San Mehat 2009-10-12 11:32:47 -07:00
parent f1b736bc56
commit fd7f587512
7 changed files with 80 additions and 77 deletions

View file

@ -15,12 +15,14 @@
*/
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define LOG_TAG "Vold"
#include <cutils/log.h>
#include <sysutils/NetlinkEvent.h>
#include "DeviceVolume.h"
@ -44,30 +46,68 @@ int DeviceVolume::addPath(const char *path) {
return 0;
}
int DeviceVolume::handleDiskInsertion(const char *dp, int maj, int min,
int nr_parts) {
PathCollection::iterator it;
int DeviceVolume::handleBlockEvent(NetlinkEvent *evt) {
const char *dp = evt->findParam("DEVPATH");
LOGD("Dv::diskInsertion - %s %d %d %d", dp, maj, min, nr_parts);
PathCollection::iterator it;
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);
/* We can handle this disk */
int action = evt->getAction();
const char *devtype = evt->findParam("DEVTYPE");
if (!strcmp(devtype, "disk")) {
if (action == NetlinkEvent::NlActionAdd)
handleDiskAdded(dp, evt);
else if (action == NetlinkEvent::NlActionRemove)
handleDiskRemoved(dp, evt);
else
LOGD("Ignoring non add/remove event");
} else {
LOGD("Dv::diskIns - waiting for %d partitions", nr_parts);
setState(Volume::State_Pending);
if (action == NetlinkEvent::NlActionAdd)
handlePartitionAdded(dp, evt);
else if (action == NetlinkEvent::NlActionRemove)
handlePartitionRemoved(dp, evt);
else
LOGD("Ignoring non add/remove event");
}
return 0;
}
}
errno = ENODEV;
return -1;
}
void DeviceVolume::handleDiskAdded(const char *devpath, NetlinkEvent *evt) {
mDiskMaj = atoi(evt->findParam("MAJOR"));
mDiskNumParts = atoi(evt->findParam("NPARTS"));
int partmask = 0;
int i;
for (i = 0; i < mDiskNumParts; i++) {
partmask |= (1 << i);
}
mPendingPartMap = partmask;
if (mDiskNumParts == 0) {
LOGD("Dv::diskIns - No partitions - good to go son!");
setState(Volume::State_Idle);
} else {
LOGD("Dv::diskIns - waiting for %d partitions (mask 0x%x)",
mDiskNumParts, mPendingPartMap);
setState(Volume::State_Pending);
}
}
void DeviceVolume::handlePartitionAdded(const char *devpath, NetlinkEvent *evt) {
int major = atoi(evt->findParam("MAJOR"));
int minor = atoi(evt->findParam("MINOR"));
int part_num = atoi(evt->findParam("PARTN"));
}
void DeviceVolume::handleDiskRemoved(const char *devpath, NetlinkEvent *evt) {
}
void DeviceVolume::handlePartitionRemoved(const char *devpath, NetlinkEvent *evt) {
}

View file

@ -29,6 +29,7 @@ protected:
int mPartIdx;
int mDiskMaj;
int mDiskNumParts;
unsigned char mPendingPartMap;
public:
DeviceVolume(const char *label, const char *mount_point, int partIdx);
@ -36,7 +37,13 @@ public:
int addPath(const char *path);
int handleDiskInsertion(const char *dp, int maj, int min, int nr_parts);
int handleBlockEvent(NetlinkEvent *evt);
private:
void handleDiskAdded(const char *devpath, NetlinkEvent *evt);
void handleDiskRemoved(const char *devpath, NetlinkEvent *evt);
void handlePartitionAdded(const char *devpath, NetlinkEvent *evt);
void handlePartitionRemoved(const char *devpath, NetlinkEvent *evt);
};
typedef android::List<DeviceVolume *> DeviceVolumeCollection;

View file

@ -44,7 +44,6 @@ int NetlinkHandler::stop() {
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");
@ -52,37 +51,7 @@ void NetlinkHandler::onEvent(NetlinkEvent *evt) {
}
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");
vm->handleBlockEvent(evt);
} else if (!strcmp(subsys, "battery")) {
} else if (!strcmp(subsys, "power_supply")) {
} else {

View file

@ -35,7 +35,7 @@ Volume::~Volume() {
free(mMountpoint);
}
int Volume::handleDiskInsertion(const char *dp, int maj, int min, int nr_parts) {
int Volume::handleBlockEvent(NetlinkEvent *evt) {
errno = ENOSYS;
return -1;
}

View file

@ -19,6 +19,8 @@
#include <utils/List.h>
class NetlinkEvent;
class Volume {
private:
int mState;
@ -43,7 +45,7 @@ public:
const char *getMountpoint() { return mMountpoint; }
int getState() { return mState; }
virtual int handleDiskInsertion(const char *dp, int maj, int min, int nr_parts);
virtual int handleBlockEvent(NetlinkEvent *evt);
protected:
void setState(int state);

View file

@ -15,12 +15,16 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define LOG_TAG "Vold"
#include <cutils/log.h>
#include <sysutils/NetlinkEvent.h>
#include "VolumeManager.h"
#include "DeviceVolume.h"
#include "ErrorCode.h"
@ -56,37 +60,24 @@ int VolumeManager::addVolume(Volume *v) {
return 0;
}
void VolumeManager::handleDiskInserted(const char *devpath, int maj, int min,
int nr_parts) {
void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
const char *devpath = evt->findParam("DEVPATH");
/* Lookup possible candidate DeviceVolumes */
/* Lookup a volume to handle this device */
VolumeCollection::iterator it;
bool hit = false;
for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {
if (!(*it)->handleDiskInsertion(devpath, maj, min, nr_parts)) {
if (!(*it)->handleBlockEvent(evt)) {
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);
LOGW("No volumes handled block event for '%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;

View file

@ -41,13 +41,7 @@ public:
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);
void handleBlockEvent(NetlinkEvent *evt);
int addVolume(Volume *v);