bind_mount_recursive: Use lstat instead of d_type of readdir
Change-Id: I0eb8d6c7e1fa5df6dbc5962a639901546a159d04
This commit is contained in:
@@ -1782,51 +1782,75 @@ static struct option mcexec_options[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ENABLE_MCOVERLAYFS
|
#ifdef ENABLE_MCOVERLAYFS
|
||||||
|
/* bind-mount files under <root>/<prefix> over <prefix> recursively */
|
||||||
void bind_mount_recursive(const char *root, char *prefix)
|
void bind_mount_recursive(const char *root, char *prefix)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
int len;
|
|
||||||
|
|
||||||
len = snprintf(path, sizeof(path) - 1, "%s/%s", root, prefix);
|
snprintf(path, sizeof(path), "%s/%s", root, prefix);
|
||||||
path[len] = 0;
|
path[sizeof(path) - 1] = 0;
|
||||||
|
|
||||||
if (!(dir = opendir(path))) {
|
if (!(dir = opendir(path))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((entry = readdir(dir))) {
|
while ((entry = readdir(dir))) {
|
||||||
len = snprintf(path, sizeof(path) - 1,
|
char fullpath[PATH_MAX];
|
||||||
"%s/%s", prefix, entry->d_name);
|
char shortpath[PATH_MAX];
|
||||||
path[len] = 0;
|
struct stat st;
|
||||||
|
|
||||||
|
/* Use lstat instead of checking dt_type of readdir
|
||||||
|
result because the latter reports DT_UNKNOWN for
|
||||||
|
files on some file systems */
|
||||||
|
snprintf(fullpath, sizeof(fullpath),
|
||||||
|
"%s/%s/%s", root, prefix, entry->d_name);
|
||||||
|
fullpath[sizeof(fullpath) - 1] = 0;
|
||||||
|
|
||||||
|
if (lstat(fullpath, &st)) {
|
||||||
|
fprintf(stderr, "%s: error: lstat %s: %s\n",
|
||||||
|
__func__, fullpath, strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Traverse target or mount point */
|
||||||
|
snprintf(shortpath, sizeof(shortpath),
|
||||||
|
"%s/%s", prefix, entry->d_name);
|
||||||
|
shortpath[sizeof(shortpath) - 1] = 0;
|
||||||
|
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
__dprintf("dir found: %s\n", fullpath);
|
||||||
|
|
||||||
if (entry->d_type == DT_DIR) {
|
|
||||||
if (strcmp(entry->d_name, ".") == 0 ||
|
if (strcmp(entry->d_name, ".") == 0 ||
|
||||||
strcmp(entry->d_name, "..") == 0)
|
strcmp(entry->d_name, "..") == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bind_mount_recursive(root, path);
|
bind_mount_recursive(root, shortpath);
|
||||||
}
|
}
|
||||||
else if (entry->d_type == DT_REG) {
|
else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
|
||||||
int ret;
|
int ret;
|
||||||
struct sys_mount_desc mount_desc;
|
struct sys_mount_desc mount_desc;
|
||||||
memset(&mount_desc, '\0', sizeof mount_desc);
|
|
||||||
char bind_path[PATH_MAX];
|
|
||||||
|
|
||||||
len = snprintf(bind_path, sizeof(bind_path) - 1,
|
__dprintf("reg/symlink found: %s\n", fullpath);
|
||||||
"%s/%s/%s", root, prefix, entry->d_name);
|
|
||||||
bind_path[len] = 0;
|
|
||||||
|
|
||||||
mount_desc.dev_name = bind_path;
|
if (lstat(shortpath, &st)) {
|
||||||
mount_desc.dir_name = path;
|
fprintf(stderr, "%s: warning: lstat of mount point (%s) failed: %s\n",
|
||||||
|
__func__, shortpath, strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&mount_desc, '\0', sizeof(mount_desc));
|
||||||
|
mount_desc.dev_name = fullpath;
|
||||||
|
mount_desc.dir_name = shortpath;
|
||||||
mount_desc.type = NULL;
|
mount_desc.type = NULL;
|
||||||
mount_desc.flags = MS_BIND | MS_PRIVATE;
|
mount_desc.flags = MS_BIND | MS_PRIVATE;
|
||||||
mount_desc.data = NULL;
|
mount_desc.data = NULL;
|
||||||
|
|
||||||
if ((ret = ioctl(fd, MCEXEC_UP_SYS_MOUNT,
|
if ((ret = ioctl(fd, MCEXEC_UP_SYS_MOUNT,
|
||||||
(unsigned long)&mount_desc)) != 0) {
|
(unsigned long)&mount_desc)) != 0) {
|
||||||
fprintf(stderr, "WARNING: failed to bind mount %s over %s: %d\n",
|
fprintf(stderr, "%s: warning: failed to bind mount %s over %s: %d\n",
|
||||||
bind_path, path, ret);
|
__func__, fullpath, shortpath, ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user