Re: [libvirt PATCHv2 11/15] nss: convert findMACs to use json-c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Sep 05, 2024 at 15:49:38 +0200, Ján Tomko wrote:
> While the parsing is still done by 1K buffers, the results
> are no longer filtered during the parsing, but the whole JSON
> has to live in memory at once, which was also the case before
> the NSS plugin dropped its dependency on libvirt_util.
> 
> Also, the new parser might be more forgiving of missing elements.
> 
> Signed-off-by: Ján Tomko <jtomko@xxxxxxxxxx>
> ---
>  tools/nss/libvirt_nss_macs.c | 278 ++++++++++-------------------------
>  1 file changed, 80 insertions(+), 198 deletions(-)
> 
> diff --git a/tools/nss/libvirt_nss_macs.c b/tools/nss/libvirt_nss_macs.c
> index f45d149793..281865a05b 100644
> --- a/tools/nss/libvirt_nss_macs.c
> +++ b/tools/nss/libvirt_nss_macs.c

As in previous patch I'll trim the deletions to just se the new code:

> +/**
> + * findMACsFromJSON
> + *
> + * @jobj: JSON object containing the leases
> + * @name: requested hostname
> + * @macs: returned array of MAC addresses leased to the hostname
> + * @nmacs: size of the returned array
> + */
>  static int
> +findMACsFromJSON(json_object *jobj,
> +                 const char *name,
> +                 char ***macs,
> +                 size_t *nmacs)
>  {
>      size_t i;
> +    int len;
>  
> +    if (!json_object_is_type(jobj, json_type_array)) {
> +        ERROR("parsed JSON does not contain the leases array");
> +        return -1;
>      }
>  
> +    len = json_object_array_length(jobj);
> +    DEBUG("Found an array of length: %zu", len);
> +    for (i = 0; i < len; i++) {
> +        json_object *entry = NULL;
> +        json_object *domain = NULL;
> +        const char *domainName;
> +        char **tmpMacs = NULL;
> +        size_t newmacs = 0;
> +        json_object *macsArray = NULL;
> +        size_t j;
> +
> +        entry = json_object_array_get_idx(jobj, i);
> +        if (!entry)
> +            continue;
>  
> +        DEBUG("Processing item %zu", i);
>  
> +        domain = json_object_object_get(entry, "domain");
> +        if (!domain)
> +            continue;
>  
> +        domainName = json_object_get_string(domain);
> +        if (!domainName)
> +            continue;
>  
> +        DEBUG("Processing domain %s", domainName);
>  
> +        if (strcasecmp(domainName, name))
> +            continue;
>  
> +        macsArray = json_object_object_get(entry, "macs");
> +        if (!macsArray)
> +            continue;
>  
> +        newmacs = json_object_array_length(macsArray);
> +        DEBUG("Found %zu MAC addresses", newmacs);
>  
> +        tmpMacs = realloc(*macs, sizeof(char *) * (*nmacs + newmacs + 1));
> +        if (!tmpMacs)
> +            return -1;
>  
> +        *macs = tmpMacs;
>  
> +        for (j = 0; j < newmacs; j++) {
> +            json_object *macobj = NULL;
> +            char *macstr;
>  
> +            macobj = json_object_array_get_idx(macsArray, j);
> +            macstr = strdup(json_object_get_string(macobj));
> +            if (!macstr)
> +                return -1;
> +            (*macs)[(*nmacs)++] = macstr;
> +        }
> +    }
> +    return 0;
>  }
>  
>  
> @@ -209,66 +119,45 @@ findMACs(const char *file,
>  {
>      int fd = -1;
>      int ret = -1;
>      char line[1024];
> +    json_object *jobj = NULL;
> +    json_tokener *tok = NULL;
> +    enum json_tokener_error jerr;
> +    int jsonflags = JSON_TOKENER_STRICT | JSON_TOKENER_VALIDATE_UTF8;
> +    ssize_t nreadTotal = 0;
>      int rv;
> +    size_t i;
>  
>      if ((fd = open(file, O_RDONLY)) < 0) {
>          ERROR("Cannot open %s", file);
>          goto cleanup;
>      }
>  
> +    tok = json_tokener_new();
> +    json_tokener_set_flags(tok, jsonflags);
>  
> +    do {
> +        rv = read(fd, line, sizeof(line) - 1);

-1 unnecessary

>          if (rv < 0)
>              goto cleanup;
>          if (rv == 0)
>              break;
> +        nreadTotal += rv;
>  
> +        jobj = json_tokener_parse_ex(tok, line, rv);
> +        jerr = json_tokener_get_error(tok);
> +    } while (jerr == json_tokener_continue);
>  
> +    if (nreadTotal > 0 && jerr != json_tokener_success) {
> +        ERROR("Cannot parse %s: %s", file, json_tokener_error_desc(jerr));

Same problem regarding the possibility to reach this with
json_tokener_continue state as in previous patch.

>          goto cleanup;
>      }
>  
> +    ret = findMACsFromJSON(jobj, name, macs, nmacs);
>  
>   cleanup:
> +    json_object_put(jobj);
> +    json_tokener_free(tok);
>      if (ret != 0) {
>          for (i = 0; i < *nmacs; i++) {
>              char *mac = (*macs)[i];

Reviewed-by: Peter Krempa <pkrempa@xxxxxxxxxx>




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux