Go to main content

man pages section 9: DDI and DKI Kernel Functions

Exit Print View

Updated: Thursday, June 13, 2019
 
 

kstat2_unregister_optional (9F)

Name

kstat2_register_optional, kstat2_unregister_optional - register or unregister optional kstats

Synopsis

#include <sys/types.h>
#include <sys/kstat2.h>
kstat2_opt_id_t kstat2_register_optional(const char *name,
const char *desc, kstat2_opt_cb_t cb, void *arg);
void kstat2_unregister_optional(kstat2_opt_id_t id);

Interface Level

Solaris DDI specific (Solaris DDI)

Parameters

The kstat2_register_optional() function has the following parameters:

name

String used to identify the optional kstats. This must be prefixed with calling the name of the module

desc

Short description of the optional kstats

cb

Callback function which implements the enabling and disabling of optional kstats for the module

arg

Private pointer which can be used to pass module-specific information in the second argument of the callback function

The kstat2_unregister_optional() function has the following parameter:

id

id is returned by a previous call to the kstat2_register_optional() function

Description

The kstat2_register_optional() function registers the name with the kstats framework. While the actual name used is up to the module developer, it has to be unique and has to be prefixed by the module or the driver name followed by a colon. The name, including the module prefix must be 30 characters or less in length, and must not contain any whitespace.

The desc string provides a short description of the optional kstats provided by the name parameter. No restriction is placed on the length of the description string length. However, However, shorter string length is better, and it must also not contain any whitespace other than the space character.

The supplied callback returns a value from the kstat2_opt_estate_t enum. Normally, this will be KSTAT2_OPT_ESTATE_ENABLED or KSTAT2_OPT_ESTATE_DISABLED. However, it can also return KSTAT2_OPT_ESTATE_ERROR, if an internal error occurred when trying to enable or disable kstats. When the callback type is KSTAT2_OPT_CB_QUERY, the callback is expected to return the current enabled state as KSTAT2_OPT_ESTATE_ENABLED or KSTAT2_OPT_ESTATE_DISABLED. Additionally, it must tag the current enabled state with KSTAT2_OPT_ESTATE_DEFAULT, if the returned state value is the default state for these optional kstats. For more information, see Examples.

The kstat2_unregister_optional() function unregisters the optional kstats associated with the given id in kstats framework. The optional kstats will no longer be visible to the kstat2adm tool, and attempts to enable or disable the optional kstat will fail. For more information, see the kstat2adm(8) man page.

Module developers must call the kstat2_unregister_optional() function in their finalization functions, that is, prior to being unloaded. Similarly, all optional kstats created by a module must be destroyed prior to leaving the module finalization function. Failure to delete kstats and unregister the optional kstat handler may result in a system panic, when the module is unloaded.

Return Values

The kstat2_register_optional() function returns a positive numeric id on success and -1 on failure. The returned id is used when unregistering the optional kstats.

Examples

Example 1 Registering Optional Kstats

The following command shows how to register optional kstats:

#include <sys/kstat2.h>

static const char *mydrv_optional_kstats_name = "mydrv:latency_kstats";
static const char *mydrv_optional_kstats_desc =
    "Latency kstats for mydrv operations";

static int mydrv_opt_kstats_cb(zoneid_t, kstat2_dyn_cb_type_t, void *);

static struct mydrv_priv_s {
        int instance;
        kmutex_t mydrv_opt_kstats_lck;
} mydrv_priv;

static kstat2_opt_id_t mydrv_opt_ksid;

int
_init(void)
{
    int rc = modinstall(&modlinkage);
    zoneid_t thiszone = getzoneid();

    mydrv_opt_ksid = kstat2_register_optional(
        mydrv_optional_kstats_name, mydrv_optional_kstats_desc,
        mydrv_optional_kstats_cb, (void *)&mydrv_priv);

    if (mydrv_opt_ksid == -1) {
            /*
             * Registration failed. A message will have been
             * reported by the kstats framework.
             */
    }
    return (rc);
}
Example 2 Optional Kstats Callback Handler
#include <sys/kstat2.h>

