Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GCC 14 compatibility fixes #54974

Merged
merged 2 commits into from Jan 14, 2024
Merged

GCC 14 compatibility fixes #54974

merged 2 commits into from Jan 14, 2024

Conversation

fweimer-rh
Copy link
Contributor

These changes should make it possible to build the C parts of Ceph with GCC 14.

Related to:

Checklist

  • Tracker (select at least one)
    • References tracker ticket
    • Very recent bug; references commit where it was introduced
    • New feature (ticket optional)
    • Doc update (no ticket needed)
    • Code cleanup (no ticket needed)
  • Component impact
    • Affects Dashboard, opened tracker ticket
    • Affects Orchestrator, opened tracker ticket
    • No impact that needs to be tracked
  • Documentation (select at least one)
    • Updates relevant documentation
    • No doc update is appropriate
  • Tests (select at least one)

Copy link
Contributor

@idryomov idryomov left a comment

Choose a reason for hiding this comment

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

@@ -525,7 +526,7 @@ cdef extern from "rbd/librbd.h" nogil:
int rbd_snap_unprotect(rbd_image_t image, const char *snap_name)
int rbd_snap_is_protected(rbd_image_t image, const char *snap_name,
int *is_protected)
int rbd_snap_exists(rbd_image_t image, const char *snapname, bint *exists)
int rbd_snap_exists(rbd_image_t image, const char *snapname, libcpp.bool *exists)
Copy link
Contributor

@idryomov idryomov Dec 20, 2023

Choose a reason for hiding this comment

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

Several Ceph APIs use bool * types, which correspond to libcpp.bool * types in Cython. The bint type has an incorrect size 4 and cannot be used as a replacement.

Part of the GCC 14 preparations, but this looks like a real bug.

These Cython bindings are against our C API, not C++ API. I thought Cython's libcpp was for working with C++?

On top of that, bint and libcpp.bool appear to be the same thing, at least at first sight:

https://github.com/cython/cython/blob/e57193ccc5337f08b6efd4225d21594906df0cb8/Cython/Includes/libcpp/__init__.pxd#L2

Could you please elaborate?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These Cython bindings are against our C API, not C++ API. I thought Cython's libcpp was for working with C++?

The Cython type libcpp.bool is translated bool, which works because the Ceph API uses bool and <stdbool.h>.

I'm not a Cython expert, but I couldn't find better type to use here.

On top of that, bint and libcpp.bool appear to be the same thing, at least at first sight:

https://github.com/cython/cython/blob/e57193ccc5337f08b6efd4225d21594906df0cb8/Cython/Includes/libcpp/__init__.pxd#L2

Could you please elaborate?

I think the way this works is that from the Python view, it's treated as bint (with conversion to the Python bool type etc.). Because it's an extern cdef, bool is preserved in the translation, which gives us the right type with the right ABI.

EDIT Earlier comment was wrong.

Copy link
Contributor

Choose a reason for hiding this comment

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

Makes sense, although it's clear that libcpp was intended only for C++ because it doesn't actually pull in stdbool.h. Looks like someone else noticed this too: cython/cython#5730.

I'm still confused about

Part of the GCC 14 preparations, but this looks like a real bug.

though. Given that it's initialized (bint _exists = False, translated to int <generated_name> = 0;), that the API sets it to either true or false, and that we then do bool(_exists != 0), what can go wrong? Can you include the warning or error reported by GCC 14 in the commit message?

Copy link
Contributor

@idryomov idryomov Dec 21, 2023

Choose a reason for hiding this comment

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

I'm asking because if it's a real bug, we would need to file a tracker ticket and backport this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If all the callers do this bint _exists = False step, then this should be okay-ish, as long as LTO isn't used and a compiler barrier exists.

I've updated the commit message to include the compiler error.

Copy link
Contributor

Choose a reason for hiding this comment

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

we could add:

cdef extern from "<stdbool.h>":
    ctypedef bint bool

I think that would mess with some bool(...) syntax in Python code, like:

ret = (<object>cb)(offset, length, bool(write))

If it's easy to adjust, let's do it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, as I look at this more, in particular src/pybind/rbd/c_rbd.pxd, there are more instances of bint being used in place of a bool, both in structs:

    ctypedef struct rbd_snap_mirror_namespace_t:
        rbd_snap_mirror_state_t state
        size_t mirror_peer_uuids_count
        char *mirror_peer_uuids
        bint complete
        char *primary_mirror_uuid
        uint64_t primary_snap_id
        uint64_t last_copied_object_number

