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.
16 #include <sys/types.h>
18 #include <sys/statvfs.h>
29 #include "elliptics/packet.h"
30 #include "elliptics/interface.h"
35 #define __unused __attribute__ ((unused))
38 #if defined HAVE_PROC_STAT
39 static int backend_vm_stat(struct dnet_stat
*st
)
44 unsigned long long stub
;
46 f
= fopen("/proc/loadavg", "r");
49 dnet_backend_log(DNET_LOG_ERROR
, "Failed to open '/proc/loadavg': %s [%d].\n",
50 strerror(errno
), errno
);
54 err
= fscanf(f
, "%f %f %f", &la
[0], &la
[1], &la
[2]);
60 dnet_backend_log(DNET_LOG_ERROR
, "Failed to read load average data: %s [%d].\n",
61 strerror(errno
), errno
);
65 st
->la
[0] = la
[0] * 100;
66 st
->la
[1] = la
[1] * 100;
67 st
->la
[2] = la
[2] * 100;
71 f
= fopen("/proc/meminfo", "r");
74 dnet_backend_log(DNET_LOG_ERROR
, "Failed to open '/proc/meminfo': %s [%d].\n",
75 strerror(errno
), errno
);
79 err
= fscanf(f
, "MemTotal:%llu kB\n", (unsigned long long *)&st
->vm_total
);
80 err
= fscanf(f
, "MemFree:%llu kB\n", (unsigned long long *)&st
->vm_free
);
81 err
= fscanf(f
, "Buffers:%llu kB\n", (unsigned long long *)&st
->vm_buffers
);
82 err
= fscanf(f
, "Cached:%llu kB\n", (unsigned long long *)&st
->vm_cached
);
83 err
= fscanf(f
, "SwapCached:%llu kB\n", (unsigned long long *)&stub
);
84 err
= fscanf(f
, "Active:%llu kB\n", (unsigned long long *)&st
->vm_active
);
85 err
= fscanf(f
, "Inactive:%llu kB\n", (unsigned long long *)&st
->vm_inactive
);
95 #elif defined HAVE_SYSCTL_STAT
96 #include <sys/sysctl.h>
97 #include <sys/resource.h>
99 static int backend_vm_stat(struct dnet_stat
*st
)
104 size_t sz
= sizeof(la
);
106 err
= sysctlbyname("vm.loadavg", &la
, &sz
, NULL
, 0);
109 dnet_backend_log(DNET_LOG_ERROR
, "Failed to get load average data: %s [%d].\n",
110 strerror(errno
), errno
);
114 st
->la
[0] = (double)la
.ldavg
[0] / la
.fscale
* 100;
115 st
->la
[1] = (double)la
.ldavg
[1] / la
.fscale
* 100;
116 st
->la
[2] = (double)la
.ldavg
[2] / la
.fscale
* 100;
118 sz
= sizeof(uint64_t);
119 sysctlbyname("vm.stats.vm.v_active_count", &st
->vm_active
, &sz
, NULL
, 0);
120 sz
= sizeof(uint64_t);
121 sysctlbyname("vm.stats.vm.v_inactive_count", &st
->vm_inactive
, &sz
, NULL
, 0);
122 sz
= sizeof(uint64_t);
123 sysctlbyname("vm.stats.vm.v_cache_count", &st
->vm_cached
, &sz
, NULL
, 0);
124 sz
= sizeof(uint64_t);
125 sysctlbyname("vm.stats.vm.v_free_count", &st
->vm_free
, &sz
, NULL
, 0);
126 sz
= sizeof(uint64_t);
127 sysctlbyname("vm.stats.vm.v_wire_count", &st
->vm_buffers
, &sz
, NULL
, 0);
128 sz
= sizeof(uint64_t);
129 sysctlbyname("vm.stats.vm.v_page_count", &st
->vm_total
, &sz
, NULL
, 0);
130 sz
= sizeof(page_size
);
131 sysctlbyname("vm.stats.vm.v_page_size", &page_size
, &sz
, NULL
, 0);
135 st
->vm_total
*= page_size
;
136 st
->vm_active
*= page_size
;
137 st
->vm_inactive
*= page_size
;
138 st
->vm_free
*= page_size
;
139 st
->vm_cached
*= page_size
;
140 st
->vm_buffers
*= page_size
;
145 static int backend_vm_stat(struct dnet_stat
*st __unused
)
151 int backend_stat_low_level(const char *path
, struct dnet_stat
*st
)
157 err
= statvfs(path
, &s
);
160 dnet_backend_log(DNET_LOG_ERROR
, "Failed to get VFS statistics of '%s': %s [%d].\n",
161 path
, strerror(errno
), errno
);
165 st
->bsize
= s
.f_bsize
;
166 st
->frsize
= s
.f_frsize
;
167 st
->blocks
= s
.f_blocks
;
168 st
->bfree
= s
.f_bfree
;
169 st
->bavail
= s
.f_bavail
;
170 st
->files
= s
.f_files
;
171 st
->ffree
= s
.f_ffree
;
172 st
->favail
= s
.f_favail
;
175 st
->namemax
= s
.f_namemax
;
177 err
= backend_vm_stat(st
);
181 la
[0] = (float)st
->la
[0] / 100.0;
182 la
[1] = (float)st
->la
[1] / 100.0;
183 la
[2] = (float)st
->la
[2] / 100.0;
185 dnet_backend_log(DNET_LOG_DEBUG
, "Stat: la: %f %f %f, mem: total: %llu, free: %llu, cache: %llu.\n",
187 (unsigned long long)st
->vm_total
, (unsigned long long)st
->vm_free
, (unsigned long long)st
->vm_cached
);
189 dnet_convert_stat(st
);
194 int backend_stat(void *state
, char *path
, struct dnet_cmd
*cmd
)
202 memset(&st
, 0, sizeof(struct dnet_stat
));
204 err
= backend_stat_low_level(path
, &st
);
208 return dnet_send_reply(state
, cmd
, &st
, sizeof(struct dnet_stat
), 0);
211 int backend_storage_size(struct dnet_config_backend
*b
, const char *root
)
216 err
= statvfs(root
, &s
);
219 dnet_backend_log(DNET_LOG_ERROR
, "Failed to get VFS statistics of '%s': %s [%d].\n",
220 root
, strerror(errno
), errno
);
224 b
->storage_size
= s
.f_frsize
* s
.f_blocks
;
225 b
->storage_free
= s
.f_bsize
* s
.f_bavail
;