ÿØÿà JFIF ` ` ÿþ
|
Server : Apache System : Linux cloud.heroica.com.br 4.18.0-553.36.1.el8_10.x86_64 #1 SMP Wed Jan 22 03:07:54 EST 2025 x86_64 User : farolpborg ( 1053) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /usr/src/file_protector-1.1-1576/ |
Upload File : |
/**
@file
@brief Linux kernel memory management interface wrapper
@details Copyright (c) 2025 Acronis International GmbH
@author Denis Kopyrin (denis.kopyrin@acronis.com)
@since $Id: $
*/
#include "memory.h"
#include "compat.h"
#include <linux/module.h>
#include <linux/kobject.h>
struct kmem_cache *g_handles_cache = NULL;
memory_metrics_t* g_memory_metrics = NULL;
struct metrics_attribute {
struct attribute attr;
ssize_t (*show)(memory_metrics_t* metrics, char *buf);
};
#define METRIC_X \
METRIC(total_file_contexts_tables) \
METRIC(total_transports) \
METRIC(total_transport_events) \
METRIC(total_msgs) \
METRIC(total_msgs_size) \
METRIC(total_sized_msgs) \
METRIC(total_sized_msgs_size)
#define METRICS_ATTR_RO(_name) \
static ssize_t _name##_show(memory_metrics_t* metrics, char *buf) \
{ \
return sprintf(buf, "%ld\n", (long) atomic64_read(&metrics->_name)); \
} \
static const struct metrics_attribute s_metrics_attr_##_name = __ATTR_RO(_name)
#define METRIC(_name) METRICS_ATTR_RO(_name);
METRIC_X
#undef METRIC
static const struct attribute *s_metrics_attrs[] = {
#define METRIC(_name) &s_metrics_attr_##_name.attr,
METRIC_X
#undef METRIC
NULL
};
#define to_metrics(_at) container_of(to_safe_kobject(_at), memory_metrics_t, skobj)
#define to_metrics_attr(_at) container_of(_at, struct metrics_attribute, attr)
static ssize_t metrics_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
memory_metrics_t* metrics = to_metrics(kobj);
struct metrics_attribute *metrics_attr = to_metrics_attr(attr);
return metrics_attr->show(metrics, buf);
}
const struct sysfs_ops s_metrics_sysfs_ops = {
.show = metrics_show,
};
static struct kobj_type s_metrics_ktype = {
.release = safe_kobject_sysfs_release,
.sysfs_ops = &s_metrics_sysfs_ops,
};
static int sysfs_metrics_add(memory_metrics_t *metrics)
{
return sysfs_create_files(&metrics->skobj.kobj, s_metrics_attrs);
}
int memory_init(void)
{
int err;
g_memory_metrics = mem_alloc(sizeof(memory_metrics_t));
if (!g_memory_metrics) {
return -ENOMEM;
}
g_handles_cache = kmem_cache_create("fileprotector_file_handle", MAX_HANDLE_SZ, 0, 0, NULL);
if (!g_handles_cache) {
mem_free(g_memory_metrics);
return -ENOMEM;
}
#define METRIC(_name) atomic64_set(&g_memory_metrics->_name, 0);
METRIC_X
#undef METRIC
safe_kobject_init(&g_memory_metrics->skobj);
err = kobject_init_and_add(&g_memory_metrics->skobj.kobj, &s_metrics_ktype, &THIS_MODULE->mkobj.kobj, "metrics");
if (err) {
// If 'init_and_add' fails, it really means that 'add' has failed
// 'put' without wait will suffice because 'sysfs' does not see metrics yet
kobject_put(&g_memory_metrics->skobj.kobj);
goto fail;
}
err = sysfs_metrics_add(g_memory_metrics);
if (err) {
// Now we are required to use 'safe_kobject_del' because sysfs saw 'add' above.
safe_kobject_del(&g_memory_metrics->skobj);
goto fail;
}
return 0;
fail:
mem_free(g_memory_metrics);
kmem_cache_destroy(g_handles_cache);
return err;
}
void memory_deinit(void)
{
if (g_handles_cache) {
kmem_cache_destroy(g_handles_cache);
}
#ifdef KERNEL_MOCK
#define METRIC(_name) BUG_ON(atomic64_read(&g_memory_metrics->_name));
METRIC_X
#undef METRIC
#endif
if (g_memory_metrics) {
sysfs_remove_files(&g_memory_metrics->skobj.kobj, s_metrics_attrs);
safe_kobject_del(&g_memory_metrics->skobj);
mem_free(g_memory_metrics);
}
}