containerfs: copy xattrs on copyup

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano 2018-07-04 14:54:31 +02:00
parent 9bc5a110e0
commit d63934d540
No known key found for this signature in database
GPG Key ID: E4730F97F60286ED

43
main.c
View File

@ -1210,16 +1210,17 @@ copyup (struct lo_data *lo, struct lo_node *node)
int ret = -1; int ret = -1;
int dfd = -1, sfd = -1; int dfd = -1, sfd = -1;
struct stat st; struct stat st;
int r;
const size_t buf_size = 1 << 20; const size_t buf_size = 1 << 20;
char *buf = NULL; char *buf = NULL;
struct timespec times[2]; struct timespec times[2];
ssize_t xattr_len;
if (node->parent) if (node->parent)
{ {
r = create_directory (lo, node->parent); ret = create_directory (lo, node->parent);
if (r < 0) if (ret < 0)
return r; return ret;
} }
if (fstatat (node_dirfd (node), node->path, &st, AT_SYMLINK_NOFOLLOW) < 0) if (fstatat (node_dirfd (node), node->path, &st, AT_SYMLINK_NOFOLLOW) < 0)
@ -1283,21 +1284,41 @@ copyup (struct lo_data *lo, struct lo_node *node)
written = 0; written = 0;
{ {
r = TEMP_FAILURE_RETRY (write (dfd, buf + written, nread)); ret = TEMP_FAILURE_RETRY (write (dfd, buf + written, nread));
if (r < 0) if (ret < 0)
goto exit; goto exit;
written += ret;
written += r; nread -= ret;
nread -= r;
} }
while (nread); while (nread);
} }
times[0] = st.st_atim; times[0] = st.st_atim;
times[1] = st.st_mtim; times[1] = st.st_mtim;
if (futimens (dfd, times) < 0) ret = futimens (dfd, times);
if (ret < 0)
goto exit; goto exit;
xattr_len = flistxattr (sfd, buf, buf_size / 2);
if (xattr_len > 0)
{
char *it;
char *xattr_buf = buf + buf_size / 2;
for (it = buf; it - buf < xattr_len; it += strlen (it) + 1)
{
ssize_t s = fgetxattr (sfd, it, xattr_buf, buf_size / 2);
if (s < 0)
{
ret = -1;
goto exit;
}
ret = fsetxattr (dfd, it, xattr_buf, s, 0);
if (ret < 0)
goto exit;
}
}
success: success:
ret = 0; ret = 0;
@ -1310,6 +1331,8 @@ copyup (struct lo_data *lo, struct lo_node *node)
close (sfd); close (sfd);
if (dfd >= 0) if (dfd >= 0)
close (dfd); close (dfd);
if (ret < 0)
unlinkat (get_upper_layer (lo)->fd, node->path, 0);
errno = saved_errno; errno = saved_errno;
return ret; return ret;