/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
*
* The lookup is based on the internal vanity naming node table. We also
* override readdir in order to delete net nodes no longer in-use.
*/
#include <sys/sysmacros.h>
/*
* Check if a net sdev_node is still valid - i.e. it represents a current
* network link.
* This serves two purposes
* - only valid net nodes are returned during lookup() and readdir().
* - since net sdev_nodes are not actively destroyed when a network link
* goes away, we use the validator to do deferred cleanup i.e. when such
* nodes are encountered during subsequent lookup() and readdir().
*/
int
{
return (SDEV_VTOR_INVALID);
if (SDEV_IS_GLOBAL(dv))
return (SDEV_VTOR_VALID);
}
/*
* This callback is invoked from devname_lookup_func() to create
* a net entry when the node is not found in the cache.
*/
static int
{
int error;
sdcmn_err12(("devnet_create_rvp: not a valid vanity name "
"network node: %s\n", nm));
return (error);
}
/*
* This is a valid network device (at least at this point in time).
* Create the node by setting the attribute; the rest is taken care
* of by devname_lookup_func().
*/
*vap = sdev_vattr_chr;
gethrestime(&now);
return (0);
}
/*
* If the entry does not exist, the devnet_create_rvp() callback
* is invoked to create it. Nodes do not persist across reboot.
*/
/*ARGSUSED3*/
static int
{
int nmlen;
return (ENOTDIR);
/*
* Empty name or ., return node itself.
*/
return (0);
}
/*
* .., return the parent directory
*/
return (0);
}
/*
* directory cache lookup:
*/
goto found;
}
/*
* ZOMBIED parent does not allow new node creation, bail out early.
*/
goto failed;
if (error != 0)
goto failed;
if (error != 0) {
goto failed;
}
/*
* SDEV_ATTR_INVALID means that this device has been
* detached, and its dev_t might've been changed too.
* Therefore, sdev_node's 'vattr' needs to be updated.
*/
}
return (error);
}
static int
{
return (0);
goto found;
return (0);
SDEV_READY) != 0) {
return (0);
}
/*
* As there is no reference holding the network device, it could be
* detached. Set SDEV_ATTR_INVALID so that the 'vattr' will be updated
* later.
*/
return (0);
}
static void
{
}
/* validate and prune only ready nodes */
continue;
switch (devnet_validate(dv)) {
case SDEV_VTOR_VALID:
case SDEV_VTOR_SKIP:
continue;
case SDEV_VTOR_INVALID:
case SDEV_VTOR_STALE:
sdcmn_err12(("devnet_filldir: destroy invalid "
break;
}
continue;
/* remove the cache node */
}
goto done;
if (SDEV_IS_GLOBAL(ddv)) {
do {
if (linkid != DATALINK_INVALID_LINKID)
} while (linkid != DATALINK_INVALID_LINKID);
} else {
(void) zone_datalink_walk(getzoneid(),
}
done:
}
/*
* Display all instantiated network datalink device nodes.
* the network datalink device succeeds.
*/
/*ARGSUSED4*/
static int
{
if (uiop->uio_offset == 0)
}
/*
* This callback is invoked from devname_inactive_func() to release
* the net entry which was held in devnet_create_rvp().
*/
static void
{
return;
/*
* "ddh" (sdev_private) could be NULL if devnet_lookup fails.
*/
}
/*ARGSUSED*/
static void
{
}
/*
* We override lookup and readdir to build entries based on the
* in kernel vanity naming node table.
*/
};