mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-23 02:44:41 +03:00
Add zfs module feature and property info to sysfs
This extends our sysfs '/sys/module/zfs' entry to include feature and property attributes. The primary consumer of this information is user processes, like the zfs CLI, that need to know what the current loaded ZFS module supports. The libzfs binary will consult this information when instantiating the zfs and zpool property tables and the pool features table. This introduces 4 kernel objects (dirs) into '/sys/module/zfs' with corresponding attributes (files): features.runtime features.pool properties.dataset properties.pool Reviewed-by: Matthew Ahrens <mahrens@delphix.com> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Don Brady <don.brady@delphix.com> Closes #7706
This commit is contained in:
committed by
Brian Behlendorf
parent
bb91178e60
commit
e8bcb693d6
@@ -29,11 +29,13 @@
|
||||
#ifndef _KERNEL
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <sys/debug.h>
|
||||
#include <sys/fs/zfs.h>
|
||||
#include <sys/inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/zfs_sysfs.h>
|
||||
#include "zfeature_common.h"
|
||||
|
||||
/*
|
||||
@@ -100,11 +102,30 @@ zfeature_is_supported(const char *guid)
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
int
|
||||
zfeature_lookup_guid(const char *guid, spa_feature_t *res)
|
||||
{
|
||||
for (spa_feature_t i = 0; i < SPA_FEATURES; i++) {
|
||||
zfeature_info_t *feature = &spa_feature_table[i];
|
||||
if (!feature->fi_zfs_mod_supported)
|
||||
continue;
|
||||
if (strcmp(guid, feature->fi_guid) == 0) {
|
||||
if (res != NULL)
|
||||
*res = i;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
int
|
||||
zfeature_lookup_name(const char *name, spa_feature_t *res)
|
||||
{
|
||||
for (spa_feature_t i = 0; i < SPA_FEATURES; i++) {
|
||||
zfeature_info_t *feature = &spa_feature_table[i];
|
||||
if (!feature->fi_zfs_mod_supported)
|
||||
continue;
|
||||
if (strcmp(name, feature->fi_uname) == 0) {
|
||||
if (res != NULL)
|
||||
*res = i;
|
||||
@@ -137,6 +158,34 @@ deps_contains_feature(const spa_feature_t *deps, const spa_feature_t feature)
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
zfs_mod_supported_feature(const char *name)
|
||||
{
|
||||
/*
|
||||
* The zfs module spa_feature_table[], whether in-kernel or in
|
||||
* libzpool, always supports all the features. libzfs needs to
|
||||
* query the running module, via sysfs, to determine which
|
||||
* features are supported.
|
||||
*/
|
||||
#if defined(_KERNEL) || defined(LIB_ZPOOL_BUILD)
|
||||
return (B_TRUE);
|
||||
#else
|
||||
struct stat64 statbuf;
|
||||
char *path;
|
||||
boolean_t supported = B_FALSE;
|
||||
int len;
|
||||
|
||||
len = asprintf(&path, "%s/%s/%s", ZFS_SYSFS_DIR,
|
||||
ZFS_SYSFS_POOL_FEATURES, name);
|
||||
|
||||
if (len > 0) {
|
||||
supported = !!(stat64(path, &statbuf) == 0);
|
||||
free(path);
|
||||
}
|
||||
return (supported);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
zfeature_register(spa_feature_t fid, const char *guid, const char *name,
|
||||
const char *desc, zfeature_flags_t flags, const spa_feature_t *deps)
|
||||
@@ -163,6 +212,7 @@ zfeature_register(spa_feature_t fid, const char *guid, const char *name,
|
||||
feature->fi_desc = desc;
|
||||
feature->fi_flags = flags;
|
||||
feature->fi_depends = deps;
|
||||
feature->fi_zfs_mod_supported = zfs_mod_supported_feature(guid);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -361,6 +411,7 @@ zpool_feature_init(void)
|
||||
}
|
||||
|
||||
#if defined(_KERNEL)
|
||||
EXPORT_SYMBOL(zfeature_lookup_guid);
|
||||
EXPORT_SYMBOL(zfeature_lookup_name);
|
||||
EXPORT_SYMBOL(zfeature_is_supported);
|
||||
EXPORT_SYMBOL(zfeature_is_valid_guid);
|
||||
|
||||
@@ -720,7 +720,8 @@ zfs_prop_readonly(zfs_prop_t prop)
|
||||
boolean_t
|
||||
zfs_prop_visible(zfs_prop_t prop)
|
||||
{
|
||||
return (zfs_prop_table[prop].pd_visible);
|
||||
return (zfs_prop_table[prop].pd_visible &&
|
||||
zfs_prop_table[prop].pd_zfs_mod_supported);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <sys/spa.h>
|
||||
#include <sys/zfs_acl.h>
|
||||
#include <sys/zfs_ioctl.h>
|
||||
#include <sys/zfs_sysfs.h>
|
||||
#include <sys/zfs_znode.h>
|
||||
#include <sys/fs/zfs.h>
|
||||
|
||||
@@ -48,6 +49,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
static zprop_desc_t *
|
||||
@@ -68,6 +70,34 @@ zprop_get_numprops(zfs_type_t type)
|
||||
return (ZFS_NUM_PROPS);
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
zfs_mod_supported_prop(const char *name, zfs_type_t type)
|
||||
{
|
||||
/*
|
||||
* The zfs module spa_feature_table[], whether in-kernel or in libzpool,
|
||||
* always supports all the properties. libzfs needs to query the running
|
||||
* module, via sysfs, to determine which properties are supported.
|
||||
*/
|
||||
#if defined(_KERNEL) || defined(LIB_ZPOOL_BUILD)
|
||||
return (B_TRUE);
|
||||
#else
|
||||
struct stat64 statbuf;
|
||||
char *path;
|
||||
boolean_t supported = B_FALSE;
|
||||
int len;
|
||||
|
||||
len = asprintf(&path, "%s/%s/%s", ZFS_SYSFS_DIR,
|
||||
(type == ZFS_TYPE_POOL) ? ZFS_SYSFS_POOL_PROPERTIES :
|
||||
ZFS_SYSFS_DATASET_PROPERTIES, name);
|
||||
|
||||
if (len > 0) {
|
||||
supported = !!(stat64(path, &statbuf) == 0);
|
||||
free(path);
|
||||
}
|
||||
return (supported);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
zprop_register_impl(int prop, const char *name, zprop_type_t type,
|
||||
uint64_t numdefault, const char *strdefault, zprop_attr_t attr,
|
||||
@@ -94,6 +124,7 @@ zprop_register_impl(int prop, const char *name, zprop_type_t type,
|
||||
pd->pd_colname = colname;
|
||||
pd->pd_rightalign = rightalign;
|
||||
pd->pd_visible = visible;
|
||||
pd->pd_zfs_mod_supported = zfs_mod_supported_prop(name, objset_types);
|
||||
pd->pd_table = idx_tbl;
|
||||
pd->pd_table_size = 0;
|
||||
while (idx_tbl && (idx_tbl++)->pi_name != NULL)
|
||||
@@ -193,6 +224,7 @@ zprop_iter_common(zprop_func func, void *cb, boolean_t show_all,
|
||||
prop = ZPROP_CONT;
|
||||
for (i = 0; i < num_props; i++) {
|
||||
if ((order[i]->pd_visible || show_all) &&
|
||||
order[i]->pd_zfs_mod_supported &&
|
||||
(func(order[i]->pd_propnum, cb) != ZPROP_CONT)) {
|
||||
prop = order[i]->pd_propnum;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user