svn commit: r231277 - in stable/9: etc/rc.d sbin/dhclient

Baptiste Daroussin bapt at FreeBSD.org
Thu Feb 9 14:16:01 UTC 2012


Author: bapt
Date: Thu Feb  9 14:16:00 2012
New Revision: 231277
URL: http://svn.freebsd.org/changeset/base/231277

Log:
  MFH r226345, r226464, r226879:
  Make dhclient use a pid file. Modify the rc script accordingly, fix some bugs
  
  Approved by:	des (mentor)

Modified:
  stable/9/etc/rc.d/dhclient
  stable/9/sbin/dhclient/Makefile
  stable/9/sbin/dhclient/dhclient.8
  stable/9/sbin/dhclient/dhclient.c
  stable/9/sbin/dhclient/dhcpd.h
  stable/9/sbin/dhclient/errwarn.c
Directory Properties:
  stable/9/etc/rc.d/   (props changed)
  stable/9/sbin/dhclient/   (props changed)

Modified: stable/9/etc/rc.d/dhclient
==============================================================================
--- stable/9/etc/rc.d/dhclient	Thu Feb  9 14:15:56 2012	(r231276)
+++ stable/9/etc/rc.d/dhclient	Thu Feb  9 14:16:00 2012	(r231277)
@@ -9,56 +9,49 @@
 . /etc/rc.subr
 . /etc/network.subr
 
+ifn="$2"
+
 name="dhclient"
 rcvar=
-start_cmd="dhclient_start"
-stop_cmd="dhclient_stop"
-
-dhclient_start()
+pidfile="/var/run/${name}.${ifn}.pid"
+start_precmd="dhclient_prestart"
+stop_precmd="dhclient_pre_check"
+
+# rc_force check can only be done at the run_rc_command
+# time, so we're testing it in the pre* hooks.
+dhclient_pre_check()
 {
-	# 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
+	if [ -z "${rc_force}" ] && ! dhcpif $ifn; then
+		err 1 "'$ifn' is not a DHCP-enabled interface"
 	fi
+}
+
+dhclient_prestart()
+{
+	dhclient_pre_check
 
-	# 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
+	rc_flags="${rc_flags} ${ifn}"
 }
 
-dhclient_stop()
-{
-	ifconfig $ifn down	# cause dhclient to die
-}
-
-ifn="$2"
-
 load_rc_config $name
 load_rc_config network
 
-if ! dhcpif $ifn; then
-	return 1
+if [ -z $ifn ] ; then
+	# only complain if a command was specified but no interface
+	if [ -n "$1" ] ; then
+		err 1 "$0: no interface specified"
+	fi
 fi
 
 run_rc_command "$1"

Modified: stable/9/sbin/dhclient/Makefile
==============================================================================
--- stable/9/sbin/dhclient/Makefile	Thu Feb  9 14:15:56 2012	(r231276)
+++ stable/9/sbin/dhclient/Makefile	Thu Feb  9 14:16:00 2012	(r231277)
@@ -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: stable/9/sbin/dhclient/dhclient.8
==============================================================================
--- stable/9/sbin/dhclient/dhclient.8	Thu Feb  9 14:15:56 2012	(r231276)
+++ stable/9/sbin/dhclient/dhclient.8	Thu Feb  9 14:16:00 2012	(r231277)
@@ -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: stable/9/sbin/dhclient/dhclient.c
==============================================================================
--- stable/9/sbin/dhclient/dhclient.c	Thu Feb  9 14:15:56 2012	(r231276)
+++ stable/9/sbin/dhclient/dhclient.c	Thu Feb  9 14:16:00 2012	(r231277)
@@ -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: stable/9/sbin/dhclient/dhcpd.h
==============================================================================
--- stable/9/sbin/dhclient/dhcpd.h	Thu Feb  9 14:15:56 2012	(r231276)
+++ stable/9/sbin/dhclient/dhcpd.h	Thu Feb  9 14:16:00 2012	(r231277)
@@ -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: stable/9/sbin/dhclient/errwarn.c
==============================================================================
--- stable/9/sbin/dhclient/errwarn.c	Thu Feb  9 14:15:56 2012	(r231276)
+++ stable/9/sbin/dhclient/errwarn.c	Thu Feb  9 14:16:00 2012	(r231277)
@@ -83,6 +83,8 @@ error(char *fmt, ...)
 		fprintf(stderr, "exiting.\n");
 		fflush(stderr);
 	}
+	if (pidfile != NULL)
+		pidfile_remove(pidfile);
 	exit(1);
 }
 


More information about the svn-src-stable-9 mailing list