From owner-p4-projects@FreeBSD.ORG Wed Jul 18 06:57:04 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C15CF16A404; Wed, 18 Jul 2007 06:57:03 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 7409316A400 for ; Wed, 18 Jul 2007 06:57:03 +0000 (UTC) (envelope-from andrew@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 6597A13C4BB for ; Wed, 18 Jul 2007 06:57:03 +0000 (UTC) (envelope-from andrew@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l6I6v3Vs057609 for ; Wed, 18 Jul 2007 06:57:03 GMT (envelope-from andrew@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l6I6v3K2057606 for perforce@freebsd.org; Wed, 18 Jul 2007 06:57:03 GMT (envelope-from andrew@freebsd.org) Date: Wed, 18 Jul 2007 06:57:03 GMT Message-Id: <200707180657.l6I6v3K2057606@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to andrew@freebsd.org using -f From: Andrew Turner To: Perforce Change Reviews Cc: Subject: PERFORCE change 123676 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Jul 2007 06:57:04 -0000 http://perforce.freebsd.org/chv.cgi?CH=123676 Change 123676 by andrew@andrew_hermies on 2007/07/18 06:56:55 When sending a SIGINT to the back end clean up before exiting Affected files ... .. //depot/projects/soc2007/andrew-update/backend/facund-be.c#14 edit Differences ... ==== //depot/projects/soc2007/andrew-update/backend/facund-be.c#14 (text+ko) ==== @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,8 @@ /* Check if there are updates every 30min */ static const time_t default_check_period = 30 * 60; +static int facund_in_loop = 1; + #define DEFAULT_CONFIG_FILE "/etc/freebsd-update-control.conf" #define UPDATE_DATA_DIR "/var/db/freebsd-update" @@ -73,6 +76,8 @@ static struct facund_response *facund_call_restart_services(const char *, struct facund_object *); +static void facund_signal_handler(int, siginfo_t *, void *); + /* * Looks for updates on the system with a root of basedir */ @@ -111,10 +116,12 @@ char db_dir[PATH_MAX]; struct timespec timeout; int *dir_fd, kq, use_kqueue, found_updates; - struct kevent *events, changes; - size_t pos, dir_count; + struct kevent event, changes; + size_t pos, dir_count, signals; char **base_dirs; + int error, first_loop; + signals = 1; base_dirs = data; for (dir_count = 0; base_dirs[dir_count] != NULL; dir_count++) continue; @@ -125,11 +132,10 @@ errx(1, "Could not allocate enough memory"); } - /* Create an array of events */ - events = malloc(dir_count * sizeof(struct kevent)); - if (events == 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/", @@ -137,29 +143,34 @@ dir_fd[pos] = open(db_dir, O_RDONLY); /* Create an event to look for files being added to the dir */ - EV_SET(&events[pos], dir_fd[pos], EVFILT_VNODE, EV_ADD, + EV_SET(&event, dir_fd[pos], EVFILT_VNODE, EV_ADD, NOTE_WRITE | NOTE_DELETE | NOTE_EXTEND, 0, (void *)pos); + + kevent(kq, &event, 1, NULL, 0, NULL); } + /* Add a signal event to check if there was a signal sent */ + EV_SET(&event, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); + kevent(kq, &event, 1, NULL, 0, NULL); + use_kqueue = 1; found_updates = 0; - /* XXX This timeout will be bigger in a live system */ timeout.tv_sec = default_check_period; timeout.tv_nsec = 0; - kq = kqueue(); - if (kq == -1) - use_kqueue = 0; + /* Scan all directories on the first run */ pos = dir_count; + first_loop = 1; + /* * This is the main loop to check for updates. It will * either wait for file system activity on the update * directories of just sleep for a fixed amount of time * then scan all directories. */ - while(1) { + while(facund_in_loop != 0) { assert(pos <= dir_count); if (use_kqueue == 0 || pos == dir_count) { /* @@ -193,6 +204,13 @@ pos = dir_count; /* + * Before we sleep again check if we are to stop running + */ + if (facund_in_loop == 0) { + break; + } + + /* * Wait for any disk activity to * quieten down before waiting again */ @@ -204,10 +222,8 @@ /* Wait for posible updates */ if (use_kqueue == 1) { /* Wait for posible updates ready to be installed */ - int error; - - error = kevent(kq, events, dir_count, &changes, 1, - &timeout); + /* There are no changes, use the same events */ + error = kevent(kq, NULL, 0, &changes, 1, &timeout); if (error == -1) { /* @@ -216,8 +232,10 @@ */ use_kqueue = 0; } else if (error > 0) { - /* Read in the item that changed */ - pos = (size_t)changes.udata; + if (changes.filter == EVFILT_VNODE) { + /* Find in the item that changed */ + pos = (size_t)changes.udata; + } } } else { sleep(default_check_period); @@ -292,21 +310,27 @@ { struct facund_conn *conn = (struct facund_conn *)data; - signal(SIGPIPE, SIG_DFL); - while(1) { int ret = 0; if(facund_server_start(conn) == -1) { - fprintf(stderr, - "ERROR: Couldn't start the connection\n"); + if (facund_in_loop != 0) { + /* + * When we are not quiting tell + * the user there was a problem + */ + fprintf(stderr, + "ERROR: Couldn't start the connection\n"); + } break; } while(ret == 0) { ret = facund_server_get_request(conn); if (ret == -1) { - fprintf(stderr, - "ERROR: Couldn't read data from network\n"); + if (facund_in_loop != 0) { + fprintf(stderr, "ERROR: Couldn't read " + "data from network\n"); + } } } @@ -518,9 +542,17 @@ return NULL; } +static void +facund_signal_handler(int sig __unused, siginfo_t *info __unused, + void *uap __unused) +{ + facund_in_loop = 0; +} + int main(int argc, char *argv[]) { + struct sigaction sa; pthread_t update_thread, comms_thread; struct facund_conn *conn; const char *config_file; @@ -548,6 +580,11 @@ basedirs_string = NULL; + sa.sa_sigaction = facund_signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sigaction(SIGINT, &sa, NULL); + /* Read in the config file */ config_fd = open(config_file, O_RDONLY); if (config_fd == -1 && errno != ENOENT) { @@ -593,6 +630,7 @@ pthread_create(&update_thread, NULL, look_for_updates, base_dirs); pthread_create(&comms_thread, NULL, do_communication, conn); + /* Wait for the threads to quit */ pthread_join(comms_thread, NULL); pthread_join(update_thread, NULL);