From peterjeremy@optushome.com.au  Tue May  5 07:28:54 2009
Return-Path: <peterjeremy@optushome.com.au>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id A248A10656A5
	for <FreeBSD-gnats-submit@freebsd.org>; Tue,  5 May 2009 07:28:54 +0000 (UTC)
	(envelope-from peterjeremy@optushome.com.au)
Received: from mail13.syd.optusnet.com.au (mail13.syd.optusnet.com.au [211.29.132.194])
	by mx1.freebsd.org (Postfix) with ESMTP id 280A28FC15
	for <FreeBSD-gnats-submit@freebsd.org>; Tue,  5 May 2009 07:28:53 +0000 (UTC)
	(envelope-from peterjeremy@optushome.com.au)
Received: from server.vk2pj.dyndns.org (c122-106-216-167.belrs3.nsw.optusnet.com.au [122.106.216.167])
	by mail13.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id n457So1s007745
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO);
	Tue, 5 May 2009 17:28:51 +1000
Received: from server.vk2pj.dyndns.org (localhost.vk2pj.dyndns.org [127.0.0.1])
	by server.vk2pj.dyndns.org (8.14.3/8.14.3) with ESMTP id n457Sn1R093791;
	Tue, 5 May 2009 17:28:49 +1000 (EST)
	(envelope-from peter@server.vk2pj.dyndns.org)
Received: (from peter@localhost)
	by server.vk2pj.dyndns.org (8.14.3/8.14.3/Submit) id n457SnCJ093790;
	Tue, 5 May 2009 17:28:49 +1000 (EST)
	(envelope-from peter)
Message-Id: <200905050728.n457SnCJ093790@server.vk2pj.dyndns.org>
Date: Tue, 5 May 2009 17:28:49 +1000 (EST)
From: peter@rulingia.com
Reply-To: peter@rulingia.com
To: FreeBSD-gnats-submit@freebsd.org
Cc: peter@rulingia.com
Subject: [patch] Reduce disk write load from save-entropy
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         134225
>Category:       kern
>Synopsis:       [libexec] [patch] Reduce disk write load from save-entropy
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          analyzed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue May 05 07:30:01 UTC 2009
>Closed-Date:    
>Last-Modified:  Mon Oct 08 08:27:08 UTC 2012
>Originator:     Peter Jeremy
>Release:        FreeBSD 8.0-CURRENT i386
>Organization:
>Environment:
System: FreeBSD aspire.vk2pj.dyndns.org 8.0-CURRENT FreeBSD 8.0-CURRENT #0: Sat Apr 25 16:44:59 EST 2009     root@aspire.vk2pj.dyndns.org:/home/obj/usr/src/sys/aspire  i386

>Description:

	By default, save-entropy is run by cron every 11 minutes to
	provide some initial entropy following a system reboot.  It
	uses the standard log-rotating approach to maintain 8 entropy
	files, with the most recent always being saved-entropy.1
	suffix and the oldest file being deleted.  As a result, each
	run of save-entropy causes 7 file renames, 1 file create &
	write and 1 file delete.

	There does not appear to be any special reason for keeping the
	most recent entropy dump in a fixed name - the order of
	reloading the entropy files should not affect the total amount
	of entropy loaded into the kernel.  In order to reduce the
	number of writes to the SSD in my laptop, I therefore
	re-engineered save-entropy to just overwrite the oldest file
	in-place.  This means that only the 2KB of entropy and 1 inode
	are touched.  In particular, by not deleting/recreating the
	file, $entropy_dir is not touched.
		
>How-To-Repeat:
	Code inspection.  Monitoring disk write transfers via devstat.
>Fix:

Index: save-entropy.sh
===================================================================
RCS file: /usr/ncvs/src/libexec/save-entropy/save-entropy.sh,v
retrieving revision 1.4
diff -u -r1.4 save-entropy.sh
--- save-entropy.sh	28 Aug 2006 06:41:50 -0000	1.4
+++ save-entropy.sh	5 May 2009 07:14:03 -0000
@@ -64,29 +64,37 @@
 	chmod 0700 "${entropy_dir}"
 fi
 
