--- libmultipath/print.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) Index: multipath-tools-130222/libmultipath/print.c =================================================================== --- multipath-tools-130222.orig/libmultipath/print.c +++ multipath-tools-130222/libmultipath/print.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "checkers.h" #include "vector.h" @@ -44,7 +45,7 @@ * information printing helpers */ static int -snprint_str (char * buff, size_t len, char * str) +snprint_str (char * buff, size_t len, const char * str) { return snprintf(buff, len, "%s", str); } @@ -432,6 +433,83 @@ snprint_path_mpp (char * buff, size_t le } static int +snprint_host_attr (char * buff, size_t len, struct path * pp, char *attr) +{ + struct udev_device *host_dev = NULL; + char host_id[32]; + const char *value = NULL; + int ret; + + if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP) + return snprintf(buff, len, "[undef]"); + sprintf(host_id, "host%d", pp->sg_id.host_no); + host_dev = udev_device_new_from_subsystem_sysname(conf->udev, "fc_host", + host_id); + if (!host_dev) { + condlog(1, "%s: No fc_host device for '%s'", pp->dev, host_id); + goto out; + } + value = udev_device_get_sysattr_value(host_dev, attr); + if (value) + ret = snprint_str(buff, len, value); + udev_device_unref(host_dev); +out: + if (!value) + ret = snprintf(buff, len, "[unknown]"); + return ret; +} + +static int +snprint_host_wwnn (char * buff, size_t len, struct path * pp) +{ + return snprint_host_attr(buff, len, pp, "node_name"); +} + +static int +snprint_host_wwpn (char * buff, size_t len, struct path * pp) +{ + return snprint_host_attr(buff, len, pp, "port_name"); +} + +static int +snprint_tgt_wwpn (char * buff, size_t len, struct path * pp) +{ + struct udev_device *rport_dev = NULL; + char rport_id[32]; + const char *value = NULL; + int ret; + + if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP) + return snprintf(buff, len, "[undef]"); + sprintf(rport_id, "rport-%d:%d-%d", + pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); + rport_dev = udev_device_new_from_subsystem_sysname(conf->udev, + "fc_remote_ports", rport_id); + if (!rport_dev) { + condlog(1, "%s: No fc_remote_port device for '%s'", pp->dev, + rport_id); + goto out; + } + value = udev_device_get_sysattr_value(rport_dev, "port_name"); + if (value) + ret = snprint_str(buff, len, value); + udev_device_unref(rport_dev); +out: + if (!value) + ret = snprintf(buff, len, "[unknown]"); + return ret; +} + + +static int +snprint_tgt_wwnn (char * buff, size_t len, struct path * pp) +{ + if (pp->tgt_node_name[0] == '\0') + return snprintf(buff, len, "[undef]"); + return snprint_str(buff, len, pp->tgt_node_name); +} + +static int snprint_path_checker (char * buff, size_t len, struct path * pp) { struct checker * c = &pp->checker; @@ -475,6 +553,10 @@ struct path_data pd[] = { {'S', "size", 0, snprint_path_size}, {'z', "serial", 0, snprint_path_serial}, {'m', "multipath", 0, snprint_path_mpp}, + {'N', "host WWNN", 0, snprint_host_wwnn}, + {'n', "target WWNN", 0, snprint_tgt_wwnn}, + {'R', "host WWPN", 0, snprint_host_wwpn}, + {'r', "target WWPN", 0, snprint_tgt_wwpn}, {0, NULL, 0 , NULL} };