mirror of
https://github.com/containers/fuse-overlayfs.git
synced 2025-09-17 03:05:02 -04:00
Merge pull request #94 from giuseppe/free-wd
main: make sure the work directory is empty
This commit is contained in:
commit
95120c05a0
@ -1215,7 +1215,6 @@ hash_print (const Hash_table *table)
|
|||||||
for (cursor = bucket; cursor; cursor = cursor->next)
|
for (cursor = bucket; cursor; cursor = cursor->next)
|
||||||
{
|
{
|
||||||
char const *s = cursor->data;
|
char const *s = cursor->data;
|
||||||
/* FIXME */
|
|
||||||
if (s)
|
if (s)
|
||||||
printf (" %s\n", s);
|
printf (" %s\n", s);
|
||||||
}
|
}
|
||||||
|
113
main.c
113
main.c
@ -1095,11 +1095,11 @@ safe_read_xattr (char **ret, int sfd, const char *name, size_t initial_size)
|
|||||||
buffer = tmp;
|
buffer = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer[s] == '\0';
|
|
||||||
|
|
||||||
if (s <= 0)
|
if (s <= 0)
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
|
buffer[s] = '\0';
|
||||||
|
|
||||||
/* Change owner. */
|
/* Change owner. */
|
||||||
*ret = buffer;
|
*ret = buffer;
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
@ -1148,27 +1148,40 @@ make_ovl_node (const char *path, struct ovl_layer *layer, const char *name, ino_
|
|||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct ovl_layer *it;
|
struct ovl_layer *it;
|
||||||
cleanup_free char *path = NULL;
|
cleanup_free char *npath = NULL;
|
||||||
|
|
||||||
path = strdup (ret->path);
|
npath = strdup (ret->path);
|
||||||
if (path == NULL)
|
if (npath == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (it = layer; it; it = it->next)
|
for (it = layer; it; it = it->next)
|
||||||
{
|
{
|
||||||
ssize_t s;
|
ssize_t s;
|
||||||
|
bool stat_only = false;
|
||||||
cleanup_free char *val = NULL;
|
cleanup_free char *val = NULL;
|
||||||
cleanup_free char *origin = NULL;
|
cleanup_free char *origin = NULL;
|
||||||
cleanup_close int fd = TEMP_FAILURE_RETRY (openat (it->fd, path, O_RDONLY|O_NONBLOCK|O_NOFOLLOW|O_PATH));
|
cleanup_close int fd = TEMP_FAILURE_RETRY (openat (it->fd, npath, O_RDONLY|O_NONBLOCK|O_NOFOLLOW));
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
continue;
|
{
|
||||||
|
/* It is a symlink, read only the ino. */
|
||||||
|
if (errno == ELOOP && fstatat (it->fd, npath, &st, AT_SYMLINK_NOFOLLOW) == 0)
|
||||||
|
{
|
||||||
|
ret->ino = st.st_ino;
|
||||||
|
ret->last_layer = it;
|
||||||
|
}
|
||||||
|
goto no_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* It is an open FD, stat the file and read the origin xattrs. */
|
||||||
if (fstat (fd, &st) == 0)
|
if (fstat (fd, &st) == 0)
|
||||||
{
|
{
|
||||||
ret->ino = st.st_ino;
|
ret->ino = st.st_ino;
|
||||||
ret->last_layer = it;
|
ret->last_layer = it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stat_only)
|
||||||
|
goto no_fd;
|
||||||
|
|
||||||
s = safe_read_xattr (&val, fd, PRIVILEGED_ORIGIN_XATTR, PATH_MAX);
|
s = safe_read_xattr (&val, fd, PRIVILEGED_ORIGIN_XATTR, PATH_MAX);
|
||||||
if (s > 0)
|
if (s > 0)
|
||||||
{
|
{
|
||||||
@ -1206,11 +1219,12 @@ make_ovl_node (const char *path, struct ovl_layer *layer, const char *name, ino_
|
|||||||
s = safe_read_xattr (&origin, fd, ORIGIN_XATTR, PATH_MAX);
|
s = safe_read_xattr (&origin, fd, ORIGIN_XATTR, PATH_MAX);
|
||||||
if (s > 0)
|
if (s > 0)
|
||||||
{
|
{
|
||||||
free (path);
|
free (npath);
|
||||||
path = origin;
|
npath = origin;
|
||||||
origin = NULL;
|
origin = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
no_fd:
|
||||||
if (parent && parent->last_layer == it)
|
if (parent && parent->last_layer == it)
|
||||||
break;
|
break;
|
||||||
if (fast_ino_check)
|
if (fast_ino_check)
|
||||||
@ -2567,27 +2581,22 @@ update_paths (struct ovl_node *node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
empty_dir (struct ovl_data *lo, struct ovl_node *node)
|
empty_dirfd (int fd)
|
||||||
{
|
{
|
||||||
cleanup_dir DIR *dp = NULL;
|
cleanup_dir DIR *dp = NULL;
|
||||||
cleanup_close int cleanup_fd = -1;
|
|
||||||
struct dirent *dent;
|
struct dirent *dent;
|
||||||
|
|
||||||
cleanup_fd = TEMP_FAILURE_RETRY (openat (get_upper_layer (lo)->fd, node->path, O_DIRECTORY));
|
dp = fdopendir (fd);
|
||||||
if (cleanup_fd < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (set_fd_opaque (cleanup_fd) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
dp = fdopendir (cleanup_fd);
|
|
||||||
if (dp == NULL)
|
if (dp == NULL)
|
||||||
return -1;
|
{
|
||||||
|
close (fd);
|
||||||
cleanup_fd = -1; /* It is not owned by dp. */
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
dent = readdir (dp);
|
dent = readdir (dp);
|
||||||
if (dent == NULL)
|
if (dent == NULL)
|
||||||
@ -2601,13 +2610,59 @@ empty_dir (struct ovl_data *lo, struct ovl_node *node)
|
|||||||
continue;
|
continue;
|
||||||
if (strcmp (dent->d_name, "..") == 0)
|
if (strcmp (dent->d_name, "..") == 0)
|
||||||
continue;
|
continue;
|
||||||
if (unlinkat (dirfd (dp), dent->d_name, 0) < 0)
|
|
||||||
unlinkat (dirfd (dp), dent->d_name, AT_REMOVEDIR);
|
ret = unlinkat (dirfd (dp), dent->d_name, 0);
|
||||||
|
if (ret < 0 && errno == EISDIR)
|
||||||
|
{
|
||||||
|
ret = unlinkat (dirfd (dp), dent->d_name, AT_REMOVEDIR);
|
||||||
|
if (ret < 0 && errno == ENOTEMPTY)
|
||||||
|
{
|
||||||
|
int dfd;
|
||||||
|
|
||||||
|
dfd = openat (dirfd (dp), dent->d_name, O_DIRECTORY);
|
||||||
|
if (dfd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = empty_dirfd (dfd);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = unlinkat (dirfd (dp), dent->d_name, AT_REMOVEDIR);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
empty_dir (struct ovl_data *lo, struct ovl_node *node)
|
||||||
|
{
|
||||||
|
cleanup_dir DIR *dp = NULL;
|
||||||
|
cleanup_close int cleanup_fd = -1;
|
||||||
|
struct dirent *dent;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
cleanup_fd = TEMP_FAILURE_RETRY (openat (get_upper_layer (lo)->fd, node->path, O_DIRECTORY));
|
||||||
|
if (cleanup_fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (set_fd_opaque (cleanup_fd) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = empty_dirfd (cleanup_fd);
|
||||||
|
|
||||||
|
cleanup_fd = -1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_rm (fuse_req_t req, fuse_ino_t parent, const char *name, bool dirp)
|
do_rm (fuse_req_t req, fuse_ino_t parent, const char *name, bool dirp)
|
||||||
{
|
{
|
||||||
@ -3120,6 +3175,7 @@ ovl_create (fuse_req_t req, fuse_ino_t parent, const char *name,
|
|||||||
fuse_reply_err (req, errno);
|
fuse_reply_err (req, errno);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fi->fh = fd;
|
fi->fh = fd;
|
||||||
fd = -1; /* Do not clean it up. */
|
fd = -1; /* Do not clean it up. */
|
||||||
|
|
||||||
@ -4355,8 +4411,7 @@ ovl_ioctl (fuse_req_t req, fuse_ino_t ino, unsigned int cmd, void *arg,
|
|||||||
{
|
{
|
||||||
case FS_IOC_GETVERSION:
|
case FS_IOC_GETVERSION:
|
||||||
case FS_IOC_GETFLAGS:
|
case FS_IOC_GETFLAGS:
|
||||||
if (fi->fh >= 0)
|
fd = fi->fh;
|
||||||
fd = fi->fh;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FS_IOC_SETVERSION:
|
case FS_IOC_SETVERSION:
|
||||||
@ -4478,7 +4533,7 @@ ovl_copy_file_range (fuse_req_t req, fuse_ino_t ino_in, off_t off_in, struct fus
|
|||||||
}
|
}
|
||||||
|
|
||||||
fd_dest = TEMP_FAILURE_RETRY (openat (node_dirfd (dnode), dnode->path, O_NONBLOCK|O_NOFOLLOW|O_WRONLY));
|
fd_dest = TEMP_FAILURE_RETRY (openat (node_dirfd (dnode), dnode->path, O_NONBLOCK|O_NOFOLLOW|O_WRONLY));
|
||||||
if (fd < 0)
|
if (fd_dest < 0)
|
||||||
{
|
{
|
||||||
fuse_reply_err (req, errno);
|
fuse_reply_err (req, errno);
|
||||||
return;
|
return;
|
||||||
@ -4763,6 +4818,7 @@ main (int argc, char *argv[])
|
|||||||
error (EXIT_FAILURE, 0, "workdir not specified");
|
error (EXIT_FAILURE, 0, "workdir not specified");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int dfd;
|
||||||
cleanup_free char *path = NULL;
|
cleanup_free char *path = NULL;
|
||||||
|
|
||||||
path = realpath (lo.workdir, NULL);
|
path = realpath (lo.workdir, NULL);
|
||||||
@ -4777,6 +4833,9 @@ main (int argc, char *argv[])
|
|||||||
lo.workdir_fd = open (lo.workdir, O_DIRECTORY);
|
lo.workdir_fd = open (lo.workdir, O_DIRECTORY);
|
||||||
if (lo.workdir_fd < 0)
|
if (lo.workdir_fd < 0)
|
||||||
error (EXIT_FAILURE, errno, "cannot open workdir");
|
error (EXIT_FAILURE, errno, "cannot open workdir");
|
||||||
|
|
||||||
|
dfd = dup (lo.workdir_fd);
|
||||||
|
empty_dirfd (dfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
umask (0);
|
umask (0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user