summaryrefslogtreecommitdiff
path: root/usr/src/cmd/devfsadm/disk_link.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/devfsadm/disk_link.c')
-rw-r--r--usr/src/cmd/devfsadm/disk_link.c66
1 files changed, 59 insertions, 7 deletions
diff --git a/usr/src/cmd/devfsadm/disk_link.c b/usr/src/cmd/devfsadm/disk_link.c
index 80e75c1694..0baa608912 100644
--- a/usr/src/cmd/devfsadm/disk_link.c
+++ b/usr/src/cmd/devfsadm/disk_link.c
@@ -19,6 +19,7 @@
* CDDL HEADER END
*/
/*
+ * Copyright 2016 Toomas Soome <tsoome@me.com>
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
@@ -30,11 +31,13 @@
#include <stdlib.h>
#include <limits.h>
#include <ctype.h>
+#include <unistd.h>
#include <sys/int_fmtio.h>
#include <sys/stat.h>
#include <bsm/devalloc.h>
#include <sys/scsi/scsi_address.h>
#include <sys/libdevid.h>
+#include <sys/lofi.h>
#define DISK_SUBPATH_MAX 100
#define RM_STALE 0x01
@@ -69,6 +72,7 @@ static void disk_common(di_minor_t minor, di_node_t node, char *disk,
int flags);
static char *diskctrl(di_node_t node, di_minor_t minor);
static int reserved_links_exist(di_node_t node, di_minor_t minor, int nflags);
+static void disk_rm_lofi_all(char *file);
static devfsadm_create_t disk_cbt[] = {
@@ -104,9 +108,12 @@ static devfsadm_create_t disk_cbt[] = {
DEVFSADM_CREATE_INIT_V0(disk_cbt);
/*
- * HOT auto cleanup of disks not desired.
+ * HOT auto cleanup of disks is done for lofi devices only.
*/
static devfsadm_remove_t disk_remove_cbt[] = {
+ { "disk", DISK_LINK_RE, RM_HOT | RM_POST | RM_ALWAYS,
+ ILEVEL_0, disk_rm_lofi_all
+ },
{ "disk", DISK_LINK_RE, RM_POST,
ILEVEL_0, devfsadm_rm_all
}
@@ -124,6 +131,44 @@ static devlink_re_t disks_re_array[] = {
static char *disk_mid = "disk_mid";
static char *modname = "disk_link";
+/*
+ * Check if link is from lofi by checking path from readlink().
+ */
+static int
+is_lofi_disk(char *file)
+{
+ char buf[PATH_MAX + 1];
+ char filepath[PATH_MAX];
+ char *ptr;
+ ssize_t size;
+
+ size = snprintf(filepath, sizeof (filepath), "%s/dev/%s",
+ devfsadm_root_path(), file);
+ if (size > sizeof (filepath))
+ return (0);
+
+ size = readlink(filepath, buf, sizeof (buf) - 1);
+ if (size == -1)
+ return (0);
+ buf[size] = '\0';
+ ptr = strchr(buf, '@');
+ if (ptr == NULL)
+ return (0);
+ ptr[1] = '\0';
+ if (strcmp(buf, "../../devices/pseudo/lofi@") != 0)
+ return (0);
+ return (1);
+}
+
+/*
+ * Wrapper around devfsadm_rm_link() for lofi devices.
+ */
+static void disk_rm_lofi_all(char *file)
+{
+ if (is_lofi_disk(file))
+ devfsadm_rm_link(file);
+}
+
int
minor_init()
{
@@ -137,13 +182,20 @@ static int
disk_callback_chan(di_minor_t minor, di_node_t node)
{
char *addr;
- char disk[20];
- uint_t targ;
- uint_t lun;
+ char disk[23];
+ char *driver;
+ uint_t targ = 0;
+ uint_t lun = 0;
+
+ driver = di_driver_name(node);
+ if (strcmp(driver, LOFI_DRIVER_NAME) != 0) {
+ addr = di_bus_addr(node);
+ (void) sscanf(addr, "%X,%X", &targ, &lun);
+ } else {
+ targ = di_instance(node);
+ }
- addr = di_bus_addr(node);
- (void) sscanf(addr, "%X,%X", &targ, &lun);
- (void) sprintf(disk, "t%dd%d", targ, lun);
+ (void) snprintf(disk, sizeof (disk), "t%dd%d", targ, lun);
disk_common(minor, node, disk, 0);
return (DEVFSADM_CONTINUE);