OpenDNSSEC-enforcer  2.1.3
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 "cmdhandler.h"
41 #include "daemon/engine.h"
42 #include "clientpipe.h"
43 #include "clientpipe.h"
44 
45 #include "daemon/queue_cmd.h"
46 #include "scheduler/task.h"
47 
48 static const char *module_str = "queue_cmd";
49 
50 static void
51 usage(int sockfd)
52 {
53  client_printf(sockfd,
54  "queue\n"
55  );
56 }
57 
58 static void
59 help(int sockfd)
60 {
61  client_printf(sockfd,
62  "queue shows all scheduled tasks with their time of earliest executions,\n"
63  "as well as all tasks currently being processed."
64  "\n\n"
65  );
66 }
67 
68 static int
69 run(int sockfd, cmdhandler_ctx_type* context, const char *cmd)
70 {
71  struct tm strtime_struct;
72  char strtime[64]; /* at least 26 according to docs plus a long integer */
73  char* taskdescription;
74  size_t i = 0;
75  int count;
76  time_t now;
77  time_t nextFireTime;
78  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
79  task_type* task = NULL;
80  int num_waiting;
81  engine_type* engine = getglobalcontext(context);
82  (void)cmd;
83 
84  ods_log_debug("[%s] list tasks command", module_str);
85 
86  ods_log_assert(engine);
87  if (!engine->taskq || !engine->taskq->tasks) {
88  client_printf(sockfd, "There are no tasks scheduled.\n");
89  return 0;
90  }
91 
92  schedule_info(engine->taskq, &nextFireTime, &num_waiting, &count);
93  if (num_waiting == engine->config->num_worker_threads) {
94  client_printf(sockfd, "All worker threads idle.\n");
95  }
96 
97  /* how many tasks */
98  client_printf(sockfd, "There %s %i %s scheduled.\n",
99  (count==1)?"is":"are", (int) count, (count==1)?"task":"tasks");
100  now = time_now();
101  strftime(strtime, sizeof(strtime), "%c", localtime_r(&now, &strtime_struct));
102  client_printf(sockfd, "It is now %s (%ld seconds since epoch)\n", (strtime[0]?strtime:"(null)"), (long)now);
103  if (nextFireTime > now) {
104  strftime(strtime, sizeof(strtime), "%c", localtime_r(&nextFireTime, &strtime_struct));
105  client_printf(sockfd, "Next task scheduled %s (%ld seconds since epoch)\n", strtime, (long)nextFireTime);
106  } else if (nextFireTime >= 0) {
107  client_printf(sockfd, "Next task scheduled immediately\n");
108  } /* else: no tasks scheduled at all. */
109 
110  /* list tasks */
111  pthread_mutex_lock(&engine->taskq->schedule_lock);
112  node = ldns_rbtree_first(engine->taskq->tasks);
113  while (node && node != LDNS_RBTREE_NULL) {
114  task = (task_type*) node->data;
115  taskdescription = schedule_describetask(task);
116  client_printf(sockfd, "%s", taskdescription);
117  free(taskdescription);
118  node = ldns_rbtree_next(node);
119  }
120  pthread_mutex_unlock(&engine->taskq->schedule_lock);
121  return 0;
122 }
123 
124 struct cmd_func_block queue_funcblock = {
125  "queue", &usage, &help, NULL, &run
126 };
127 
128 static void
129 usage_flush(int sockfd)
130 {
131  client_printf(sockfd,
132  "flush\n"
133  );
134 }
135 
136 static void
137 help_flush(int sockfd)
138 {
139  client_printf(sockfd,
140  "Execute all scheduled tasks immediately.\n\n");
141 }
142 
143 static int
144 run_flush(int sockfd, cmdhandler_ctx_type* context, const char *cmd)
145 {
146  engine_type* engine = getglobalcontext(context);
147  (void)cmd;
148  ods_log_debug("[%s] flush tasks command", module_str);
149  ods_log_assert(engine);
150  ods_log_assert(engine->taskq);
151 
152  schedule_flush(engine->taskq);
153 
154  client_printf(sockfd, "All tasks scheduled immediately.\n");
155  ods_log_verbose("[cmdhandler] all tasks scheduled immediately");
156  return 0;
157 }
158 
159 struct cmd_func_block flush_funcblock = {
160  "flush", &usage_flush, &help_flush, NULL, &run_flush
161 };
engine_type * getglobalcontext(cmdhandler_ctx_type *context)
engineconfig_type * config
Definition: engine.h:48
int num_worker_threads
Definition: cfg.h:73
struct cmd_func_block flush_funcblock
Definition: queue_cmd.c:159
schedule_type * taskq
Definition: engine.h:60
struct cmd_func_block queue_funcblock
Definition: queue_cmd.c:124