On 12/17/13, Simon Kelley <si...@thekelleys.org.uk> wrote: > On 16/12/13 21:26, Nehal J Wani wrote: >> Is the environment variable DNSMASQ_INTERFACE set when "del" action is >> called? If not, why? > > It _may_ be, if the interface associated with the lease is known. That > information is not stored in the lease file, so restarting dnsmasq will > lose the knowledge of the interface and DNSMASQ_INTERFACE will not be > set, unless there's an intervening event that provides the information. > > So > > <restart dnsmasq> > <renew DHCP lease> > <DHCP lease expires> > <del event sent> > > will set DNSMASQ_INTERFACE > > but > > <stop dnsmasq> > <wait whilst lease expires> > <start dnsmasq> > <dnsmasq notices that lease has expired and sends del event> > > won't. > > This is also true of many of the other data supplied, eg > DNSMASQ_VENDOR_CLASS, DNSMASQ_SUPPLIED_HOSTNAME, DNSMASQ_CIRCUIT_ID > > Cheers, > > > Simon. > > > > >> >> On 12/17/13, Simon Kelley <si...@thekelleys.org.uk> wrote: >>> On 16/12/13 19:06, Nehal J Wani wrote: >>>> Suppose I am using the script for dnsmasq lease-change hook >>>> ([dnsmasq.git] / contrib / mactable / macscript) and 3 leases have >>>> been handed out for a particular network. Now, if I shutdown the >>>> network and start dnsmasq again after these 3 leases have expired, the >>>> leases file has zero entries, but the "/tmp/dnsmasq-ip-mac.status" >>>> file will have those old entries. How will I clean them up? Will I >>>> have to manually check the timestamps and remove those entries or >>>> dnsmasq provides something that I am missing? >>>> >>> >>> You'll see "del" events for the leases, either when they actually >>> expire, or (if dnsmasq isn't running then) when dnsmasq is started >>> again. >>> >>> >>> Cheers, >>> >>> Simon. >>> >>> >>> _______________________________________________ >>> Dnsmasq-discuss mailing list >>> Dnsmasq-discuss@lists.thekelleys.org.uk >>> http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss >>> >> >> > >
Actually, while developing the leases API for libvirt, I have to keep separate custom-leases file for each network. (One active network is mapped to one interface only) So, I thought, why not use the env DNSMASQ_INTERFACE to differentiate? I have attached the source code of script. The problem arises during: <restart dnsmasq> <renew DHCP lease> <DHCP lease expires> <del event sent> Now, since the interface is not known, I'll have to compare IP address in each file! Is there no way of knowing which file it should correspond to? I want to keep leases in different files to ease my task, so that once a network is completely destroyed and undefined, its leases can also be deleted easily (by just using unlink() on the desired file). -- Nehal J Wani
/* * 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.k...@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" #include "configmake.h" #define VIR_FROM_THIS VIR_FROM_NETWORK /** * 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 6 /** * 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 *leases_str = NULL; char *lease_file = 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; FILE *fp = NULL; virBuffer buf_new_lease = VIR_BUFFER_INITIALIZER; virBuffer buf_all_leases = VIR_BUFFER_INITIALIZER; if (virAsprintf(&lease_file, "%s/%s.status", LOCALSTATEDIR "/lib/libvirt/dnsmasq/", interface) < 0) goto cleanup; 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\n", 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\n", lease_fields[0], lease_fields[1], lease_fields[2], lease_fields[3], lease_fields[4], lease_fields[5]); 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; }
_______________________________________________ Dnsmasq-discuss mailing list Dnsmasq-discuss@lists.thekelleys.org.uk http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss