Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Oct 2011 17:20:45 +0000 (UTC)
From:      Dag-Erling Smorgrav <des@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r226345 - in head: etc/rc.d sbin/dhclient
Message-ID:  <201110131720.p9DHKjWn024920@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: des
Date: Thu Oct 13 17:20:45 2011
New Revision: 226345
URL: http://svn.freebsd.org/changeset/base/226345

Log:
  Make dhclient use a pid file.  Modify the rc script accordingly; while
  there, clean it up and add some error checks.
  
  Glanced at by:	brooks@
  MFC after:	3 weeks

Modified:
  head/etc/rc.d/dhclient
  head/sbin/dhclient/Makefile
  head/sbin/dhclient/dhclient.8
  head/sbin/dhclient/dhclient.c
  head/sbin/dhclient/dhcpd.h
  head/sbin/dhclient/errwarn.c

Modified: head/etc/rc.d/dhclient
==============================================================================
--- head/etc/rc.d/dhclient	Thu Oct 13 16:29:24 2011	(r226344)
+++ head/etc/rc.d/dhclient	Thu Oct 13 17:20:45 2011	(r226345)
@@ -9,55 +9,39 @@
 . /etc/rc.subr
 . /etc/network.subr
 
+ifn="$2"
+
 name="dhclient"
 rcvar=
-start_cmd="dhclient_start"
-stop_cmd="dhclient_stop"
+pidfile="/var/run/${name}.${ifn}.pid"
+start_precmd="dhclient_prestart"
 
-dhclient_start()
+dhclient_prestart()
 {
-	# prevent unnecessary restarts
-	# XXX: dhclient had better create a pidfile
-	if [ -x /bin/pgrep ]; then
-		pids=`/bin/pgrep -f "dhclient: $ifn(\$| .*)"`
-		if [ -n "$pids" ]; then
-			sleep 1
-			pids=`/bin/pgrep -f "dhclient: $ifn(\$| .*)"`
-			if [ -n "$pids" ]; then
-				exit 0
-			fi
-		elif [ -e /var/run/dhclient.pid ]; then
-			if [ -n "`pgrep -F /var/run/dhclient.pid`" ]; then
-				exit 0
-			fi
-		fi
-	fi
-
-	# Override for $ifn specific flags (see rc.subr for $flags setting)
-	specific=`get_if_var $ifn dhclient_flags_IF`
+	# Interface-specific flags (see rc.subr for $flags setting)
+	specific=$(get_if_var $ifn dhclient_flags_IF)
 	if [ -z "$flags" -a -n "$specific" ]; then
 		rc_flags=$specific
 	fi
 
-	background_dhclient=`get_if_var $ifn background_dhclient_IF $background_dhclient`
+	background_dhclient=$(get_if_var $ifn background_dhclient_IF $background_dhclient)
 	if checkyesno background_dhclient; then
 		rc_flags="${rc_flags} -b"
 	fi
 
-	${dhclient_program} ${rc_flags} $ifn
-}
-
-dhclient_stop()
-{
-	ifconfig $ifn down	# cause dhclient to die
+	rc_flags="${rc_flags} ${ifn}"
 }
 
-ifn="$2"
-
 load_rc_config $name
 load_rc_config network
 
-if ! dhcpif $ifn; then
+if [ -z $ifn ] ; then
+	# only complain if a command was specified but no interface
+	if [ -n "$1" ] ; then
+		echo 1>&2 "$0: no interface specified"
+		return 1
+	fi
+elif [ -n "${rc_force}" ] && ! dhcpif $ifn; then
 	return 1
 fi
 

Modified: head/sbin/dhclient/Makefile
==============================================================================
--- head/sbin/dhclient/Makefile	Thu Oct 13 16:29:24 2011	(r226344)
+++ head/sbin/dhclient/Makefile	Thu Oct 13 17:20:45 2011	(r226345)
@@ -39,6 +39,8 @@ PROG=	dhclient
 SCRIPTS=dhclient-script
 MAN=	dhclient.8 dhclient.conf.5 dhclient.leases.5 dhcp-options.5 \
 	dhclient-script.8
+DPADD=	${LIBUTIL}
+LDADD=	-lutil
 
 WARNS?=	2
 

Modified: head/sbin/dhclient/dhclient.8
==============================================================================
--- head/sbin/dhclient/dhclient.8	Thu Oct 13 16:29:24 2011	(r226344)
+++ head/sbin/dhclient/dhclient.8	Thu Oct 13 17:20:45 2011	(r226345)
@@ -38,7 +38,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd August 13, 2007
+.Dd October 13, 2011
 .Dt DHCLIENT 8
 .Os
 .Sh NAME
@@ -49,6 +49,7 @@
 .Op Fl bdqu
 .Op Fl c Ar file
 .Op Fl l Ar file
+.Op Fl p Ar file
 .Ar interface
 .Sh DESCRIPTION
 The
@@ -83,6 +84,10 @@ will revert to running in the background
 Specify an alternate location,
 .Ar file ,
 for the leases file.
+.It Fl p Ar file
+Specify an alternate location for the PID file.
+The default is
+.Pa /var/run/dhclient. Ns Ar interface Ns Pa .pid .
 .It Fl q
 Forces
 .Nm

