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
|
||||
/* bind-mount files under <root>/<prefix> over <prefix> recursively */
|
||||
void bind_mount_recursive(const char *root, char *prefix)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
char path[PATH_MAX];
|
||||
int len;
|
||||
|
||||
len = snprintf(path, sizeof(path) - 1, "%s/%s", root, prefix);
|
||||
path[len] = 0;
|
||||
snprintf(path, sizeof(path), "%s/%s", root, prefix);
|
||||
path[sizeof(path) - 1] = 0;
|
||||
|
||||
if (!(dir = opendir(path))) {
|
||||
return;
|
||||
}
|
||||
|
||||
while ((entry = readdir(dir))) {
|
||||
len = snprintf(path, sizeof(path) - 1,
|
||||
"%s/%s", prefix, entry->d_name);
|
||||
path[len] = 0;
|
||||
char fullpath[PATH_MAX];
|
||||
char shortpath[PATH_MAX];
|
||||
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 ||
|
||||
strcmp(entry->d_name, "..") == 0)
|
||||
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;
|
||||
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,
|
||||
"%s/%s/%s", root, prefix, entry->d_name);
|
||||
bind_path[len] = 0;
|
||||
__dprintf("reg/symlink found: %s\n", fullpath);
|
||||
|
||||
mount_desc.dev_name = bind_path;
|
||||
mount_desc.dir_name = path;
|
||||
if (lstat(shortpath, &st)) {
|
||||
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.flags = MS_BIND | MS_PRIVATE;
|
||||
mount_desc.data = NULL;
|
||||
|
||||
if ((ret = ioctl(fd, MCEXEC_UP_SYS_MOUNT,
|
||||
(unsigned long)&mount_desc)) != 0) {
|
||||
fprintf(stderr, "WARNING: failed to bind mount %s over %s: %d\n",
|
||||
bind_path, path, ret);
|
||||
fprintf(stderr, "%s: warning: failed to bind mount %s over %s: %d\n",
|
||||
__func__, fullpath, shortpath, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user