[libvirt] [RFC] net-dhcp-leases: Query: Reg: Leases API Script

Nehal J Wani nehaljw.kkd1 at gmail.com
Mon Nov 4 10:09:08 UTC 2013


On Thu, Oct 24, 2013 at 8:31 PM, Nehal J Wani <nehaljw.kkd1 at gmail.com> wrote:
> I tried writing the helper program, didn't send v5, since I have some doubts.
> The program works. Problems listed below.
>
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 21b9caf..ef88132 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -825,6 +825,9 @@ STORAGE_HELPER_DISK_SOURCES =
>                  \
>  UTIL_IO_HELPER_SOURCES =                                       \
>                 util/iohelper.c
>
> +UTIL_IO_LEASES_SOURCES =                                       \
> +               util/leaseshelper.c
> +
>  # Network filters
>  NWFILTER_DRIVER_SOURCES =                                              \
>                 nwfilter/nwfilter_driver.h nwfilter/nwfilter_driver.c   \
> @@ -2384,6 +2387,23 @@ libvirt_iohelper_CFLAGS = \
>                 $(NULL)
>  endif WITH_LIBVIRTD
>
> +if WITH_LIBVIRTD
> +libexec_PROGRAMS += libvirt_leaseshelper
> +libvirt_leaseshelper_SOURCES = $(UTIL_IO_LEASES_SOURCES)
> +libvirt_leaseshelper_LDFLAGS = \
> +               $(NULL)
> +libvirt_leaseshelper_LDADD =           \
> +               libvirt_util.la         \
> +               ../gnulib/lib/libgnu.la
> +if WITH_DTRACE_PROBES
> +libvirt_leaseshelper_LDADD += libvirt_probes.lo
> +endif WITH_DTRACE_PROBES
> +
> +libvirt_leaseshelper_CFLAGS = \
> +               $(PIE_CFLAGS) \
> +               $(NULL)
> +endif WITH_LIBVIRTD
> +
>  if WITH_STORAGE_DISK
>  if WITH_LIBVIRTD
>  libexec_PROGRAMS += libvirt_parthelper
> diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
> index 3ce3130..182a426 100644
> --- a/src/network/bridge_driver.c
> +++ b/src/network/bridge_driver.c
> @@ -1058,6 +1058,8 @@
> networkBuildDhcpDaemonCommandLine(virNetworkObjPtr network,
>
>      cmd = virCommandNew(dnsmasqCapsGetBinaryPath(caps));
>      virCommandAddArgFormat(cmd, "--conf-file=%s", configfile);
> +    virCommandAddArgFormat(cmd, "--dhcp-script=%s",
> "/home/Wani/libvirt/src/libvirt_leaseshelper");
> +    //virCommandAddArgFormat(cmd, "--dhcp-script=%s",
> "/var/lib/libvirt/dnsmasq/dhcp-script");
>      *cmdout = cmd;
>      ret = 0;
>  cleanup:
>
>
> /*
>  * leasehelper.c:
>  *
>  * Copyright (C) 2013-2014 Red Hat, Inc.
>  *
>  * This library is free software; you can redistribute it and/or
>  * modify it under the terms of the GNU Lesser General Public
>  * License as published by the Free Software Foundation; either
>  * version 2.1 of the License, or (at your option) any later version.
>  *
>  * This library is distributed in the hope that it will be useful,
>  * but WITHOUT ANY WARRANTY; without even the implied warranty of
>  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>  * Lesser General Public License for more details.
>  *
>  * You should have received a copy of the GNU Lesser General Public
>  * License along with this library.  If not, see
>  * <http://www.gnu.org/licenses/>.
>  *
>  * Author: Nehal J Wani <nehaljw.kkd1 at gmail.com>
>  *
>  */
>
> #include <config.h>
>
> #include <stdio.h>
> #include <stdlib.h>
>
> #include "virutil.h"
> #include "virfile.h"
> #include "virbuffer.h"
> #include "virstring.h"
> #include "virerror.h"
> #include "viralloc.h"
>
> /**
>  * VIR_NETWORK_DHCP_LEASE_FIELDS:
>  *
>  * Macro providing the maximum number of fields in an entry in
>  * the leases file
>  */
> #define VIR_NETWORK_DHCP_LEASE_FIELDS 7
> /**
>  * VIR_NETWORK_DHCP_LEASE_FILE_SIZE_MAX:
>  *
>  * Macro providing the upper limit on the size of leases file
>  */
> #define VIR_NETWORK_DHCP_LEASE_FILE_SIZE_MAX 2097152
>
> /*
>  * Use this when passing possibly-NULL strings to printf-a-likes.
>  */
> # define NULL_STR(s) ((s) ? (s) : "*")
>
> int
> main(int argc, char **argv) {
>     /* Doesn't hurt to check */
>     if (argc < 4)
>         return -1;
>
>     const char *action = argv[1];
>     const char *interface = NULL_STR(getenv("DNSMASQ_INTERFACE"));
>     const char *expirytime = NULL_STR(getenv("DNSMASQ_LEASE_EXPIRES"));
>     const char *mac = argv[2];
>     const char *ip = argv[3];
>     const char *iaid = NULL_STR(getenv("DNSMASQ_IAID"));
>     const char *hostname = NULL_STR(getenv("DNSMASQ_SUPPLIED_HOSTNAME"));
>     const char *clientid = NULL_STR(getenv("DNSMASQ_CLIENT_ID"));
>     const char *lease_file = "/var/lib/libvirt/dnsmasq/dnsmasq-ip-mac.status";
>     const char *leases_str = NULL;
>     char *lease_entries = NULL;
>     char *lease_entry = NULL;
>     char **lease_fields = NULL;
>     bool delete = false;
>     bool add = false;
>     int rv = -1;
>     int lease_file_len = 0;
>     virBuffer buf_new_lease = VIR_BUFFER_INITIALIZER;
>     virBuffer buf_all_leases = VIR_BUFFER_INITIALIZER;
>     FILE *fp = NULL;
>
>     if (getenv("DNSMASQ_IAID")) {
>         mac = NULL_STR(getenv("DNSMASQ_MAC"));
>         clientid = argv[2];
>     }
>
>     /* Make sure the file exists. If not, 'touch' it */
>     fp = fopen(lease_file, "a+");
>     fclose(fp);
>
>     /* Read entire contents */
>     if ((lease_file_len = virFileReadAll(lease_file,
>                                         VIR_NETWORK_DHCP_LEASE_FILE_SIZE_MAX,
>                                         &lease_entries)) < 0) {
>         goto cleanup;
>     }
>
>
>     if (STREQ(action, "add") || STREQ(action, "old") || STREQ(action, "del")) {
>         if (mac || STREQ(action, "del")) {
>             /* Delete the corresponding lease */
>             delete = true;
>             if (STREQ(action, "add") || STREQ(action, "old")) {
>                 add = true;
>                 /* Enter new lease */
>                 virBufferAsprintf(&buf_new_lease, "%s %s %s %s %s %s
> %s\n", interface,
>                                   expirytime, mac, iaid, ip, hostname,
> clientid);
>
>                 if (virBufferError(&buf_new_lease)) {
>                     virBufferFreeAndReset(&buf_new_lease);
>                 //  virReportOOMError();
>                     goto cleanup;
>                 }
>             }
>         }
>     }
>
>     lease_entry = lease_entries[0] == '\0' ? NULL : lease_entries;
>
>     while (lease_entry) {
>         int nfields = 0;
>
>         char *eol = strchr(lease_entry, '\n');
>         *eol = '\0';
>
>         /* Split the lease line */
>         if (!(lease_fields = virStringSplit(lease_entry, " ",
>                                             VIR_NETWORK_DHCP_LEASE_FIELDS)))
>             goto cleanup;
>
>         nfields = virStringListLength(lease_fields);
>
>         /* Forward lease_entry to the next lease */
>         lease_entry = strchr(lease_entry, '\0');
>         if (lease_entry - lease_entries + 1 < lease_file_len)
>             lease_entry++;
>         else
>             lease_entry = NULL;
>
>         if (nfields != VIR_NETWORK_DHCP_LEASE_FIELDS)
>             goto cleanup;
>
>         if (delete && STREQ(lease_fields[4], ip))
>             continue;
>         else {
>             virBufferAsprintf(&buf_all_leases, "%s %s %s %s %s %s %s\n",
>                               lease_fields[0], lease_fields[1], lease_fields[2],
>                               lease_fields[3], lease_fields[4], lease_fields[5],
>                               lease_fields[6]);
>
>             if (virBufferError(&buf_all_leases)) {
>                 virBufferFreeAndReset(&buf_all_leases);
>                 //virReportOOMError();
>                 goto cleanup;
>             }
>         }
>     }
>
>     if (add)
>         virBufferAsprintf(&buf_all_leases, "%s",
> virBufferContentAndReset(&buf_new_lease));
>
>     rv = 0;
>
>     /* Write to file */
>     leases_str = virBufferContentAndReset(&buf_all_leases);
>     if (!leases_str)
>         leases_str = "";
>
>     if (virFileWriteStr(lease_file, leases_str, 0) < 0)
>         rv = -1;
>
> cleanup:
>     VIR_FREE(lease_file);
>     VIR_FREE(lease_entries);
>     if (lease_fields)
>         virStringFreeList(lease_fields);
>     return rv;
> }
>
>
> Q1. Does every file have to include "* Copyright (C) 2013-2014 Red
> Hat, Inc." in its copyright? (hacking.html doesn't mention in detail)
>
> Q2. I am not able to use  virReportOOMError();. It keeps asking for
> VIR_FROM_THIS
>
> Q3. Currently, I have hard-coded the location of custom-leasefile:
>  const char *lease_file = "/var/lib/libvirt/dnsmasq/dnsmasq-ip-mac.status";
> If we don't hard-code the location of file, then the program will have
> to ask src/network/bridge_driver.c, which is not allowed, as it is
> private to the network driver.
> Now, we have two options, either we leave the above as only one file
> and add leases of all networks to it, or, have different files for
> each network.
> The only difficulty in option 1 is, when a network is destroyed, its
> corresponding leases will also have to be deleted in the custom lease
> file. If we go for option 2, and have different files for each
> network, how will the above program know, while custom lease file has
> to be updated?
>
> --
> Nehal J Wani
>

ping

-- 
Nehal J Wani




More information about the libvir-list mailing list