diff mbox series

[1/3] osdep: Add qemu_mkdir_with_parents()

Message ID 20241216161413.1644171-2-peterx@redhat.com (mailing list archive)
State New
Headers show
Series tests: Fix some new coverity issues reported | expand

Commit Message

Peter Xu Dec. 16, 2024, 4:14 p.m. UTC
QEMU uses g_mkdir_with_parents() a lot, especially in the case where the
failure case is ignored so an abort is expected when happened.

Provide a helper qemu_mkdir_with_parents() to do that, and use it in the
two cases in qga/.  To be used in more places later.

Signed-off-by: Peter Xu <peterx@redhat.com>
---
 include/qemu/osdep.h     | 7 +++++++
 qga/commands-posix-ssh.c | 8 ++------
 util/osdep.c             | 6 ++++++
 3 files changed, 15 insertions(+), 6 deletions(-)

Comments

Peter Maydell Dec. 16, 2024, 4:56 p.m. UTC | #1
On Mon, 16 Dec 2024 at 16:14, Peter Xu <peterx@redhat.com> wrote:
>
> QEMU uses g_mkdir_with_parents() a lot, especially in the case where the
> failure case is ignored so an abort is expected when happened.
>
> Provide a helper qemu_mkdir_with_parents() to do that, and use it in the
> two cases in qga/.  To be used in more places later.
>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
>  include/qemu/osdep.h     | 7 +++++++
>  qga/commands-posix-ssh.c | 8 ++------
>  util/osdep.c             | 6 ++++++
>  3 files changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
> index fdff07fd99..dc67fb2e5e 100644
> --- a/include/qemu/osdep.h
> +++ b/include/qemu/osdep.h
> @@ -828,6 +828,13 @@ static inline int platform_does_not_support_system(const char *command)
>  }
>  #endif /* !HAVE_SYSTEM_FUNCTION */
>
> +/**
> + * qemu_mkdir_with_parents:
> + *
> + * Create directories with parents.  Abort on failures.
> + */
> +void qemu_mkdir_with_parents(const char *dir, int mode);

Don't put new function prototypes into osdep.h, please.
It is included by every single C file in the codebase.
There is always somewhere better to put things.

QEMU shouldn't abort on things that are kind of expected
OS errors like "couldn't create a directory", so I'm
a bit dubious about this function.

The two use cases in this commit seem to be test code,
so asserting is reasonable. But a "for test code only"
function should go in a header file that's only included
by test cases and the comment should be clear about that,
and it shouldn't have a function name that implies
"this is the normal way any code in QEMU might want
to create directories".

For the qtest tests, I currently ignore Coverity
reports in our test code unless it seems particularly
worthwhile to fix them. This is especially true for
complaints about unchecked return values and the like.

Even in a test case it is still not great to call
g_assert(), because this makes the test binary crash,
rather than reporting an error. The surrounding TAP
protocol parsing code then doesn't report the test
failure the way you might like.

thanks
-- PMM
Peter Xu Dec. 16, 2024, 5:12 p.m. UTC | #2
On Mon, Dec 16, 2024 at 04:56:33PM +0000, Peter Maydell wrote:
> On Mon, 16 Dec 2024 at 16:14, Peter Xu <peterx@redhat.com> wrote:
> >
> > QEMU uses g_mkdir_with_parents() a lot, especially in the case where the
> > failure case is ignored so an abort is expected when happened.
> >
> > Provide a helper qemu_mkdir_with_parents() to do that, and use it in the
> > two cases in qga/.  To be used in more places later.
> >
> > Signed-off-by: Peter Xu <peterx@redhat.com>
> > ---
> >  include/qemu/osdep.h     | 7 +++++++
> >  qga/commands-posix-ssh.c | 8 ++------
> >  util/osdep.c             | 6 ++++++
> >  3 files changed, 15 insertions(+), 6 deletions(-)
> >
> > diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
> > index fdff07fd99..dc67fb2e5e 100644
> > --- a/include/qemu/osdep.h
> > +++ b/include/qemu/osdep.h
> > @@ -828,6 +828,13 @@ static inline int platform_does_not_support_system(const char *command)
> >  }
> >  #endif /* !HAVE_SYSTEM_FUNCTION */
> >
> > +/**
> > + * qemu_mkdir_with_parents:
> > + *
> > + * Create directories with parents.  Abort on failures.
> > + */
> > +void qemu_mkdir_with_parents(const char *dir, int mode);
> 
> Don't put new function prototypes into osdep.h, please.
> It is included by every single C file in the codebase.
> There is always somewhere better to put things.
> 
> QEMU shouldn't abort on things that are kind of expected
> OS errors like "couldn't create a directory", so I'm
> a bit dubious about this function.

