Blame source/uds/sysfs.c

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     = &parameterOps,
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, &parameterObjectType);
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
}