static kstat2_t *mydrv_opt_kstat1 = NULL;
static kstat2_t *mydrv_opt_kstat2 = NULL;

/*
 * When called to enable kstats, creates them in the zone
 * passed in as an argument.
 */
static kstat2_opt_estate_t
mydrv_opt_kstats_cb(zoneid_t zid, kstat2_dyn_cb_type_t op, void *arg)
{
        struct mydrv_priv_s *priv = (struct mydrv_priv_s *)arg;
        kstat2_opt_estate_enabled rc = KSTAT2_OPT_ESTATE_ERROR;

        /*
         * Enter a mutex to prevent multiple calls to this fn
         * messing with the kstats at the same time.
         */
               mutex_enter(&priv->mydrv_opt_kstats_lck);

               switch (op) {
               case KSTAT2_OPT_CB_ENABLE:
                       if (mydrv_opt_kstat1 == NULL) {
                               mydrv_opt_kstat1 = kstat2_create(zid, ...);
                               if (mydrv_opt_kstat1 != NULL) {
                                       mydrv_opt_kstat1->ks2_priv = priv;
                                       kstat2_install(mydrv_opt_kstat1);
                                       rc = KSTAT2_OPT_ESTATE_ENABLED;
                               } else {
                                       /* Report the failure */
                                       rc = KSTAT2_OPT_ESTATE_ERROR;
                               }
                       } else {
                           /*
                            * Optional kstats already exist, so the
                            * return state should indicate they are
                            * enabled.
                            */
                           rc = KSTAT2_OPT_ESTATE_ENABLED;
                   }
                   break;

           case KSTAT2_OPT_CB_DISABLE:
                   if (mydrv_opt_kstat1 != NULL) {
                           kstat2_delete(mydrv_opt_kstat1);
                           mydrv_opt_kstat1 = NULL;
                   }
                   rc = KSTAT2_OPT_ESTATE_DISABLED;
                   break;

           case KSTAT2_OPT_CB_QUERY:
                   if (mydrv_opt_kstat1 == NULL) {
                           /*
                            * The default state of these optional kstats
                            * is disabled, so tag the query result
                            * accordingly.
                            */
                           rc = KSTAT2_OPT_ESTATE_DISABLED |
                               KSTAT2_OPT_ESTATE_DEFAULT;
                   } else {
                           rc = KSTAT2_OPT_ESTATE_ENABLED;
                   }
                   break;

           default:
                   rc = KSTAT2_OPT_ESTATE_ERROR;
                   break;
           }

           mutex_exit(&priv->mydrv_opt_kstats_lck);
           return (rc);
}
Example 3 Suggested Module Finalization

Typically, a module finalization function will look similar to the following:

#include <sys/kstat2.h>

       static const char *mydrv_optional_kstats_name = "mydrv:latency_kstats";
       static kstat2_t *mydrv_opt_kstat1 = NULL;
       static kstat2_t *mydrv_opt_kstat2 = NULL;

       int
       _fini(void)
       {
               /*
                * Unregister the optional kstats.
                * It is important to do this before the kstats are deleted
                * to prevent a race-condition with a client trying to enable,
                * disable or query the optional kstat state.
                */
               kstat2_unregister_optional(mydrv_opt_ksid);

               /* Delete any active optional kstats */
               if (mydrv_opt_kstat1 != NULL) {
                   kstat2_delete(mydrv_opt_kstat1);
                   kstat2_delete(mydrv_opt_kstat2);
                   ...
               }

               /* Other tidying up as needed */
               
               return (mod_remove(&modlinkage));
       }

Another implementation might be able to return EBUSY from the _fini() function, if optional kstats are enabled.

Context

The functions can be called from any context.

See Also

kstat2_create(9F), kstat2_install (9F) , kstat2adm(8)