That's what qga/ is doing right now, rather than a decision made in this
series, though.

> 
> The two use cases in this commit seem to be test code,
> so asserting is reasonable. But a "for test code only"
> function should go in a header file that's only included
> by test cases and the comment should be clear about that,
> and it shouldn't have a function name that implies
> "this is the normal way any code in QEMU might want
> to create directories".
> 
> For the qtest tests, I currently ignore Coverity
> reports in our test code unless it seems particularly
> worthwhile to fix them. This is especially true for
> complaints about unchecked return values and the like.

OK.

> 
> Even in a test case it is still not great to call
> g_assert(), because this makes the test binary crash,
> rather than reporting an error. The surrounding TAP
> protocol parsing code then doesn't report the test
> failure the way you might like.

Hmm, I normally always think crash is better especially in tests to keep
everything around when an error happens as general rule.

TAP parsing especially on errors is more useful to me when we constantly
expect failures, IIUC that's not the case for QEMU tests?  Because I do
expect the CI to pass all the tests always.  But I also admit I don't know
the whole picture of QEMU tests..

If we don't care about retval checks in tests, we can definitely drop patch
1-2 here in all cases.

Thanks,
Alex Bennée Dec. 16, 2024, 5:16 p.m. UTC | #3
Peter Xu <peterx@redhat.com> writes:

> QEMU uses g_mkdir_with_parents() a lot, especially in the case where the
> failure case is ignored so an abort is expected when happened.
>
> Provide a helper qemu_mkdir_with_parents() to do that, and use it in the
> two cases in qga/.  To be used in more places later.
>
> Signed-off-by: Peter Xu <peterx@redhat.com>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Konstantin Kostiuk Dec. 16, 2024, 5:28 p.m. UTC | #4
On Mon, Dec 16, 2024 at 7:12 PM Peter Xu <peterx@redhat.com> wrote:

> On Mon, Dec 16, 2024 at 04:56:33PM +0000, Peter Maydell wrote:
> > On Mon, 16 Dec 2024 at 16:14, Peter Xu <peterx@redhat.com> wrote:
> > >
> > > QEMU uses g_mkdir_with_parents() a lot, especially in the case where
> the
> > > failure case is ignored so an abort is expected when happened.
> > >
> > > Provide a helper qemu_mkdir_with_parents() to do that, and use it in
> the
> > > two cases in qga/.  To be used in more places later.
> > >
> > > Signed-off-by: Peter Xu <peterx@redhat.com>
> > > ---
> > >  include/qemu/osdep.h     | 7 +++++++
> > >  qga/commands-posix-ssh.c | 8 ++------
> > >  util/osdep.c             | 6 ++++++
> > >  3 files changed, 15 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
> > > index fdff07fd99..dc67fb2e5e 100644
> > > --- a/include/qemu/osdep.h
> > > +++ b/include/qemu/osdep.h
> > > @@ -828,6 +828,13 @@ static inline int
> platform_does_not_support_system(const char *command)
> > >  }
> > >  #endif /* !HAVE_SYSTEM_FUNCTION */
> > >
> > > +/**
> > > + * qemu_mkdir_with_parents:
> > > + *
> > > + * Create directories with parents.  Abort on failures.
> > > + */
> > > +void qemu_mkdir_with_parents(const char *dir, int mode);
> >
> > Don't put new function prototypes into osdep.h, please.
> > It is included by every single C file in the codebase.
> > There is always somewhere better to put things.
> >
> > QEMU shouldn't abort on things that are kind of expected
> > OS errors like "couldn't create a directory", so I'm
> > a bit dubious about this function.
>
> That's what qga/ is doing right now, rather than a decision made in this
> series, though.
>

I think we need to fix this behavior in QGA and report the real error,
instead of wrapping the `assert` into some function that will make
it not so obvious.


