PERFORCE change 123875 for review

Andrew Turner andrew at FreeBSD.org
Sun Jul 22 03:13:21 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=123875

Change 123875 by andrew at andrew_hermies on 2007/07/22 03:13:14

	Add a struct to describe each base directory we are watching

Affected files ...

.. //depot/projects/soc2007/andrew-update/backend/facund-be.c#17 edit

Differences ...

==== //depot/projects/soc2007/andrew-update/backend/facund-be.c#17 (text+ko) ====

@@ -58,9 +58,9 @@
 #define DEFAULT_CONFIG_FILE	"/etc/freebsd-update-control.conf"
 #define UPDATE_DATA_DIR		"/var/db/freebsd-update"
 
-static int	  has_update(const char *);
+static int	  facund_has_update(unsigned int);
 static void	 *look_for_updates(void *);
-static char	**get_base_dirs(char *);
+static int	  facund_read_base_dirs(const char *);
 static void	 *do_communication(void *);
 
 static struct facund_response * facund_get_update_types(const char *,
@@ -86,18 +86,31 @@
 static void	facund_signal_handler(int, siginfo_t *, void *);
 
 /*
+ * Structure describing the current state of
+ * the freebsd-update database directory
+ */
+struct fbsd_update_db {
+	char	 *db_base;
+	char	 *db_dir;
+	int	  db_fd;
+};
+
+static unsigned int watched_db_count = 0;
+static struct fbsd_update_db *watched_db = NULL;
+
+/*
  * Looks for updates on the system with a root of basedir
  */
 static int
-has_update(const char *basedir)
+facund_has_update(unsigned int pos)
 {
 	struct stat sb;
 	char install_link[PATH_MAX], sha_base[PATH_MAX], sum[65];
 
-	snprintf(sha_base, PATH_MAX, "%s\n", basedir);
+	snprintf(sha_base, PATH_MAX, "%s\n", watched_db[pos].db_base);
 	SHA256_Data(sha_base, strlen(sha_base), sum);
-	snprintf(install_link, PATH_MAX, "%s" UPDATE_DATA_DIR "/%s-install",
-	    basedir, sum);
+	snprintf(install_link, PATH_MAX, "%s/%s-install",
+	    watched_db[pos].db_dir, sum);
 
 	/* Look for the install link and check if it is a symlink */
 	if (lstat(install_link, &sb) == 0) {
@@ -118,39 +131,26 @@
  * sleeping is we may see the update sooner this way.
  */
 void *
-look_for_updates(void *data)
+look_for_updates(void *data __unused)
 {
-	char db_dir[PATH_MAX];
 	struct timespec timeout;
-	int *dir_fd, kq, use_kqueue, found_updates;
+	int kq, use_kqueue, found_updates;
 	struct kevent event, changes;
-	size_t pos, dir_count, signals;
-	char **base_dirs;
+	size_t pos, signals;
 	int error, first_loop;
 
 	signals = 1;
-	base_dirs = data;
-	for (dir_count = 0; base_dirs[dir_count] != NULL; dir_count++)
-		continue;
-
-	/* Create a list of directories to watch */
-	dir_fd = malloc(dir_count * sizeof(int));
-	if (dir_fd == NULL) {
-		errx(1, "Could not allocate enough memory");
-	}
 
 	/* Create the kqueue to wait for events */
 	kq = kqueue();
 	if (kq == -1)
 		use_kqueue = 0;
 
-	for (pos = 0; pos < dir_count; pos++) {
-		snprintf(db_dir, PATH_MAX, "%s/var/db/freebsd-update/",
-		    base_dirs[pos]);
-		dir_fd[pos] = open(db_dir, O_RDONLY);
+	for (pos = 0; pos < watched_db_count; pos++) {
+		watched_db[pos].db_fd = open(watched_db[pos].db_dir, O_RDONLY);
 
 		/* Create an event to look for files being added to the dir */
-		EV_SET(&event, dir_fd[pos], EVFILT_VNODE, EV_ADD,
+		EV_SET(&event, watched_db[pos].db_fd, EVFILT_VNODE, EV_ADD,
 		    NOTE_WRITE | NOTE_DELETE | NOTE_EXTEND, 0, (void *)pos);
 
 		kevent(kq, &event, 1, NULL, 0, NULL);
@@ -173,7 +173,7 @@
 	timeout.tv_nsec = 0;
 
 	/* Scan all directories on the first run */
-	pos = dir_count;
+	pos = watched_db_count;
 
 	first_loop = 1;
 
@@ -184,37 +184,37 @@
 	 * then scan all directories.
 	 */
 	while(facund_in_loop != 0) {
-		assert(pos <= dir_count);
-		if (use_kqueue == 0 || pos == dir_count) {
+		assert(pos <= watched_db_count);
+		if (use_kqueue == 0 || pos == watched_db_count) {
 			/*
 			 * We are using sleep to wait for updates or
 			 * kqueue timed out. This means we have to check
 			 * all directories to see if they have an update.
 			 */
-			for (pos = 0; base_dirs[pos] != NULL; pos++) {
-				if (has_update(base_dirs[pos])) {
+			for (pos = 0; pos < watched_db_count; pos++) {
+				if (facund_has_update(pos)) {
 					printf("Updates found in %s\n",
-					    base_dirs[pos]);
+					    watched_db[pos].db_base);
 					found_updates = 1;
 				}
 			}
 			/* Check we have looked at all directories */
-			assert(pos == dir_count);
+			assert(pos == watched_db_count);
 		} else {
 			/*
 			 * We are using kqueue to wait for updates.
 			 * pos will contain the position in base_dirs of
 			 * the directory that had file system activity.
 			 */
-			if (pos < dir_count) {
-				if (has_update(base_dirs[pos])) {
+			if (pos < watched_db_count) {
+				if (facund_has_update(pos)) {
 					printf("Updates found in %s\n",
-					    base_dirs[pos]);
+					    watched_db[pos].db_base);
 					found_updates = 1;
 				}
 			}
 		}
-		pos = dir_count;
+		pos = watched_db_count;
 
 		/*
 		 * Before we sleep again check if we are to stop running
@@ -255,7 +255,9 @@
 		}
 	}
 
-	free(dir_fd);
+	for (pos = 0; pos < watched_db_count; pos++) {
+		close(watched_db[pos].db_fd);
+	}
 	return NULL;
 }
 
@@ -263,18 +265,20 @@
  * Takes in a string of space seperated directories and returns
  * a NULL terminated array of pointers to each directory
  */
-char **
-get_base_dirs(char *str)
+static int
+facund_read_base_dirs(const char *str __unused)
 {
-	char *ptr, **ret;
-	int dir_count;
+	const char *ptr, *next_ptr;
+	unsigned int pos, len;
 
 	/* An empty string will contain no directories */
 	if (str == NULL || str[0] == '\0')
-		return NULL;
+		return -1;
+
+	/* Check we havn't already read in the directories */
+	if (watched_db_count != 0 || watched_db != NULL)
+		return -1;
 
-	/* Count the number of dirs to read */
-	dir_count = 0;
 	ptr = str;
 	while (ptr != NULL) {
 		/* Skip leading spaces */
@@ -282,42 +286,52 @@
 			*ptr++;
 
 		ptr = strchr(ptr, ' ');
-		dir_count++;
+		watched_db_count++;
 	}
 
 	/*
 	 * There must be at least one directory utherwise
 	 * the empty string check would have returned
 	 */
-	assert(dir_count > 0);
+	assert(watched_db_count > 0);
 
 	/* create an array to hold pointers to the dir names */
-	ret = calloc((dir_count + 1) * sizeof(char *), 1);
-
+	watched_db = calloc(watched_db_count,
+	    sizeof(struct fbsd_update_db));
 
 	/* Set the point the ret array to the directories */
-	dir_count = 0;
 	ptr = str;
+	pos = 0;
 	while (ptr != NULL) {
 		/* Skip leading spaces */
 		while (ptr[0] == ' ')
 			*ptr++;
 
-		/* Point to the directory name */
-		ret[dir_count] = ptr;
-		ptr = strchr(ptr, ' ');
+		next_ptr = strchr(ptr, ' ');
+		if (next_ptr == NULL) {
+			next_ptr = strchr(ptr, '\0');
+		}
+		assert(next_ptr > ptr);
+		len = next_ptr - ptr;
+		len++;
 
-		/* Make the previous directory null terminated */
-		if (ptr != NULL) {
-			ptr[0] = '\0';
-			*ptr++;
+		watched_db[pos].db_base = calloc(len, sizeof(char *));
+		if (watched_db[pos].db_base == NULL) {
+			/* TODO: Clean up */
+			return -1;
 		}
+		strlcpy(watched_db[pos].db_base, ptr, len);
+		asprintf(&watched_db[pos].db_dir, "%s" UPDATE_DATA_DIR,
+		    watched_db[pos].db_base);
+		printf("%s\n", watched_db[pos].db_dir);
 
-		dir_count++;
+		ptr = next_ptr;
+		if (ptr[0] == '\0') {
+			return 0;
+		}
+		pos++;
 	}
-	ret[dir_count] = NULL;
-
-	return ret;
+	return -1;
 }
 
 static void *
@@ -558,7 +572,7 @@
 		facund_object_set_string(item, base_dirs[pos]);
 		facund_object_array_append(pair, item);
 
-		/* Add a list of directories to the array */
+		/* Add a list of updates to the array */
 		updates = facund_object_new_array();
 		item = facund_object_new_string();
 		facund_object_set_string(item, "6.2-p2");
@@ -624,7 +638,7 @@
 		facund_object_set_string(item, base_dirs[pos]);
 		facund_object_array_append(pair, item);
 
-		/* Add a list of directories to the array */
+		/* Add a list of updates to the array */
 		updates = facund_object_new_array();
 		item = facund_object_new_string();
 		facund_object_set_string(item, "6.2-p1");
@@ -679,7 +693,7 @@
 	pthread_t update_thread, comms_thread;
 	struct facund_conn *conn;
 	const char *config_file;
-	char *basedirs_string, **base_dirs;
+	char *basedirs_string;
 	unsigned int pos;
 	int config_fd;
 	properties config_data;
@@ -734,8 +748,7 @@
 	}
 
 	/* Read in the base dirs */
-	base_dirs = get_base_dirs(basedirs_string);
-	if (base_dirs == NULL) {
+	if (facund_read_base_dirs(basedirs_string) != 0) {
 		errx(1, "No base dirs were given, set base_dirs in %s",
 		    config_file);
 	}
@@ -754,7 +767,7 @@
 	facund_server_add_call("rollback_patches",facund_call_rollback_patches);
 	facund_server_add_call("restart_services",facund_call_restart_services);
 
-	pthread_create(&update_thread, NULL, look_for_updates, base_dirs);
+	pthread_create(&update_thread, NULL, look_for_updates, NULL);
 	pthread_create(&comms_thread, NULL, do_communication, conn);
 
 	/* Wait for the threads to quit */
@@ -766,12 +779,17 @@
 	pthread_kill(update_thread, SIGINT);
 	pthread_join(update_thread, NULL);
 
+	if (watched_db != NULL) {
+		for (pos = 0; pos < watched_db_count; pos++) {
+			free(watched_db[pos].db_base);
+			free(watched_db[pos].db_dir);
+		}
+		free(watched_db);
+	}
+
 	if (conn != NULL)
 		facund_cleanup(conn);
 
-	if (base_dirs != NULL)
-		free(base_dirs);
-
 	free(basedirs_string);
 	return 0;
 }


More information about the p4-projects mailing list