OpenDNSSEC-enforcer  2.0.4
queue_cmd.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 NLNet Labs
3  * Copyright (c) 2014 OpenDNSSEC AB (svb)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
29 #include "config.h"
30 
31 #include <pthread.h>
32 #include <time.h>
33 
34 #include "file.h"
35 #include "log.h"
36 #include "str.h"
37 #include "duration.h"
38 #include "scheduler/schedule.h"
39 #include "daemon/cmdhandler.h"
40 #include "daemon/engine.h"
41 #include "clientpipe.h"
42 #include "clientpipe.h"
43 
44 #include "daemon/queue_cmd.h"
45 
46 static const char *module_str = "queue_cmd";
47 
48 static void
49 usage(int sockfd)
50 {
51  client_printf(sockfd,
52  "queue\n"
53  );
54 }
55 
56 static void
57 help(int sockfd)
58 {
59  client_printf(sockfd,
60  "queue shows all scheduled tasks with their time of earliest executions,\n"
61  "as well as all tasks currently being processed."
62  "\n\n"
63  );
64 }
65 
66 static int
67 handles(const char *cmd, ssize_t n)
68 {
69  return ods_check_command(cmd, n, queue_funcblock()->cmdname)?1:0;
70 }
71 
72 static int
73 run(int sockfd, engine_type* engine, const char *cmd, ssize_t n,
74  db_connection_t *dbconn)
75 {
76  struct tm strtime_struct;
77  char strtime[64]; /* at least 26 according to docs plus a long integer */
78  char buf[ODS_SE_MAXLINE];
79  size_t i = 0, count;
80  time_t now;
81  time_t nextFireTime;
82  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
83  task_type* task = NULL;
84  (void)cmd; (void)n; (void)dbconn;
85 
86  ods_log_debug("[%s] list tasks command", module_str);
87 
88  ods_log_assert(engine);
89  if (!engine->taskq || !engine->taskq->tasks) {
90  client_printf(sockfd, "There are no tasks scheduled.\n");
91  return 0;
92  }
93 
94  /* current work */
95  pthread_mutex_lock(&engine->taskq->schedule_lock);
96  for (i=0; i < (size_t) engine->config->num_worker_threads; i++) {
97  task = engine->workers[i]->task;
98  if (task) {
99  /* TODO: even holding that lock, this is not safe! */
100  client_printf(sockfd, "Working with [%s] %s\n",
101  task_what2str(task->what), task_who2str(task->who));
102  }
103  }
104  pthread_mutex_unlock(&engine->taskq->schedule_lock);
105 
106  /* how many tasks */
107  count = schedule_taskcount(engine->taskq);
108  client_printf(sockfd, "There %s %i %s scheduled.\n",
109  (count==1)?"is":"are", (int) count, (count==1)?"task":"tasks");
110  now = time_now();
111  strftime(strtime, sizeof(strtime), "%c", localtime_r(&now, &strtime_struct));
112  client_printf(sockfd, "It is now %s (%ld seconds since epoch)\n", (strtime[0]?strtime:"(null)"), (long)now);
113  nextFireTime = schedule_time_first(engine->taskq);
114  if (nextFireTime > 0) {
115  strftime(strtime, sizeof(strtime), "%c", localtime_r(&nextFireTime, &strtime_struct));
116  client_printf(sockfd, "Next task scheduled %s (%ld seconds since epoch)\n", strtime, (long)nextFireTime);
117  } else if (nextFireTime == 0) {
118  client_printf(sockfd, "Next task scheduled immediately\n");
119  }
120 
121  /* list tasks */
122  pthread_mutex_lock(&engine->taskq->schedule_lock);
123  node = ldns_rbtree_first(engine->taskq->tasks);
124  while (node && node != LDNS_RBTREE_NULL) {
125  task = (task_type*) node->data;
126  memset(buf, 0, ODS_SE_MAXLINE);
127  (void)task2str(task, buf);
128  client_printf(sockfd, "%s", buf);
129  node = ldns_rbtree_next(node);
130  }
131  pthread_mutex_unlock(&engine->taskq->schedule_lock);
132  return 0;
133 }
134 
135 static struct cmd_func_block funcblock = {
136  "queue", &usage, &help, &handles, &run
137 };
138 
139 struct cmd_func_block*
141 {
142  return &funcblock;
143 }
144 
145 static void
146 usage_flush(int sockfd)
147 {
148  client_printf(sockfd,
149  "flush\n"
150  );
151 }
152 
153 static void
154 help_flush(int sockfd)
155 {
156  client_printf(sockfd,
157  "Execute all scheduled tasks immediately.\n\n");
158 }
159 
160 static int
161 handles_flush(const char *cmd, ssize_t n)
162 {
163  return ods_check_command(cmd, n, flush_funcblock()->cmdname)?1:0;
164 }
165 
166 static int
167 run_flush(int sockfd, engine_type *engine, const char *cmd, ssize_t n,
168  db_connection_t *dbconn)
169 {
170  (void)cmd; (void)n; (void)dbconn;
171  ods_log_debug("[%s] flush tasks command", module_str);
172  ods_log_assert(engine);
173  ods_log_assert(engine->taskq);
174 
175  schedule_flush(engine->taskq);
176 
177  client_printf(sockfd, "All tasks scheduled immediately.\n");
178  ods_log_verbose("[cmdhandler] all tasks scheduled immediately");
179  return 0;
180 }
181 
182 static struct cmd_func_block funcblock_flush = {
183  "flush", &usage_flush, &help_flush, &handles_flush, &run_flush
184 };
185 
186 struct cmd_func_block*
188 {
189  return &funcblock_flush;
190 }
void(* help)(int sockfd)
Definition: cmdhandler.h:64
void ods_log_debug(const char *format,...)
Definition: log.c:41
char * who
Definition: task.h:66
pthread_mutex_t schedule_lock
Definition: schedule.h:52
int(* run)(int sockfd, struct engine_struct *engine, const char *cmd, ssize_t n, db_connection_t *dbconn)
Definition: cmdhandler.h:79
const char * cmdname
Definition: cmdhandler.h:59
struct cmd_func_block * queue_funcblock(void)
Definition: queue_cmd.c:140
void(* usage)(int sockfd)
Definition: cmdhandler.h:61
task_type * task
Definition: worker.h:47
engineconfig_type * config
Definition: engine.h:53
struct cmd_func_block * flush_funcblock(void)
Definition: queue_cmd.c:187
int num_worker_threads
Definition: cfg.h:73
time_t schedule_time_first(schedule_type *schedule)
Definition: schedule.c:246
worker_type ** workers
Definition: engine.h:54
const char * task_what2str(int what)
Definition: task.c:212
const char * task_who2str(const char *who)
Definition: task.c:240
void ods_log_verbose(const char *format,...)
Definition: log.c:48
task_id what
Definition: task.h:60
ldns_rbtree_t * tasks
Definition: schedule.h:49
schedule_type * taskq
Definition: engine.h:55
char * task2str(task_type *task, char *buftask)
Definition: task.c:254
int(* handles)(const char *cmd, ssize_t n)
Definition: cmdhandler.h:67
void schedule_flush(schedule_type *schedule)
Definition: schedule.c:273
size_t schedule_taskcount(schedule_type *schedule)
Definition: schedule.c:266