>
> >
> > The two use cases in this commit seem to be test code,
> > so asserting is reasonable. But a "for test code only"
> > function should go in a header file that's only included
> > by test cases and the comment should be clear about that,
> > and it shouldn't have a function name that implies
> > "this is the normal way any code in QEMU might want
> > to create directories".
> >
> > For the qtest tests, I currently ignore Coverity
> > reports in our test code unless it seems particularly
> > worthwhile to fix them. This is especially true for
> > complaints about unchecked return values and the like.
>
> OK.
>
> >
> > Even in a test case it is still not great to call
> > g_assert(), because this makes the test binary crash,
> > rather than reporting an error. The surrounding TAP
> > protocol parsing code then doesn't report the test
> > failure the way you might like.
>
> Hmm, I normally always think crash is better especially in tests to keep
> everything around when an error happens as general rule.
>
> TAP parsing especially on errors is more useful to me when we constantly
> expect failures, IIUC that's not the case for QEMU tests?  Because I do
> expect the CI to pass all the tests always.  But I also admit I don't know
> the whole picture of QEMU tests..
>
> If we don't care about retval checks in tests, we can definitely drop patch
> 1-2 here in all cases.
>
> Thanks,
>
> --
> Peter Xu
>
>
Peter Xu Dec. 16, 2024, 5:54 p.m. UTC | #5
On Mon, Dec 16, 2024 at 07:28:19PM +0200, Konstantin Kostiuk wrote:
> On Mon, Dec 16, 2024 at 7:12 PM Peter Xu <peterx@redhat.com> wrote:
> 
> > On Mon, Dec 16, 2024 at 04:56:33PM +0000, Peter Maydell wrote:
> > > On Mon, 16 Dec 2024 at 16:14, Peter Xu <peterx@redhat.com> wrote:
> > > >
> > > > QEMU uses g_mkdir_with_parents() a lot, especially in the case where
> > the
> > > > failure case is ignored so an abort is expected when happened.
> > > >
> > > > Provide a helper qemu_mkdir_with_parents() to do that, and use it in
> > the
> > > > two cases in qga/.  To be used in more places later.
> > > >
> > > > Signed-off-by: Peter Xu <peterx@redhat.com>
> > > > ---
> > > >  include/qemu/osdep.h     | 7 +++++++
> > > >  qga/commands-posix-ssh.c | 8 ++------
> > > >  util/osdep.c             | 6 ++++++
> > > >  3 files changed, 15 insertions(+), 6 deletions(-)
> > > >
> > > > diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
> > > > index fdff07fd99..dc67fb2e5e 100644
> > > > --- a/include/qemu/osdep.h
> > > > +++ b/include/qemu/osdep.h
> > > > @@ -828,6 +828,13 @@ static inline int
> > platform_does_not_support_system(const char *command)
> > > >  }
> > > >  #endif /* !HAVE_SYSTEM_FUNCTION */
> > > >
> > > > +/**
> > > > + * qemu_mkdir_with_parents:
> > > > + *
> > > > + * Create directories with parents.  Abort on failures.
> > > > + */
> > > > +void qemu_mkdir_with_parents(const char *dir, int mode);
> > >
> > > Don't put new function prototypes into osdep.h, please.
> > > It is included by every single C file in the codebase.
> > > There is always somewhere better to put things.
> > >
> > > QEMU shouldn't abort on things that are kind of expected
> > > OS errors like "couldn't create a directory", so I'm
> > > a bit dubious about this function.
> >
> > That's what qga/ is doing right now, rather than a decision made in this
> > series, though.
> >
> 
> I think we need to fix this behavior in QGA and report the real error,
> instead of wrapping the `assert` into some function that will make
> it not so obvious.

Even if we want to do that, we can also do that on top, btw.  As this patch
is as simple as a cleanup to dedup two chunks of code.

But if this patch is not liked by most from different angles, we can simply
drop it.. together with patch 2, as in my previous reply.

