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>
diff --git a/DirectVolume.cpp b/DirectVolume.cpp
index 67f89ea..9de7aea 100644
--- a/DirectVolume.cpp
+++ b/DirectVolume.cpp
@@ -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 @@
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 @@
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 @@
}
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 */
diff --git a/DirectVolume.h b/DirectVolume.h
index beda7c3..b1388bb 100644
--- a/DirectVolume.h
+++ b/DirectVolume.h
@@ -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: