]> git.proxmox.com Git - ceph.git/blame - ceph/src/pmdk/src/tools/rpmemd/rpmemd.c
import ceph 16.2.7
[ceph.git] / ceph / src / pmdk / src / tools / rpmemd / rpmemd.c
CommitLineData
a4b75251
TL
1// SPDX-License-Identifier: BSD-3-Clause
2/* Copyright 2016-2020, Intel Corporation */
3
4/*
5 * rpmemd.c -- rpmemd main source file
6 */
7
8#include <stdlib.h>
9#include <unistd.h>
10#include <errno.h>
11#include <string.h>
12#include <sys/socket.h>
13#include <netinet/in.h>
14
15#include "librpmem.h"
16#include "rpmemd.h"
17#include "rpmemd_log.h"
18#include "rpmemd_config.h"
19#include "rpmem_common.h"
20#include "rpmemd_fip.h"
21#include "rpmemd_obc.h"
22#include "rpmemd_db.h"
23#include "rpmemd_util.h"
24#include "pool_hdr.h"
25#include "os.h"
26#include "os_thread.h"
27#include "util.h"
28#include "uuid.h"
29#include "set.h"
30
31/*
32 * rpmemd -- rpmem handle
33 */
34struct rpmemd {
35 struct rpmemd_obc *obc; /* out-of-band connection handle */
36 struct rpmemd_db *db; /* pool set database handle */
37 struct rpmemd_db_pool *pool; /* pool handle */
38 char *pool_desc; /* pool descriptor */
39 struct rpmemd_fip *fip; /* fabric provider handle */
40 struct rpmemd_config config; /* configuration */
41 enum rpmem_persist_method persist_method;
42 int closing; /* set when closing connection */
43 int created; /* pool created */
44 os_thread_t fip_thread;
45 int fip_running;
46};
47
48#ifdef DEBUG
49/*
50 * bool2str -- convert bool to yes/no string
51 */
52static inline const char *
53bool2str(int v)
54{
55 return v ? "yes" : "no";
56}
57#endif
58
59/*
60 * str_or_null -- return null string instead of NULL pointer
61 */
62static inline const char *
63_str(const char *str)
64{
65 if (!str)
66 return "(null)";
67 return str;
68}
69
70/*
71 * uuid2str -- convert uuid to string
72 */
73static const char *
74uuid2str(const uuid_t uuid)
75{
76 static char uuid_str[64] = {0, };
77
78 int ret = util_uuid_to_string(uuid, uuid_str);
79 if (ret != 0) {
80 return "(error)";
81 }
82
83 return uuid_str;
84}
85
86/*
87 * rpmemd_get_pm -- returns persist method based on configuration
88 */
89static enum rpmem_persist_method
90rpmemd_get_pm(struct rpmemd_config *config)
91{
92 enum rpmem_persist_method ret = RPMEM_PM_GPSPM;
93
94 if (config->persist_apm)
95 ret = RPMEM_PM_APM;
96
97 return ret;
98}
99
100/*
101 * rpmemd_db_get_status -- convert error number to status for db operation
102 */
103static int
104rpmemd_db_get_status(int err)
105{
106 switch (err) {
107 case EEXIST:
108 return RPMEM_ERR_EXISTS;
109 case EACCES:
110 return RPMEM_ERR_NOACCESS;
111 case ENOENT:
112 return RPMEM_ERR_NOEXIST;
113 case EWOULDBLOCK:
114 return RPMEM_ERR_BUSY;
115 case EBADF:
116 return RPMEM_ERR_BADNAME;
117 case EINVAL:
118 return RPMEM_ERR_POOL_CFG;
119 default:
120 return RPMEM_ERR_FATAL;
121 }
122}
123
124/*
125 * rpmemd_check_pool -- verify pool parameters
126 */
127static int
128rpmemd_check_pool(struct rpmemd *rpmemd, const struct rpmem_req_attr *req,
129 int *status)
130{
131 if (rpmemd->pool->pool_size < RPMEM_MIN_POOL) {
132 RPMEMD_LOG(ERR, "invalid pool size -- must be >= %zu",
133 RPMEM_MIN_POOL);
134 *status = RPMEM_ERR_POOL_CFG;
135 return -1;
136 }
137
138 if (rpmemd->pool->pool_size < req->pool_size) {
139 RPMEMD_LOG(ERR, "requested size is too big");
140 *status = RPMEM_ERR_BADSIZE;
141 return -1;
142 }
143
144 return 0;
145}
146
147/*
148 * rpmemd_deep_persist -- perform deep persist operation
149 */
150static int
151rpmemd_deep_persist(const void *addr, size_t size, void *ctx)
152{
153 struct rpmemd *rpmemd = (struct rpmemd *)ctx;
154 return util_replica_deep_persist(addr, size, rpmemd->pool->set, 0);
155}
156
157/*
158 * rpmemd_common_fip_init -- initialize fabric provider
159 */
160static int
161rpmemd_common_fip_init(struct rpmemd *rpmemd, const struct rpmem_req_attr *req,
162 struct rpmem_resp_attr *resp, int *status)
163{
164 /* register the whole pool with header in RDMA */
165 void *addr = (void *)((uintptr_t)rpmemd->pool->pool_addr);
166 struct rpmemd_fip_attr fip_attr = {
167 .addr = addr,
168 .size = req->pool_size,
169 .nlanes = req->nlanes,
170 .nthreads = rpmemd->config.nthreads,
171 .provider = req->provider,
172 .persist_method = rpmemd->persist_method,
173 .deep_persist = rpmemd_deep_persist,
174 .ctx = rpmemd,
175 .buff_size = req->buff_size,
176 };
177
178 const int is_pmem = rpmemd_db_pool_is_pmem(rpmemd->pool);
179 if (rpmemd_apply_pm_policy(&fip_attr.persist_method,
180 &fip_attr.persist,
181 &fip_attr.memcpy_persist,
182 is_pmem)) {
183 *status = RPMEM_ERR_FATAL;
184 goto err_fip_init;
185 }
186
187 const char *node = rpmem_get_ssh_conn_addr();
188 enum rpmem_err err;
189
190 rpmemd->fip = rpmemd_fip_init(node, NULL, &fip_attr, resp, &err);
191 if (!rpmemd->fip) {
192 *status = (int)err;
193 goto err_fip_init;
194 }
195
196 return 0;
197err_fip_init:
198 return -1;
199}
200
201/*
202 * rpmemd_print_req_attr -- print request attributes
203 */
204static void
205rpmemd_print_req_attr(const struct rpmem_req_attr *req)
206{
207 RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "pool descriptor: '%s'",
208 _str(req->pool_desc));
209 RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "pool size: %lu", req->pool_size);
210 RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "nlanes: %u", req->nlanes);
211 RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "provider: %s",
212 rpmem_provider_to_str(req->provider));
213 RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "buff_size: %lu", req->buff_size);
214}
215
216/*
217 * rpmemd_print_pool_attr -- print pool attributes
218 */
219static void
220rpmemd_print_pool_attr(const struct rpmem_pool_attr *attr)
221{
222 if (attr == NULL) {
223 RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "NULL");
224 } else {
225 RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "signature: '%s'",
226 _str(attr->signature));
227 RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "major: %u", attr->major);
228 RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "compat_features: 0x%x",
229 attr->compat_features);
230 RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "incompat_features: 0x%x",
231 attr->incompat_features);
232 RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "ro_compat_features: 0x%x",
233 attr->ro_compat_features);
234 RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "poolset_uuid: %s",
235 uuid2str(attr->poolset_uuid));
236 RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "uuid: %s",
237 uuid2str(attr->uuid));
238 RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "next_uuid: %s",
239 uuid2str(attr->next_uuid));
240 RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "prev_uuid: %s",
241 uuid2str(attr->prev_uuid));
242 }
243}
244
245/*
246 * rpmemd_print_resp_attr -- print response attributes
247 */
248static void
249rpmemd_print_resp_attr(const struct rpmem_resp_attr *attr)
250{
251 RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "port: %u", attr->port);
252 RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "rkey: 0x%lx", attr->rkey);
253 RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "raddr: 0x%lx", attr->raddr);
254 RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "nlanes: %u", attr->nlanes);
255 RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "persist method: %s",
256 rpmem_persist_method_to_str(attr->persist_method));
257}
258
259/*
260 * rpmemd_fip_thread -- background thread for establishing in-band connection
261 */
262static void *
263rpmemd_fip_thread(void *arg)
264{
265 struct rpmemd *rpmemd = (struct rpmemd *)arg;
266 int ret;
267
268 RPMEMD_LOG(INFO, "waiting for in-band connection");
269
270 ret = rpmemd_fip_accept(rpmemd->fip, RPMEM_ACCEPT_TIMEOUT);
271 if (ret)
272 goto err_accept;
273
274 RPMEMD_LOG(NOTICE, "in-band connection established");
275
276 ret = rpmemd_fip_process_start(rpmemd->fip);
277 if (ret)
278 goto err_process_start;
279
280 return NULL;
281err_process_start:
282 rpmemd_fip_close(rpmemd->fip);
283err_accept:
284 return (void *)(uintptr_t)ret;
285}
286
287/*
288 * rpmemd_fip_start_thread -- start background thread for establishing
289 * in-band connection
290 */
291static int
292rpmemd_fip_start_thread(struct rpmemd *rpmemd)
293{
294 errno = os_thread_create(&rpmemd->fip_thread, NULL,
295 rpmemd_fip_thread, rpmemd);
296 if (errno) {
297 RPMEMD_LOG(ERR, "!creating in-band thread");
298 goto err_os_thread_create;
299 }
300
301 rpmemd->fip_running = 1;
302
303 return 0;
304err_os_thread_create:
305 return -1;
306}
307
308/*
309 * rpmemd_fip_stop_thread -- stop background thread for in-band connection
310 */
311static int
312rpmemd_fip_stop_thread(struct rpmemd *rpmemd)
313{
314 RPMEMD_ASSERT(rpmemd->fip_running);
315 void *tret;
316 errno = os_thread_join(&rpmemd->fip_thread, &tret);
317 if (errno)
318 RPMEMD_LOG(ERR, "!waiting for in-band thread");
319
320 int ret = (int)(uintptr_t)tret;
321 if (ret)
322 RPMEMD_LOG(ERR, "in-band thread failed -- '%d'", ret);
323
324 return ret;
325}
326
327/*
328 * rpmemd_fip-stop -- stop in-band thread and stop processing thread
329 */
330static int
331rpmemd_fip_stop(struct rpmemd *rpmemd)
332{
333 int ret;
334
335 int fip_ret = rpmemd_fip_stop_thread(rpmemd);
336 if (fip_ret) {
337 RPMEMD_LOG(ERR, "!in-band thread failed");
338 }
339
340 if (!fip_ret) {
341 ret = rpmemd_fip_process_stop(rpmemd->fip);
342 if (ret) {
343 RPMEMD_LOG(ERR, "!stopping fip process failed");
344 }
345 }
346
347 rpmemd->fip_running = 0;
348
349 return fip_ret;
350}
351
352/*
353 * rpmemd_close_pool -- close pool and remove it if required
354 */
355static int
356rpmemd_close_pool(struct rpmemd *rpmemd, int remove)
357{
358 int ret = 0;
359
360 RPMEMD_LOG(NOTICE, "closing pool");
361 rpmemd_db_pool_close(rpmemd->db, rpmemd->pool);
362 RPMEMD_LOG(INFO, "pool closed");
363
364 if (remove) {
365 RPMEMD_LOG(NOTICE, "removing '%s'", rpmemd->pool_desc);
366 ret = rpmemd_db_pool_remove(rpmemd->db,
367 rpmemd->pool_desc, 0, 0);
368 if (ret) {
369 RPMEMD_LOG(ERR, "!removing pool '%s' failed",
370 rpmemd->pool_desc);
371 } else {
372 RPMEMD_LOG(INFO, "removed '%s'", rpmemd->pool_desc);
373 }
374 }
375
376 free(rpmemd->pool_desc);
377
378 return ret;
379}
380
381/*
382 * rpmemd_req_cleanup -- cleanup in-band connection and all resources allocated
383 * during open/create requests
384 */
385static void
386rpmemd_req_cleanup(struct rpmemd *rpmemd)
387{
388 if (!rpmemd->fip_running)
389 return;
390
391 int ret;
392
393 ret = rpmemd_fip_stop(rpmemd);
394 if (!ret) {
395 rpmemd_fip_close(rpmemd->fip);
396 rpmemd_fip_fini(rpmemd->fip);
397 }
398
399 int remove = rpmemd->created && ret;
400 rpmemd_close_pool(rpmemd, remove);
401}
402
403/*
404 * rpmemd_req_create -- handle create request
405 */
406static int
407rpmemd_req_create(struct rpmemd_obc *obc, void *arg,
408 const struct rpmem_req_attr *req,
409 const struct rpmem_pool_attr *pool_attr)
410{
411 RPMEMD_ASSERT(arg != NULL);
412 RPMEMD_LOG(NOTICE, "create request:");
413 rpmemd_print_req_attr(req);
414 RPMEMD_LOG(NOTICE, "pool attributes:");
415 rpmemd_print_pool_attr(pool_attr);
416
417 struct rpmemd *rpmemd = (struct rpmemd *)arg;
418
419 int ret;
420 int status = 0;
421 int err_send = 1;
422 struct rpmem_resp_attr resp;
423 memset(&resp, 0, sizeof(resp));
424
425 if (rpmemd->pool) {
426 RPMEMD_LOG(ERR, "pool already opened");
427 ret = -1;
428 status = RPMEM_ERR_FATAL;
429 goto err_pool_opened;
430 }
431
432 rpmemd->pool_desc = strdup(req->pool_desc);
433 if (!rpmemd->pool_desc) {
434 RPMEMD_LOG(ERR, "!allocating pool descriptor");
435 ret = -1;
436 status = RPMEM_ERR_FATAL;
437 goto err_strdup;
438 }
439
440 rpmemd->pool = rpmemd_db_pool_create(rpmemd->db,
441 req->pool_desc, 0, pool_attr);
442 if (!rpmemd->pool) {
443 ret = -1;
444 status = rpmemd_db_get_status(errno);
445 goto err_pool_create;
446 }
447
448 rpmemd->created = 1;
449
450 ret = rpmemd_check_pool(rpmemd, req, &status);
451 if (ret)
452 goto err_pool_check;
453
454 ret = rpmemd_common_fip_init(rpmemd, req, &resp, &status);
455 if (ret)
456 goto err_fip_init;
457
458 RPMEMD_LOG(NOTICE, "create request response: (status = %u)", status);
459 if (!status)
460 rpmemd_print_resp_attr(&resp);
461 ret = rpmemd_obc_create_resp(obc, status, &resp);
462 if (ret)
463 goto err_create_resp;
464
465 ret = rpmemd_fip_start_thread(rpmemd);
466 if (ret)
467 goto err_fip_start;
468
469 return 0;
470err_fip_start:
471err_create_resp:
472 err_send = 0;
473 rpmemd_fip_fini(rpmemd->fip);
474err_fip_init:
475err_pool_check:
476 rpmemd_db_pool_close(rpmemd->db, rpmemd->pool);
477 rpmemd_db_pool_remove(rpmemd->db, req->pool_desc, 0, 0);
478err_pool_create:
479 free(rpmemd->pool_desc);
480err_strdup:
481err_pool_opened:
482 if (err_send)
483 ret = rpmemd_obc_create_resp(obc, status, &resp);
484 rpmemd->closing = 1;
485 return ret;
486}
487
488/*
489 * rpmemd_req_open -- handle open request
490 */
491static int
492rpmemd_req_open(struct rpmemd_obc *obc, void *arg,
493 const struct rpmem_req_attr *req)
494{
495 RPMEMD_ASSERT(arg != NULL);
496 RPMEMD_LOG(NOTICE, "open request:");
497 rpmemd_print_req_attr(req);
498 struct rpmemd *rpmemd = (struct rpmemd *)arg;
499
500 int ret;
501 int status = 0;
502 int err_send = 1;
503 struct rpmem_resp_attr resp;
504 memset(&resp, 0, sizeof(resp));
505
506 struct rpmem_pool_attr pool_attr;
507 memset(&pool_attr, 0, sizeof(pool_attr));
508
509 if (rpmemd->pool) {
510 RPMEMD_LOG(ERR, "pool already opened");
511 ret = -1;
512 status = RPMEM_ERR_FATAL;
513 goto err_pool_opened;
514 }
515
516 rpmemd->pool_desc = strdup(req->pool_desc);
517 if (!rpmemd->pool_desc) {
518 RPMEMD_LOG(ERR, "!allocating pool descriptor");
519 ret = -1;
520 status = RPMEM_ERR_FATAL;
521 goto err_strdup;
522 }
523
524 rpmemd->pool = rpmemd_db_pool_open(rpmemd->db,
525 req->pool_desc, 0, &pool_attr);
526 if (!rpmemd->pool) {
527 ret = -1;
528 status = rpmemd_db_get_status(errno);
529 goto err_pool_open;
530 }
531
532 RPMEMD_LOG(NOTICE, "pool attributes:");
533 rpmemd_print_pool_attr(&pool_attr);
534
535 ret = rpmemd_check_pool(rpmemd, req, &status);
536 if (ret)
537 goto err_pool_check;
538
539 ret = rpmemd_common_fip_init(rpmemd, req, &resp, &status);
540 if (ret)
541 goto err_fip_init;
542
543 RPMEMD_LOG(NOTICE, "open request response: (status = %u)", status);
544 if (!status)
545 rpmemd_print_resp_attr(&resp);
546
547 ret = rpmemd_obc_open_resp(obc, status, &resp, &pool_attr);
548 if (ret)
549 goto err_open_resp;
550
551 ret = rpmemd_fip_start_thread(rpmemd);
552 if (ret)
553 goto err_fip_start;
554
555 return 0;
556err_fip_start:
557err_open_resp:
558 err_send = 0;
559 rpmemd_fip_fini(rpmemd->fip);
560err_fip_init:
561err_pool_check:
562 rpmemd_db_pool_close(rpmemd->db, rpmemd->pool);
563err_pool_open:
564 free(rpmemd->pool_desc);
565err_strdup:
566err_pool_opened:
567 if (err_send)
568 ret = rpmemd_obc_open_resp(obc, status, &resp, &pool_attr);
569 rpmemd->closing = 1;
570 return ret;
571}
572
573/*
574 * rpmemd_req_close -- handle close request
575 */
576static int
577rpmemd_req_close(struct rpmemd_obc *obc, void *arg, int flags)
578{
579 RPMEMD_ASSERT(arg != NULL);
580 RPMEMD_LOG(NOTICE, "close request");
581
582 struct rpmemd *rpmemd = (struct rpmemd *)arg;
583
584 rpmemd->closing = 1;
585
586 int ret;
587 int status = 0;
588
589 if (!rpmemd->pool) {
590 RPMEMD_LOG(ERR, "pool not opened");
591 status = RPMEM_ERR_FATAL;
592 return rpmemd_obc_close_resp(obc, status);
593 }
594
595 ret = rpmemd_fip_stop(rpmemd);
596 if (ret) {
597 status = RPMEM_ERR_FATAL;
598 } else {
599 rpmemd_fip_close(rpmemd->fip);
600 rpmemd_fip_fini(rpmemd->fip);
601 }
602
603 int remove = rpmemd->created &&
604 (status || (flags & RPMEM_CLOSE_FLAGS_REMOVE));
605 if (rpmemd_close_pool(rpmemd, remove))
606 RPMEMD_LOG(ERR, "closing pool failed");
607
608 RPMEMD_LOG(NOTICE, "close request response (status = %u)", status);
609 ret = rpmemd_obc_close_resp(obc, status);
610
611 return ret;
612}
613
614/*
615 * rpmemd_req_set_attr -- handle set attributes request
616 */
617static int
618rpmemd_req_set_attr(struct rpmemd_obc *obc, void *arg,
619 const struct rpmem_pool_attr *pool_attr)
620{
621 RPMEMD_ASSERT(arg != NULL);
622 RPMEMD_LOG(NOTICE, "set attributes request");
623 struct rpmemd *rpmemd = (struct rpmemd *)arg;
624 RPMEMD_ASSERT(rpmemd->pool != NULL);
625
626 int ret;
627 int status = 0;
628 int err_send = 1;
629
630 ret = rpmemd_db_pool_set_attr(rpmemd->pool, pool_attr);
631 if (ret) {
632 ret = -1;
633 status = rpmemd_db_get_status(errno);
634 goto err_set_attr;
635 }
636
637 RPMEMD_LOG(NOTICE, "new pool attributes:");
638 rpmemd_print_pool_attr(pool_attr);
639
640 ret = rpmemd_obc_set_attr_resp(obc, status);
641 if (ret)
642 goto err_set_attr_resp;
643
644 return ret;
645err_set_attr_resp:
646 err_send = 0;
647err_set_attr:
648 if (err_send)
649 ret = rpmemd_obc_set_attr_resp(obc, status);
650 return ret;
651}
652
653static struct rpmemd_obc_requests rpmemd_req = {
654 .create = rpmemd_req_create,
655 .open = rpmemd_req_open,
656 .close = rpmemd_req_close,
657 .set_attr = rpmemd_req_set_attr,
658};
659
660/*
661 * rpmemd_print_info -- print basic info and configuration
662 */
663static void
664rpmemd_print_info(struct rpmemd *rpmemd)
665{
666 RPMEMD_LOG(NOTICE, "ssh connection: %s",
667 _str(os_getenv("SSH_CONNECTION")));
668 RPMEMD_LOG(NOTICE, "user: %s", _str(os_getenv("USER")));
669 RPMEMD_LOG(NOTICE, "configuration");
670 RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "pool set directory: '%s'",
671 _str(rpmemd->config.poolset_dir));
672 RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "persist method: %s",
673 rpmem_persist_method_to_str(rpmemd->persist_method));
674 RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "number of threads: %lu",
675 rpmemd->config.nthreads);
676 RPMEMD_DBG(RPMEMD_LOG_INDENT "persist APM: %s",
677 bool2str(rpmemd->config.persist_apm));
678 RPMEMD_DBG(RPMEMD_LOG_INDENT "persist GPSPM: %s",
679 bool2str(rpmemd->config.persist_general));
680 RPMEMD_DBG(RPMEMD_LOG_INDENT "use syslog: %s",
681 bool2str(rpmemd->config.use_syslog));
682 RPMEMD_DBG(RPMEMD_LOG_INDENT "log file: %s",
683 _str(rpmemd->config.log_file));
684 RPMEMD_DBG(RPMEMD_LOG_INDENT "log level: %s",
685 rpmemd_log_level_to_str(rpmemd->config.log_level));
686}
687
688int
689main(int argc, char *argv[])
690{
691 util_init();
692
693 int send_status = 1;
694 int ret = 1;
695
696 struct rpmemd *rpmemd = calloc(1, sizeof(*rpmemd));
697 if (!rpmemd) {
698 RPMEMD_LOG(ERR, "!calloc");
699 goto err_rpmemd;
700 }
701
702 rpmemd->obc = rpmemd_obc_init(STDIN_FILENO, STDOUT_FILENO);
703 if (!rpmemd->obc) {
704 RPMEMD_LOG(ERR, "out-of-band connection initialization");
705 goto err_obc;
706 }
707
708 if (rpmemd_log_init(DAEMON_NAME, NULL, 0)) {
709 RPMEMD_LOG(ERR, "logging subsystem initialization failed");
710 goto err_log_init;
711 }
712
713 if (rpmemd_config_read(&rpmemd->config, argc, argv) != 0) {
714 RPMEMD_LOG(ERR, "reading configuration failed");
715 goto err_config;
716 }
717
718 rpmemd_log_close();
719 rpmemd_log_level = rpmemd->config.log_level;
720 if (rpmemd_log_init(DAEMON_NAME, rpmemd->config.log_file,
721 rpmemd->config.use_syslog)) {
722 RPMEMD_LOG(ERR, "logging subsystem initialization"
723 " failed (%s, %d)", rpmemd->config.log_file,
724 rpmemd->config.use_syslog);
725 goto err_log_init_config;
726 }
727
728 RPMEMD_LOG(INFO, "%s version %s", DAEMON_NAME, SRCVERSION);
729 rpmemd->persist_method = rpmemd_get_pm(&rpmemd->config);
730
731 rpmemd->db = rpmemd_db_init(rpmemd->config.poolset_dir, 0666);
732 if (!rpmemd->db) {
733 RPMEMD_LOG(ERR, "!pool set db initialization");
734 goto err_db_init;
735 }
736
737 if (rpmemd->config.rm_poolset) {
738 RPMEMD_LOG(INFO, "removing '%s'",
739 rpmemd->config.rm_poolset);
740 if (rpmemd_db_pool_remove(rpmemd->db,
741 rpmemd->config.rm_poolset,
742 rpmemd->config.force,
743 rpmemd->config.pool_set)) {
744 RPMEMD_LOG(ERR, "removing '%s' failed",
745 rpmemd->config.rm_poolset);
746 ret = errno;
747 } else {
748 RPMEMD_LOG(NOTICE, "removed '%s'",
749 rpmemd->config.rm_poolset);
750 ret = 0;
751 }
752 send_status = 0;
753 goto out_rm;
754 }
755
756 ret = rpmemd_obc_status(rpmemd->obc, 0);
757 if (ret) {
758 RPMEMD_LOG(ERR, "writing status failed");
759 goto err_status;
760 }
761
762 rpmemd_print_info(rpmemd);
763
764 while (!ret) {
765 ret = rpmemd_obc_process(rpmemd->obc, &rpmemd_req, rpmemd);
766 if (ret) {
767 RPMEMD_LOG(ERR, "out-of-band connection"
768 " process failed");
769 goto err;
770 }
771
772 if (rpmemd->closing)
773 break;
774 }
775
776 rpmemd_db_fini(rpmemd->db);
777 rpmemd_config_free(&rpmemd->config);
778 rpmemd_log_close();
779 rpmemd_obc_fini(rpmemd->obc);
780 free(rpmemd);
781
782 return 0;
783err:
784 rpmemd_req_cleanup(rpmemd);
785err_status:
786out_rm:
787 rpmemd_db_fini(rpmemd->db);
788err_db_init:
789err_log_init_config:
790 rpmemd_config_free(&rpmemd->config);
791err_config:
792 rpmemd_log_close();
793err_log_init:
794 if (send_status) {
795 if (rpmemd_obc_status(rpmemd->obc, (uint32_t)errno))
796 RPMEMD_LOG(ERR, "writing status failed");
797 }
798 rpmemd_obc_fini(rpmemd->obc);
799err_obc:
800 free(rpmemd);
801err_rpmemd:
802 return ret;
803}