Do not double-close python init file
[elliptics.git] / example / backends.c
blob1193f711f04efa58243486d8700b34ccf52d6387
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 "config.h"
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <sys/statvfs.h>
22 #include <errno.h>
23 #include <ctype.h>
24 #include <dirent.h>
25 #include <fcntl.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
31 #include "elliptics/packet.h"
32 #include "elliptics/interface.h"
34 #include "backends.h"
36 #ifndef __unused
37 #define __unused __attribute__ ((unused))
38 #endif
40 #if defined HAVE_PROC_STAT
41 static int backend_vm_stat(struct dnet_stat *st)
43 int err;
44 FILE *f;
45 float la[3];
46 unsigned long long stub;
48 f = fopen("/proc/loadavg", "r");
49 if (!f) {
50 err = -errno;
51 dnet_backend_log(DNET_LOG_ERROR, "Failed to open '/proc/loadavg': %s [%d].\n",
52 strerror(errno), errno);
53 goto err_out_exit;
56 err = fscanf(f, "%f %f %f", &la[0], &la[1], &la[2]);
57 if (err != 3) {
58 err = -errno;
59 if (!err)
60 err = -EINVAL;
62 dnet_backend_log(DNET_LOG_ERROR, "Failed to read load average data: %s [%d].\n",
63 strerror(errno), errno);
64 goto err_out_close;
67 st->la[0] = la[0] * 100;
68 st->la[1] = la[1] * 100;
69 st->la[2] = la[2] * 100;
71 fclose(f);
73 f = fopen("/proc/meminfo", "r");
74 if (!f) {
75 err = -errno;
76 dnet_backend_log(DNET_LOG_ERROR, "Failed to open '/proc/meminfo': %s [%d].\n",
77 strerror(errno), errno);
78 goto err_out_exit;
81 err = fscanf(f, "MemTotal:%llu kB\n", (unsigned long long *)&st->vm_total);
82 err = fscanf(f, "MemFree:%llu kB\n", (unsigned long long *)&st->vm_free);
83 err = fscanf(f, "Buffers:%llu kB\n", (unsigned long long *)&st->vm_buffers);
84 err = fscanf(f, "Cached:%llu kB\n", (unsigned long long *)&st->vm_cached);
85 err = fscanf(f, "SwapCached:%llu kB\n", (unsigned long long *)&stub);
86 err = fscanf(f, "Active:%llu kB\n", (unsigned long long *)&st->vm_active);
87 err = fscanf(f, "Inactive:%llu kB\n", (unsigned long long *)&st->vm_inactive);
89 fclose(f);
90 return 0;
92 err_out_close:
93 fclose(f);
94 err_out_exit:
95 return err;
97 #elif defined HAVE_SYSCTL_STAT
98 #include <sys/sysctl.h>
99 #include <sys/resource.h>
101 static int backend_vm_stat(struct dnet_stat *st)
103 int err;
104 struct loadavg la;
105 long page_size = 0;
106 size_t sz = sizeof(la);
108 err = sysctlbyname("vm.loadavg", &la, &sz, NULL, 0);
109 if (err) {
110 err = -errno;
111 dnet_backend_log(DNET_LOG_ERROR, "Failed to get load average data: %s [%d].\n",
112 strerror(errno), errno);
113 return err;
116 st->la[0] = (double)la.ldavg[0] / la.fscale * 100;
117 st->la[1] = (double)la.ldavg[1] / la.fscale * 100;
118 st->la[2] = (double)la.ldavg[2] / la.fscale * 100;
120 sz = sizeof(uint64_t);
121 sysctlbyname("vm.stats.vm.v_active_count", &st->vm_active, &sz, NULL, 0);
122 sz = sizeof(uint64_t);
123 sysctlbyname("vm.stats.vm.v_inactive_count", &st->vm_inactive, &sz, NULL, 0);
124 sz = sizeof(uint64_t);
125 sysctlbyname("vm.stats.vm.v_cache_count", &st->vm_cached, &sz, NULL, 0);
126 sz = sizeof(uint64_t);
127 sysctlbyname("vm.stats.vm.v_free_count", &st->vm_free, &sz, NULL, 0);
128 sz = sizeof(uint64_t);
129 sysctlbyname("vm.stats.vm.v_wire_count", &st->vm_buffers, &sz, NULL, 0);
130 sz = sizeof(uint64_t);
131 sysctlbyname("vm.stats.vm.v_page_count", &st->vm_total, &sz, NULL, 0);
132 sz = sizeof(page_size);
133 sysctlbyname("vm.stats.vm.v_page_size", &page_size, &sz, NULL, 0);
135 page_size /= 1024;
137 st->vm_total *= page_size;
138 st->vm_active *= page_size;
139 st->vm_inactive *= page_size;
140 st->vm_free *= page_size;
141 st->vm_cached *= page_size;
142 st->vm_buffers *= page_size;
144 return 0;
146 #else
147 static int backend_vm_stat(struct dnet_stat *st __unused)
149 return 0;
151 #endif
153 int backend_stat_low_level(const char *path, struct dnet_stat *st)
155 struct statvfs s;
156 int err;
157 float la[3];
159 err = statvfs(path, &s);
160 if (err) {
161 err = -errno;
162 dnet_backend_log(DNET_LOG_ERROR, "Failed to get VFS statistics of '%s': %s [%d].\n",
163 path, strerror(errno), errno);
164 return err;
167 st->bsize = s.f_bsize;
168 st->frsize = s.f_frsize;
169 st->blocks = s.f_blocks;
170 st->bfree = s.f_bfree;
171 st->bavail = s.f_bavail;
172 st->files = s.f_files;
173 st->ffree = s.f_ffree;
174 st->favail = s.f_favail;
175 st->fsid = s.f_fsid;
176 st->flag = s.f_flag;
177 st->namemax = s.f_namemax;
179 err = backend_vm_stat(st);
180 if (err)
181 return err;
183 la[0] = (float)st->la[0] / 100.0;
184 la[1] = (float)st->la[1] / 100.0;
185 la[2] = (float)st->la[2] / 100.0;
187 dnet_backend_log(DNET_LOG_DSA, "Stat: la: %f %f %f, mem: total: %llu, free: %llu, cache: %llu.\n",
188 la[0], la[1], la[2],
189 (unsigned long long)st->vm_total, (unsigned long long)st->vm_free, (unsigned long long)st->vm_cached);
191 dnet_convert_stat(st);
193 return 0;
196 int backend_stat(void *state, char *path, struct dnet_cmd *cmd, struct dnet_attr *attr)
198 struct dnet_stat st;
199 int err;
201 if (!path)
202 path = ".";
204 memset(&st, 0, sizeof(struct dnet_stat));
206 err = backend_stat_low_level(path, &st);
207 if (err)
208 return err;
210 return dnet_send_reply(state, cmd, attr, &st, sizeof(struct dnet_stat), 0);
213 int backend_storage_size(struct dnet_config_backend *b, const char *root)
215 struct statvfs s;
216 int err;
218 err = statvfs(root, &s);
219 if (err) {
220 err = -errno;
221 dnet_backend_log(DNET_LOG_ERROR, "Failed to get VFS statistics of '%s': %s [%d].\n",
222 root, strerror(errno), errno);
223 return err;
226 b->storage_size = s.f_frsize * s.f_blocks;
227 b->storage_free = s.f_bsize * s.f_bavail;
229 return 0;