Skip to content

Commit

Permalink
6602 lofi should support labeled devices
Browse files Browse the repository at this point in the history
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Dan McDonald <danmcd@omniti.com>
  • Loading branch information
tsoome authored and Dan McDonald committed Jun 21, 2016
1 parent f3a07f9 commit 406fc51
Show file tree
Hide file tree
Showing 18 changed files with 2,150 additions and 1,171 deletions.
76 changes: 56 additions & 20 deletions usr/src/cmd/devfsadm/devfsadm.c
Expand Up @@ -20,6 +20,7 @@
*/

/*
* Copyright 2016 Toomas Soome <tsoome@me.com>
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
*/

Expand Down Expand Up @@ -3289,7 +3290,7 @@ rm_parent_dir_if_empty(char *pathname)
*/
void
devfsadm_rm_stale_links(char *dir_re, char *valid_link, di_node_t node,
di_minor_t minor)
di_minor_t minor)
{
link_t *link;
linkhead_t *head;
Expand Down Expand Up @@ -4837,7 +4838,7 @@ get_component(char *str, const char *comp_str)
*/
int
devfsadm_enumerate_int(char *devfs_path, int index, char **buf,
devfsadm_enumerate_t rules[], int nrules)
devfsadm_enumerate_t rules[], int nrules)
{
return (find_enum_id(rules, nrules,
devfs_path, index, "0", INTEGER, buf, 0));
Expand All @@ -4857,7 +4858,7 @@ disk_enumerate_int(char *devfs_path, int index, char **buf,
*/
static int
devfsadm_enumerate_int_start(char *devfs_path, int index, char **buf,
devfsadm_enumerate_t rules[], int nrules, char *start)
devfsadm_enumerate_t rules[], int nrules, char *start)
{
return (find_enum_id(rules, nrules,
devfs_path, index, start, INTEGER, buf, 0));
Expand All @@ -4869,7 +4870,7 @@ devfsadm_enumerate_int_start(char *devfs_path, int index, char **buf,
*/
int
devfsadm_enumerate_char(char *devfs_path, int index, char **buf,
devfsadm_enumerate_t rules[], int nrules)
devfsadm_enumerate_t rules[], int nrules)
{
return (find_enum_id(rules, nrules,
devfs_path, index, "a", LETTER, buf, 0));
Expand All @@ -4881,7 +4882,7 @@ devfsadm_enumerate_char(char *devfs_path, int index, char **buf,
*/
int
devfsadm_enumerate_char_start(char *devfs_path, int index, char **buf,
devfsadm_enumerate_t rules[], int nrules, char *start)
devfsadm_enumerate_t rules[], int nrules, char *start)
{
return (find_enum_id(rules, nrules,
devfs_path, index, start, LETTER, buf, 0));
Expand All @@ -4898,8 +4899,8 @@ devfsadm_enumerate_char_start(char *devfs_path, int index, char **buf,
*/
static int
find_enum_id(devfsadm_enumerate_t rules[], int nrules,
char *devfs_path, int index, char *min, int type, char **buf,
int multiple)
char *devfs_path, int index, char *min, int type, char **buf,
int multiple)
{
numeral_t *matchnp;
numeral_t *numeral;
Expand Down Expand Up @@ -4999,7 +5000,7 @@ find_enum_id(devfsadm_enumerate_t rules[], int nrules,
*/
static int
lookup_enum_cache(numeral_set_t *set, char *cmp_str,
devfsadm_enumerate_t rules[], int index, numeral_t **matchnpp)
devfsadm_enumerate_t rules[], int index, numeral_t **matchnpp)
{
int matchcount = 0, rv = -1;
int uncached;
Expand Down Expand Up @@ -5390,7 +5391,7 @@ new_id(numeral_t *numeral, int type, char *min)

static int
enumerate_parse(char *rsvstr, char *path_left, numeral_set_t *setp,
devfsadm_enumerate_t rules[], int index)
devfsadm_enumerate_t rules[], int index)
{
char *slash1 = NULL;
char *slash2 = NULL;
Expand Down Expand Up @@ -5506,7 +5507,7 @@ enumerate_parse(char *rsvstr, char *path_left, numeral_set_t *setp,
*/
static void
enumerate_recurse(char *current_dir, char *path_left, numeral_set_t *setp,
devfsadm_enumerate_t rules[], int index)
devfsadm_enumerate_t rules[], int index)
{
char *slash;
char *new_path;
Expand Down Expand Up @@ -5661,7 +5662,7 @@ create_reserved_numeral(numeral_set_t *setp, char *numeral_id)
*/
static void
create_cached_numeral(char *path, numeral_set_t *setp, char *numeral_id,
devfsadm_enumerate_t rules[], int index)
devfsadm_enumerate_t rules[], int index)
{
char linkbuf[PATH_MAX + 1];
char lpath[PATH_MAX + 1];
Expand Down Expand Up @@ -5838,7 +5839,7 @@ devfsadm_copy(void)
/*ARGSUSED*/
static int
devfsadm_copy_file(const char *file, const struct stat *stat,
int flags, struct FTW *ftw)
int flags, struct FTW *ftw)
{
struct stat sp;
dev_t newdev;
Expand Down Expand Up @@ -6290,7 +6291,7 @@ read_devlinktab_file(void)
*/
static int
split_devlinktab_entry(char *entry, char **selector, char **p_link,
char **s_link)
char **s_link)
{
char *tab;

Expand Down Expand Up @@ -6726,7 +6727,7 @@ get_anchored_re(char *link, char *anchored_re, char *pattern)

static int
construct_devlink(char *link, link_list_t *link_build, char *contents,
di_minor_t minor, di_node_t node, char *pattern)
di_minor_t minor, di_node_t node, char *pattern)
{
int counter_offset = -1;
devfsadm_enumerate_t rules[1] = {NULL};
Expand Down Expand Up @@ -7133,7 +7134,7 @@ dequote(char *src)
*/
static void
getattr(char *phy_path, char *aminor, int spectype, dev_t dev, mode_t *mode,
uid_t *uid, gid_t *gid)
uid_t *uid, gid_t *gid)
{
char devname[PATH_MAX + 1];
char *node_name;
Expand Down Expand Up @@ -8219,6 +8220,26 @@ build_event_attributes(char *class, char *subclass, char *node_path,
goto out;

if (strcmp(subclass, ESC_DISK) == 0) {
/*
* While we're removing labeled lofi device, we will receive
* event for every registered minor device and lastly,
* an event with minor set to NULL, as in following example:
* class: EC_dev_remove subclass: disk
* node_path: /pseudo/lofi@1 driver: lofi minor: u,raw
* class: EC_dev_remove subclass: disk
* node_path: /pseudo/lofi@1 driver: lofi minor: NULL
*
* When we receive this last event with minor set to NULL,
* all lofi minor devices are already removed and the call to
* lookup_disk_dev_name() would result in error.
* To prevent name lookup error messages for this case, we
* need to filter out that last event.
*/
if (strcmp(class, EC_DEV_REMOVE) == 0 &&
strcmp(driver_name, "lofi") == 0 && minor == NULL) {
nvlist_free(nvl);
return (NULL);
}
if ((dev_name = lookup_disk_dev_name(node_path)) == NULL) {
dev_name_lookup_err = 1;
goto out;
Expand All @@ -8239,11 +8260,26 @@ build_event_attributes(char *class, char *subclass, char *node_path,
* The raw minor node is created or removed after the block
* node. Lofi devfs events are dependent on this behavior.
* Generate the sysevent only for the raw minor node.
*
* If the lofi mapping is created, we will receive the following
* event: class: EC_dev_add subclass: lofi minor: NULL
*
* As in case of EC_dev_add, the minor is NULL pointer,
* to get device links created, we will need to provide the
* type of minor node for lookup_lofi_dev_name()
*
* If the lofi device is unmapped, we will receive following
* events:
* class: EC_dev_remove subclass: lofi minor: disk
* class: EC_dev_remove subclass: lofi minor: disk,raw
* class: EC_dev_remove subclass: lofi minor: NULL
*/
if (strstr(minor, "raw") == NULL) {
if (nvl) {
nvlist_free(nvl);
}

if (strcmp(class, EC_DEV_ADD) == 0 && minor == NULL)
minor = "disk,raw";

if (minor == NULL || strstr(minor, "raw") == NULL) {
nvlist_free(nvl);
return (NULL);
}
if ((dev_name = lookup_lofi_dev_name(node_path, minor)) ==
Expand Down Expand Up @@ -8374,7 +8410,7 @@ process_syseventq()

static void
build_and_enq_event(char *class, char *subclass, char *node_path,
di_node_t node, char *minor)
di_node_t node, char *minor)
{
nvlist_t *nvl;

Expand Down
66 changes: 59 additions & 7 deletions usr/src/cmd/devfsadm/disk_link.c
Expand Up @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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
}
Expand 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()
{
Expand All @@ -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);

Expand Down
29 changes: 11 additions & 18 deletions usr/src/cmd/devfsadm/lofi_link.c
Expand Up @@ -19,12 +19,11 @@
* CDDL HEADER END
*/
/*
* Copyright 2016 Toomas Soome <tsoome@me.com>
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

#pragma ident "%Z%%M% %I% %E% SMI"

#include <regex.h>
#include <devfsadm.h>
#include <stdio.h>
Expand Down Expand Up @@ -73,35 +72,29 @@ lofi_rm_all(char *link)
* For the master device:
* /dev/lofictl -> /devices/pseudo/lofi@0:ctl
* For each other device
* /dev/lofi/1 -> /devices/pseudo/lofi@0:1
* /dev/rlofi/1 -> /devices/pseudo/lofi@0:1,raw
* /dev/lofi/1 -> /devices/pseudo/lofi@1:disk
* /dev/rlofi/1 -> /devices/pseudo/lofi@1:disk,raw
*/
static int
lofi(di_minor_t minor, di_node_t node)
{
dev_t dev;
int instance;
char mn[MAXNAMELEN + 1];
char blkname[MAXNAMELEN + 1];
char rawname[MAXNAMELEN + 1];
char path[PATH_MAX + 1];

(void) strcpy(mn, di_minor_name(minor));

if (strcmp(mn, "ctl") == 0) {
(void) devfsadm_mklink(LOFI_CTL_NAME, node, minor, 0);
} else {
dev = di_minor_devt(minor);
(void) snprintf(blkname, sizeof (blkname), "%d",
(int)minor(dev));
(void) snprintf(rawname, sizeof (rawname), "%d,raw",
(int)minor(dev));
instance = di_instance(node);

if (strcmp(mn, blkname) == 0) {
(void) snprintf(path, sizeof (path), "%s/%s",
LOFI_BLOCK_NAME, blkname);
} else if (strcmp(mn, rawname) == 0) {
(void) snprintf(path, sizeof (path), "%s/%s",
LOFI_CHAR_NAME, blkname);
if (strcmp(mn, LOFI_BLOCK_NODE) == 0) {
(void) snprintf(path, sizeof (path), "%s/%d",
LOFI_BLOCK_NAME, instance);
} else if (strcmp(mn, LOFI_CHAR_NODE) == 0) {
(void) snprintf(path, sizeof (path), "%s/%d",
LOFI_CHAR_NAME, instance);
} else {
return (DEVFSADM_CONTINUE);
}
Expand Down

0 comments on commit 406fc51

Please sign in to comment.