Re: [libvirt PATCH v3] ch: Fix cloud-hypervisor version processing

2023-09-07 Thread Praveen Paladugu
On Thu, Sep 07, 2023 at 09:34:59AM +0200, Martin Kletzander wrote:
> On Wed, Sep 06, 2023 at 10:50:30AM -0500, Praveen K Paladugu wrote:
> >Refactor the version processing logic in ch driver to support versions
> >from non-release cloud-hypervisor binaries. This version also supports
> >versions with branch prefixes in them.
> >
> >Signed-off-by: Praveen K Paladugu 
> >---
> >src/ch/ch_conf.c | 42 --
> >1 file changed, 40 insertions(+), 2 deletions(-)
> >
> >diff --git a/src/ch/ch_conf.c b/src/ch/ch_conf.c
> >index a8565d9537..5573119b23 100644
> >--- a/src/ch/ch_conf.c
> >+++ b/src/ch/ch_conf.c
> >@@ -172,6 +172,37 @@ virCHDriverConfigDispose(void *obj)
> >
> >#define MIN_VERSION ((15 * 100) + (0 * 1000) + (0))
> >
> >+/**
> >+ * chPreProcessVersionString:
> >+ *
> >+ * Returns: a pointer to numerical version without branch/commit info
> >+ */
> >+static char *
> >+chPreProcessVersionString(char *version)
> >+{
> >+char *tmp_version = version;
> >+g_autofree char *ret_version = NULL;
> >+char *sub_string;
> >+
> >+if ((sub_string = strrchr(version, '/')) != NULL) {
> >+tmp_version = sub_string + 1;
> >+}
> >+
> >+if (tmp_version[0] == 'v') {
> >+tmp_version = tmp_version + 1;
> >+}
> >+
> >+// Duplicate the string in both cases. This would allow the calling 
> >method
> >+// free the returned string in a consistent manner.
> >+if ((sub_string = strchr(tmp_version, '-')) != NULL) {
> >+ret_version = g_strndup(tmp_version, sub_string - tmp_version);
> >+} else{
> >+ret_version = g_strdup(tmp_version);
> >+}
> >+
> >+return g_steal_pointer(_version);
> >+
> >+}
> 
> What would be wrong with the following?
> 
> static char *
> chPreProcessVersionString(const char *version)
> {
> const char *tmp = strrchr(version, '/');
> 
> if (tmp)
> version = tmp + 1;
> 
> if (version[0] == 'v')
> version++;
> 
> tmp = strchr(tmp_version, '-');
> if (tmp)
> return g_strndup(version, tmp - version);
> else
> return g_strdup(version;
> }
> 
> isn't that more readable?
> 
> >int
> >chExtractVersion(virCHDriver *driver)
> >{
> >@@ -193,13 +224,20 @@ chExtractVersion(virCHDriver *driver)
> >
> >tmp = help;
> >
> >-/* expected format: cloud-hypervisor v.. */
> >-if ((tmp = STRSKIP(tmp, "cloud-hypervisor v")) == NULL) {
> >+/* Below are some example version formats and expected outputs:
> >+ *  cloud-hypervisor v32.0.0 (expected: 32.0.0)
> >+ *  cloud-hypervisor v33.0-104-ge0e3779e-dirty (expected: 33.0)
> >+ *  cloud-hypervisor testing/v32.0.131-1-ga5d6db5c-dirty (expected: 
> >32.0.131)
> >+ */
> >+if ((tmp = STRSKIP(tmp, "cloud-hypervisor ")) == NULL) {
> >virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> >   _("Unexpected output of cloud-hypervisor binary"));
> >return -1;
> >}
> >
> >+tmp = chPreProcessVersionString(tmp);
> >+VIR_DEBUG("Cloud-Hypervisor version detected: %s", tmp);
> >+
> 
> Also tmp is not free'd in this function which introduces a leak.
> 
> But since @help is not used for anything else we could simplify the
> processing of the version by not duplicating anything:
> 
> static char *
> chPreProcessVersionString(char *version)
> {
> char *tmp = strrchr(version, '/');
> 
> if (tmp)
> version = tmp + 1;
> 
> if (version[0] == 'v')
> version++;
> 
> tmp = strchr(version, '-');
> if (tmp)
> *tmp = '\0';
> 
> return version;
> }
> 
> and keep this part just as you changed it.

Thanks. I like this version. I will adopt this in my next revision.

> 
> >if (virStringParseVersion(, tmp, true) < 0) {
> >virReportError(VIR_ERR_INTERNAL_ERROR,
> >   _("Unable to parse cloud-hypervisor version: %1$s"), 
> > tmp);
> >-- 
> >2.41.0
> >




Re: [libvirt PATCH v3] ch: Fix cloud-hypervisor version processing

2023-09-07 Thread Praveen Paladugu
On Thu, Sep 07, 2023 at 09:02:44AM +0200, Jiri Denemark wrote:
> On Wed, Sep 06, 2023 at 10:50:30 -0500, Praveen K Paladugu wrote:
> > Refactor the version processing logic in ch driver to support versions
> > from non-release cloud-hypervisor binaries. This version also supports
> > versions with branch prefixes in them.
> > 
> > Signed-off-by: Praveen K Paladugu 
> > ---
> >  src/ch/ch_conf.c | 42 --
> >  1 file changed, 40 insertions(+), 2 deletions(-)
> > 
> > diff --git a/src/ch/ch_conf.c b/src/ch/ch_conf.c
> > index a8565d9537..5573119b23 100644
> > --- a/src/ch/ch_conf.c
> > +++ b/src/ch/ch_conf.c
> > @@ -172,6 +172,37 @@ virCHDriverConfigDispose(void *obj)
> >  
> >  #define MIN_VERSION ((15 * 100) + (0 * 1000) + (0))
> >  
> > +/**
> > + * chPreProcessVersionString:
> > + *
> > + * Returns: a pointer to numerical version without branch/commit info
> > + */
> > +static char *
> > +chPreProcessVersionString(char *version)
> > +{
> > +char *tmp_version = version;
> > +g_autofree char *ret_version = NULL;
> 
> As Daniel pointed out in previous version this g_autofree and
> g_steal_pointer below are useless as there is no path that actually free
> the string here.
>
Thanks Jirka, I expected "autofree" attribute to be carried to "tmp" in the 
calling method,
which would be freed when tmp goes out of scope. So, I implemented it this way.

With some experimentation, I confirmed the correct behavior.
I will fix this in my next version.

> > +char *sub_string;
> > +
> > +if ((sub_string = strrchr(version, '/')) != NULL) {
> > +tmp_version = sub_string + 1;
> > +}
> > +
> > +if (tmp_version[0] == 'v') {
> > +tmp_version = tmp_version + 1;
> > +}
> > +
> > +// Duplicate the string in both cases. This would allow the calling 
> > method
> > +// free the returned string in a consistent manner.
> 
> Our coding style document says we prefer /* ... */ comments.
> 
> > +if ((sub_string = strchr(tmp_version, '-')) != NULL) {
> > +ret_version = g_strndup(tmp_version, sub_string - tmp_version);
> > +} else{
> > +ret_version = g_strdup(tmp_version);
> > +}
> > +
> > +return g_steal_pointer(_version);
> > +
> > +}
> >  int
> >  chExtractVersion(virCHDriver *driver)
> >  {
> > @@ -193,13 +224,20 @@ chExtractVersion(virCHDriver *driver)
> >  
> >  tmp = help;
> >  
> > -/* expected format: cloud-hypervisor v.. */
> > -if ((tmp = STRSKIP(tmp, "cloud-hypervisor v")) == NULL) {
> > +/* Below are some example version formats and expected outputs:
> > + *  cloud-hypervisor v32.0.0 (expected: 32.0.0)
> > + *  cloud-hypervisor v33.0-104-ge0e3779e-dirty (expected: 33.0)
> > + *  cloud-hypervisor testing/v32.0.131-1-ga5d6db5c-dirty (expected: 
> > 32.0.131)
> > + */
> > +if ((tmp = STRSKIP(tmp, "cloud-hypervisor ")) == NULL) {
> >  virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> > _("Unexpected output of cloud-hypervisor binary"));
> >  return -1;
> >  }
> >  
> > +tmp = chPreProcessVersionString(tmp);
> 
> So chPreProcessVersionString returns an allocated string that will never
> be freed because you assign it to tmp that's only used to point inside
> other buffers and thus is (correctly) not freed anywhere. You need to
> make sure the pointer returned here is freed before chExtractVersion
> exits.

Understood.
> 
> > +VIR_DEBUG("Cloud-Hypervisor version detected: %s", tmp);
> > +
> >  if (virStringParseVersion(, tmp, true) < 0) {
> >  virReportError(VIR_ERR_INTERNAL_ERROR,
> > _("Unable to parse cloud-hypervisor version: 
> > %1$s"), tmp);
> 
> Jirka



Re: [libvirt PATCH v3] ch: Fix cloud-hypervisor version processing

2023-09-07 Thread Martin Kletzander

On Wed, Sep 06, 2023 at 10:50:30AM -0500, Praveen K Paladugu wrote:

Refactor the version processing logic in ch driver to support versions
from non-release cloud-hypervisor binaries. This version also supports
versions with branch prefixes in them.

Signed-off-by: Praveen K Paladugu 
---
src/ch/ch_conf.c | 42 --
1 file changed, 40 insertions(+), 2 deletions(-)

diff --git a/src/ch/ch_conf.c b/src/ch/ch_conf.c
index a8565d9537..5573119b23 100644
--- a/src/ch/ch_conf.c
+++ b/src/ch/ch_conf.c
@@ -172,6 +172,37 @@ virCHDriverConfigDispose(void *obj)

#define MIN_VERSION ((15 * 100) + (0 * 1000) + (0))

+/**
+ * chPreProcessVersionString:
+ *
+ * Returns: a pointer to numerical version without branch/commit info
+ */
+static char *
+chPreProcessVersionString(char *version)
+{
+char *tmp_version = version;
+g_autofree char *ret_version = NULL;
+char *sub_string;
+
+if ((sub_string = strrchr(version, '/')) != NULL) {
+tmp_version = sub_string + 1;
+}
+
+if (tmp_version[0] == 'v') {
+tmp_version = tmp_version + 1;
+}
+
+// Duplicate the string in both cases. This would allow the calling method
+// free the returned string in a consistent manner.
+if ((sub_string = strchr(tmp_version, '-')) != NULL) {
+ret_version = g_strndup(tmp_version, sub_string - tmp_version);
+} else{
+ret_version = g_strdup(tmp_version);
+}
+
+return g_steal_pointer(_version);
+
+}


What would be wrong with the following?

static char *
chPreProcessVersionString(const char *version)
{
const char *tmp = strrchr(version, '/');

if (tmp)
version = tmp + 1;

if (version[0] == 'v')
version++;

tmp = strchr(tmp_version, '-');
if (tmp)
return g_strndup(version, tmp - version);
else
return g_strdup(version;
}

isn't that more readable?


int
chExtractVersion(virCHDriver *driver)
{
@@ -193,13 +224,20 @@ chExtractVersion(virCHDriver *driver)

tmp = help;

-/* expected format: cloud-hypervisor v.. */
-if ((tmp = STRSKIP(tmp, "cloud-hypervisor v")) == NULL) {
+/* Below are some example version formats and expected outputs:
+ *  cloud-hypervisor v32.0.0 (expected: 32.0.0)
+ *  cloud-hypervisor v33.0-104-ge0e3779e-dirty (expected: 33.0)
+ *  cloud-hypervisor testing/v32.0.131-1-ga5d6db5c-dirty (expected: 
32.0.131)
+ */
+if ((tmp = STRSKIP(tmp, "cloud-hypervisor ")) == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
   _("Unexpected output of cloud-hypervisor binary"));
return -1;
}

+tmp = chPreProcessVersionString(tmp);
+VIR_DEBUG("Cloud-Hypervisor version detected: %s", tmp);
+


Also tmp is not free'd in this function which introduces a leak.

But since @help is not used for anything else we could simplify the
processing of the version by not duplicating anything:

static char *
chPreProcessVersionString(char *version)
{
char *tmp = strrchr(version, '/');

if (tmp)
version = tmp + 1;

if (version[0] == 'v')
version++;

tmp = strchr(version, '-');
if (tmp)
*tmp = '\0';

return version;
}

and keep this part just as you changed it.


if (virStringParseVersion(, tmp, true) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
   _("Unable to parse cloud-hypervisor version: %1$s"), 
tmp);
--
2.41.0



signature.asc
Description: PGP signature