repo/checkout: Verify early if src/destination are on same device
At least in all Linux kernels up to today, one can never `link()` across devices, so we might as well verify that up front. This will help for a future patch to add a new type of union-add checkout, since Linux checks for `EEXIST` before `EXDEV`. Closes: #714 Approved by: jlebon
This commit is contained in:
parent
3219a5d0ee
commit
ff34810097
|
|
@ -641,6 +641,8 @@ checkout_tree_at (OstreeRepo *self,
|
||||||
gboolean did_exist = FALSE;
|
gboolean did_exist = FALSE;
|
||||||
glnx_fd_close int destination_dfd = -1;
|
glnx_fd_close int destination_dfd = -1;
|
||||||
int res;
|
int res;
|
||||||
|
struct stat repo_dfd_stat;
|
||||||
|
struct stat destination_stat;
|
||||||
g_autoptr(GVariant) xattrs = NULL;
|
g_autoptr(GVariant) xattrs = NULL;
|
||||||
g_autoptr(GFileEnumerator) dir_enum = NULL;
|
g_autoptr(GFileEnumerator) dir_enum = NULL;
|
||||||
|
|
||||||
|
|
@ -666,6 +668,25 @@ checkout_tree_at (OstreeRepo *self,
|
||||||
&destination_dfd, error))
|
&destination_dfd, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (fstat (self->repo_dir_fd, &repo_dfd_stat) < 0)
|
||||||
|
{
|
||||||
|
glnx_set_error_from_errno (error);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (fstat (destination_dfd, &destination_stat) < 0)
|
||||||
|
{
|
||||||
|
glnx_set_error_from_errno (error);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options->no_copy_fallback && repo_dfd_stat.st_dev != destination_stat.st_dev)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Unable to do hardlink checkout across devices (src=%lu destination=%lu)",
|
||||||
|
repo_dfd_stat.st_dev, destination_stat.st_dev);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the xattrs now, so any derived labeling works */
|
/* Set the xattrs now, so any derived labeling works */
|
||||||
if (!did_exist && options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
|
if (!did_exist && options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,6 @@ assert_file_has_content mnt/test2-checkout-copy-fallback/anewfile-for-fuse anewf
|
||||||
if ${CMD_PREFIX} ostree --repo=repo checkout -UH test2 mnt/test2-checkout-copy-hardlinked 2>err.txt; then
|
if ${CMD_PREFIX} ostree --repo=repo checkout -UH test2 mnt/test2-checkout-copy-hardlinked 2>err.txt; then
|
||||||
assert_not_reached "Checking out via hardlinks across mountpoint unexpectedly succeeded!"
|
assert_not_reached "Checking out via hardlinks across mountpoint unexpectedly succeeded!"
|
||||||
fi
|
fi
|
||||||
assert_file_has_content err.txt "Invalid cross-device link"
|
assert_file_has_content err.txt "Unable to do hardlink checkout across devices"
|
||||||
|
|
||||||
echo "ok checkout copy fallback"
|
echo "ok checkout copy fallback"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue