Skip to content

Comments

client: Handle empty pathnames for ceph_chownat() and ceph_statxat()#59936

Merged
mchangir merged 3 commits intoceph:mainfrom
anoopcs9:client-chown-statx-fixes
Dec 17, 2024
Merged

client: Handle empty pathnames for ceph_chownat() and ceph_statxat()#59936
mchangir merged 3 commits intoceph:mainfrom
anoopcs9:client-chown-statx-fixes

Conversation

@anoopcs9
Copy link
Contributor

@anoopcs9 anoopcs9 commented Sep 23, 2024

man fchownat(2) and man statx(2) explains about the special case where empty pathnames are valid with AT_EMPTY_PATH flag specified. But current client code crashes for ceph_chownat() and ceph_statxat() under this situation which should be gracefully handled as per the standards.

Fixes: https://tracker.ceph.com/issues/68189

Review with: git show -w

@github-actions github-actions bot added cephfs Ceph File System tests labels Sep 23, 2024
@anoopcs9
Copy link
Contributor Author

ceph_chownat():

#0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
#1  0x00007fea2757f6d3 in __pthread_kill_internal (threadid=<optimized out>, signo=6) at pthread_kill.c:78
#2  0x00007fea27526c4e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x00007fea2750e902 in __GI_abort () at abort.c:79
#4  0x00007fea266dabf0 in std::__glibcxx_assert_fail (file=file@entry=0x7fea27849680 "/usr/include/c++/14/string_view", line=line@entry=256, 
    function=function@entry=0x7fea27849580 "constexpr const std::basic_string_view<_CharT, _Traits>::value_type& std::basic_string_view<_CharT, _Traits>::operator[](size_type) const [with _CharT = char; _Traits = std::char_traits<char>; const_r"..., condition=condition@entry=0x7fea27854568 "__pos < this->_M_len") at ../../../../../libstdc++-v3/src/c++11/assert_fail.cc:41
#5  0x00007fea2774f6df in std::basic_string_view<char, std::char_traits<char> >::operator[] (this=<optimized out>, __pos=<optimized out>) at /usr/include/c++/14/string_view:254
#6  std::basic_string_view<char, std::char_traits<char> >::operator[] (this=<synthetic pointer>, __pos=0) at /usr/include/c++/14/string_view:254
#7  filepath::set_path (this=0x7fff29cd1e30, s=...) at /usr/src/debug/ceph-18.2.4-1.fc40.x86_64/src/include/filepath.h:101
#8  filepath::filepath (this=<optimized out>, s=<optimized out>, this=<optimized out>, s=<optimized out>) at /usr/src/debug/ceph-18.2.4-1.fc40.x86_64/src/include/filepath.h:94
#9  0x00007fea277a4764 in Client::chownat (this=0x32794a40, dirfd=10, relpath=0x4020d0 "", new_uid=65534, new_gid=65534, flags=0, perms=...)
    at /usr/src/debug/ceph-18.2.4-1.fc40.x86_64/src/client/Client.cc:8835
#10 0x00007fea2772a0c3 in ceph_chownat (cmount=<optimized out>, dirfd=<optimized out>, relpath=<optimized out>, uid=<optimized out>, gid=<optimized out>, flags=<optimized out>)
    at /usr/src/debug/ceph-18.2.4-1.fc40.x86_64/src/libcephfs.cc:1181
#11 0x00000000004013e1 in main ()

ceph_statxat():

#0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
#1  0x00007f6528fc26d3 in __pthread_kill_internal (threadid=<optimized out>, signo=6) at pthread_kill.c:78
#2  0x00007f6528f69c4e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x00007f6528f51902 in __GI_abort () at abort.c:79
#4  0x00007f65280dabf0 in std::__glibcxx_assert_fail (file=file@entry=0x7f652928c680 "/usr/include/c++/14/string_view", line=line@entry=256, 
    function=function@entry=0x7f652928c580 "constexpr const std::basic_string_view<_CharT, _Traits>::value_type& std::basic_string_view<_CharT, _Traits>::operator[](size_type) const [with _CharT = char; _Traits = std::char_traits<char>; const_r"..., condition=condition@entry=0x7f6529297568 "__pos < this->_M_len") at ../../../../../libstdc++-v3/src/c++11/assert_fail.cc:41