Thanks,
Daniel P. Berrangé Dec. 16, 2024, 6:34 p.m. UTC | #6
On Mon, Dec 16, 2024 at 04:56:33PM +0000, Peter Maydell wrote:
> On Mon, 16 Dec 2024 at 16:14, Peter Xu <peterx@redhat.com> wrote:
> >
> > QEMU uses g_mkdir_with_parents() a lot, especially in the case where the
> > failure case is ignored so an abort is expected when happened.
> >
> > Provide a helper qemu_mkdir_with_parents() to do that, and use it in the
> > two cases in qga/.  To be used in more places later.
> >
> > Signed-off-by: Peter Xu <peterx@redhat.com>
> > ---
> >  include/qemu/osdep.h     | 7 +++++++
> >  qga/commands-posix-ssh.c | 8 ++------
> >  util/osdep.c             | 6 ++++++
> >  3 files changed, 15 insertions(+), 6 deletions(-)
> >
> > diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
> > index fdff07fd99..dc67fb2e5e 100644
> > --- a/include/qemu/osdep.h
> > +++ b/include/qemu/osdep.h
> > @@ -828,6 +828,13 @@ static inline int platform_does_not_support_system(const char *command)
> >  }
> >  #endif /* !HAVE_SYSTEM_FUNCTION */
> >
> > +/**
> > + * qemu_mkdir_with_parents:
> > + *
> > + * Create directories with parents.  Abort on failures.
> > + */
> > +void qemu_mkdir_with_parents(const char *dir, int mode);
> 
> Don't put new function prototypes into osdep.h, please.
> It is included by every single C file in the codebase.
> There is always somewhere better to put things.
> 
> QEMU shouldn't abort on things that are kind of expected
> OS errors like "couldn't create a directory", so I'm
> a bit dubious about this function.
> 
> The two use cases in this commit seem to be test code,
> so asserting is reasonable. But a "for test code only"
> function should go in a header file that's only included
> by test cases and the comment should be clear about that,
> and it shouldn't have a function name that implies
> "this is the normal way any code in QEMU might want
> to create directories".
> 
> For the qtest tests, I currently ignore Coverity
> reports in our test code unless it seems particularly
> worthwhile to fix them. This is especially true for
> complaints about unchecked return values and the like.
> 
> Even in a test case it is still not great to call
> g_assert(), because this makes the test binary crash,
> rather than reporting an error. The surrounding TAP
> protocol parsing code then doesn't report the test
> failure the way you might like.

I also think qemu_mkdir_with_parents is *worse* than the
current code. It saves 1 line in the test file, but hides
the fact that it asserts on failure which is an relevant
observation. If we really want to save that 1 line of code
then just condense it inplace

  g_assert(g_mkdir_with_parents(dir, mode) == 0);


With regards,
Daniel
diff mbox series

Patch

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index fdff07fd99..dc67fb2e5e 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -828,6 +828,13 @@  static inline int platform_does_not_support_system(const char *command)
 }
 #endif /* !HAVE_SYSTEM_FUNCTION */
 
+/**
+ * qemu_mkdir_with_parents:
+ *
+ * Create directories with parents.  Abort on failures.
+ */
+void qemu_mkdir_with_parents(const char *dir, int mode);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/qga/commands-posix-ssh.c b/qga/commands-posix-ssh.c
index 246171d323..a39abcbaa5 100644
--- a/qga/commands-posix-ssh.c
+++ b/qga/commands-posix-ssh.c
@@ -18,7 +18,6 @@  static struct passwd *
 test_get_passwd_entry(const gchar *user_name, GError **error)
 {
     struct passwd *p;
-    int ret;
 
     if (!user_name || g_strcmp0(user_name, g_get_user_name())) {
         g_set_error(error, G_UNIX_ERROR, 0, "Invalid user name");
@@ -30,8 +29,7 @@  test_get_passwd_entry(const gchar *user_name, GError **error)
     p->pw_uid = geteuid();
     p->pw_gid = getegid();
 
-    ret = g_mkdir_with_parents(p->pw_dir, 0700);
-    g_assert(ret == 0);
+    qemu_mkdir_with_parents(p->pw_dir, 0700);
 
     return p;
 }
@@ -263,11 +261,9 @@  test_authorized_keys_set(const char *contents)
 {
     g_autoptr(GError) err = NULL;
     g_autofree char *path = NULL;
-    int ret;
 
     path = g_build_filename(g_get_home_dir(), ".ssh", NULL);
-    ret = g_mkdir_with_parents(path, 0700);
-    g_assert(ret == 0);
+    qemu_mkdir_with_parents(path, 0700);
     g_free(path);
 
     path = test_get_authorized_keys_path();
diff --git a/util/osdep.c b/util/osdep.c
index 770369831b..3a724c1814 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -613,3 +613,9 @@  int qemu_fdatasync(int fd)
     return fsync(fd);
 #endif
 }
+
+void qemu_mkdir_with_parents(const char *dir, int mode)
+{
+    int ret = g_mkdir_with_parents(dir, 0700);
+    g_assert(ret == 0);
+}