vold: wildcard support for device path matching

Switching the kernel to the new sysfs layout (unselecting
CONFIG_SYSFS_DEPRECATED) complicates VolD block device recognition.

The uevents are reporting full specific paths, such as:

/devices/pci0000:0e/0000:0e:18.0/mmc_host/mmc0/mmc0:1234/block/mmcblk0

Because the full device path may contain variable IDs (in this MMC
case "1234") using full path entries in fstab does not work. Android
supports partial matches but only as a prefix at the beginning of the
path.

This patch adds support for matching shell wildcard patterns via
fnmatch(). The prefix matching rule is preserved, but if it is
detected a warning is issued.

Change-Id: Ia0c5eddec06bd71bec6ce838be3b5345278e0bab
Author:    Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Radu Moisan <radu.moisan@intel.com>
Signed-off-by: Jim Bride <jim.bride@intel.com>
Reviewed-by: Bergeron, Michael <michael.bergeron@intel.com>
Tested-by: Uyyala, Sridhar <sridhar.uyyala@intel.com>
Reviewed-by: Leung, Daniel <daniel.leung@intel.com>
Reviewed-by: Uyyala, Sridhar <sridhar.uyyala@intel.com>
gugelfrei
Octavian Purdila 10 years ago
parent 470f0b3ff4
commit 46c301c03e

@ -18,6 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fnmatch.h>
#include <linux/kdev_t.h>
@ -33,6 +34,42 @@
// #define PARTITION_DEBUG
PathInfo::PathInfo(const char *p)
{
warned = false;
pattern = strdup(p);
if (!strchr(pattern, '*')) {
patternType = prefix;
} else {
patternType = wildcard;
}
}
PathInfo::~PathInfo()
{
free(pattern);
}
bool PathInfo::match(const char *path)
{
switch (patternType) {
case prefix:
{
bool ret = (strncmp(path, pattern, strlen(pattern)) == 0);
if (!warned && ret && (strlen(pattern) != strlen(path))) {
SLOGW("Deprecated implied prefix pattern detected, please use '%s*' instead", pattern);
warned = true;
}
return ret;
}
case wildcard:
return fnmatch(pattern, path, 0) == 0;
}
SLOGE("Bad matching type");
return false;
}
DirectVolume::DirectVolume(VolumeManager *vm, const fstab_rec* rec, int flags) :
Volume(vm, rec, flags) {
mPaths = new PathCollection();
@ -62,12 +99,12 @@ DirectVolume::~DirectVolume() {
PathCollection::iterator it;
for (it = mPaths->begin(); it != mPaths->end(); ++it)
free(*it);
delete *it;
delete mPaths;
}
int DirectVolume::addPath(const char *path) {
mPaths->push_back(strdup(path));
mPaths->push_back(new PathInfo(path));
return 0;
}
@ -96,7 +133,7 @@ int DirectVolume::handleBlockEvent(NetlinkEvent *evt) {
PathCollection::iterator it;
for (it = mPaths->begin(); it != mPaths->end(); ++it) {
if (!strncmp(dp, *it, strlen(*it))) {
if ((*it)->match(dp)) {
/* We can handle this disk */
int action = evt->getAction();
const char *devtype = evt->findParam("DEVTYPE");
@ -407,7 +444,7 @@ int DirectVolume::updateDeviceInfo(char *new_path, int new_major, int new_minor)
}
it = mPaths->begin();
free(*it); /* Free the string storage */
delete *it; /* Free the string storage */
mPaths->erase(it); /* Remove it from the list */
addPath(new_path); /* Put the new path on the list */

@ -21,7 +21,19 @@
#include "Volume.h"
typedef android::List<char *> PathCollection;
class PathInfo {
public:
PathInfo(const char *pattern);
~PathInfo();
bool match(const char *path);
private:
bool warned;
char *pattern;
enum PatternType { prefix, wildcard };
PatternType patternType;
};
typedef android::List<PathInfo *> PathCollection;
class DirectVolume : public Volume {
public:

Loading…
Cancel
Save