#5  0x00007f65291926df in std::basic_string_view<char, std::char_traits<char> >::operator[] (this=<optimized out>, __pos=<optimized out>) at /usr/include/c++/14/string_view:254
#6  std::basic_string_view<char, std::char_traits<char> >::operator[] (this=<synthetic pointer>, __pos=0) at /usr/include/c++/14/string_view:254
#7  filepath::set_path (this=0x7ffe98822e10, s=...) at /usr/src/debug/ceph-18.2.4-1.fc40.x86_64/src/include/filepath.h:101
#8  filepath::filepath (this=<optimized out>, s=<optimized out>, this=<optimized out>, s=<optimized out>) at /usr/src/debug/ceph-18.2.4-1.fc40.x86_64/src/include/filepath.h:94
#9  0x00007f65291fad9e in Client::statxat (this=0x3bd71310, dirfd=10, relpath=0x4020d0 "", stx=0x7ffe98822ee0, perms=..., want=4095, flags=0)
    at /usr/src/debug/ceph-18.2.4-1.fc40.x86_64/src/client/Client.cc:11507
#10 0x00007f652916bd10 in ceph_statxat (cmount=<optimized out>, dirfd=<optimized out>, relpath=<optimized out>, stx=<optimized out>, want=<optimized out>, flags=<optimized out>)
    at /usr/src/debug/ceph-18.2.4-1.fc40.x86_64/src/libcephfs.cc:986
#11 0x0000000000401428 in main ()

@anoopcs9 anoopcs9 marked this pull request as ready for review September 23, 2024 16:14
@anoopcs9 anoopcs9 force-pushed the client-chown-statx-fixes branch from 5e6b231 to 91f9ab9 Compare September 24, 2024 07:17
@dparmar18 dparmar18 requested a review from a team September 24, 2024 09:10
Copy link
Contributor

@dparmar18 dparmar18 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

@anoopcs9
Copy link
Contributor Author

jenkins test make check

@anoopcs9
Copy link
Contributor Author

jenkins test make check arm64

@anoopcs9
Copy link
Contributor Author

jenkins test windows

@anoopcs9
Copy link
Contributor Author

jenkins test make check arm64

@dparmar18
Copy link
Contributor

jenkins test windows

Copy link
Contributor

@dparmar18 dparmar18 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what i thought in my last approval was a comment, sorry!

@batrick
Copy link
Member

batrick commented Sep 26, 2024

Windows test failure ticket: https://tracker.ceph.com/issues/68282

Also appears in #58936. Doesn't appear to be caused by this PR.

Copy link
Contributor

@chrisphoffman chrisphoffman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also do a teuthology run to show that the linux code path passes?

@anoopcs9 anoopcs9 force-pushed the client-chown-statx-fixes branch from 91f9ab9 to 9462874 Compare September 27, 2024 06:51
@anoopcs9
Copy link
Contributor Author

Can you also do a teuthology run to show that the linux code path passes?

Someone else will have to perform a teuthology run on my behalf I guess.

@anoopcs9
Copy link
Contributor Author

jenkins test api

@petrutlucian94
Copy link
Contributor

petrutlucian94 commented Sep 27, 2024

The Windows CI failure is legitimate, the test is failing on a clean Linux-only vstart environment:

ubuntu@ubuntu-ceph:/mnt/data/workspace/ceph_linux/build$ ./bin/ceph_test_libcephfs --gtest_filter="Lib
CephFS.Statxat"
Note: Google Test filter = LibCephFS.Statxat
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from LibCephFS
[ RUN      ] LibCephFS.Statxat
/mnt/data/workspace/ceph_linux/src/test/libcephfs/test.cc:2706: Failure
Expected equality of these values:
  ceph_statxat(cmount, dir_fd, "", &stx, 0x1000, 0)
    Which is: -2
  0
