|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
310c69 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
310c69 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
310c69 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
310c69 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
310c69 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
310c69 |
* GNU General Public License for more details.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
310c69 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
310c69 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
310c69 |
* 02110-1301, USA.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* $Id: //eng/uds-releases/jasper/kernelLinux/uds/sysfs.c#4 $
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "sysfs.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include <linux/kobject.h>
|
|
Packit Service |
310c69 |
#include <linux/module.h>
|
|
Packit Service |
310c69 |
#include <linux/slab.h>
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "logger.h"
|
|
Packit Service |
310c69 |
#include "memoryAlloc.h"
|
|
Packit Service |
310c69 |
#include "stringUtils.h"
|
|
Packit Service |
310c69 |
#include "uds.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
static struct {
|
|
Packit Service |
310c69 |
struct kobject kobj; // /sys/uds
|
|
Packit Service |
310c69 |
struct kobject parameterKobj; // /sys/uds/parameter
|
|
Packit Service |
310c69 |
// These flags are used to ensure a clean shutdown
|
|
Packit Service |
310c69 |
bool flag; // /sys/uds
|
|
Packit Service |
310c69 |
bool parameterFlag; // /sys/uds/parameter
|
|
Packit Service |
310c69 |
} objectRoot;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static char *bufferToString(const char *buf, size_t length)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
char *string;
|
|
Packit Service |
310c69 |
if (ALLOCATE(length + 1, char, __func__, &string) != UDS_SUCCESS) {
|
|
Packit Service |
310c69 |
return NULL;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
memcpy(string, buf, length);
|
|
Packit Service |
310c69 |
string[length] = '\0';
|
|
Packit Service |
310c69 |
if (string[length - 1] == '\n') {
|
|
Packit Service |
310c69 |
string[length - 1] = '\0';
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return string;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
// This is the code for a directory in the /sys/<module_name> tree that
|
|
Packit Service |
310c69 |
// contains no regular files (only subdirectories).
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static void emptyRelease(struct kobject *kobj)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
// Many of our sysfs share this release function that does nothing.
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static ssize_t emptyShow(struct kobject *kobj,
|
|
Packit Service |
310c69 |
struct attribute *attr,
|
|
Packit Service |
310c69 |
char *buf)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return 0;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static ssize_t emptyStore(struct kobject *kobj,
|
|
Packit Service |
310c69 |
struct attribute *attr,
|
|
Packit Service |
310c69 |
const char *buf,
|
|
Packit Service |
310c69 |
size_t length)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return length;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
static struct sysfs_ops emptyOps = {
|
|
Packit Service |
310c69 |
.show = emptyShow,
|
|
Packit Service |
310c69 |
.store = emptyStore,
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
static struct attribute *emptyAttrs[] = {
|
|
Packit Service |
310c69 |
NULL,
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
static struct kobj_type emptyObjectType = {
|
|
Packit Service |
310c69 |
.release = emptyRelease,
|
|
Packit Service |
310c69 |
.sysfs_ops = &emptyOps,
|
|
Packit Service |
310c69 |
.default_attrs = emptyAttrs,
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
// This is the the code for the /sys/<module_name>/parameter directory.
|
|
Packit Service |
310c69 |
//
|
|
Packit Service |
310c69 |
// <dir>/log_level UDS_LOG_LEVEL
|
|
Packit Service |
310c69 |
//
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
typedef struct {
|
|
Packit Service |
310c69 |
struct attribute attr;
|
|
Packit Service |
310c69 |
const char *(*showString)(void);
|
|
Packit Service |
310c69 |
void (*storeString)(const char *);
|
|
Packit Service |
310c69 |
} ParameterAttribute;
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static ssize_t parameterShow(struct kobject *kobj,
|
|
Packit Service |
310c69 |
struct attribute *attr,
|
|
Packit Service |
310c69 |
char *buf)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
ParameterAttribute *pa = container_of(attr, ParameterAttribute, attr);
|
|
Packit Service |
310c69 |
if (pa->showString != NULL) {
|
|
Packit Service |
310c69 |
return sprintf(buf, "%s\n", pa->showString());
|
|
Packit Service |
310c69 |
} else {
|
|
Packit Service |
310c69 |
return -EINVAL;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static ssize_t parameterStore(struct kobject *kobj,
|
|
Packit Service |
310c69 |
struct attribute *attr,
|
|
Packit Service |
310c69 |
const char *buf,
|
|
Packit Service |
310c69 |
size_t length)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
ParameterAttribute *pa = container_of(attr, ParameterAttribute, attr);
|
|
Packit Service |
310c69 |
char *string = bufferToString(buf, length);
|
|
Packit Service |
310c69 |
if (string == NULL) {
|
|
Packit Service |
310c69 |
return -ENOMEM;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
int result = UDS_SUCCESS;
|
|
Packit Service |
310c69 |
if (pa->storeString != NULL) {
|
|
Packit Service |
310c69 |
pa->storeString(string);
|
|
Packit Service |
310c69 |
} else {
|
|
Packit Service |
310c69 |
return -EINVAL;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
FREE(string);
|
|
Packit Service |
310c69 |
return result == UDS_SUCCESS ? length : result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
static const char *parameterShowLogLevel(void)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return priorityToString(getLogLevel());
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
static void parameterStoreLogLevel(const char *string)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setLogLevel(stringToPriority(string));
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
static ParameterAttribute logLevelAttr = {
|
|
Packit Service |
310c69 |
.attr = { .name = "log_level", .mode = 0600 },
|
|
Packit Service |
310c69 |
.showString = parameterShowLogLevel,
|
|
Packit Service |
310c69 |
.storeString = parameterStoreLogLevel,
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
static struct attribute *parameterAttrs[] = {
|
|
Packit Service |
310c69 |
&logLevelAttr.attr,
|
|
Packit Service |
310c69 |
NULL,
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
static struct sysfs_ops parameterOps = {
|
|
Packit Service |
310c69 |
.show = parameterShow,
|
|
Packit Service |
310c69 |
.store = parameterStore,
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
static struct kobj_type parameterObjectType = {
|
|
Packit Service |
310c69 |
.release = emptyRelease,
|
|
Packit Service |
310c69 |
.sysfs_ops = ¶meterOps,
|
|
Packit Service |
310c69 |
.default_attrs = parameterAttrs,
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
int initSysfs(void)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
memset(&objectRoot, 0, sizeof(objectRoot));
|
|
Packit Service |
310c69 |
kobject_init(&objectRoot.kobj, &emptyObjectType);
|
|
Packit Service |
310c69 |
int result = kobject_add(&objectRoot.kobj, NULL, THIS_MODULE->name);
|
|
Packit Service |
310c69 |
if (result == 0) {
|
|
Packit Service |
310c69 |
objectRoot.flag = true;
|
|
Packit Service |
310c69 |
kobject_init(&objectRoot.parameterKobj, ¶meterObjectType);
|
|
Packit Service |
310c69 |
result = kobject_add(&objectRoot.parameterKobj, &objectRoot.kobj,
|
|
Packit Service |
310c69 |
"parameter");
|
|
Packit Service |
310c69 |
if (result == 0) {
|
|
Packit Service |
310c69 |
objectRoot.parameterFlag = true;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (result != 0) {
|
|
Packit Service |
310c69 |
putSysfs();
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return result;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
void putSysfs()
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (objectRoot.parameterFlag) {
|
|
Packit Service |
310c69 |
kobject_put(&objectRoot.parameterKobj);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (objectRoot.flag) {
|
|
Packit Service |
310c69 |
kobject_put(&objectRoot.kobj);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|