Blame source/vdo/kernel/sysfs.c

Packit Service 75d76b
/*
Packit Service 75d76b
 * Copyright (c) 2020 Red Hat, Inc.
Packit Service 75d76b
 *
Packit Service 75d76b
 * This program is free software; you can redistribute it and/or
Packit Service 75d76b
 * modify it under the terms of the GNU General Public License
Packit Service 75d76b
 * as published by the Free Software Foundation; either version 2
Packit Service 75d76b
 * of the License, or (at your option) any later version.
Packit Service 75d76b
 * 
Packit Service 75d76b
 * This program is distributed in the hope that it will be useful,
Packit Service 75d76b
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 75d76b
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 75d76b
 * GNU General Public License for more details.
Packit Service 75d76b
 * 
Packit Service 75d76b
 * You should have received a copy of the GNU General Public License
Packit Service 75d76b
 * along with this program; if not, write to the Free Software
Packit Service 75d76b
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 75d76b
 * 02110-1301, USA. 
Packit Service 75d76b
 *
Packit Service 75d76b
 * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/sysfs.c#5 $
Packit Service 75d76b
 */
Packit Service 75d76b
Packit Service 75d76b
#include "sysfs.h"
Packit Service 75d76b
Packit Service 75d76b
#include <linux/module.h>
Packit Service 75d76b
#include <linux/version.h>
Packit Service 75d76b
Packit Service 75d76b
#include "dedupeIndex.h"
Packit Service 75d76b
#include "dmvdo.h"
Packit Service 75d76b
#include "logger.h"
Packit Service 75d76b
Packit Service 75d76b
extern int defaultMaxRequestsActive;
Packit Service 75d76b
Packit Service 75d76b
typedef struct vdoAttribute {
Packit Service 75d76b
  struct attribute  attr;
Packit Service 75d76b
  ssize_t (*show)(struct kvdoDevice *d, struct attribute *attr, char *buf);
Packit Service 75d76b
  ssize_t (*store)(struct kvdoDevice *d, const char *value, size_t count);
Packit Service 75d76b
  // Location of value, if .show == showInt or showUInt or showBool.
Packit Service 75d76b
  void     *valuePtr;
Packit Service 75d76b
} VDOAttribute;
Packit Service 75d76b
Packit Service 75d76b
static char *statusStrings[] = {
Packit Service 75d76b
  "UNINITIALIZED",
Packit Service 75d76b
  "READY",
Packit Service 75d76b
  "SHUTTING DOWN",
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t vdoStatusShow(struct kvdoDevice *device,
Packit Service 75d76b
                             struct attribute  *attr,
Packit Service 75d76b
                             char              *buf)
Packit Service 75d76b
{
Packit Service 75d76b
  return sprintf(buf, "%s\n", statusStrings[device->status]);
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t vdoLogLevelShow(struct kvdoDevice *device,
Packit Service 75d76b
                               struct attribute  *attr,
Packit Service 75d76b
                               char              *buf)
Packit Service 75d76b
{
Packit Service 75d76b
  return sprintf(buf, "%s\n", priorityToString(getLogLevel()));
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t vdoLogLevelStore(struct kvdoDevice *device,
Packit Service 75d76b
                                const char *buf, size_t n)
Packit Service 75d76b
{
Packit Service 75d76b
  static char internalBuf[11];
Packit Service 75d76b
Packit Service 75d76b
  if (n > 10) {
Packit Service 75d76b
    return -EINVAL;
Packit Service 75d76b
  }
Packit Service 75d76b
Packit Service 75d76b
  memset(internalBuf, '\000', sizeof(internalBuf));
Packit Service 75d76b
  memcpy(internalBuf, buf, n);
Packit Service 75d76b
  if (internalBuf[n - 1] == '\n') {
Packit Service 75d76b
    internalBuf[n - 1] = '\000';
Packit Service 75d76b
  }
Packit Service 75d76b
  setLogLevel(stringToPriority(internalBuf));
Packit Service 75d76b
  return n;
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t scanInt(const char *buf,
Packit Service 75d76b
                       size_t      n,
Packit Service 75d76b
                       int        *valuePtr,
Packit Service 75d76b
                       int         minimum,
Packit Service 75d76b
                       int         maximum)
Packit Service 75d76b
{
Packit Service 75d76b
  if (n > 12) {
Packit Service 75d76b
    return -EINVAL;
Packit Service 75d76b
  }
Packit Service 75d76b
  unsigned int value;
Packit Service 75d76b
  if (sscanf(buf, "%d", &value) != 1) {
Packit Service 75d76b
    return -EINVAL;
Packit Service 75d76b
  }
Packit Service 75d76b
  if (value < minimum) {
Packit Service 75d76b
    value = minimum;
Packit Service 75d76b
  } else if (value > maximum) {
Packit Service 75d76b
    value = maximum;
Packit Service 75d76b
  }
Packit Service 75d76b
  *valuePtr = value;
Packit Service 75d76b
  return n;
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t showInt(struct kvdoDevice *device,
Packit Service 75d76b
                       struct attribute  *attr,
Packit Service 75d76b
                       char              *buf)
Packit Service 75d76b
{
Packit Service 75d76b
  VDOAttribute *vdoAttr = container_of(attr, VDOAttribute, attr);
Packit Service 75d76b
Packit Service 75d76b
  return sprintf(buf, "%d\n", *(int *)vdoAttr->valuePtr);
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t scanUInt(const char   *buf,
Packit Service 75d76b
                        size_t        n,
Packit Service 75d76b
                        unsigned int *valuePtr,
Packit Service 75d76b
                        unsigned int  minimum,
Packit Service 75d76b
                        unsigned int  maximum)
Packit Service 75d76b
{
Packit Service 75d76b
  if (n > 12) {
Packit Service 75d76b
    return -EINVAL;
Packit Service 75d76b
  }
Packit Service 75d76b
  unsigned int value;
Packit Service 75d76b
  if (sscanf(buf, "%u", &value) != 1) {
Packit Service 75d76b
    return -EINVAL;
Packit Service 75d76b
  }
Packit Service 75d76b
  if (value < minimum) {
Packit Service 75d76b
    value = minimum;
Packit Service 75d76b
  } else if (value > maximum) {
Packit Service 75d76b
    value = maximum;
Packit Service 75d76b
  }
Packit Service 75d76b
  *valuePtr = value;
Packit Service 75d76b
  return n;
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t showUInt(struct kvdoDevice *device,
Packit Service 75d76b
                        struct attribute  *attr,
Packit Service 75d76b
                        char              *buf)
Packit Service 75d76b
{
Packit Service 75d76b
  VDOAttribute *vdoAttr = container_of(attr, VDOAttribute, attr);
Packit Service 75d76b
Packit Service 75d76b
  return sprintf(buf, "%u\n", *(unsigned int *)vdoAttr->valuePtr);
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t scanBool(const char *buf, size_t n, bool *valuePtr)
Packit Service 75d76b
{
Packit Service 75d76b
  unsigned int intValue = 0;
Packit Service 75d76b
  n = scanUInt(buf, n, &intValue, 0, 1);
Packit Service 75d76b
  if (n > 0) {
Packit Service 75d76b
    *valuePtr = (intValue != 0);
Packit Service 75d76b
  }
Packit Service 75d76b
  return n;
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t showBool(struct kvdoDevice *device,
Packit Service 75d76b
                        struct attribute  *attr,
Packit Service 75d76b
                        char              *buf)
Packit Service 75d76b
{
Packit Service 75d76b
  VDOAttribute *vdoAttr = container_of(attr, VDOAttribute, attr);
Packit Service 75d76b
Packit Service 75d76b
  return sprintf(buf, "%u\n", *(bool *)vdoAttr->valuePtr ? 1 : 0);
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t vdoTraceRecordingStore(struct kvdoDevice *device,
Packit Service 75d76b
                                      const char        *buf,
Packit Service 75d76b
                                      size_t             n)
Packit Service 75d76b
{
Packit Service 75d76b
  return scanBool(buf, n, &traceRecording);
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t vdoMaxReqActiveStore(struct kvdoDevice *device,
Packit Service 75d76b
                                    const char        *buf,
Packit Service 75d76b
                                    size_t             n)
Packit Service 75d76b
{
Packit Service 75d76b
  /*
Packit Service 75d76b
   * The base code has some hardcoded assumptions about the maximum
Packit Service 75d76b
   * number of requests that can be in progress. Maybe someday we'll
Packit Service 75d76b
   * do calculations with the actual number; for now, just make sure
Packit Service 75d76b
   * the assumption holds.
Packit Service 75d76b
   */
Packit Service 75d76b
  return scanInt(buf, n, &defaultMaxRequestsActive, 1, MAXIMUM_USER_VIOS);
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t vdoAlbireoTimeoutIntervalStore(struct kvdoDevice *device,
Packit Service 75d76b
                                              const char        *buf,
Packit Service 75d76b
                                              size_t             n)
Packit Service 75d76b
{
Packit Service 75d76b
  unsigned int value;
Packit Service 75d76b
  ssize_t result = scanUInt(buf, n, &value, 0, UINT_MAX);
Packit Service 75d76b
  if (result > 0) {
Packit Service 75d76b
    setAlbireoTimeoutInterval(value);
Packit Service 75d76b
  }
Packit Service 75d76b
  return result;
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t vdoMinAlbireoTimerIntervalStore(struct kvdoDevice *device,
Packit Service 75d76b
                                               const char        *buf,
Packit Service 75d76b
                                               size_t             n)
Packit Service 75d76b
{
Packit Service 75d76b
  unsigned int value;
Packit Service 75d76b
  ssize_t result = scanUInt(buf, n, &value, 0, UINT_MAX);
Packit Service 75d76b
  if (result > 0) {
Packit Service 75d76b
    setMinAlbireoTimerInterval(value);
Packit Service 75d76b
  }
Packit Service 75d76b
  return result;
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t vdoVersionShow(struct kvdoDevice *device,
Packit Service 75d76b
                              struct attribute  *attr,
Packit Service 75d76b
                              char              *buf)
Packit Service 75d76b
{
Packit Service 75d76b
  return sprintf(buf, "%s\n", CURRENT_VERSION);
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t vdoAttrShow(struct kobject   *kobj,
Packit Service 75d76b
                           struct attribute *attr,
Packit Service 75d76b
                           char             *buf)
Packit Service 75d76b
{
Packit Service 75d76b
  VDOAttribute *vdoAttr = container_of(attr, VDOAttribute, attr);
Packit Service 75d76b
  if (vdoAttr->show == NULL) {
Packit Service 75d76b
    return -EINVAL;
Packit Service 75d76b
  }
Packit Service 75d76b
Packit Service 75d76b
  struct kvdoDevice *device = container_of(kobj, struct kvdoDevice, kobj);
Packit Service 75d76b
  return (*vdoAttr->show)(device, attr, buf);
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static ssize_t vdoAttrStore(struct kobject   *kobj,
Packit Service 75d76b
                            struct attribute *attr,
Packit Service 75d76b
                            const char       *buf,
Packit Service 75d76b
                            size_t            length)
Packit Service 75d76b
{
Packit Service 75d76b
  VDOAttribute *vdoAttr = container_of(attr, VDOAttribute, attr);
Packit Service 75d76b
  if (vdoAttr->store == NULL) {
Packit Service 75d76b
    return -EINVAL;
Packit Service 75d76b
  }
Packit Service 75d76b
Packit Service 75d76b
  struct kvdoDevice *device = container_of(kobj, struct kvdoDevice, kobj);
Packit Service 75d76b
  return (*vdoAttr->store)(device, buf, length);
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
static VDOAttribute vdoStatusAttr = {
Packit Service 75d76b
  .attr  = { .name = "status", .mode = 0444, },
Packit Service 75d76b
  .show  = vdoStatusShow,
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
static VDOAttribute vdoLogLevelAttr = {
Packit Service 75d76b
  .attr  = {.name = "log_level", .mode = 0644, },
Packit Service 75d76b
  .show  = vdoLogLevelShow,
Packit Service 75d76b
  .store = vdoLogLevelStore,
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
static VDOAttribute vdoMaxReqActiveAttr = {
Packit Service 75d76b
  .attr     = {.name = "max_requests_active", .mode = 0644, },
Packit Service 75d76b
  .show     = showInt,
Packit Service 75d76b
  .store    = vdoMaxReqActiveStore,
Packit Service 75d76b
  .valuePtr = &defaultMaxRequestsActive,
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
static VDOAttribute vdoAlbireoTimeoutInterval = {
Packit Service 75d76b
  .attr     = {.name = "deduplication_timeout_interval", .mode = 0644, },
Packit Service 75d76b
  .show     = showUInt,
Packit Service 75d76b
  .store    = vdoAlbireoTimeoutIntervalStore,
Packit Service 75d76b
  .valuePtr = &albireoTimeoutInterval,
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
static VDOAttribute vdoMinAlbireoTimerInterval = {
Packit Service 75d76b
  .attr     = {.name = "min_deduplication_timer_interval", .mode = 0644, },
Packit Service 75d76b
  .show     = showUInt,
Packit Service 75d76b
  .store    = vdoMinAlbireoTimerIntervalStore,
Packit Service 75d76b
  .valuePtr = &minAlbireoTimerInterval,
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
static VDOAttribute vdoTraceRecording = {
Packit Service 75d76b
  .attr     = {.name = "trace_recording", .mode = 0644, },
Packit Service 75d76b
  .show     = showBool,
Packit Service 75d76b
  .store    = vdoTraceRecordingStore,
Packit Service 75d76b
  .valuePtr = &traceRecording,
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
static VDOAttribute vdoVersionAttr = {
Packit Service 75d76b
  .attr  = { .name = "version", .mode = 0444, },
Packit Service 75d76b
  .show  = vdoVersionShow,
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
static struct attribute *defaultAttrs[] = {
Packit Service 75d76b
  &vdoStatusAttr.attr,
Packit Service 75d76b
  &vdoLogLevelAttr.attr,
Packit Service 75d76b
  &vdoMaxReqActiveAttr.attr,
Packit Service 75d76b
  &vdoAlbireoTimeoutInterval.attr,
Packit Service 75d76b
  &vdoMinAlbireoTimerInterval.attr,
Packit Service 75d76b
  &vdoTraceRecording.attr,
Packit Service 75d76b
  &vdoVersionAttr.attr,
Packit Service 75d76b
  NULL
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
static struct sysfs_ops vdoSysfsOps = {
Packit Service 75d76b
  .show  = vdoAttrShow,
Packit Service 75d76b
  .store = vdoAttrStore,
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
static void vdoRelease(struct kobject *kobj)
Packit Service 75d76b
{
Packit Service 75d76b
  return;
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
struct kobj_type vdo_ktype = {
Packit Service 75d76b
  .release   = vdoRelease,
Packit Service 75d76b
  .sysfs_ops = &vdoSysfsOps,
Packit Service 75d76b
  .default_attrs = defaultAttrs,
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
int vdoInitSysfs(struct kobject *deviceObject)
Packit Service 75d76b
{
Packit Service 75d76b
  kobject_init(deviceObject, &vdo_ktype);
Packit Service 75d76b
  int result = kobject_add(deviceObject, NULL, THIS_MODULE->name);
Packit Service 75d76b
  if (result < 0) {
Packit Service 75d76b
    logError("kobject_add failed with status %d", -result);
Packit Service 75d76b
    kobject_put(deviceObject);
Packit Service 75d76b
  }
Packit Service 75d76b
  logDebug("added sysfs objects");
Packit Service 75d76b
  return result;
Packit Service 75d76b
};
Packit Service 75d76b
Packit Service 75d76b
/**********************************************************************/
Packit Service 75d76b
void vdoPutSysfs(struct kobject *deviceObject)
Packit Service 75d76b
{
Packit Service 75d76b
  kobject_put(deviceObject);
Packit Service 75d76b
}