From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Victor Toso <victortoso@redhat.com>
Cc: qemu-devel@nongnu.org, John Snow <jsnow@redhat.com>,
Eric Blake <eblake@redhat.com>,
Markus Armbruster <armbru@redhat.com>
Subject: Re: [RFC PATCH v1 1/8] qapi: golang: Generate qapi's enum types in Go
Date: Tue, 10 May 2022 12:19:57 +0100 [thread overview]
Message-ID: <YnpKXf4fynWupiVC@redhat.com> (raw)
In-Reply-To: <20220510111532.tm5cyljsxxnvk7l2@tapioca>
On Tue, May 10, 2022 at 01:15:32PM +0200, Victor Toso wrote:
> Hi,
>
> On Tue, May 10, 2022 at 11:06:16AM +0100, Daniel P. Berrangé wrote:
> > On Sat, Apr 02, 2022 at 12:40:57AM +0200, Victor Toso wrote:
> > > This patch handles QAPI enum types and generates its equivalent in Go.
> > >
> > > The highlights of this implementation are:
> > >
> > > 1. For each QAPI enum, we will define an int32 type in Go to be the
> > > assigned type of this specific enum
> >
> > I think there's a potential case to be made for considering
> > representation of enums as strings in Golang, as it more
> > gracefully degrades.
> >
> > Consider the 'SHUTDOWN' event in QEMU, which has a 'reason' field.
> >
> > This implementation has
> >
> > type ShutdownCause int32
> >
> > const (
> > ShutdownCauseNone ShutdownCause = iota
> > ShutdownCauseHostError // An error prevents further use of guest
> > ShutdownCauseHostQmpQuit // Reaction to the QMP command 'quit'
> > ShutdownCauseHostQmpSystemReset // Reaction to the QMP command 'system_reset'
> > ShutdownCauseHostSignal // Reaction to a signal, such as SIGINT
> > ShutdownCauseHostUi // Reaction to a UI event, like window close
> > ShutdownCauseGuestShutdown // Guest shutdown/suspend request, via ACPI or other hardware-specific means
> > ShutdownCauseGuestReset // Guest reset request, and command line turns that into a shutdown
> > ShutdownCauseGuestPanic // Guest panicked, and command line turns that into a shutdown
> > ShutdownCauseSubsystemReset // Partial guest reset that does not trigger QMP events and ignores --no-reboot. This is useful for sanitizing hypercalls on s390 that are used during kexec/kdump/boot
> > )
> >
> > and
> >
> > type ShutdownEvent struct {
> > Guest bool `json:"guest"` // If true, the shutdown was triggered by a guest request (such as a guest-initiated ACPI shutdown request or other hardware-specific action) rather than a host request (such as sending qemu a SIGINT). (since 2.10)
> > Reason ShutdownCause `json:"reason"` // The @ShutdownCause which resulted in the SHUTDOWN. (since 4.0)
> > }
> >
> > Consider that the application is compiled against the QAPI
> > generated API from QEMU 7.0. The application is believed to run
> > happily against 7.1, because app doesn't need any of the
> > functionality added in 7.1 QAPI. But consider that QEMU 7.1
> > had introduced a new shutdown reason value.
> >
> > The application may want to know that the guest has shutdown,
> > but does NOT care about the reason for the shutdown.
> >
> > Since the ShutdownReason is implemented as an int though, the
> > unmarshalling for the reason field is going to fail.
>
> Marshalling does error if you try to convert an int that is not
> in the range of the enum type.
>
> Unmarshalling should not error in this case, but the field ends
> up not being set which defaults to 0 (in this case,
> ShutdownCauseNone). That could mislead the *actual* reason but
> not without a warning which is expected in this case, imho.
>
> (I know is not an actual warning, just a Println, but it'll be
> fixed in the next iteration)
I don't thinnk we should be emitting warnings/printlns at all
in this case though. The app should be able to consume the
enum without needing a warning. If the app wants to validate
against a specific set of constants, it can decide to emit
a warning if there was a case it can't handle. We shouldn't
emit warnings/errors in the unmarshalling step though,as it
isn't the right place to decide on such policy.
>
> | func (s *ShutdownCause) UnmarshalJSON(data []byte) error {
> | var name string
> |
> | if err := json.Unmarshal(data, &name); err != nil {
> | return err
> | }
> |
> | switch name {
> | case "none":
> | (*s) = ShutdownCauseNone
> | case "host-error":
> | (*s) = ShutdownCauseHostError
> | case "host-qmp-quit":
> | (*s) = ShutdownCauseHostQmpQuit
> | case "host-qmp-system-reset":
> | (*s) = ShutdownCauseHostQmpSystemReset
> | case "host-signal":
> | (*s) = ShutdownCauseHostSignal
> | case "host-ui":
> | (*s) = ShutdownCauseHostUi
> | case "guest-shutdown":
> | (*s) = ShutdownCauseGuestShutdown
> | case "guest-reset":
> | (*s) = ShutdownCauseGuestReset
> | case "guest-panic":
> | (*s) = ShutdownCauseGuestPanic
> | case "subsystem-reset":
> | (*s) = ShutdownCauseSubsystemReset
> | default:
> | fmt.Println("Failed to decode ShutdownCause", *s)
> | }
> | return nil
> | }
>
> > If the enums were just represented as strings, then we can
> > gracefully accept any new enum value that arrives in future.
> > The application can thus also still log the shutdown reason
> > string, even though it was not a value explicitly known to the
> > generated API.
>
> As a string, the warning should still exist and default value of
> "" or nil for ptr would apply. IMHO, between string + warning and
> int + warning, I'd still go with int here.
>
> That's a design decision to be made. All in all, I don't know
> much about the changes in QEMU/QAPI per version to take this
> decision, so I'll rely on you and the list for this, not just for
> enums but for the other types too.
Essentially every release of QEMU will have QAPI changes. Most of
the time these are append-only changes. ie a new struct, new command,
new field, new enum value. Sometimes there will be removals due
to deprecation, though note my other reply saying that we really
ought to stop doing removals from the schema, and instead just
annotate when a field stops being used.
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
next prev parent reply other threads:[~2022-05-10 11:25 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-01 22:40 [RFC PATCH v1 0/8] qapi: add generator for Golang interface Victor Toso
2022-04-01 22:40 ` [RFC PATCH v1 1/8] qapi: golang: Generate qapi's enum types in Go Victor Toso
2022-05-10 10:06 ` Daniel P. Berrangé
2022-05-10 11:15 ` Victor Toso
2022-05-10 11:19 ` Daniel P. Berrangé [this message]
2022-05-10 11:28 ` Victor Toso
2022-05-10 11:39 ` Daniel P. Berrangé
2022-04-01 22:40 ` [RFC PATCH v1 2/8] qapi: golang: Generate qapi's alternate " Victor Toso
2022-05-10 10:10 ` Daniel P. Berrangé
2022-05-10 11:21 ` Victor Toso
2022-05-10 11:28 ` Daniel P. Berrangé
2022-04-01 22:40 ` [RFC PATCH v1 3/8] qapi: golang: Generate qapi's struct " Victor Toso
2022-04-01 22:41 ` [RFC PATCH v1 4/8] qapi: golang: Generate qapi's union " Victor Toso
2022-05-10 10:26 ` Daniel P. Berrangé
2022-05-10 11:32 ` Victor Toso
2022-05-10 11:42 ` Daniel P. Berrangé
2022-04-01 22:41 ` [RFC PATCH v1 5/8] qapi: golang: Generate qapi's event " Victor Toso
2022-05-10 10:42 ` Daniel P. Berrangé
2022-05-10 11:38 ` Victor Toso
2022-04-01 22:41 ` [RFC PATCH v1 6/8] qapi: golang: Generate qapi's command " Victor Toso
2022-04-01 22:41 ` [RFC PATCH v1 7/8] qapi: golang: Add CommandResult type to Go Victor Toso
2022-04-01 22:41 ` [RFC PATCH v1 8/8] qapi: golang: document skip function visit_array_types Victor Toso
2022-04-19 18:12 ` [RFC PATCH v1 0/8] qapi: add generator for Golang interface Andrea Bolognani
2022-04-19 18:42 ` Andrea Bolognani
2022-04-28 13:50 ` Markus Armbruster
2022-04-29 13:15 ` Andrea Bolognani
2022-05-02 7:21 ` Markus Armbruster
2022-05-02 9:04 ` Andrea Bolognani
2022-05-02 11:46 ` Markus Armbruster
2022-05-02 14:01 ` Andrea Bolognani
2022-05-03 7:57 ` Markus Armbruster
2022-05-03 9:40 ` Andrea Bolognani
2022-05-03 11:04 ` Kevin Wolf
2022-05-10 9:55 ` Daniel P. Berrangé
2022-05-11 6:15 ` Markus Armbruster
2022-05-09 18:53 ` Victor Toso
2022-05-10 8:06 ` Markus Armbruster
2022-05-10 11:48 ` Victor Toso
2022-05-10 9:52 ` Daniel P. Berrangé
2022-05-10 15:25 ` Andrea Bolognani
2022-05-11 13:45 ` Markus Armbruster
2022-05-09 10:21 ` Victor Toso
2022-05-10 17:37 ` Andrea Bolognani
2022-05-10 18:02 ` Daniel P. Berrangé
2022-04-26 11:14 ` Markus Armbruster
2022-05-09 10:52 ` Victor Toso
2022-05-10 8:53 ` Daniel P. Berrangé
2022-05-10 9:06 ` Victor Toso
2022-05-10 9:17 ` Daniel P. Berrangé
2022-05-10 9:32 ` Daniel P. Berrangé
2022-05-10 10:50 ` Victor Toso
2022-05-10 10:57 ` Daniel P. Berrangé
2022-05-10 12:02 ` Markus Armbruster
2022-05-10 12:34 ` Daniel P. Berrangé
2022-05-10 12:51 ` Daniel P. Berrangé
2022-05-11 14:17 ` Markus Armbruster
2022-05-11 14:41 ` Daniel P. Berrangé
2022-05-11 15:38 ` Andrea Bolognani
2022-05-11 15:50 ` Daniel P. Berrangé
2022-05-11 16:22 ` Andrea Bolognani
2022-05-11 16:32 ` Daniel P. Berrangé
2022-05-18 8:10 ` Victor Toso
2022-05-18 8:51 ` Daniel P. Berrangé
2022-05-18 9:01 ` Victor Toso
2022-05-11 14:17 ` Markus Armbruster
2022-05-18 8:55 ` Victor Toso
2022-05-18 12:30 ` Markus Armbruster
2022-05-25 13:49 ` Andrea Bolognani
2022-05-25 14:10 ` Markus Armbruster
2022-06-01 13:53 ` Victor Toso
2022-05-10 10:47 ` Daniel P. Berrangé
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YnpKXf4fynWupiVC@redhat.com \
--to=berrange@redhat.com \
--cc=armbru@redhat.com \
--cc=eblake@redhat.com \
--cc=jsnow@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=victortoso@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).