summaryrefslogtreecommitdiffstats
path: root/utils/statd/sm-notify.c
Commit message (Collapse)AuthorAgeFilesLines
* libnsm.a: Add support for multiple lines in monitor record filesChuck Lever2010-01-151-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | To support IPv6, statd must support multi-homed remote peers. For our purposes, "multi-homed peer" means that more than one unique IP address maps to the one canonical host name for that peer. An SM_MON request from the local lockd has a "mon_name" argument that statd reverse maps to a canonical hostname (ie the A record for that host). statd assumes the canonical hostname is unique enough that it stores the callback data for this mon_name in a file named after that canonical hostname. Because lockd can't distinguish between two unique IP addresses that may be from the same physical host, the kernel can hand statd a mon_name that maps to the same canonical hostname as some previous mon_name. So that the kernel can keep this instance of the mon_name unique, it creates a fresh priv cookie for each new address. Note that a mon_name can be a presentation address string, or the caller_name string sent in each NLMPROC_LOCK request. There's nothing that requires the caller_name to be a fully-qualified hostname, thus it's uniqueness is not guaranteed. The current design of statd assumes that canonical hostnames will be unique enough. When a mon_name for a fresh SM_MON request maps to the same canonical hostname as an existing monitored peer, but the priv cookie is new, statd will try to write the information for the fresh request into an existing monitor record file, wiping out the contents of the file. This is because the mon_name/cookie combination won't match any record statd already has. Currently, statd doesn't check if a record file already exists before writing into it. statd's logic assumes that the svc routine has already checked that no matching record exists in the in-core monitor list. And, it doesn't use O_EXCL when opening the record file. Not only is the old data in that file wiped out, but statd's in-core monitor list will no longer match what's in the on-disk monitor list. Note that IPv6 isn't needed to exercise multi-homed peer support. Any IPv4 peer that has multiple addresses that map to its canonical hostname will trigger this behavior. However, this scenario will become quite common when all hosts on a network automatically get both an IPv4 address and an IPv6 address. I can think of a few ways to address this: 1. Replace the current on-disk format with a database that has a uniqueness constraint on the monitor records 2. Create a new file naming scheme; eg. one that uses a truly unique name such as a hash generated from the mon_name, my_name, and priv cookie 3. Support multiple lines in each monitor record file Since statd's on-disk format constitutes a formal API, options 1 and 2 are right out. This patch implements option 3. There are two parts: adding a new line to an existing file; and deleting a line from a file with more than one line. Interestingly, the existing code already supports reading more than one line from these files, so we don't need to add extra code here to do that. One file may contain a line for every unique mon_name / priv cookie where the mon_name reverse maps to the same canonical hostname. We use the atomic write facility added by a previous patch to ensure the on-disk monitor record list is updated atomically. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
* sm-notify: Save mon_name and my_name stringsChuck Lever2010-01-151-5/+17
| | | | | | | | | Currently sm-notify does not use the mon_name and my_name strings passed to smn_get_host(). Very soon we're going to need the mon_name and my_name strings, so add code to store those strings in struct nsm_host, and free them when each host is forgotten. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
* nfs-utils: Collect socket address helpers into one locationChuck Lever2010-01-151-0/+1
| | | | | | | | | | | | | Introduce generic helpers for managing socket addresses. These are general enough that they are useful for pretty much any component of nfs-utils. We also include the definition of nfs_sockaddr here, so it can be shared. See: https://bugzilla.redhat.com/show_bug.cgi?id=448743 Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
* sm-notify: Support IPv6 DNS lookups in smn_lookupChuck Lever2010-01-151-7/+12
| | | | | | | When IPV6_SUPPORTED is enabled and the local system has IPv6 support, request AF_INET6 and AF_INET addresses from the DNS resolver. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
* sm-notify: Use getaddrinfo(3) to create bind address in smn_create_socket()Chuck Lever2010-01-151-31/+51
| | | | | | | | | | | | This patch updates the "bind to a user-specified port" arm of smn_create_socket() so it can deal with IPv6 bind addresses. A single getaddrinfo(3) call can convert a user-specified bind address or hostname to a socket address, optionally plant a provided port number, or whip up an appropriate wildcard address for use as the main socket's bind address. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
* sm-notify: IPv6 support in reserved port binding in smn_create_socket()Chuck Lever2010-01-151-1/+28
| | | | | | | This patch updates the "bind to an arbitrary privileged port" arm of smn_create_socket() so it can deal with IPv6 bind addresses. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
* sm-notify: Support creating a PF_INET6 socket in smn_create_socket()Chuck Lever2010-01-151-5/+76
| | | | | | | | | | | | | | Socket creation is unfortunately complicated by the need to handle the case where sm-notify is built with IPv6 support, but the local system has disabled it entirely at run-time (ie, socket(3) returns EAFNOSUPPORT when we try to create an AF_INET6 socket). The run-time address family setting is made available in the global variable nsm_family. This setting can control the family of the socket's bind address and what kind of addresses we want returned by smn_lookup(). Support for that is added in subsequent patches. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
* sm-notify: factor socket creation out of notify()Chuck Lever2010-01-151-60/+77
| | | | | | | | | | | | The top half of the notify() function creates the main socket that sm-notify uses to do its job. To make adding IPv6 support simpler, refactor that piece into a separate function. The logic is modified slightly so that exit(3) is invoked only in main(). This is not required, but it makes the code slightly easier to understand and maintain. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
* sm-notify: Replace RPC codeChuck Lever2010-01-151-122/+66
| | | | | | | | | | | | Replace the open code to construct SM_NOTIFY and PMAP_GETPORT RPC requests with calls to our new library routines that support IPv6 and RPCB_GETADDR as well. This change allows sm-notify to send RPCB_GETADDR, but it won't do that until the main sm-notify socket supports PF_INET6 and the DNS resolution logic is updated to return IPv6 addresses. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
* statd: Use the new nsm_ file.c calls in sm_notifyChuck Lever2010-01-121-225/+63
| | | | | | | | | | | | Replace open-coded accesses to on-disk NSM data with calls to the new libnsm.a API. One major change is that sync(2) is no longer called when the NSM state number is updated at boot time. Otherwise sm-notify should behave much the same as it did before. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
* statd: replace smn_{get,set}_port() with the shared equivalentsChuck Lever2009-12-121-33/+7
| | | | | | | | | Use shared sockaddr port management functions instead of duplicating this functionality in sm-notify. This is now easy because sm-notify is linked with libnfs.a, where nfs_{get,set}_port() reside. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
* statd: squelch compiler warning in sm-notify.cSteve Dickson2009-12-121-3/+7
| | | | | | | | | | | | | | Clean up: Get rid of a false positive compiler warning, seen with -Wextra. sm-notify.c: In function ¿record_pid¿: sm-notify.c:690: warning: comparison between signed and unsigned integer expressions Document some ignored return codes while we're here. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
* statd: Replace nsm_log() with xlog() in sm-notify commandChuck Lever2009-11-241-99/+64
| | | | | | | | | | | To facilitate code sharing between statd and sm-notify (and with other components of nfs-utils), replace sm-notify's nsm_log() with xlog(). Since opt_quiet is used in only a handful of insignificant cases, it is removed. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
* sm-notify: Failed DNS lookups should be retriedChuck Lever2009-05-181-12/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently, if getaddrinfo(3) fails when trying to resolve a hostname, sm-notify gives up immediately on that host. If sm-notify is started before network service is available on a system, that means it quits without notifying anyone. Or, if DNS service isn't available due to a network partition or because the DNS server crashed, sm-notify will simply remove all of its callback files and exit. Really, sm-notify should try harder. We know that the hostnames passed in to notify_host() have already been vetted by statd, which won't monitor a hostname that it can't resolve. So it's likely that any DNS failure we meet here is a temporary condition. If it isn't, then sm-notify will stop trying to notify that host in 15 minutes anyway. [ The host's file is left in /var/lib/nfs/sm.bak in this case, but sm.bak is not read again until the next time sm-notify runs. ] sm-notify already has retry logic for handling RPC timeouts. We can co-opt that to drive DNS resolution retries. We also add AI_ADDRCONFIG because on systems whose network startup is handled by NetworkManager, there appears to be a bug that causes processes that started calling getaddinfo(3) before the network came up to continue getting EAI_AGAIN even after the network is fully operating. As I understand it, legacy glibc (before AI_ADDRCONFIG was exposed in headers) sets AI_ADDRCONFIG by default, although I haven't checked this. In any event, pre-glibc-2.2 systems probably won't run NetworkManager anyway, so this may not be much of a problem for them. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
* sm-notify: Don't orphan addrinfo structsChuck Lever2009-05-181-13/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | sm-notify orphans an addrinfo struct in its address list rotation logic if only a single result was returned from getaddrinfo(3). For each host, the first time through notify_host(), we want to send a PMAP_GETPORT request. ->ai is NULL, and retries is set to 100, forcing a DNS lookup and an address rotation. If only a single addrinfo struct is returned, the rotation logic causes a NULL to be planted in ->ai, copied from the ai_next field of the returned result. This means that the second time through notify_host() (to perform the actual SM_NOTIFY call) we do a second DNS lookup, since ->ai is NULL. The result of the first lookup has been orphaned, and extra network traffic is generated. This scenario is actually fairly common. Since we pass .ai_protocol = IPPROTO_UDP, to getaddrinfo(3), for most hosts, which have a single forward and reverse pointer in the DNS database, we get back a single addrinfo struct as a result. To address this problem, only perform the address list rotation if there is more than one element on the list returned by getaddrinfo(3). Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
* In recent Fedora builds, the '-D _FORTIFY_SOURCE=2' compileSteve Dickson2009-03-231-3/+10
| | | | | | | | flag has been set. This cause warnings to be generated when return values from reads/writes (and other calls) are not checked. The patch address those warnings. Signed-off-by: Steve Dickson <steved@redhat.com>
* sm-notify command: fix a use-after-free bugChuck Lever2008-12-171-11/+14
| | | | | | | | | | | | | The recv_reply() function was referencing host->ai in a freeaddrinfo(3) call after it had freed @host. This is not likely to be harmful in a single-threaded user context, but it's still bad form, and it will get called out if testing sm-notify with poisoned free memory. The less noise, the better we are able to see real problems. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
* sm-notify: always exiting without any notificationSteve Dickson2008-12-061-1/+2
| | | | | | | | Added curly brackets around the record_pid() check which stop sm-notify from exiting when a pid file does not exist. Signed-off-by: Steve Dickson <steved@redhat.com>
* sm-notify should exit as soon as its determinedPhil Endecott2008-10-141-3/+10
| | | | | | | there are no hosts to notify. This also decreases start up time by a few seconds. Signed-off-by: Steve Dickson <steved@redhat.com>
* sm-notify command: use static function definitionsChuck Lever2008-09-261-10/+10
| | | | | | | | | | | | | | | | Clean up. The sm-notify command is built from a single source file. Some of its internal functions are appropriately defined as static. However, some are declared static, but defined as global. Some are declared and defined as global. None of them are used outside of utils/statd/sm-notify.c. Make all the internal functions in utils/statd/sm-notify.cstatic. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
* sm-notify command: replace nsm_address typedefChuck Lever2008-09-261-66/+63
| | | | | | | | | Clean up: replace "typedef struct sockaddr_storage nsm_address" with standard socket address types. This makes sm-notify.c consistent with other parts of nfs-utils, and with typical network application coding conventions. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
* sm-notify command: clean up error loggingChuck Lever2008-09-261-19/+29
| | | | | | | | | | | | | | | | | | | | | | Clean up a few issues with logging in sm-notify.c. Sometimes in sm-notify, when a system call fails the problem is reported to stderr but not logged, and then usually sm-notify exits. In cases like this, there are probably more hosts to notify, but sm-notify dies silently. Make sure these errors are logged, and that the log messages explain the nature of the problem. Also, if sm-notify exits prematurely, make sure this is always reported at the LOG_ERR level, not at the LOG_WARNING level. Remove a couple of unnecessary '\n' in the arguments of nsm_log() calls -- nsm_log() already appends an '\n' to the message. Finally, use exit() consistently in main(). Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
* sm-notify command: getaddrinfo(3) addrinfo leakChuck Lever2008-09-261-1/+4
| | | | | | | | | | | Make sure the results of getaddrinfo(3) are properly freed in notify(). Note this is a one-time addrinfo allocation that would be automatically freed when sm-notify exits anyway, so this is more of a nit than a real bug fix. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
* sm-notify command: include <config.h>Chuck Lever2008-09-261-2/+4
| | | | | | | | Clean up: Include config.h as other source files do; instead of using "config.h" use the HAVE_CONFIG_H macro and include <config.h>. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
* sm-notify: perform DNS lookup in the background.Steve Dickson2008-07-251-20/+40
| | | | | | | | | | | | | If an NFS server has no network connectivity when it reboots, it will block in sm-notify waiting for DNS lookup for a potentially large number of hosts. This is not helpful and just annoys the sysadmin. So do the DNS lookup in the backgrounded phase of sm-notify, before sending off the NOTIFY requests. Acked-by: NeilBrown <neilb@suse.de> Signed-off-by: Steve Dickson <steved@redhat.com>
* Add -Wstrict-prototypes to compiler args, and fix warnings caused.Neil Brown2007-07-291-2/+2
|
* Make that last patch compile...Neil Brown2007-04-161-2/+3
|
* Be more cautious about use for privilege ports (<1024).Neil Brown2007-04-161-0/+10
| | | | | | | | | | | | | Ports < 1024 are a scarce resource and should not be used carelessly. Technically they should be not used at all without registration with IANA, but sometimes we need them despite that. So: for the socket that RPC services listen on, don't use a <1024 port by default. There is no need. For sockets that we send messages on, that are long-lived, and that might need to appear 'privileged', avoid using a number that is registered in /etc/services if possible.
* Tell NFS/lockd client what that local state number is.Neil Brown2007-04-021-3/+18
| | | | | | | | | | | | Both SM_STAT and SM_MON can return the state of an NSM, but it is unclear which NSM they return the state of, so the value cannot be used, and lockd doesn't use it. Document this confusion, and give the current state to the kernel via a sysctl if that sysctl is available (since about 2.6.19). This should make is possible for the NFS server to detect a small class of bad SM_NOTIFY packets and not flush locks in that case. Signed-off-by: Neil Brown <neilb@suse.de>
* sm-notify: Try all addresses of a multihomed host.Neil Brown2007-03-291-17/+28
| | | | | | | When sending an SM_NOTIFY to multi-homed host, try all the addresses in rotation. After 4 failures on one address, try the next. Signed-off-by: Neil Brown <neilb@suse.de>
* sm-notify - fix bugs related to run-only-once.Neil Brown2007-03-291-2/+2
| | | | | | Make sure that sm-notify really runs only once per reboot. Signed-off-by: Neil Brown <neilb@suse.de>
* sm-notify - Fix typos in Usage message.Neil Brown2007-03-221-1/+1
|
* sm-notify - use state directory provided via ./configureNeil Brown2007-03-201-1/+5
|
* sm-notify - compile and installNeil Brown2007-03-201-0/+1
| | | | | Add sm-notify to the compile/install scripts, (and fix a compile warning).
* sm-notify - drop privileges before receiving packets from network.Neil Brown2007-03-201-0/+31
| | | | | If /var/lib/nfs/sm is owned by non-root, setuid to that uid after opening sockets but before receiving answers.
* Prevent sm-notify from being run multiple times per reboot.Neil Brown2007-03-201-2/+35
| | | | | | | | | As "mount.nfs" can start statd, and as statd can start sm-notify, the risk of sm-notify being run multiple times increases. As this is not normally appropriate, sm-notify now creates a file in /var/run which will stop future instances from being run (though ofcourse this behaviour can be controlled by a new command line option).
* sm-notify: remove addr_parseNeil Brown2007-03-201-22/+2
| | | | | This functionality is alreday present in getaddrinfo so it isn't needed explicitly.
* sm-notify: Allow base path to be set by command line option.Neil Brown2007-03-201-4/+26
| | | | for compat with statd.
* Add sm-notify from SuSENeil Brown2007-03-201-0/+678
Not included in build yet.