Last active
December 31, 2017 05:10
-
-
Save mgerdts/4ef21eb42d71f95e0c203466cc9564fb to your computer and use it in GitHub Desktop.
OS-XXX sdev plugin should not force number of the beast
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit efd2c605947a09c8c641ec66ec327082fa62f239 | |
Author: Mike Gerdts <[email protected]> | |
Date: Sat Dec 30 05:18:57 2017 +0000 | |
OS-XXX sdev plugin should not force number of the beast | |
diff --git a/usr/src/uts/common/fs/dev/sdev_plugin.c b/usr/src/uts/common/fs/dev/sdev_plugin.c | |
index dd81a52..58f7256 100644 | |
--- a/usr/src/uts/common/fs/dev/sdev_plugin.c | |
+++ b/usr/src/uts/common/fs/dev/sdev_plugin.c | |
@@ -272,24 +272,29 @@ sdev_plugin_mknod(sdev_ctx_t ctx, char *name, mode_t mode, dev_t dev) | |
sdev_node_t *sdvp; | |
timestruc_t now; | |
struct vattr vap; | |
+ mode_t devmode = mode & (S_IFCHR | S_IFBLK); | |
if (sdev_plugin_name_isvalid(name, SDEV_PLUGIN_NAMELEN) == 0) | |
return (EINVAL); | |
sdvp = (sdev_node_t *)ctx; | |
ASSERT(RW_WRITE_HELD(&sdvp->sdev_contents)); | |
- if (mode != S_IFCHR && mode != S_IFBLK) | |
+ if (devmode != S_IFCHR && devmode != S_IFBLK) | |
return (EINVAL); | |
+ /* Default to relatively safe permission bits if none specified. */ | |
+ if ((mode & 0666) == 0) | |
+ mode = devmode | 0600; | |
+ | |
ASSERT(sdvp->sdev_private != NULL); | |
- vap = *sdev_getdefault_attr(mode == S_IFCHR ? VCHR : VBLK); | |
+ vap = *sdev_getdefault_attr(devmode == S_IFCHR ? VCHR : VBLK); | |
gethrestime(&now); | |
vap.va_atime = now; | |
vap.va_mtime = now; | |
vap.va_ctime = now; | |
vap.va_rdev = dev; | |
- vap.va_mode = mode | 0666; | |
+ vap.va_mode = mode; | |
/* Despite the similar name, this is in fact a different function */ | |
return (sdev_plugin_mknode(sdvp->sdev_private, sdvp, name, &vap)); | |
diff --git a/usr/src/uts/common/io/vnd/vnd.c b/usr/src/uts/common/io/vnd/vnd.c | |
index 27fdba6..1bd1743 100644 | |
--- a/usr/src/uts/common/io/vnd/vnd.c | |
+++ b/usr/src/uts/common/io/vnd/vnd.c | |
@@ -5418,8 +5418,9 @@ vnd_sdev_fillzone(vnd_pnsd_t *nsp, sdev_ctx_t ctx) | |
mutex_enter(&vdp->vdd_lock); | |
if ((vdp->vdd_flags & VND_D_LINKED) && | |
!(vdp->vdd_flags & (VND_D_CONDEMNED | VND_D_ZONE_DYING))) { | |
- ret = sdev_plugin_mknod(ctx, vdp->vdd_lname, S_IFCHR, | |
- vdp->vdd_devid); | |
+ /* XXX-mg 0666 added for compatibility. Dubious. */ | |
+ ret = sdev_plugin_mknod(ctx, vdp->vdd_lname, | |
+ S_IFCHR | 0666, vdp->vdd_devid); | |
if (ret != 0 && ret != EEXIST) { | |
mutex_exit(&vdp->vdd_lock); | |
mutex_exit(&nsp->vpnd_lock); | |
@@ -5463,7 +5464,8 @@ vnd_sdev_filldir_root(sdev_ctx_t ctx) | |
* Always add a reference to the control node. There's no need to | |
* reference it since it always exists and is always what we clone from. | |
*/ | |
- ret = sdev_plugin_mknod(ctx, "ctl", S_IFCHR, | |
+ /* XXX-mg 0666 added for compatibility. Dubious. */ | |
+ ret = sdev_plugin_mknod(ctx, "ctl", S_IFCHR | 0666, | |
makedevice(ddi_driver_major(vnd_dip), 0)); | |
if (ret != 0 && ret != EEXIST) | |
return (ret); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 97c495beb6e4dc7330046e5f8198a98b638d7d4e | |
Author: Mike Gerdts <[email protected]> | |
Date: Sat Dec 30 00:11:14 2017 +0000 | |
OS-XXXX sdev_plugin needs a gitminor function | |
diff --git a/usr/src/uts/common/fs/dev/sdev_plugin.c b/usr/src/uts/common/fs/dev/sdev_plugin.c | |
index 8851911..dd81a52 100644 | |
--- a/usr/src/uts/common/fs/dev/sdev_plugin.c | |
+++ b/usr/src/uts/common/fs/dev/sdev_plugin.c | |
@@ -145,6 +145,21 @@ sdev_ctx_name(sdev_ctx_t ctx) | |
return (sdp->sdev_name); | |
} | |
+int | |
+sdev_ctx_minor(sdev_ctx_t ctx, minor_t *minorp) | |
+{ | |
+ sdev_node_t *sdp = (sdev_node_t *)ctx; | |
+ | |
+ ASSERT(RW_LOCK_HELD(&sdp->sdev_contents)); | |
+ if (sdp->sdev_vnode->v_type == VCHR || | |
+ sdp->sdev_vnode->v_type == VBLK) { | |
+ *minorp = sdp->sdev_vnode->v_rdev; | |
+ return (0); | |
+ } | |
+ | |
+ return (ENODEV); | |
+} | |
+ | |
/* | |
* Currently we only support psasing through a single flag -- SDEV_IS_GLOBAL. | |
*/ | |
@@ -159,7 +174,8 @@ sdev_ctx_flags(sdev_ctx_t ctx) | |
/* | |
* Return some amount of private data specific to the vtype. In the case of a | |
- * character or block device this is the device number. | |
+ * character or block device this is the device number. So as to not confuse | |
+ * NULL and minor 0, a better interface for minor numbers is sdev_ctx_minor(). | |
*/ | |
const void * | |
sdev_ctx_vtype_data(sdev_ctx_t ctx) | |
diff --git a/usr/src/uts/common/sys/fs/sdev_plugin.h b/usr/src/uts/common/sys/fs/sdev_plugin.h | |
index 8783df5..bfa4ce7 100644 | |
--- a/usr/src/uts/common/sys/fs/sdev_plugin.h | |
+++ b/usr/src/uts/common/sys/fs/sdev_plugin.h | |
@@ -88,6 +88,7 @@ typedef enum sdev_ctx_flags { | |
extern sdev_ctx_flags_t sdev_ctx_flags(sdev_ctx_t); | |
extern const char *sdev_ctx_name(sdev_ctx_t); | |
extern const char *sdev_ctx_path(sdev_ctx_t); | |
+extern int sdev_ctx_minor(sdev_ctx_t, minor_t *); | |
extern enum vtype sdev_ctx_vtype(sdev_ctx_t); | |
extern const void *sdev_ctx_vtype_data(sdev_ctx_t); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SDEV_PLUGINS(9F) Kernel Functions for Drivers SDEV_PLUGINS(9F) | |
NAME | |
sdev_plugins - plugin interfaces for dev(7FS) | |
SYNOPSIS | |
#include <sys/fs/sdev_plugin.h> | |
sdev_plugin_hdl_t | |
sdev_plugin_register(const char *name, sdev_plugin_ops_t *sdev_ops, | |
int *errp); | |
void | |
sdev_plugin_unregister(sdev_plugin_hdl_t sdev_hdl); | |
sdev_ctx_flags_t | |
sdev_ctx_flags(sdev_ctx_t sdev_ctx); | |
const char * | |
sdev_ctx_name(sdev_ctx_t sdev_ctx); | |
const char * | |
sdev_ctx_path(sdev_ctx_t sdev_ctx); | |
int | |
sdev_ctx_minor(sdev_ctx_t sdev_ctx, minor_t *minorp); | |
vtype_t | |
sdev_ctx_vtype(sdev_ctx_t sdev_ctx); | |
void * | |
sdev_ctx_vtype_data(sdev_ctx_t sdev_ctx); | |
int | |
sdev_plugin_mkdir(sdev_ctx_t sdev_ctx, const char *dirname); | |
int | |
sdev_plugin_mknod(sdev_ctx_t sdev_ctx, const char *devname, mode_t mode, | |
dev_t dev); | |
INTERFACE LEVEL | |
Evolving - This interface is still evolving in illumos. API and ABI | |
stability is not guaranteed. | |
PARAMETERS | |
sdev_hdl A sdev_plugin_hdl_t handle, as described in the Plugin | |
Registration section. | |
sdev_ops Pointer to sdev_plugin_ops_t structure, as described in the | |
Plugin Registration section. | |
sdev_ctx An opaque context passed to the plugin by dev(7FS) to the | |
various callbacks. See the Context Helper Functions | |
section for details. | |
DESCRIPTION | |
The sdev_plugins interfaces described in this page are used to | |
dynamically generate directories and device nodes within the /dev | |
directory. They obviate the need for devfsadm(1M) plugins for modules | |
that use these interfaces. | |
Plugin registration | |
The sdev_plugin_register() function is used to register initial path and | |
the callbacks used by dev(7FS) as /dev is traversed. The | |
sdev_plugin_ops_t type is defined as: | |
typedef struct sdev_plugin_ops { | |
int spo_version; | |
sdev_plugin_flags_t spo_flags; | |
sp_valid_f spo_validate; | |
sp_filldir_f spo_filldir; | |
sp_inactive_f spo_inactive; | |
} sdev_plugin_ops_t; | |
The value of spo_version should be set to SDEV_PLUGIN_VERSION and | |
spo_flags may include the following: | |
SDEV_PLUGIN_NO_NCACHE | |
XXX FIXME | |
SDEV_PLUGIN_SUBDIR | |
This plugin will create devices in a subdirectory of | |
/dev with a name matching that of the name argument. | |
See the Callbacks section for details on the spo_validate, spo_filldir, | |
and spo_inactive callbacks. | |
The structure referenced by the sdev_ops variable may be used by dev(7FS) | |
until sdev_plugin_unregister() is called with the same sdev_plugin_hdl_t | |
as was returned by the earlier call to the sdev_plugin_register() | |
function. | |
Callbacks | |
dev(7FS) will call the callback functions defined in the | |
sdev_plugin_ops_t as the system accesses relevant paths through the /dev | |
directory. | |
Callbacks make extensive use of Context Helper Functions. Additionally, | |
they will call into dev(7FS) to create subidrectories and device nodes | |
with the following functions. | |
int sdev_plugin_mkdir(sdev_ctx_t ctx, const char *dirname) | |
Creates a subdirectory named dirname within the directory | |
referenced by ctx. | |
int sdev_plugin_mknod(sdev_ctx_t ctx, const char *nodename, mode_t mode, | |
dev_t dev) | |
Creates a block or character device named nodename within the | |
directory referenced by ctx. The mode argument must contain | |
S_IFCHR or S_IFBLK. If no other read or write mode bits are set, | |
S_IREAD|S_IWRITE (0600) is assumed. See stat.h(3HEAD). The dev | |
argument is as returned by makedev(3C). | |
The following callbacks must be implemented by every plugin. | |
sdev_plugin_validate_t spo_validate(sdev_ctxt_t ctx) | |
The validate callback is called to verify that a particular device | |
node or directory is still valid. The callback shall return one of | |
the following values: | |
SDEV_VTOR_INVALID | |
The directory or device node is no longer valid and | |
should be removed. | |
SDEV_VTOR_SKIP | |
XXX | |
SDEV_VTOR_VALID | |
The directory or device node is valid and should not | |
be changed. | |
SDEV_VTOR_STALE | |
The directory or device node should be present, but | |
it is stale and should be regenerated. XXX This | |
triggers spo_filldir? | |
int spo_filldir(sdev_ctxt_t ctx) | |
The fill directory callback is called to generate or re-generate | |
the contents of a directory. This callback will typically make one | |
more calls to the spo_plugin_mkdir() and/or spo_plugin_mknod() | |
functions to create directories and device nodes. This callback | |
should be tolerant of being called on a directory that is already | |
partially filled. That is, spo_plugin_mkdir() and | |
spo_plugin_mknod() may return EEXIST which is likely not a fatal | |
error. | |
The callback shall return 0 on success or a valid errno value on | |
falure. | |
void spo_inactive(sdev_ctxt_t ctx) | |
The inactive callback is called when dev(7FS) is removing an entry. | |
This callback should be used by the module to reduce reference | |
counts and/or any other house keeping that is required as device | |
nodes are removed. | |
If the device(s) are different between the global zone and non-global | |
zones, callbacks should use sdev_ctx_flags() to check for the SDEV_GLOBAL | |
flag. | |
If a module creates a directory hierarchy, sdev_ctx_path() will be | |
essential to ensuring that operations are being performed in the intended | |
directory. | |
Context Helper Functions | |
Context helper functions are used within callbacks to gain access to | |
various fields within sdev_ctxt_t structures. See the Callbacks section. | |
The sdev_ctx_flags() function may retrieve the flags for a particular | |
directory or device node. The supported flags are: | |
SDEV_GLOBAL This dev(7FS) instance is in the global zone. | |
The sdev_ctx_name() function returns the last component of the path of | |
the directory or device node. | |
The sdev_ctx_path() function returns the absolute path of the directory | |
or device node. | |
The sdev_ctx_minor() function returns via the location referenced by | |
minorp the minor node of the device node referenced by the sdev_ctx | |
function argument. If sdev_ctx does not refer to a block or character | |
device, an error is returned and the location referend by minorp is not | |
changed. | |
The sdev_ctx_vtype() function returns the vnode type of the vnode | |
corresponding to element referenced by the sdev_ctx function argument. | |
The following values are expected: | |
VDIR Directory | |
VBLK Block device | |
VCHR Character device | |
The dev_ctx_vtype_data() function is obsolete. Use dev_ctx_minor() | |
instead. | |
CONTEXT | |
These functions may be called only in kernel context. | |
RETURN VALUES | |
The sdev_plugin_register() function returns a non-NULL value on success. | |
On failure it returns NULL and if errp is non-NULL, errp is set to an | |
appropriate errno value. If sdev_ops is not properly initialized, this | |
value will be EINVAL. If the plugin is already registered or there is | |
another name collision, EEXIST is returned via errp. | |
SEE ALSO | |
devfsadm(1M), makedev(3C), stat.h(3HEAD), dev(7FS) | |
illumos December 30, 2017 illumos |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment