4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2016 Toomas Soome <tsoome@me.com>
  24  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  25  * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
  26  */
  27 
  28 /*
  29  * Devfsadm replaces drvconfig, audlinks, disks, tapes, ports, devlinks
  30  * as a general purpose device administrative utility.  It creates
  31  * devices special files in /devices and logical links in /dev, and
  32  * coordinates updates to /etc/path_to_instance with the kernel.  It
  33  * operates in both command line mode to handle user or script invoked
  34  * reconfiguration updates, and operates in daemon mode to handle dynamic
  35  * reconfiguration for hotplugging support.
  36  */
  37 
  38 #include <string.h>
  39 #include <deflt.h>
  40 #include <tsol/label.h>
  41 #include <bsm/devices.h>
  42 #include <bsm/devalloc.h>
  43 #include <utime.h>
  44 #include <sys/param.h>
 
 
8206         if ((err = nvlist_alloc(&nvl, NV_UNIQUE_NAME_TYPE, 0)) != 0) {
8207                 nvl = NULL;
8208                 goto out;
8209         }
8210 
8211         if ((err = nvlist_add_int32(nvl, EV_VERSION, EV_V1)) != 0)
8212                 goto out;
8213 
8214         if ((err = nvlist_add_string(nvl, DEV_PHYS_PATH, node_path)) != 0)
8215                 goto out;
8216 
8217         if (strcmp(class, EC_DEV_ADD) != 0 &&
8218             strcmp(class, EC_DEV_REMOVE) != 0)
8219                 return (nvl);
8220 
8221         if (driver_name == NULL || instance == -1)
8222                 goto out;
8223 
8224         if (strcmp(subclass, ESC_DISK) == 0) {
8225                 /*
8226                  * While we're removing labeled lofi device, we will receive
8227                  * event for every registered minor device and lastly,
8228                  * an event with minor set to NULL, as in following example:
8229                  * class: EC_dev_remove subclass: disk
8230                  * node_path: /pseudo/lofi@1 driver: lofi minor: u,raw
8231                  * class: EC_dev_remove subclass: disk
8232                  * node_path: /pseudo/lofi@1 driver: lofi minor: NULL
8233                  *
8234                  * When we receive this last event with minor set to NULL,
8235                  * all lofi minor devices are already removed and the call to
8236                  * lookup_disk_dev_name() would result in error.
8237                  * To prevent name lookup error messages for this case, we
8238                  * need to filter out that last event.
8239                  */
8240                 if (strcmp(class, EC_DEV_REMOVE) == 0 &&
8241                     strcmp(driver_name, "lofi") ==  0 && minor == NULL) {
8242                         nvlist_free(nvl);
8243                         return (NULL);
8244                 }
8245                 if ((dev_name = lookup_disk_dev_name(node_path)) == NULL) {
8246                         dev_name_lookup_err = 1;
8247                         goto out;
8248                 }
8249         } else if (strcmp(subclass, ESC_NETWORK) == 0) {
8250                 if ((dev_name = lookup_network_dev_name(node_path, driver_name))
8251                     == NULL) {
8252                         dev_name_lookup_err = 1;
8253                         goto out;
8254                 }
8255         } else if (strcmp(subclass, ESC_PRINTER) == 0) {
8256                 if ((dev_name = lookup_printer_dev_name(node_path)) == NULL) {
8257                         dev_name_lookup_err = 1;
8258                         goto out;
8259                 }
8260         } else if (strcmp(subclass, ESC_LOFI) == 0) {
8261                 /*
8262                  * The raw minor node is created or removed after the block
8263                  * node.  Lofi devfs events are dependent on this behavior.
 
 | 
 
 
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2016 Toomas Soome <tsoome@me.com>
  24  * Copyright 2018 Nexenta Systems, Inc.
  25  * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
  26  */
  27 
  28 /*
  29  * Devfsadm replaces drvconfig, audlinks, disks, tapes, ports, devlinks
  30  * as a general purpose device administrative utility.  It creates
  31  * devices special files in /devices and logical links in /dev, and
  32  * coordinates updates to /etc/path_to_instance with the kernel.  It
  33  * operates in both command line mode to handle user or script invoked
  34  * reconfiguration updates, and operates in daemon mode to handle dynamic
  35  * reconfiguration for hotplugging support.
  36  */
  37 
  38 #include <string.h>
  39 #include <deflt.h>
  40 #include <tsol/label.h>
  41 #include <bsm/devices.h>
  42 #include <bsm/devalloc.h>
  43 #include <utime.h>
  44 #include <sys/param.h>
 
 
8206         if ((err = nvlist_alloc(&nvl, NV_UNIQUE_NAME_TYPE, 0)) != 0) {
8207                 nvl = NULL;
8208                 goto out;
8209         }
8210 
8211         if ((err = nvlist_add_int32(nvl, EV_VERSION, EV_V1)) != 0)
8212                 goto out;
8213 
8214         if ((err = nvlist_add_string(nvl, DEV_PHYS_PATH, node_path)) != 0)
8215                 goto out;
8216 
8217         if (strcmp(class, EC_DEV_ADD) != 0 &&
8218             strcmp(class, EC_DEV_REMOVE) != 0)
8219                 return (nvl);
8220 
8221         if (driver_name == NULL || instance == -1)
8222                 goto out;
8223 
8224         if (strcmp(subclass, ESC_DISK) == 0) {
8225                 /*
8226                  * FIXME Currently we will get ESC_devfs_devi_remove for labeled
8227                  * lofi devices only after all its minors are already removed,
8228                  * so the lookup_disk_dev_name() call below will fail.
8229                  *
8230                  * Given the above, ignore all lofi events except for lofi minor
8231                  * remove event for minor 'a' (chosen arbitrarily) so that we
8232                  * post exactly one ESC_dev_remove/disk event for labeled lofi
8233                  * devices, and don't get error from lookup_disk_dev_name().
8234                  */
8235                 if (strcmp(class, EC_DEV_REMOVE) == 0 &&
8236                     strcmp(driver_name, "lofi") == 0 &&
8237                     (minor == NULL || strcmp(minor, "a") != 0)) {
8238                         nvlist_free(nvl);
8239                         return (NULL);
8240                 }
8241                 /*
8242                  * Don't post disk minor events (except for lofi workaround),
8243                  * they don't provide any useful information.
8244                  */
8245                 if (minor != NULL && strcmp(minor, "a") != 0) {
8246                         nvlist_free(nvl);
8247                         return (NULL);
8248                 }
8249                 if ((dev_name = lookup_disk_dev_name(node_path)) == NULL) {
8250                         dev_name_lookup_err = 1;
8251                         goto out;
8252                 }
8253         } else if (strcmp(subclass, ESC_NETWORK) == 0) {
8254                 if ((dev_name = lookup_network_dev_name(node_path, driver_name))
8255                     == NULL) {
8256                         dev_name_lookup_err = 1;
8257                         goto out;
8258                 }
8259         } else if (strcmp(subclass, ESC_PRINTER) == 0) {
8260                 if ((dev_name = lookup_printer_dev_name(node_path)) == NULL) {
8261                         dev_name_lookup_err = 1;
8262                         goto out;
8263                 }
8264         } else if (strcmp(subclass, ESC_LOFI) == 0) {
8265                 /*
8266                  * The raw minor node is created or removed after the block
8267                  * node.  Lofi devfs events are dependent on this behavior.
 
 |