Elliptics version update: 2.19.0.0
[elliptics.git] / example / ids.c
bloba8ae47f62cc809ce3221b2716449ebb267ae4e8d
1 /*
2 * 2008+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
3 * All rights reserved.
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.
16 #include <sys/stat.h>
17 #include <sys/statvfs.h>
19 #include <errno.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <signal.h>
26 #include "elliptics/interface.h"
28 static void ids_usage(char *p)
30 fprintf(stderr, "Usage: %s <options>\n"
31 " -i file - ids file\n"
32 " -r file - random file\n"
33 " -d dir - storage dir path\n"
34 " -t - use total size of the storage device instead of free size\n"
35 " -h - this help\n"
36 , p);
37 exit(-1);
40 static int ids_append(char *random_file, int fd, unsigned long long diff)
42 unsigned long long sz = 1024 * 1024;
43 void *buf;
44 int err, rnd;
46 rnd = open(random_file, O_RDONLY);
47 if (rnd == -1) {
48 err = -errno;
49 fprintf(stderr, "Failed to open random file '%s': %s [%d]\n",
50 random_file, strerror(errno), errno);
51 goto err_out_exit;
54 buf = malloc(sz);
55 if (!buf) {
56 err = -ENOMEM;
57 goto err_out_close;
60 while (diff != 0) {
61 if (sz > diff)
62 sz = diff;
64 err = read(rnd, buf, sz);
65 if (err <= 0) {
66 fprintf(stderr, "Failed to read from random file '%s': %s [%d]\n",
67 random_file, strerror(errno), errno);
68 goto err_out_free;
71 err = write(fd, buf, err);
72 if (err <= 0) {
73 fprintf(stderr, "Failed to write into ids file: %s [%d]\n",
74 strerror(errno), errno);
75 goto err_out_free;
78 diff -= err;
80 err = 0;
82 err_out_free:
83 free(buf);
84 err_out_close:
85 close(fd);
86 err_out_exit:
87 return err;
90 static int ids_update(char *ids_file, char *random_file, unsigned long long new_size)
92 struct stat st;
93 int fd, err;
94 unsigned long long new_num, old_num;
96 fd = open(ids_file, O_RDWR | O_CREAT | O_APPEND, 0644);
97 if (fd == -1) {
98 err = -errno;
99 fprintf(stderr, "Faield to open ids file '%s': %s [%d]\n",
100 ids_file, strerror(errno), errno);
101 goto err_out_exit;
104 err = fstat(fd, &st);
105 if (err == -1) {
106 err = -errno;
107 fprintf(stderr, "Faield to stat ids file '%s': %s [%d]\n",
108 ids_file, strerror(errno), errno);
109 goto err_out_close;
112 old_num = st.st_size / DNET_ID_SIZE;
113 new_num = new_size / (100 * 1024 * 1024 * 1024ULL) + 1;
115 if (new_num < old_num) {
116 err = ftruncate(fd, new_num * DNET_ID_SIZE);
117 if (err == -1) {
118 err = -errno;
119 fprintf(stderr, "Faield to truncate ids file '%s': %llu -> %llu (in IDs, not bytes): %s [%d]\n",
120 ids_file, old_num, new_num, strerror(errno), errno);
121 goto err_out_close;
123 } else {
124 err = ids_append(random_file, fd, (new_num - old_num) * DNET_ID_SIZE);
125 if (err)
126 goto err_out_close;
128 err = 0;
130 fprintf(stderr, "Updated '%s': %llu -> %llu (in IDs, not bytes)\n",
131 ids_file, old_num, new_num);
133 err_out_close:
134 close(fd);
135 err_out_exit:
136 return err;
139 int main(int argc, char *argv[])
141 int ch, err;
142 struct statvfs s;
143 char *random = "/dev/urandom";
144 char *ids = NULL;
145 char *dir = NULL;
146 int total = 0;
147 unsigned long long storage_size;
149 while ((ch = getopt(argc, argv, "i:r:d:th")) != -1) {
150 switch (ch) {
151 case 'i':
152 ids = optarg;
153 break;
154 case 'r':
155 random = optarg;
156 break;
157 case 'd':
158 dir = optarg;
159 break;
160 case 't':
161 total = 1;
162 break;
163 case 'h':
164 default:
165 ids_usage(argv[0]);
166 /* not reached */
170 if (!ids || !dir) {
171 fprintf(stderr, "Both ids and dir options must be specified\n");
172 ids_usage(argv[0]);
173 /* not reached */
176 err = statvfs(dir, &s);
177 if (err) {
178 err = -errno;
179 fprintf(stderr, "Failed to get VFS statistics of '%s': %s [%d].\n",
180 dir, strerror(errno), errno);
181 return err;
184 if (total)
185 storage_size = s.f_frsize * s.f_blocks;
186 else
187 storage_size = s.f_bsize * s.f_bavail;
189 return ids_update(ids, random, storage_size);