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.
18 #include <sys/types.h>
20 #include <sys/statvfs.h>
31 #include "elliptics/packet.h"
32 #include "elliptics/interface.h"
37 #define __unused __attribute__ ((unused))
40 #if defined HAVE_PROC_STAT
41 static int backend_vm_stat(struct dnet_stat
*st
)
46 unsigned long long stub
;
48 f
= fopen("/proc/loadavg", "r");
51 dnet_backend_log(DNET_LOG_ERROR
, "Failed to open '/proc/loadavg': %s [%d].\n",
52 strerror(errno
), errno
);
56 err
= fscanf(f
, "%f %f %f", &la
[0], &la
[1], &la
[2]);
62 dnet_backend_log(DNET_LOG_ERROR
, "Failed to read load average data: %s [%d].\n",
63 strerror(errno
), errno
);
67 st
->la
[0] = la
[0] * 100;
68 st
->la
[1] = la
[1] * 100;
69 st
->la
[2] = la
[2] * 100;
73 f
= fopen("/proc/meminfo", "r");
76 dnet_backend_log(DNET_LOG_ERROR
, "Failed to open '/proc/meminfo': %s [%d].\n",
77 strerror(errno
), errno
);
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
);
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
)
106 size_t sz
= sizeof(la
);
108 err
= sysctlbyname("vm.loadavg", &la
, &sz
, NULL
, 0);
111 dnet_backend_log(DNET_LOG_ERROR
, "Failed to get load average data: %s [%d].\n",
112 strerror(errno
), errno
);
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);
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
;
147 static int backend_vm_stat(struct dnet_stat
*st __unused
)
153 int backend_stat_low_level(const char *path
, struct dnet_stat
*st
)
159 err
= statvfs(path
, &s
);
162 dnet_backend_log(DNET_LOG_ERROR
, "Failed to get VFS statistics of '%s': %s [%d].\n",
163 path
, strerror(errno
), errno
);
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
;
177 st
->namemax
= s
.f_namemax
;
179 err
= backend_vm_stat(st
);
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",
189 (unsigned long long)st
->vm_total
, (unsigned long long)st
->vm_free
, (unsigned long long)st
->vm_cached
);
191 dnet_convert_stat(st
);
196 int backend_stat(void *state
, char *path
, struct dnet_cmd
*cmd
, struct dnet_attr
*attr
)
204 memset(&st
, 0, sizeof(struct dnet_stat
));
206 err
= backend_stat_low_level(path
, &st
);
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
)
218 err
= statvfs(root
, &s
);
221 dnet_backend_log(DNET_LOG_ERROR
, "Failed to get VFS statistics of '%s': %s [%d].\n",
222 root
, strerror(errno
), errno
);
226 b
->storage_size
= s
.f_frsize
* s
.f_blocks
;
227 b
->storage_free
= s
.f_bsize
* s
.f_bavail
;