-umask 377
-
-esn_m1=$(( ${entropy_save_num} - 1 ))
-for file_num in `jot $esn_m1 $esn_m1 1`; do
-	if [ -e "${entropy_dir}/saved-entropy.${file_num}" ]; then
-		if [ -f "${entropy_dir}/saved-entropy.${file_num}" ]; then
-			new_file=saved-entropy.$(( $file_num + 1 ))
-			if [ -e "${entropy_dir}/${new_file}" ]; then
-				unlink ${entropy_dir}/${new_file}
-			fi
-			mv "${entropy_dir}/saved-entropy.${file_num}" \
-			    "${entropy_dir}/${new_file}"
-		else
+# Scan files 1..$entropy_save_num picking a non-existent file or
+# the oldest existing file
+save_file="${entropy_dir}/saved-entropy.1"
+if [ -e "${save_file}" ] ; then
+	if [ ! -f "${save_file}" ] ; then
+		logger -is -t "$0" \
+"${save_file} is not a regular file, and therefore \
+it will not be rotated. Entropy file harvesting is aborted."
+		exit 1
+	fi
+	next_try=2
+	while [ ${next_try} -le ${entropy_save_num} ]; do
+		next="${entropy_dir}/saved-entropy.${next_try}"
+		if [ ! -e "${next}" ] ; then
+			save_file="${next}"
+			break
+		elif [ ! -f "${next}" ] ; then
 			logger -is -t "$0" \
-"${entropy_dir}/saved-entropy.${file_num} is not a regular file, and therefore \
+"${next} is not a regular file, and therefore \
 it will not be rotated. Entropy file harvesting is aborted."
 			exit 1
+		elif [ "${next}" -ot "${save_file}" ] ; then
+			save_file="${next}"
 		fi
-	fi
-done
+		next_try=$(( ${next_try} + 1 ))
+	done
+fi
 
-dd if=/dev/random of="${entropy_dir}/saved-entropy.1" \
-    bs="$entropy_save_sz" count=1 2> /dev/null
+[ -e "${save_file}" ] && chmod 600 "${save_file}"
 
-exit 0
+dd if=/dev/random of="${save_file}" bs="$entropy_save_sz" count=1 2> /dev/null
+chmod 400 "${save_file}"
 
+exit 0



>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->eadler 
Responsible-Changed-By: eadler 
Responsible-Changed-When: Sun Mar 25 03:33:03 UTC 2012 
Responsible-Changed-Why:  
take - and reminder to get secteam review of my final patch 

http://www.freebsd.org/cgi/query-pr.cgi?pr=134225 
Responsible-Changed-From-To: eadler->freebsd-bugs 
Responsible-Changed-By: eadler 
Responsible-Changed-When: Sun Sep 2 17:05:38 UTC 2012 
Responsible-Changed-Why:  
I won't be looking at this PR for a while and I need to clear some out 
of my queue 

http://www.freebsd.org/cgi/query-pr.cgi?pr=134225 
State-Changed-From-To: open->analyzed 
State-Changed-By: dougb 
State-Changed-When: Tue Sep 4 22:24:54 UTC 2012 
State-Changed-Why:  

Interesting idea, I'll look at a variation of it shortly. 


Responsible-Changed-From-To: freebsd-bugs->dougb 
Responsible-Changed-By: dougb 
Responsible-Changed-When: Tue Sep 4 22:24:54 UTC 2012 
Responsible-Changed-Why:  

My script. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=134225 

From: Doug Barton <dougb@FreeBSD.org>
To: bug-followup@FreeBSD.org, peter@rulingia.com
Cc:  
Subject: Re: kern/134225: [libexec] [patch] Reduce disk write load from save-entropy
Date: Sun, 23 Sep 2012 21:49:51 -0700

 FWIW, part of the reason for rotation is to use different/newer files
 first on a subsequent boot where uptime was not long enough to replace
 all the files. However, I'd like to see that issue addressed by
 pseudo-randomizing the order in which the files in /var/db/entropy are
 used by rc.d/random, so once that is done this type of change should be
 both safe and desirable.
 
 Other considerations, make sure that there are at least
 $entropy_save_num files with >0 size before replacing one of them. (So
 that if 1 or more files are accidentally deleted, you are still adding
 to the total number of files.) The same pre-processing loop could test
 that, and test what the oldest file is.
 
 Doug
Responsible-Changed-From-To: dougb->freebsd-bugs 
Responsible-Changed-By: dougb 
Responsible-Changed-When: Mon Oct 8 08:26:46 UTC 2012 
Responsible-Changed-Why:  

Back into the pool 

http://www.freebsd.org/cgi/query-pr.cgi?pr=134225 
>Unformatted:
