Motr  M0
kemc.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2019-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <fcntl.h>
32 #include <signal.h>
33 #include <unistd.h>
34 #include <string.h>
35 #include <sys/time.h>
36 #include <assert.h>
37 #include <errno.h>
38 
39 #include "addb2/addb2.h"
40 #include "addb2/global.h"
41 #include "lib/uuid.h"
42 #include "lib/locality.h"
43 #include "module/instance.h"
44 
47 
48 enum {
52  ADDB2_STOB_SIZE = 4 * 1024 * 1024 * 1024ull,
53 };
54 
55 const char *stob_location = "linuxstob:./_kemc";
56 const char *kemd_dev_path = "/dev/";
57 
58 struct kemc_ctx {
59  unsigned int kc_dev_num;
62  volatile sig_atomic_t kc_done;
66  struct m0 kc_instance;
67 };
68 
69 static struct kemc_ctx kemc_ctx;
70 
71 static inline void kem_int_set(struct kemc_ctx *ctx, unsigned int v)
72 {
73  ctx->kc_done = v;
74 }
75 
76 static inline unsigned int kem_int_get(struct kemc_ctx *ctx)
77 {
78  return ctx->kc_done;
79 }
80 
81 static void kem_sigint(int signum)
82 {
83  kem_int_set(&kemc_ctx, 1);
84 }
85 
86 static void usage(void)
87 {
88  fprintf(stderr, "m0kemc: missing CPU number\n"
89  "Usage: sudo ./kemc [CPU]\n");
90  exit(1);
91 }
92 
93 void ke_pf_print(struct pf_event *event)
94 {
95  printf("KE_PAGE_FAULT pid %5d tid %5d addr 0x%016lx wr %u "
96  "fault 0x%04x rdtsc_diff 0x%llx\n",
97  event->pfe_tgid, event->pfe_pid, event->pfe_address,
98  event->pfe_write_access, event->pfe_fault,
99  event->pfe_rdtsc_ret - event->pfe_rdtsc_call);
100 }
101 
102 void ke_cs_print(struct cs_event *event)
103 {
104  printf("KE_CTX_SWITCH prev_pid %5d prev_tid %5d next_pid %5d "
105  "next_tid %5d rdtsc 0x%llx\n",
106  event->cse_prev_tgid, event->cse_prev_pid,
107  event->cse_next_tgid, event->cse_next_pid,
108  event->cse_rdtsc);
109 }
110 
111 void kem_print(struct ke_msg *msg)
112 {
113  printf("%ld.%06ld ", msg->kem_timestamp.tv_sec,
114  msg->kem_timestamp.tv_usec);
115 
116  switch ((enum ke_type)msg->kem_data.ked_type) {
117  case KE_PAGE_FAULT:
118  ke_pf_print(&msg->kem_data.u.ked_pf);
119  return;
120  case KE_CONTEXT_SWITCH:
121  ke_cs_print(&msg->kem_data.u.ked_cs);
122  return;
123  default:
124  fprintf(stderr, "Unknown event ID: %u\n",
125  msg->kem_data.ked_type);
126  }
127 }
128 
129 static int kem_addb2_init(struct kemc_ctx *ctx)
130 {
131  int rc;
132  struct m0_addb2_sys *gsys;
133  struct m0_addb2_sys *sys;
134 
135  m0_instance_setup(&ctx->kc_instance);
137  rc = m0_module_init(&ctx->kc_instance.i_self, M0_LEVEL_INST_READY);
138  if (rc < 0) {
139  fprintf(stderr, "m0kemc: Unable to init m0 (%d).\n", rc);
140  goto exit;
141  }
142 
143  sys = m0_fom_dom()->fd_addb2_sys;
144  gsys = m0_addb2_global_get();
145 
146  sprintf(ctx->kc_stob_loc, "%s%u", stob_location,
147  ctx->kc_dev_num);
148  fprintf(stderr, "m0kemc: Trying to create ADDB2 stob:\t%s\n",
149  ctx->kc_stob_loc);
150 
151  rc = m0_addb2_sys_stor_start(sys, ctx->kc_stob_loc, 13, true, true,
153  if (rc != 0) {
154  fprintf(stderr, "m0kemc: Unable to start ADDB2 stor.\n");
155  goto module;
156  }
157 
158  m0_addb2_sys_attach(gsys, sys);
160  m0_addb2_sys_sm_start(gsys);
161 
162  M0_ADDB2_PUSH(M0_AVI_KEM_CPU, ctx->kc_dev_num);
163 
164  return 0;
165 
166  module:
167  m0_module_fini(&ctx->kc_instance.i_self, M0_LEVEL_INST_READY);
168  exit:
169  return rc;
170 }
171 
172 static void kem_addb2_fini(struct kemc_ctx *ctx)
173 {
174  struct m0_addb2_sys *sys = m0_fom_dom()->fd_addb2_sys;
175  struct m0_addb2_sys *gsys = m0_addb2_global_get();
176 
178 
179  m0_addb2_sys_detach(gsys);
180  m0_addb2_sys_sm_stop(gsys);
184 }
185 
186 
187 static void kem_addb2_log(struct ke_msg *msg)
188 {
189  switch ((enum ke_type)msg->kem_data.ked_type) {
190  case KE_PAGE_FAULT: {
191  struct pf_event *event = &msg->kem_data.u.ked_pf;
192 
194  event->pfe_tgid, event->pfe_pid,
195  event->pfe_address,
196  event->pfe_write_access, event->pfe_fault,
197  event->pfe_rdtsc_ret -
198  event->pfe_rdtsc_call);
199 
200  return;
201  }
202  case KE_CONTEXT_SWITCH: {
203  struct cs_event *event = &msg->kem_data.u.ked_cs;
204 
206  event->cse_prev_tgid, event->cse_prev_pid,
207  event->cse_next_tgid, event->cse_next_pid,
208  event->cse_rdtsc);
209 
210  return;
211  }
212  default:
213  fprintf(stderr, "Unknown event ID: %u\n",
214  msg->kem_data.ked_type);
215  }
216 }
217 
218 static int kem_init(struct kemc_ctx *ctx, int dev_num,
219  void (*sighandler)(int),
220  bool use_stdout, bool use_addb2)
221 {
222  struct sigaction sa;
223  int rc = 0;
224 
225  memset(ctx, 0, sizeof(*ctx));
226 
227  ctx->kc_use_stdout = use_stdout;
228  ctx->kc_use_addb2 = use_addb2;
229 
230  if (!(ctx->kc_use_addb2 || ctx->kc_use_stdout)) {
231  fprintf(stderr, "m0kemc: back end not specified\n");
232  rc = -EINVAL;
233  goto exit;
234  }
235 
236  ctx->kc_dev_num = dev_num;
237  sprintf(ctx->kc_kemd_filename, "%s%s%u", kemd_dev_path,
238  KEMD_DEV_NAME, ctx->kc_dev_num);
239  fprintf(stderr, "m0kemc: Trying to open:\t%s\n",
240  ctx->kc_kemd_filename);
241 
242  ctx->kc_kemd_fd = open(ctx->kc_kemd_filename, O_RDONLY);
243  if (ctx->kc_kemd_fd < 0) {
244  fprintf(stderr, "m0kemc: Unable to open:%s %d\n",
245  ctx->kc_kemd_filename, ctx->kc_kemd_fd);
246  rc = -errno;
247  goto exit;
248  }
249 
250  kem_int_set(ctx, 0);
251 
252  sigemptyset(&sa.sa_mask);
253  sa.sa_handler = sighandler;
254  rc = sigaction(SIGINT, &sa, NULL);
255  if (rc < 0) {
256  fprintf(stderr, "m0kemc: Unable to set signal handler (%d).\n",
257  rc);
258  close(ctx->kc_kemd_fd);
259  goto exit;
260  }
261 
262  if (ctx->kc_use_addb2) {
263  rc = kem_addb2_init(ctx);
264 
265  if (rc < 0) {
266  fprintf(stderr, "m0kemc: Unable to init addb2 back end"
267  " (%d)\n", rc);
268  close(ctx->kc_kemd_fd);
269  goto exit;
270  }
271  }
272  exit:
273  return rc;
274 }
275 
276 static void kem_fini(struct kemc_ctx *ctx)
277 {
278  if (ctx->kc_use_addb2) {
280  }
281 
282  fflush(stdout);
283  fflush(stderr);
284 
285  close(ctx->kc_kemd_fd);
286 }
287 
288 static void kem_log(struct kemc_ctx *ctx, struct ke_msg *msg)
289 {
290  if (ctx->kc_use_stdout)
291  kem_print(msg);
292 
293  if (ctx->kc_use_addb2)
294  kem_addb2_log(msg);
295 }
296 
297 static int kem_read(struct kemc_ctx *ctx, struct ke_msg *msg)
298 {
299  return read(ctx->kc_kemd_fd, msg, sizeof(*msg));
300 }
301 
302 int main(int argc, char** argv)
303 {
304  bool use_stdout;
305  bool use_addb2;
306  int rc;
307  int dev_num;
308  ssize_t bytes_read;
309  struct kemc_ctx *ctx;
310  struct ke_msg ke_msg;
311  struct ke_msg *ent;
312 
313  if (argc < 2)
314  usage();
315 
316  /* TODO: Handling of options */
317  use_stdout = false;
318  use_addb2 = true;
319  dev_num = atoi(argv[1]);
320 
321  ctx = &kemc_ctx;
322  rc = kem_init(ctx, dev_num, &kem_sigint,
323  use_stdout, use_addb2);
324  if (rc < 0)
325  return rc;
326 
327  ent = &ke_msg;
328  while(kem_int_get(ctx) == 0) {
329  bytes_read = kem_read(ctx, ent);
330  if ((bytes_read < 0 && errno == -EINTR) ||
331  !bytes_read) {
332  continue;
333  } else if (bytes_read < 0) {
334  fprintf(stderr, "kem_read() returned -1, errno %d\n",
335  errno);
336  kem_int_set(ctx, 1);
337  continue;
338  }
339 
340  assert(bytes_read == sizeof(*ent));
341 
342  kem_log(ctx, ent);
343  }
344  fprintf(stderr, "Caught SIGINT, exit...\n");
345 
346  kem_fini(ctx);
347 
348  return 0;
349 }
350 
353 /*
354  * Local variables:
355  * c-indentation-style: "K&R"
356  * c-basic-offset: 8
357  * tab-width: 8
358  * fill-column: 80
359  * scroll-step: 1
360  * End:
361  */
362 /*
363  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
364  */
struct m0 kc_instance
Definition: kemc.c:66
void m0_addb2_sys_net_stop(struct m0_addb2_sys *sys)
Definition: sys.c:322
static void kem_addb2_log(struct ke_msg *msg)
Definition: kemc.c:187
#define NULL
Definition: misc.h:38
void m0_addb2_sys_sm_stop(struct m0_addb2_sys *sys)
Definition: sys.c:384
unsigned long long pfe_rdtsc_call
Definition: kem.h:47
void m0_addb2_sys_sm_start(struct m0_addb2_sys *sys)
Definition: sys.c:377
unsigned long long cse_rdtsc
Definition: kem.h:59
static void usage(void)
Definition: kemc.c:86
void ke_pf_print(struct pf_event *event)
Definition: kemc.c:93
#define M0_ADDB2_PUSH(id,...)
Definition: addb2.h:261
#define KEMD_DEV_NAME
Definition: kem.h:37
static void kem_int_set(struct kemc_ctx *ctx, unsigned int v)
Definition: kemc.c:71
void m0_addb2_sys_attach(struct m0_addb2_sys *sys, struct m0_addb2_sys *src)
Definition: sys.c:408
M0_INTERNAL void m0_instance_setup(struct m0 *instance)
Definition: instance.c:110
int kc_kemd_fd
Definition: kemc.c:60
static struct kemc_ctx kemc_ctx
Definition: kemc.c:69
M0_ADDB2_ADD(M0_AVI_FS_CREATE, new_fid.f_container, new_fid.f_key, mode, rc)
char kc_kemd_filename[KEMD_FILENAME_SIZE]
Definition: kemc.c:61
pid_t cse_prev_pid
Definition: kem.h:55
Definition: kemc.c:58
unsigned int ked_type
Definition: kem.h:63
static void kem_fini(struct kemc_ctx *ctx)
Definition: kemc.c:276
unsigned long long pfe_rdtsc_ret
Definition: kem.h:48
bool kc_use_stdout
Definition: kemc.c:63
void m0_addb2_sys_detach(struct m0_addb2_sys *sys)
Definition: sys.c:416
static int kem_addb2_init(struct kemc_ctx *ctx)
Definition: kemc.c:129
pid_t cse_next_pid
Definition: kem.h:57
ke_type
Definition: kem.h:39
int pfe_fault
Definition: kem.h:51
void kem_print(struct ke_msg *msg)
Definition: kemc.c:111
void m0_node_uuid_string_set(const char *uuid)
Definition: uuuid.c:64
int main(int argc, char **argv)
Definition: kemc.c:302
Definition: kem.h:44
Definition: instance.h:80
pid_t pfe_pid
Definition: kem.h:45
pid_t cse_next_tgid
Definition: kem.h:58
Definition: kem.h:70
const char * stob_location
Definition: kemc.c:55
static struct fdmi_ctx ctx
Definition: main.c:80
static int kem_read(struct kemc_ctx *ctx, struct ke_msg *msg)
Definition: kemc.c:297
void m0_addb2_pop(uint64_t id)
Definition: addb2.c:440
static int kem_init(struct kemc_ctx *ctx, int dev_num, void(*sighandler)(int), bool use_stdout, bool use_addb2)
Definition: kemc.c:218
unsigned long pfe_address
Definition: kem.h:49
volatile sig_atomic_t kc_done
Definition: kemc.c:62
static unsigned int kem_int_get(struct kemc_ctx *ctx)
Definition: kemc.c:76
unsigned int pfe_write_access
Definition: kem.h:50
char kc_stob_loc[ADDB2_STOB_NAME_SIZE]
Definition: kemc.c:65
int m0_addb2_sys_stor_start(struct m0_addb2_sys *sys, const char *location, uint64_t key, bool mkfs, bool force, m0_bcount_t size)
Definition: sys.c:357
struct timeval kem_timestamp
Definition: kem.h:71
M0_INTERNAL struct m0_fom_domain * m0_fom_dom(void)
Definition: locality.c:575
M0_INTERNAL struct m0_addb2_sys * m0_addb2_global_get(void)
Definition: global.c:99
static void kem_log(struct kemc_ctx *ctx, struct ke_msg *msg)
Definition: kemc.c:288
struct pf_event ked_pf
Definition: kem.h:65
pid_t pfe_tgid
Definition: kem.h:46
struct cs_event ked_cs
Definition: kem.h:66
bool kc_use_addb2
Definition: kemc.c:64
void ke_cs_print(struct cs_event *event)
Definition: kemc.c:102
unsigned int kc_dev_num
Definition: kemc.c:59
struct m0_addb2_sys * fd_addb2_sys
Definition: fom.h:338
struct ke_data kem_data
Definition: kem.h:72
static void kem_addb2_fini(struct kemc_ctx *ctx)
Definition: kemc.c:172
pid_t cse_prev_tgid
Definition: kem.h:56
Definition: nucleus.c:42
Definition: kem.h:54
struct m0_dirent * ent
Definition: dir.c:1029
void m0_addb2_sys_stor_stop(struct m0_addb2_sys *sys)
Definition: sys.c:370
union ke_data::@474 u
const char * kemd_dev_path
Definition: kemc.c:56
int32_t rc
Definition: trigger_fop.h:47
static void kem_sigint(int signum)
Definition: kemc.c:81
M0_INTERNAL void m0_module_fini(struct m0_module *module, int level)
Definition: module.c:142
M0_INTERNAL int m0_module_init(struct m0_module *module, int level)
Definition: module.c:131