Add mkdirs() command.

Apps without sdcard_r or sdcard_rw need to have someone create
package-specific directories on their behalf.  If apps have trouble
creating on their own, they now delegate through system to have
vold create the paths.

Requires that the requested path is actually managed by vold.

Bug: 10577808
Change-Id: I6835fc8f52240f9de07f89742a426a153e3ca32a
This commit is contained in:
Jeff Sharkey 2013-09-17 17:24:38 -07:00
parent e550f78a3f
commit 71ebe154a5
3 changed files with 37 additions and 1 deletions

View file

@ -202,6 +202,12 @@ int CommandListener::VolumeCmd::runCommand(SocketClient *cli,
(enabled ? "Share enabled" : "Share disabled"), false); (enabled ? "Share enabled" : "Share disabled"), false);
} }
return 0; return 0;
} else if (!strcmp(argv[1], "mkdirs")) {
if (argc != 3) {
cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume mkdirs <path>", false);
return 0;
}
rc = vm->mkdirs(argv[2]);
} else { } else {
cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume cmd", false); cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume cmd", false);
} }

View file

@ -32,6 +32,7 @@
#include <openssl/md5.h> #include <openssl/md5.h>
#include <cutils/fs.h>
#include <cutils/log.h> #include <cutils/log.h>
#include <sysutils/NetlinkEvent.h> #include <sysutils/NetlinkEvent.h>
@ -1577,6 +1578,26 @@ int VolumeManager::cleanupAsec(Volume *v, bool force) {
} }
return rc; return rc;
} }
int VolumeManager::mkdirs(char* path) {
// Require that path lives under a volume we manage
const char* emulated_source = getenv("EMULATED_STORAGE_SOURCE");
const char* root = NULL;
if (!strncmp(path, emulated_source, strlen(emulated_source))) {
root = emulated_source;
} else {
Volume* vol = getVolumeForFile(path);
if (vol) {
root = vol->getMountpoint();
}
}
if (!root) {
SLOGE("Failed to find volume for %s", path);
return -EINVAL;
}
/* fs_mkdirs() does symlink checking and relative path enforcement */
return fs_mkdirs(path, 0700);
}

View file

@ -140,6 +140,15 @@ public:
int getDirectVolumeList(struct volume_info *vol_list); int getDirectVolumeList(struct volume_info *vol_list);
int unmountAllAsecsInDir(const char *directory); int unmountAllAsecsInDir(const char *directory);
/*
* Ensure that all directories along given path exist, creating parent
* directories as needed. Validates that given path is absolute and that
* it contains no relative "." or ".." paths or symlinks. Last path segment
* is treated as filename and ignored, unless the path ends with "/". Also
* ensures that path belongs to a volume managed by vold.
*/
int mkdirs(char* path);
private: private:
VolumeManager(); VolumeManager();
void readInitialState(); void readInitialState();