[  FAILED  ] LibCephFS.Statxat (41 ms)
[----------] 1 test from LibCephFS (41 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (41 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] LibCephFS.Statxat

The other Windows failure was legitimate as well, #58936 (forcefully merged) broke MDS, which now crashes whenever we attempt to do a mount: #58936 (comment)

Copy link
Contributor

@chrisphoffman chrisphoffman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also seeing the same test failure as seen in: #59936 (comment)

Can you track this down?

@dparmar18 dparmar18 self-requested a review September 27, 2024 18:40
@anoopcs9 anoopcs9 force-pushed the client-chown-statx-fixes branch from 9462874 to 143528c Compare October 16, 2024 18:03
@anoopcs9
Copy link
Contributor Author

anoopcs9 commented Oct 16, 2024

I'm also seeing the same test failure as seen in: #59936 (comment)

Can you track this down?

Oh..that was a silly mistake from my side mixing up the order of flags argument with want for ceph_statxat() in tests. PTAL.

Copy link
Contributor

@chrisphoffman chrisphoffman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running into an issue on linux:

$ ceph_test_libcephfs --gtest_filter=*Statxat
Note: Google Test filter = *Statxat
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from LibCephFS
[ RUN      ] LibCephFS.Statxat
ceph/src/test/libcephfs/test.cc:2713: Failure
Expected equality of these values:
  ceph_statxat(cmount, dir_fd, "", &stx, 0, 0x1000)
    Which is: -22
  0
[  FAILED  ] LibCephFS.Statxat (60 ms)
[----------] 1 test from LibCephFS (60 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (60 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] LibCephFS.Statxat

 1 FAILED TEST

Do you have a linux based machine to do local tests on? After you address the above, can you run both tests you modified and post here the output passing?

@anoopcs9
Copy link
Contributor Author

Running into an issue on linux:

$ ceph_test_libcephfs --gtest_filter=*Statxat
Note: Google Test filter = *Statxat
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from LibCephFS
[ RUN      ] LibCephFS.Statxat
ceph/src/test/libcephfs/test.cc:2713: Failure
Expected equality of these values:
  ceph_statxat(cmount, dir_fd, "", &stx, 0, 0x1000)
    Which is: -22
  0
[  FAILED  ] LibCephFS.Statxat (60 ms)
[----------] 1 test from LibCephFS (60 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (60 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] LibCephFS.Statxat

 1 FAILED TEST

Do you have a linux based machine to do local tests on? After you address the above, can you run both tests you modified and post here the output passing?

Fine, this time its -22 which might point towards something internal preventing the added logic to work.

Alright I won't bother you hereafter until I make the tests work as expected. Thanks for running it through all this while.

@anoopcs9 anoopcs9 requested a review from dparmar18 October 23, 2024 05:57
@dparmar18 dparmar18 self-assigned this Oct 23, 2024
Copy link
Contributor

@chrisphoffman chrisphoffman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests look good!

Since we're adding support for AT_EMPTY_PATH for some calls, I recommend we look and add support to all calls that normally handle it. That way we won't have to circle back to this in the future.

For example:
link, stat, lstat etc

Copy link
Contributor Author

@anoopcs9 anoopcs9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're adding support for AT_EMPTY_PATH for some calls, I recommend we look and add support to all calls that normally handle it. That way we won't have to circle back to this in the future.

This was briefly touched on previously here and the current PR was a followup to that discussion.

For example: link, stat, lstat etc

IIUC, AT_EMPTY_PATH flag is only relevant with *at() calls and not others. With an implementation missing for linkat() I don't think we are left with any APIs accepting AT_EMPTY_PATH. faccessat() and utimensat() are comparatively recent additions(since Linux 5.8) to honour this flag which I prefer to be considered after a while(as we might still have systems with Linux < 5.8).

@anoopcs9 anoopcs9 force-pushed the client-chown-statx-fixes branch from 235e3b1 to 4598444 Compare October 25, 2024 09:20
Copy link
Contributor

@dparmar18 dparmar18 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@chrisphoffman
Copy link
Contributor

Since we're adding support for AT_EMPTY_PATH for some calls, I recommend we look and add support to all calls that normally handle it. That way we won't have to circle back to this in the future.

This was briefly touched on previously here and the current PR was a followup to that discussion.

I missed that, wanted to make sure we followed up on remaining calls. Thanks!

For example: link, stat, lstat etc

IIUC, AT_EMPTY_PATH flag is only relevant with *at() calls and not others. With an implementation missing for linkat() I don't think we are left with any APIs accepting AT_EMPTY_PATH. faccessat() and utimensat() are comparatively recent additions(since Linux 5.8) to honour this flag which I prefer to be considered after a while(as we might still have systems with Linux < 5.8).

I came up with those examples above from the man pages. I agree it seems like it should only apply at *at() calls.

That being said, I'm still a bit confused if this is actually the case. There's statx that accept flags and then call the *at() functions directly.

See:

ceph/src/client/Client.cc

Lines 8583 to 8588 in 4598444

int Client::statx(const char *relpath, struct ceph_statx *stx,
const UserPerm& perms,
unsigned int want, unsigned int flags)
{
return statxat(CEPHFS_AT_FDCWD, relpath, stx, perms, want, flags);
}

See the man page here to see AT_EMPTY_PATH:
https://man7.org/linux/man-pages/man2/statx.2.html

nit: While that shows there's no code that needs to be changed, I recommend changes in libcephfs.h show AT_EMPTY_PATH does work now for statx.

* @param flags bitfield that can be used to set AT_* modifier flags (AT_STATX_SYNC_AS_STAT, AT_STATX_FORCE_SYNC, AT_STATX_DONT_SYNC and AT_SYMLINK_NOFOLLOW)

Copy link
Contributor

@chrisphoffman chrisphoffman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM- thanks for all your work and discussion!

@anoopcs9
Copy link
Contributor Author

That being said, I'm still a bit confused if this is actually the case. There's statx that accept flags and then call the *at() functions directly.

See:

ceph/src/client/Client.cc

Lines 8583 to 8588 in 4598444

int Client::statx(const char *relpath, struct ceph_statx *stx,
const UserPerm& perms,
unsigned int want, unsigned int flags)
{
return statxat(CEPHFS_AT_FDCWD, relpath, stx, perms, want, flags);
}

See the man page here to see AT_EMPTY_PATH: https://man7.org/linux/man-pages/man2/statx.2.html

tl;dr
ceph_statx() doesn't comply with the standard statx() because it doesn't accept the required dirfd argument instead always operates at AT_FDCWD and thus we have ceph_statxat() to handle this case.

longer version
As you already know we have struct stat and struct statx these days although I think struct statx is preferred. Normal calls like stat(), fstat(), lstat() and fstatat() operates with struct stat. Among these only fstatat() is relevant for AT_EMPTY_PATH flag. But ceph doesn't have an equivalent *at() API designed to operate with struct stat. Instead we have two variants to work with struct statx namely ceph_statx() and ceph_statxat(). It is the latter which accepts a dirfd argument. That's why it make sense to honour AT_EMPTY_PATH flag only for ceph_statxat() and not ceph_statx().

Given that, I think it would make more sense to reference statx(2) than fstatat(2) in the commit message/PR description. Let me know if I should update once more.

nit: While that shows there's no code that needs to be changed, I recommend changes in libcephfs.h show AT_EMPTY_PATH does work now for statx.

* @param flags bitfield that can be used to set AT_* modifier flags (AT_STATX_SYNC_AS_STAT, AT_STATX_FORCE_SYNC, AT_STATX_DONT_SYNC and AT_SYMLINK_NOFOLLOW)

I think the earlier explanation invalidates the above suggestion.

@rishabh-d-dave rishabh-d-dave added the wip-rishabh-testing Rishabh's testing label label Oct 29, 2024
man fchownat(2)[1] says the following:
. . .
AT_EMPTY_PATH (since Linux 2.6.39)
    If pathname is an empty string, operate on the file referred to by
    dirfd (which may have been obtained using the open(2) O_PATH flag).
    In this case, dirfd can refer to any type of file, not just a
    directory. If dirfd is AT_FDCWD, the call operates on the current
    working directory.
. . .

Look out for an empty pathname and use the relative fd's inode in the
presence of AT_EMPTY_PATH flag before calling internal _setattr().

Fixes: https://tracker.ceph.com/issues/68189

Review with: git show -w

[1] https://www.man7.org/linux/man-pages/man2/fchownat.2.html

Signed-off-by: Anoop C S <[email protected]>
flags parameter for ceph_statxat() API is supposed to accept only
AT_STATX_DONT_SYNC and AT_SYMLINK_NOFOLLOW. Modify the corresponding
documentation to reflect the acceptance of above two flags.

Signed-off-by: Anoop C S <[email protected]>
man statx(2)[1] says the following:
. . .
AT_EMPTY_PATH
    If pathname is an empty string, operate on the file referred to by
    dirfd (which may have been obtained using the open(2) O_PATH flag).
    In this case, dirfd can refer to any type of file, not just a
    directory.

    If dirfd is AT_FDCWD, the call operates on the current working
    directory.
. . .

Look out for an empty pathname and use the relative fd's inode in the
presence of AT_EMPTY_PATH flag before calling internal _getattr().

Fixes: https://tracker.ceph.com/issues/68189

Review with: git show -w

[1] https://www.man7.org/linux/man-pages/man2/statx.2.html

Signed-off-by: Anoop C S <[email protected]>
@anoopcs9 anoopcs9 force-pushed the client-chown-statx-fixes branch from 4598444 to edd7fe7 Compare November 7, 2024 05:17
@anoopcs9
Copy link
Contributor Author

anoopcs9 commented Nov 7, 2024

I've updated commit message and PR description to link statx(2) instead of fstatat(2).

@anoopcs9
Copy link
Contributor Author

@vshankar can I have the final blessings here?

@vshankar
Copy link
Contributor

@vshankar can I have the final blessings here?

@mchangir is involved in running tests for sometime (I've been tied up with some cephalocon stuff).

@mchangir
Copy link
Contributor

joscollin pushed a commit to joscollin/ceph that referenced this pull request Dec 12, 2024
* refs/pull/59936/head:
	client: Gracefully handle empty pathname for statxat()
	libcephfs.h: Fix API documentation for ceph_statxat
	client: Gracefully handle empty pathname for chownat()

Reviewed-by: Dhairya Parmar <[email protected]>
Reviewed-by: Christopher Hoffman <[email protected]>
@anoopcs9
Copy link
Contributor Author

This PR is under test in https://tracker.ceph.com/issues/69069.

@mchangir Where are we with the teuthology runs? Is this good to go in now?

@mchangir
Copy link
Contributor

This PR is under test in https://tracker.ceph.com/issues/69069.

@mchangir Where are we with the teuthology runs? Is this good to go in now?

looks okay ... I've just finished reviewing the QA run
Venky should be able to ack it in a day or two

@mchangir
Copy link
Contributor

wiki section for qa run

@vshankar
Copy link
Contributor

This PR is under test in https://tracker.ceph.com/issues/69069.

@mchangir Where are we with the teuthology runs? Is this good to go in now?

looks okay ... I've just finished reviewing the QA run Venky should be able to ack it in a day or two

If the test run passes, please go ahead and merge. @mchangir

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cephfs Ceph File System tests wip-rishabh-testing Rishabh's testing label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants