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