Modified: head/sbin/dhclient/dhclient.c
==============================================================================
--- head/sbin/dhclient/dhclient.c	Thu Oct 13 16:29:24 2011	(r226344)
+++ head/sbin/dhclient/dhclient.c	Thu Oct 13 17:20:45 2011	(r226345)
@@ -95,6 +95,9 @@ struct iaddr iaddr_broadcast = { 4, { 25
 struct in_addr inaddr_any;
 struct sockaddr_in sockaddr_broadcast;
 
+char *path_dhclient_pidfile;
+struct pidfh *pidfile;
+
 /*
  * ASSERT_STATE() does nothing now; it used to be
  * assert (state_is == state_shouldbe).
@@ -316,6 +319,8 @@ die:
 	if (ifi->client->alias)
 		script_write_params("alias_", ifi->client->alias);
 	script_go();
+	if (pidfile != NULL)
+		pidfile_remove(pidfile);
 	exit(1);
 }
 
@@ -327,12 +332,13 @@ main(int argc, char *argv[])
 	int			 pipe_fd[2];
 	int			 immediate_daemon = 0;
 	struct passwd		*pw;
+	pid_t			 otherpid;
 
 	/* Initially, log errors to stderr as well as to syslogd. */
 	openlog(__progname, LOG_PID | LOG_NDELAY, DHCPD_LOG_FACILITY);
 	setlogmask(LOG_UPTO(LOG_DEBUG));
 
-	while ((ch = getopt(argc, argv, "bc:dl:qu")) != -1)
+	while ((ch = getopt(argc, argv, "bc:dl:p:qu")) != -1)
 		switch (ch) {
 		case 'b':
 			immediate_daemon = 1;
@@ -346,6 +352,9 @@ main(int argc, char *argv[])
 		case 'l':
 			path_dhclient_db = optarg;
 			break;
+		case 'p':
+			path_dhclient_pidfile = optarg;
+			break;
 		case 'q':
 			quiet = 1;
 			break;
@@ -362,6 +371,21 @@ main(int argc, char *argv[])
 	if (argc != 1)
 		usage();
 
+	if (path_dhclient_pidfile == NULL) {
+		asprintf(&path_dhclient_pidfile,
+		    "%sdhclient.%s.pid", _PATH_VARRUN, *argv);
+		if (path_dhclient_pidfile == NULL)
+			error("asprintf");
+	}
+	pidfile = pidfile_open(path_dhclient_pidfile, 0600, &otherpid);
+	if (pidfile == NULL) {
+		if (errno == EEXIST)
+			error("dhclient already running, pid: %d.", otherpid);
+		if (errno == EAGAIN)
+			error("dhclient already running.");
+		warning("Cannot open or create pidfile: %m");
+	}
+
 	if ((ifi = calloc(1, sizeof(struct interface_info))) == NULL)
 		error("calloc");
 	if (strlcpy(ifi->name, argv[0], IFNAMSIZ) >= IFNAMSIZ)
@@ -385,6 +409,12 @@ main(int argc, char *argv[])
 
 	read_client_conf();
 
+	/* The next bit is potentially very time-consuming, so write out
+	   the pidfile right away.  We will write it out again with the
+	   correct pid after daemonizing. */
+	if (pidfile != NULL)
+		pidfile_write(pidfile);
+
 	if (!interface_link_status(ifi->name)) {
 		fprintf(stderr, "%s: no link ...", ifi->name);
 		fflush(stderr);
@@ -2298,6 +2328,9 @@ go_daemon(void)
 	if (daemon(1, 0) == -1)
 		error("daemon");
 
+	if (pidfile != NULL)
+		pidfile_write(pidfile);
+
 	/* we are chrooted, daemon(3) fails to open /dev/null */
 	if (nullfd != -1) {
 		dup2(nullfd, STDIN_FILENO);

Modified: head/sbin/dhclient/dhcpd.h
==============================================================================
--- head/sbin/dhclient/dhcpd.h	Thu Oct 13 16:29:24 2011	(r226344)
+++ head/sbin/dhclient/dhcpd.h	Thu Oct 13 17:20:45 2011	(r226345)
@@ -41,7 +41,7 @@
  * $FreeBSD$
  */
 
-#include <sys/types.h>
+#include <sys/param.h>
 
 #include <sys/socket.h>
 #include <sys/sockio.h>
@@ -60,6 +60,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <libutil.h>
 #include <limits.h>
 #include <netdb.h>
 #include <paths.h>
@@ -353,6 +354,8 @@ extern int log_perror;
 
 extern struct client_config top_level_config;
 
+extern struct pidfh *pidfile;
+
 void dhcpoffer(struct packet *);
 void dhcpack(struct packet *);
 void dhcpnak(struct packet *);

Modified: head/sbin/dhclient/errwarn.c
==============================================================================
--- head/sbin/dhclient/errwarn.c	Thu Oct 13 16:29:24 2011	(r226344)
+++ head/sbin/dhclient/errwarn.c	Thu Oct 13 17:20:45 2011	(r226345)
@@ -83,6 +83,8 @@ error(char *fmt, ...)
 		fprintf(stderr, "exiting.\n");
 		fflush(stderr);
 	}
+	if (pidfile != NULL)
+		pidfile_remove(pidfile);
 	exit(1);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110131720.p9DHKjWn024920>