svn commit: r202147 - user/ed/utmpx/lib/libc/gen

Ed Schouten ed at FreeBSD.org
Tue Jan 12 09:55:25 UTC 2010


Author: ed
Date: Tue Jan 12 09:55:25 2010
New Revision: 202147
URL: http://svn.freebsd.org/changeset/base/202147

Log:
  Fix allocation policy of utx.active.
  
  It is a bad idea to always overwrite the first DEAD_PROCESS/invalid
  entry we see, because there may be another DEAD_PROCESS entry further on
  whose ut_id value matches the record we want to add, making getutxid()
  return multiple records. Be sure to scan the file for an exact match and
  only overwrite DEAD_PROCESS/invalid entries when no exact match was
  found.
  
  This still keeps the file size to a minimum, because the maximum size of
  the file will be limited to the highest amount of logins at a certain
  moment in time.

Modified:
  user/ed/utmpx/lib/libc/gen/pututxline.c

Modified: user/ed/utmpx/lib/libc/gen/pututxline.c
==============================================================================
--- user/ed/utmpx/lib/libc/gen/pututxline.c	Tue Jan 12 09:07:55 2010	(r202146)
+++ user/ed/utmpx/lib/libc/gen/pututxline.c	Tue Jan 12 09:55:25 2010	(r202147)
@@ -61,6 +61,7 @@ utx_active_add(const struct futx *fu)
 {
 	int fd;
 	struct futx fe;
+	off_t partial = -1;
 
 	/*
 	 * Register user login sessions.  Overwrite entries of sessions
@@ -78,15 +79,30 @@ utx_active_add(const struct futx *fu)
 		case USER_PROCESS:
 		case INIT_PROCESS:
 		case LOGIN_PROCESS:
-			if (memcmp(fu->fu_id, fe.fu_id, sizeof fe.fu_id) != 0)
-				continue;
+		case DEAD_PROCESS:
+			/* Overwrite when ut_id matches. */
+			if (memcmp(fu->fu_id, fe.fu_id, sizeof fe.fu_id) == 0) {
+				lseek(fd, -sizeof fe, SEEK_CUR);
+				goto exact;
+			}
+			if (fe.fu_type != DEAD_PROCESS)
+				break;
 			/* FALLTHROUGH */
 		default:
-			lseek(fd, -sizeof fe, SEEK_CUR);
-			goto found;
+			/* Allow us to overwrite unused records. */
+			if (partial == -1)
+				partial = lseek(fd, 0, SEEK_CUR);
+			break;
 		}
 	}
-found:
+	
+	/*
+	 * No exact match found.  Use the partial match.  If no partial
+	 * match was found, just append a new record.
+	 */
+	if (partial != -1)
+		lseek(fd, partial, SEEK_SET);
+exact:
 	_write(fd, fu, sizeof *fu);
 	lockf(fd, F_ULOCK, 0);
 	_close(fd);


More information about the svn-src-user mailing list