From d7dd4e1f899cbcf633efe234c8b1a24a3da842b8 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Thu, 28 Nov 2019 14:25:07 +0100 Subject: [PATCH] nss: Don't fail on empty files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before we rewrote nss plugin so that it doesn't use libvirt's internal functions it used virLeaseReadCustomLeaseFile() to parse .status files. After the rewrite it's using read() + yajl_parse() + yajl_complete_parse(). There's one catch though, virLeaseReadCustomLeaseFile() skipped over empty files. An empty .status file is created when a network is started. This is because we configure dnsmasq to use our leasehelper. So the first thing it does it calls it as follows: DNSMASQ_INTERFACE=virbr0 /usr/libexec/libvirt_leaseshelper init which causes the leasehelper to create empty virbr0.status file. If there is only one libvirt network then that is no problem - there are no other .status files to parse anyway. But if there are two or more networks then the first empty .status file causes whole parsing process and subsequently the whole name lookup process to fail. Fixes: v5.7.0-rc1~343 Reported-by: Pavel Hrdina Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrangé --- tools/nss/libvirt_nss_leases.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/nss/libvirt_nss_leases.c b/tools/nss/libvirt_nss_leases.c index e96e260da8..7c431e4d53 100644 --- a/tools/nss/libvirt_nss_leases.c +++ b/tools/nss/libvirt_nss_leases.c @@ -379,6 +379,7 @@ findLeases(const char *file, }; yajl_handle parser = NULL; char line[1024]; + ssize_t nreadTotal = 0; int rv; if ((fd = open(file, O_RDONLY)) < 0) { @@ -398,6 +399,7 @@ findLeases(const char *file, goto cleanup; if (rv == 0) break; + nreadTotal += rv; if (yajl_parse(parser, (const unsigned char *)line, rv) != yajl_status_ok) { @@ -409,7 +411,8 @@ findLeases(const char *file, } } - if (yajl_complete_parse(parser) != yajl_status_ok) { + if (nreadTotal > 0 && + yajl_complete_parse(parser) != yajl_status_ok) { ERROR("Parse failed %s", yajl_get_error(parser, 1, NULL, 0)); goto cleanup; -- GitLab