Date: Sun, 22 Jul 2007 03:13:20 GMT From: Andrew Turner <andrew@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 123875 for review Message-ID: <200707220313.l6M3DKnX098632@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=123875 Change 123875 by andrew@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; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200707220313.l6M3DKnX098632>