From: Peter Jones <pjones@redhat.com>
To: linux-hotplug@vger.kernel.org
Subject: [PATCH] Add fc_id, which gives ID_PORT_NAME and ID_LUN on appropriate devices.
Date: Tue, 21 Jul 2009 19:23:46 +0000 [thread overview]
Message-ID: <1248204226-7103-1-git-send-email-pjones@redhat.com> (raw)
In-Reply-To: <1248203904-6561-1-git-send-email-pjones@redhat.com>
This makes it easier for consumers to use the individual pieces of
information instead of having to parse path_id's output.
(this version fixes Makefile.am)
---
| 1 +
| 1 +
| 13 +++
| 271 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 286 insertions(+), 0 deletions(-)
create mode 100644 extras/fc_id/.gitignore
create mode 100644 extras/fc_id/Makefile.am
create mode 100644 extras/fc_id/fc_id.c
--git a/extras/Makefile.am b/extras/Makefile.am
index b7c9fe8..5377a8e 100644
--- a/extras/Makefile.am
+++ b/extras/Makefile.am
@@ -5,6 +5,7 @@ SUBDIRS = \
cdrom_id \
edd_id \
path_id \
+ fc_id \
firmware \
collect \
floppy \
--git a/extras/fc_id/.gitignore b/extras/fc_id/.gitignore
new file mode 100644
index 0000000..1d7d107
--- /dev/null
+++ b/extras/fc_id/.gitignore
@@ -0,0 +1 @@
+fc_id
--git a/extras/fc_id/Makefile.am b/extras/fc_id/Makefile.am
new file mode 100644
index 0000000..6d4c8d1
--- /dev/null
+++ b/extras/fc_id/Makefile.am
@@ -0,0 +1,13 @@
+include $(top_srcdir)/Makefile.am.inc
+
+libexec_PROGRAMS = \
+ fc_id
+
+fc_id_SOURCES = \
+ fc_id.c \
+ ../../libudev/libudev.h \
+ ../../libudev/libudev.c \
+ ../../libudev/libudev-device.c \
+ ../../libudev/libudev-enumerate.c \
+ ../../libudev/libudev-list.c \
+ ../../libudev/libudev-util.c
--git a/extras/fc_id/fc_id.c b/extras/fc_id/fc_id.c
new file mode 100644
index 0000000..d8cb597
--- /dev/null
+++ b/extras/fc_id/fc_id.c
@@ -0,0 +1,271 @@
+/*
+ * report Fibre Channel Path Name and Lun
+ *
+ * Copyright (C) 2009 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright 2009 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <getopt.h>
+
+#include "libudev.h"
+#include "libudev-private.h"
+
+int debug;
+
+static void log_fn(struct udev *udev, int priority,
+ const char *file, int line, const char *fn,
+ const char *format, va_list args)
+{
+ if (debug) {
+ fprintf(stderr, "%s: ", fn != NULL ? fn : file);
+ vfprintf(stderr, format, args);
+ } else {
+ vsyslog(priority, format, args);
+ }
+}
+
+static struct udev_device *skip_subsystem(struct udev_device *dev, const char *subsys)
+{
+ struct udev_device *parent = dev;
+
+ while (parent != NULL) {
+ const char *subsystem;
+
+ subsystem = udev_device_get_subsystem(parent);
+ if (subsystem = NULL || strcmp(subsystem, subsys) != 0)
+ break;
+ dev = parent;
+ parent = udev_device_get_parent(parent);
+ }
+ return dev;
+}
+
+static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent)
+{
+ struct udev *udev = udev_device_get_udev(parent);
+ struct udev_device *targetdev;
+ struct udev_device *fcdev = NULL;
+ const char *port;
+ unsigned int lun;
+
+ targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
+ if (targetdev = NULL)
+ return NULL;
+
+ fcdev = udev_device_new_from_subsystem_sysname(udev, "fc_transport", udev_device_get_sysname(targetdev));
+ if (fcdev = NULL)
+ return NULL;
+ port = udev_device_get_sysattr_value(fcdev, "port_name");
+ if (port = NULL) {
+ parent = NULL;
+ goto out;
+ }
+ lun = strtoul(udev_device_get_sysnum(parent), NULL, 10);
+
+ printf("ID_PORT_NAME=%s\n", port);
+ printf("ID_LUN=%08x\n", lun);
+out:
+ udev_device_unref(fcdev);
+ return parent;
+}
+
+static struct udev_device *handle_scsi_sas(struct udev_device *parent)
+{
+ return NULL;
+}
+
+static struct udev_device *handle_scsi_iscsi(struct udev_device *parent)
+{
+ return NULL;
+}
+
+static struct udev_device *handle_scsi(struct udev_device *parent)
+{
+ const char *devtype;
+ const char *name;
+ const char *id;
+
+ devtype = udev_device_get_devtype(parent);
+ if (devtype = NULL || strcmp(devtype, "scsi_device") != 0)
+ return parent;
+
+ /* firewire */
+ id = udev_device_get_sysattr_value(parent, "ieee1394_id");
+ if (id != NULL) {
+ parent = skip_subsystem(parent, "scsi");
+ goto out;
+ }
+
+ /* lousy scsi sysfs does not have a "subsystem" for the transport */
+ name = udev_device_get_syspath(parent);
+
+ if (strstr(name, "/rport-") != NULL) {
+ parent = handle_scsi_fibre_channel(parent);
+ goto out;
+ }
+
+ if (strstr(name, "/end_device-") != NULL) {
+ parent = handle_scsi_sas(parent);
+ goto out;
+ }
+
+ if (strstr(name, "/session") != NULL) {
+ parent = handle_scsi_iscsi(parent);
+ goto out;
+ }
+
+ parent = skip_subsystem(parent, "scsi");
+out:
+ return parent;
+}
+
+static struct udev_device *handle_cciss(struct udev_device *parent)
+{
+ return NULL;
+}
+
+static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev)
+{
+ struct udev_device *scsi_dev;
+
+ scsi_dev = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device");
+ if (scsi_dev != NULL) {
+ const char *wwpn;
+ const char *lun;
+ const char *hba_id;
+
+ hba_id = udev_device_get_sysattr_value(scsi_dev, "hba_id");
+ if (hba_id != NULL)
+ printf("ID_HDA=%s\n", hba_id);
+ wwpn = udev_device_get_sysattr_value(scsi_dev, "wwpn");
+ if (wwpn != NULL)
+ printf("ID_PORT_NAME=%s\n", wwpn);
+ lun = udev_device_get_sysattr_value(scsi_dev, "fcp_lun");
+ if (lun != NULL)
+ printf("ID_LUN=%s\n", lun);
+ }
+
+ parent = skip_subsystem(parent, "ccw");
+ return parent;
+}
+
+int main(int argc, char **argv)
+{
+ static const struct option options[] = {
+ { "debug", no_argument, NULL, 'd' },
+ { "help", no_argument, NULL, 'h' },
+ {}
+ };
+ struct udev *udev;
+ struct udev_device *dev;
+ struct udev_device *parent;
+ char syspath[UTIL_PATH_SIZE];
+ const char *devpath;
+ int rc = 1;
+
+ udev = udev_new();
+ if (udev = NULL)
+ goto exit;
+
+ udev_log_init("fc_id");
+ udev_set_log_fn(udev, log_fn);
+
+ while (1) {
+ int option;
+
+ option = getopt_long(argc, argv, "dh", options, NULL);
+ if (option = -1)
+ break;
+
+ switch (option) {
+ case 'd':
+ debug = 1;
+ if (udev_get_log_priority(udev) < LOG_INFO)
+ udev_set_log_priority(udev, LOG_INFO);
+ break;
+ case 'h':
+ printf("Usage: fc_id [--debug] [--help] <devpath>\n"
+ " --debug print debug information\n"
+ " --help print this help text\n\n");
+ default:
+ rc = 1;
+ goto exit;
+ }
+ }
+
+ devpath = argv[optind];
+ if (devpath = NULL) {
+ fprintf(stderr, "No device specified\n");
+ rc = 2;
+ goto exit;
+ }
+
+ util_strscpyl(syspath, sizeof(syspath), udev_get_sys_path(udev), devpath, NULL);
+ dev = udev_device_new_from_syspath(udev, syspath);
+ if (dev = NULL) {
+ fprintf(stderr, "unable to access '%s'\n", devpath);
+ rc = 3;
+ goto exit;
+ }
+
+ /* S390 ccw bus */
+ parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccw", NULL);
+ if (parent != NULL) {
+ handle_ccw(parent, dev);
+ goto out;
+ }
+
+ /* walk up the chain of devices and compose path */
+ parent = dev;
+ while (parent != NULL) {
+ const char *subsys;
+
+ subsys = udev_device_get_subsystem(parent);
+
+ if (subsys = NULL) {
+ ;
+ } else if (strcmp(subsys, "scsi") = 0) {
+ parent = handle_scsi(parent);
+ } else if (strcmp(subsys, "cciss") = 0) {
+ handle_cciss(parent);
+ } else if (strcmp(subsys, "serio") = 0) {
+ parent = skip_subsystem(parent, "serio");
+ } else if (strcmp(subsys, "pci") = 0) {
+ parent = skip_subsystem(parent, "pci");
+ } else if (strcmp(subsys, "platform") = 0) {
+ parent = skip_subsystem(parent, "platform");
+ } else if (strcmp(subsys, "xen") = 0) {
+ parent = skip_subsystem(parent, "xen");
+ }
+
+ parent = udev_device_get_parent(parent);
+ }
+out:
+ udev_device_unref(dev);
+exit:
+ udev_unref(udev);
+ udev_log_close();
+ return rc;
+}
--
1.6.2.2
next prev parent reply other threads:[~2009-07-21 19:23 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-21 19:18 [PATCH] Add fc_id, which gives ID_PORT_NAME and ID_LUN on appropriate devices Peter Jones
2009-07-21 19:23 ` Peter Jones [this message]
2009-07-21 20:29 ` [PATCH] Add fc_id, which gives ID_PORT_NAME and ID_LUN on David Zeuthen
2009-07-21 21:07 ` [PATCH] Add fc_id, which gives ID_PORT_NAME and ID_LUN on appropriate Peter Jones
2009-07-21 22:04 ` [PATCH] Add fc_id, which gives ID_PORT_NAME and ID_LUN on Kay Sievers
2009-07-22 2:47 ` [PATCH] Add fc_id, which gives ID_PORT_NAME and ID_LUN on appropriate devices Andrey Borzenkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1248204226-7103-1-git-send-email-pjones@redhat.com \
--to=pjones@redhat.com \
--cc=linux-hotplug@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).