for

typedef struct {
  rbd_snap_mirror_state_t state;
  size_t mirror_peer_uuids_count;
  char *mirror_peer_uuids;
  bool complete;
  char *primary_mirror_uuid;
  uint64_t primary_snap_id;
  uint64_t last_copied_object_number;
} rbd_snap_mirror_namespace_t;

and as a non-pointer parameter:

    int rbd_mirror_image_disable(rbd_image_t image, bint force)

for

CEPH_RBD_API int rbd_mirror_image_disable(rbd_image_t image, bool force);

We probably need to clean up all of bint usage here...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding

cdef extern from "<stdbool.h>":
    pass

just to src/pybind/rbd/mock_rbd.pxi should work around it. Feel free to force push that and we will see.

I had to add a similar change to src/pybind/rgw/rgw.pyx, but the documentation builds now.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you move the RBD one to .pyx or the RGW one to .pxi so that we are consistent?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you move the RBD one to .pyx or the RGW one to .pxi so that we are consistent?

This should be fixed in the latest rebase.

We probably need to clean up all of bint usage here...

I think use of bint is only a problem if it is used in such a way that Cython emits an int type for it. If it's nested in a struct or used to describe another type (like libcpp does for exposing bool), the C layout discrepancy does not matter. Not ideal, but not an immediate problem either.

@fweimer-rh
Copy link
Contributor Author

Please sign off commits per https://github.com/ceph/ceph/blob/main/SubmittingPatches.rst#sign-your-work.

Done.

src/pybind/rgw/mock_rgw.pxi Outdated Show resolved Hide resolved
src/pybind/rgw/rgw.pyx Show resolved Hide resolved
src/tracing/librados.tp Outdated Show resolved Hide resolved
src/tracing/librados.tp Outdated Show resolved Hide resolved
This fixes type errors like this:

In file included from /usr/include/lttng/tracepoint-event.h:69,
                 from …-build/include/tracing/librados.h:4143,
                 from …/src/tracing/librados.c:6
:
…-build/include/tracing/librados.h:
 In function ‘lttng_ust__event_probe__librados___rados_mon_command_exit’:
…-build/include/tracing/librados.h:477:9: error: initialization of ‘size_t’ {aka ‘long unsigned int’} from ‘size_t *’ {aka ‘long unsigned int *’} makes integer from pointer without a cast
  477 |         ceph_ctf_integerp(size_t, outslen, outslen)
      |         ^~~~~~~~~~~~~~~~~

GCC 14 will likely treat these type mismatches as an error
and fail the build.

Signed-off-by: Florian Weimer <fweimer@redhat.com>
Several Ceph APIs use bool * types, which correspond to
libcpp.bool * types in Cython.  The bint type has an incorrect
size 4 and cannot be used as a replacement.

This prevents a compilation failure with future compilers:

…-build/src/pybind/rbd/rbd.c: In function ‘__pyx_pf_3rbd_3RBD_104namespace_exists’:
…-build/src/pybind/rbd/rbd.c:42165:76: error: passing argument 3 of ‘rbd_namespace_exists’ from incompatible pointer type
42165 |         __pyx_v_ret = rbd_namespace_exists(__pyx_v__ioctx, __pyx_v__name, (&__pyx_v__exists));
      |                                                                           ~^~~~~~~~~~~~~~~~~
      |                                                                            |
      |                                                                            int *
In file included from …-build/src/pybind/rbd/rbd.c:1268:
…/src/include/rbd/librbd.h:1496:45: note: expected ‘_Bool *’ but argument is of type ‘int *’
 1496 |                                       bool *exists);
      |                                             ^

Signed-off-by: Florian Weimer <fweimer@redhat.com>
@idryomov idryomov added the rgw label Jan 8, 2024
@idryomov
Copy link
Contributor

idryomov commented Jan 8, 2024

@cbodley A change in RGW bindings here, PTAL.

@idryomov idryomov requested a review from a team January 8, 2024 15:30
@idryomov
Copy link
Contributor

@idryomov
Copy link
Contributor

@cbodley @mattbenjamin This is good to merge from the RBD perspective. Can I get a +1 from the RGW side?

@idryomov idryomov merged commit d5457a2 into ceph:main Jan 14, 2024
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants