2 * 2008+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
24 #include "elliptics.h"
25 #include "elliptics/interface.h"
27 static int dnet_ids_generate(struct dnet_node
*n
, const char *file
, unsigned long long storage_free
)
29 int fd
, err
, size
= 1024, i
, num
;
31 struct dnet_raw_id raw
;
32 unsigned long long q
= 100 * 1024 * 1024 * 1024ULL;
35 srand(time(NULL
) + (unsigned long)n
+ (unsigned long)file
+ (unsigned long)&buf
);
37 fd
= open(file
, O_RDWR
| O_CREAT
| O_TRUNC
| O_APPEND
| O_CLOEXEC
, 0644);
40 dnet_log_err(n
, "failed to open/create ids file '%s'", file
);
50 num
= storage_free
/ q
+ 1;
51 for (i
=0; i
<num
; ++i
) {
53 memcpy(buf
, &n
->addr
, sizeof(struct dnet_addr
));
54 memcpy(buf
+ sizeof(struct dnet_addr
), &r
, sizeof(r
));
56 dnet_transform(n
, buf
, size
, &id
);
57 memcpy(&raw
, id
.id
, sizeof(struct dnet_raw_id
));
59 err
= write(fd
, &raw
, sizeof(struct dnet_raw_id
));
60 if (err
!= sizeof(struct dnet_raw_id
)) {
61 dnet_log_err(n
, "failed to write id into ids file '%s'", file
);
77 static struct dnet_raw_id
*dnet_ids_init(struct dnet_node
*n
, const char *hdir
, int *id_num
, unsigned long long storage_free
)
80 const char *file
= "ids";
81 char path
[strlen(hdir
) + 1 + strlen(file
) + 1]; /* / + null-byte */
83 struct dnet_raw_id
*ids
;
85 snprintf(path
, sizeof(path
), "%s/%s", hdir
, file
);
88 fd
= open(path
, O_RDONLY
| O_CLOEXEC
);
92 err
= dnet_ids_generate(n
, path
, storage_free
);
99 dnet_log_err(n
, "failed to open ids file '%s'", path
);
103 err
= fstat(fd
, &st
);
107 if (st
.st_size
% sizeof(struct dnet_raw_id
)) {
108 dnet_log(n
, DNET_LOG_ERROR
, "Ids file size (%lu) is wrong, must be modulo of raw ID size (%zu).\n",
109 (unsigned long)st
.st_size
, sizeof(struct dnet_raw_id
));
113 num
= st
.st_size
/ sizeof(struct dnet_raw_id
);
115 dnet_log(n
, DNET_LOG_ERROR
, "No ids read, exiting.\n");
120 ids
= malloc(st
.st_size
);
126 err
= read(fd
, ids
, st
.st_size
);
127 if (err
!= st
.st_size
) {
129 dnet_log_err(n
, "Failed to read ids file '%s'", path
);
146 static int dnet_node_check_stack(struct dnet_node
*n
)
151 err
= pthread_attr_getstacksize(&n
->attr
, &stack_size
);
154 dnet_log_err(n
, "Failed to get stack size: %d", err
);
158 if (stack_size
<= 1024 * 1024) {
159 dnet_log(n
, DNET_LOG_ERROR
, "Stack size (%zd bytes) is too small, exiting\n", stack_size
);
164 dnet_log(n
, DNET_LOG_NOTICE
, "Stack size: %zd bytes\n", stack_size
);
170 struct dnet_node
*dnet_server_node_create(struct dnet_config
*cfg
)
173 struct dnet_raw_id
*ids
= NULL
;
177 n
= dnet_node_create(cfg
);
181 err
= dnet_node_check_stack(n
);
183 goto err_out_node_destroy
;
185 if (!n
->notify_hash_size
) {
186 n
->notify_hash_size
= DNET_DEFAULT_NOTIFY_HASH_SIZE
;
188 err
= dnet_notify_init(n
);
190 goto err_out_node_destroy
;
192 dnet_log(n
, DNET_LOG_NOTICE
, "No notify hash size provided, using default %d.\n",
193 n
->notify_hash_size
);
196 err
= dnet_cache_init(n
);
198 goto err_out_notify_exit
;
200 if (cfg
->flags
& DNET_CFG_JOIN_NETWORK
) {
203 err
= dnet_locks_init(n
, cfg
->oplock_num
);
205 goto err_out_cache_cleanup
;
207 ids
= dnet_ids_init(n
, cfg
->history_env
, &id_num
, cfg
->storage_free
);
209 goto err_out_locks_destroy
;
211 n
->addr
.addr_len
= sizeof(n
->addr
.addr
);
212 err
= dnet_socket_create(n
, cfg
, &n
->addr
, 1);
214 goto err_out_ids_cleanup
;
217 dnet_setup_id(&n
->id
, cfg
->group_id
, ids
[0].id
);
219 n
->st
= dnet_state_create(n
, cfg
->group_id
, ids
, id_num
, &n
->addr
, s
, &err
, DNET_JOIN
, dnet_state_accept_process
);
222 goto err_out_state_destroy
;
228 err
= dnet_srw_init(n
, cfg
);
230 dnet_log(n
, DNET_LOG_ERROR
, "srw: initialization failure: %s %d\n", strerror(-err
), err
);
234 dnet_log(n
, DNET_LOG_DEBUG
, "New server node has been created at %s, ids: %d.\n",
235 dnet_dump_node(n
), id_num
);
239 err_out_state_destroy
:
241 dnet_state_put(n
->st
);
244 err_out_locks_destroy
:
245 dnet_locks_destroy(n
);
246 err_out_cache_cleanup
:
247 dnet_cache_cleanup(n
);
250 err_out_node_destroy
:
251 dnet_node_destroy(n
);
256 void dnet_server_node_destroy(struct dnet_node
*n
)
258 dnet_log(n
, DNET_LOG_DEBUG
, "Destroying server node at %s, st: %p.\n",
259 dnet_dump_node(n
), n
->st
);
263 dnet_node_cleanup_common_resources(n
);
265 if (n
->cb
&& n
->cb
->backend_cleanup
)
266 n
->cb
->backend_cleanup(n
->cb
->command_private
);
268 dnet_locks_destroy(n
);