static int dnet_ids_generate(struct dnet_node *n, const char *file, unsigned long long storage_free) { int fd, err, size = 1024, i, num; struct dnet_raw_id id; struct dnet_raw_id raw; unsigned long long q = 100 * 1024 * 1024 * 1024ULL; char *buf; srand(time(NULL) + (unsigned long)n + (unsigned long)file + (unsigned long)&buf); fd = open(file, O_RDWR | O_CREAT | O_TRUNC | O_APPEND | O_CLOEXEC, 0644); if (fd < 0) { err = -errno; dnet_log_err(n, "failed to open/create ids file '%s'", file); goto err_out_exit; } buf = malloc(size); if (!buf) { err = -ENOMEM; goto err_out_close; } memset(buf, 0, size); num = storage_free / q + 1; for (i=0; i<num; ++i) { int r = rand(); memcpy(buf, &r, sizeof(r)); dnet_transform_node(n, buf, size, id.id, sizeof(id.id)); memcpy(&raw, id.id, sizeof(struct dnet_raw_id)); err = write(fd, &raw, sizeof(struct dnet_raw_id)); if (err != sizeof(struct dnet_raw_id)) { dnet_log_err(n, "failed to write id into ids file '%s'", file); goto err_out_unlink; } } free(buf); close(fd); return 0; err_out_unlink: unlink(file); free(buf); err_out_close: close(fd); err_out_exit: return err; }
static int dnet_node_check_stack(struct dnet_node *n) { size_t stack_size; size_t min_stack_size = 1024 * 1024; int err; err = pthread_attr_getstacksize(&n->attr, &stack_size); if (err) { err = -err; dnet_log_err(n, "Failed to get stack size: %d", err); goto err_out_exit; } if (stack_size < min_stack_size) { dnet_log(n, DNET_LOG_ERROR, "Stack size (%zd bytes) is too small, should be at least %zd, exiting", stack_size, min_stack_size); err = -ENOMEM; goto err_out_exit; } dnet_log(n, DNET_LOG_NOTICE, "Stack size: %zd bytes", stack_size); err_out_exit: return err; }
static struct dnet_raw_id *dnet_ids_init(struct dnet_node *n, const char *hdir, int *id_num, unsigned long long storage_free) { int fd, err, num; const char *file = "ids"; char path[strlen(hdir) + 1 + strlen(file) + 1]; /* / + null-byte */ struct stat st; struct dnet_raw_id *ids; snprintf(path, sizeof(path), "%s/%s", hdir, file); again: fd = open(path, O_RDONLY | O_CLOEXEC); if (fd < 0) { err = -errno; if (err == -ENOENT) { err = dnet_ids_generate(n, path, storage_free); if (err) goto err_out_exit; goto again; } dnet_log_err(n, "failed to open ids file '%s'", path); goto err_out_exit; } err = fstat(fd, &st); if (err) goto err_out_close; if (st.st_size % sizeof(struct dnet_raw_id)) { dnet_log(n, DNET_LOG_ERROR, "Ids file size (%lu) is wrong, must be modulo of raw ID size (%zu).\n", (unsigned long)st.st_size, sizeof(struct dnet_raw_id)); goto err_out_close; } num = st.st_size / sizeof(struct dnet_raw_id); if (!num) { dnet_log(n, DNET_LOG_ERROR, "No ids read, exiting.\n"); err = -EINVAL; goto err_out_close; } ids = malloc(st.st_size); if (!ids) { err = -ENOMEM; goto err_out_close; } err = read(fd, ids, st.st_size); if (err != st.st_size) { err = -errno; dnet_log_err(n, "Failed to read ids file '%s'", path); goto err_out_free; } close(fd); *id_num = num; return ids; err_out_free: free(ids); err_out_close: close(fd); err_out_exit: return NULL; }