+ get_database_dir();
+ PARA_NOTICE_LOG("opening %u osl tables in %s\n", NUM_AFS_TABLES,
+ database_dir);
+ for (i = 0; i < NUM_AFS_TABLES; i++) {
+ ret = afs_tables[i].open(database_dir);
+ if (ret >= 0)
+ continue;
+ PARA_ERROR_LOG("%s init: %s\n", afs_tables[i].name,
+ para_strerror(-ret));
+ break;
+ }
+ if (ret >= 0)
+ return ret;
+ while (i)
+ afs_tables[--i].close();
+ return ret;
+}
+
+static void signal_pre_select(struct sched *s, struct task *t)
+{
+ struct signal_task *st = container_of(t, struct signal_task, task);
+ para_fd_set(st->fd, &s->rfds, &s->max_fileno);
+}
+
+static void afs_signal_post_select(struct sched *s, struct task *t)
+{
+ struct signal_task *st = container_of(t, struct signal_task, task);
+ if (getppid() == 1) {
+ PARA_EMERG_LOG("para_server died\n");
+ goto shutdown;
+ }
+ if (!FD_ISSET(st->fd, &s->rfds))
+ return;
+ st->signum = para_next_signal();
+ if (st->signum == SIGHUP) {
+ close_afs_tables();
+ parse_config_or_die(1);
+ t->error = open_afs_tables();
+ if (t->error < 0)
+ return;
+ init_admissible_files(current_mop);
+ return;
+ }
+ PARA_EMERG_LOG("terminating on signal %d\n", st->signum);
+shutdown:
+ sched_shutdown();
+ t->error = -E_AFS_SIGNAL;
+}
+
+static void register_signal_task(void)
+{
+ struct signal_task *st = &signal_task_struct;
+
+ para_sigaction(SIGPIPE, SIG_IGN);
+ st->fd = para_signal_init();
+ PARA_INFO_LOG("signal pipe: fd %d\n", st->fd);
+ para_install_sighandler(SIGINT);
+ para_install_sighandler(SIGTERM);
+ para_install_sighandler(SIGHUP);
+
+ st->task.pre_select = signal_pre_select;
+ st->task.post_select = afs_signal_post_select;
+ sprintf(st->task.status, "signal task");
+ register_task(&st->task);
+}
+
+static struct list_head afs_client_list;
+
+/** Describes on connected afs client. */
+struct afs_client {
+ /** Position in the afs client list. */
+ struct list_head node;
+ /** The socket file descriptor for this client. */
+ int fd;
+ /** The time the client connected. */
+ struct timeval connect_time;
+};
+
+static void command_pre_select(struct sched *s, struct task *t)
+{
+ struct command_task *ct = container_of(t, struct command_task, task);
+ struct afs_client *client;
+
+ para_fd_set(server_socket, &s->rfds, &s->max_fileno);
+ para_fd_set(ct->fd, &s->rfds, &s->max_fileno);
+ list_for_each_entry(client, &afs_client_list, node)
+ para_fd_set(client->fd, &s->rfds, &s->max_fileno);
+}