Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Jan 2010 09:55:25 +0000 (UTC)
From:      Ed Schouten <ed@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r202147 - user/ed/utmpx/lib/libc/gen
Message-ID:  <201001120955.o0C9tPZf047681@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



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