[PATCH] support identification of Xen virtual block devices

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



* Add xenvb_id utility to identify Xen disk and CD-ROM devices.
* Add support to path_id for Xen vbd devices

With this symlinks such as /dev/cdrom are correctly created for Xen devices
configured with the "cdrom" tag and utilities which rely on ID_TYPE or ID_CDROM
(such as the Debian Installer) can correctly identify the disks.

Signed-off-by: Ian Campbell <ijc@xxxxxxxxxxxxxx>
---
 configure.ac                        |    1 +
 extras/Makefile.am                  |    3 +-
 extras/path_id/path_id              |   27 ++++
 extras/xenvbd_id/.gitignore         |    1 +
 extras/xenvbd_id/60-xenvbd_id.rules |    3 +
 extras/xenvbd_id/Makefile.am        |   19 +++
 extras/xenvbd_id/xenvbd_id.8        |   37 ++++++
 extras/xenvbd_id/xenvbd_id.c        |  227 +++++++++++++++++++++++++++++++++++
 8 files changed, 317 insertions(+), 1 deletions(-)
 create mode 100644 extras/xenvbd_id/.gitignore
 create mode 100644 extras/xenvbd_id/60-xenvbd_id.rules
 create mode 100644 extras/xenvbd_id/Makefile.am
 create mode 100644 extras/xenvbd_id/xenvbd_id.8
 create mode 100644 extras/xenvbd_id/xenvbd_id.c

diff --git a/configure.ac b/configure.ac
index cbe2833..a968163 100644
--- a/configure.ac
+++ b/configure.ac
@@ -100,6 +100,7 @@ AC_CONFIG_FILES([
 	extras/volume_id/Makefile
 	extras/volume_id/lib/Makefile
 	extras/volume_id/lib/libvolume_id.pc
+	extras/xenvbd_id/Makefile
 ])
 AC_OUTPUT
 
diff --git a/extras/Makefile.am b/extras/Makefile.am
index fc46668..f364631 100644
--- a/extras/Makefile.am
+++ b/extras/Makefile.am
@@ -12,4 +12,5 @@ SUBDIRS = \
 	rule_generator \
 	scsi_id \
 	usb_id \
-	volume_id
+	volume_id \
+	xenvbd_id
diff --git a/extras/path_id/path_id b/extras/path_id/path_id
index d21dea7..7b4973f 100755
--- a/extras/path_id/path_id
+++ b/extras/path_id/path_id
@@ -129,6 +129,30 @@ handle_platform () {
 	RESULT=0
 }
 
+handle_xen () {
+	local DEV=$1
+	cd -P $1
+	vbd_id=${DEV##*/}
+	host_dev_path=$DEV
+	while [ ! -z "$host_dev_path" ] ; do
+		case "$host_dev_path" in
+			*/vbd*)
+				host_dev_path=${host_dev_path%/*}
+				;;
+			*)
+				break
+				;;
+		esac
+	done
+	if [ "$d" ]; then
+		d="xen-$vbd_id-$d"
+	else
+		d="xen-$vbd_id"
+	fi
+	D="$host_dev_path"
+	RESULT=0
+}
+
 handle_serio () {
 	local DEV=$1
 	cd -P $1
@@ -532,6 +556,9 @@ handle_device () {
 			*/platform/*)
 				handle_platform "$D"
 				;;
+			*/vbd-[0-9]*)
+				handle_xen "$D"
+				;;
 			*/devices)
 				D=
 				;;
diff --git a/extras/xenvbd_id/.gitignore b/extras/xenvbd_id/.gitignore
new file mode 100644
index 0000000..c0ae90e
--- /dev/null
+++ b/extras/xenvbd_id/.gitignore
@@ -0,0 +1 @@
+xenvbd_id
diff --git a/extras/xenvbd_id/60-xenvbd_id.rules b/extras/xenvbd_id/60-xenvbd_id.rules
new file mode 100644
index 0000000..ed3aa5f
--- /dev/null
+++ b/extras/xenvbd_id/60-xenvbd_id.rules
@@ -0,0 +1,3 @@
+# import Xen virtual drive properties
+
+ACTION=="add|change", KERNEL=="xvd*[!0-9]", DRIVERS=="vbd", IMPORT{program}="xenvbd_id --export $tempnode"
diff --git a/extras/xenvbd_id/Makefile.am b/extras/xenvbd_id/Makefile.am
new file mode 100644
index 0000000..370db2b
--- /dev/null
+++ b/extras/xenvbd_id/Makefile.am
@@ -0,0 +1,19 @@
+include $(top_srcdir)/Makefile.am.inc
+
+udevhomedir = $(udev_prefix)/lib/udev
+udevhome_PROGRAMS = \
+	xenvbd_id
+
+udevrulesdir = $(udev_prefix)/lib/udev/rules.d
+dist_udevrules_DATA = \
+	60-xenvbd_id.rules
+
+xenvbd_id_SOURCES = \
+	xenvbd_id.c \
+	../../udev/lib/libudev.h \
+	../../udev/lib/libudev.c \
+	../../udev/lib/libudev-list.c \
+	../../udev/lib/libudev-util.c
+
+dist_man_MANS = \
+	xenvbd_id.8
diff --git a/extras/xenvbd_id/xenvbd_id.8 b/extras/xenvbd_id/xenvbd_id.8
new file mode 100644
index 0000000..420a412
--- /dev/null
+++ b/extras/xenvbd_id/xenvbd_id.8
@@ -0,0 +1,37 @@
+.TH XENVBD_ID 8 "January 2009" "" "Linux Administrator's Manual"
+.SH NAME
+xenvbd_id \- udev callout to determine the capabilities of Xen virtual
+block devices
+.SH SYNOPSIS
+.B xenvbd_id
+[\fB--export\fP] [\fB--debug\fP] \fIdevice\fP
+.br
+.B xenvbd_id
+\fB--help\fP
+.SH "DESCRIPTION"
+.B xenvbd_id
+is normally called from a udev rule, to provide udev with the list of
+capabilities of a Xen virtual block device.
+.SH USAGE
+.B xenvbd_id
+opens the device node specified at the commandline and prints the
+discovered capabilities.
+.SH OPTIONS
+The following commandline switches are supported to specify what xenvbd_id
+should print:
+.TP
+.B -x, --export
+Print all values as environment keys. This is the default at present, so this
+option is currently redundant.
+.TP
+.B -d, --debug
+Print a debug trace.
+.TP
+.B -h, --help
+Print usage help.
+.RE
+.SH SEE ALSO
+.BR udev (7)
+.SH AUTHORS
+Developed by Ian Campbell <ijc@xxxxxxxxxxxxxx> based on cdrom_id by Kay Sievers <kay.sievers@xxxxxxxx>.
+
diff --git a/extras/xenvbd_id/xenvbd_id.c b/extras/xenvbd_id/xenvbd_id.c
new file mode 100644
index 0000000..4dadf01
--- /dev/null
+++ b/extras/xenvbd_id/xenvbd_id.c
@@ -0,0 +1,227 @@
+/*
+ * xenvbd_id - optical drive and media information prober
+ *
+ * Copyright (C) 2009 Ian Campbell <ijc@xxxxxxxxxxxxxx>
+ * Copyright (C) 2008 Kay Sievers <kay.sievers@xxxxxxxx>
+ *
+ * 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/>.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <getopt.h>
+#include <scsi/sg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <linux/cdrom.h>
+
+#include "../../udev/udev.h"
+
+static 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);
+		vfprintf(stderr, format, args);
+	} else {
+		vsyslog(priority, format, args);
+	}
+}
+
+/* device info */
+static unsigned int cd_cd_rom;
+static unsigned int cd_cd_r;
+static unsigned int cd_cd_rw;
+static unsigned int cd_dvd_rom;
+static unsigned int cd_dvd_r;
+static unsigned int cd_dvd_rw;
+static unsigned int cd_dvd_ram;
+static unsigned int cd_dvd_plus_r;
+static unsigned int cd_dvd_plus_rw;
+static unsigned int cd_dvd_plus_r_dl;
+static unsigned int cd_dvd_plus_rw_dl;
+static unsigned int cd_bd;
+static unsigned int cd_bd_r;
+static unsigned int cd_bd_re;
+static unsigned int cd_hddvd;
+static unsigned int cd_hddvd_r;
+static unsigned int cd_hddvd_rw;
+static unsigned int cd_mo;
+static unsigned int cd_mrw;
+static unsigned int cd_mrw_w;
+
+static int cd_capability_compat(struct udev *udev, int fd)
+{
+	int capabilty;
+
+	capabilty = ioctl(fd, CDROM_GET_CAPABILITY, NULL);
+	if (capabilty < 0) {
+		info(udev, "CDROM_GET_CAPABILITY failed\n");
+		return -1;
+	}
+
+	if (capabilty & CDC_CD_R)
+		cd_cd_r = 1;
+	if (capabilty & CDC_CD_RW)
+		cd_cd_rw = 1;
+	if (capabilty & CDC_DVD)
+		cd_dvd_rom = 1;
+	if (capabilty & CDC_DVD_R)
+		cd_dvd_r = 1;
+	if (capabilty & CDC_DVD_RAM)
+		cd_dvd_ram = 1;
+	if (capabilty & CDC_MRW)
+		cd_mrw = 1;
+	if (capabilty & CDC_MRW_W)
+		cd_mrw_w = 1;
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	struct udev *udev;
+	static const struct option options[] = {
+		{ "export", no_argument, NULL, 'x' },
+		{ "debug", no_argument, NULL, 'd' },
+		{ "help", no_argument, NULL, 'h' },
+		{}
+	};
+	const char *node = NULL;
+	int export = 0;
+	int fd = -1;
+	int rc = 0;
+
+	udev = udev_new();
+	if (udev == NULL)
+		goto exit;
+
+	logging_init("xenvbd_id");
+	udev_set_log_fn(udev, log_fn);
+
+	while (1) {
+		int option;
+
+		option = getopt_long(argc, argv, "dxh", 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 'x':
+			export = 1;
+			break;
+		case 'h':
+			printf("Usage: xenvbd_id [options] <device>\n"
+			       "  --export        export key/value pairs\n"
+			       "  --debug         debug to stderr\n"
+			       "  --help          print this help text\n\n");
+			goto exit;
+		default:
+			rc = 1;
+			goto exit;
+		}
+	}
+
+	node = argv[optind];
+	if (!node) {
+		err(udev, "no device\n");
+		fprintf(stderr, "no device\n");
+		rc = 1;
+		goto exit;
+	}
+
+	fd = open(node, O_RDONLY | O_NONBLOCK);
+	if (fd < 0) {
+		info(udev, "unable to open '%s'\n", node);
+		rc = 1;
+		goto exit;
+	}
+	info(udev, "probing: '%s'\n", node);
+
+	/* same data as original cdrom_id */
+	if (cd_capability_compat(udev, fd) < 0) {
+		printf("ID_TYPE=disk\n");
+	} else {
+		printf("ID_TYPE=cd\n");
+		printf("ID_CDROM=1\n");
+
+		if (cd_cd_rom)
+			printf("ID_CDROM_CD=1\n");
+		if (cd_cd_r)
+			printf("ID_CDROM_CD_R=1\n");
+		if (cd_cd_rw)
+			printf("ID_CDROM_CD_RW=1\n");
+		if (cd_dvd_rom)
+			printf("ID_CDROM_DVD=1\n");
+		if (cd_dvd_r)
+			printf("ID_CDROM_DVD_R=1\n");
+		if (cd_dvd_rw)
+			printf("ID_CDROM_DVD_RW=1\n");
+		if (cd_dvd_ram)
+			printf("ID_CDROM_DVD_RAM=1\n");
+		if (cd_dvd_plus_r)
+			printf("ID_CDROM_DVD_PLUS_R=1\n");
+		if (cd_dvd_plus_rw)
+			printf("ID_CDROM_DVD_PLUS_RW=1\n");
+		if (cd_dvd_plus_r_dl)
+			printf("ID_CDROM_DVD_PLUS_R_DL=1\n");
+		if (cd_dvd_plus_rw_dl)
+			printf("ID_CDROM_DVD_PLUS_RW_DL=1\n");
+		if (cd_bd)
+			printf("ID_CDROM_BD=1\n");
+		if (cd_bd_r)
+			printf("ID_CDROM_BD_R=1\n");
+		if (cd_bd_re)
+			printf("ID_CDROM_BD_RE=1\n");
+		if (cd_hddvd)
+			printf("ID_CDROM_HDDVD=1\n");
+		if (cd_hddvd_r)
+			printf("ID_CDROM_HDDVD_R=1\n");
+		if (cd_hddvd_rw)
+			printf("ID_CDROM_HDDVD_RW=1\n");
+		if (cd_mo)
+			printf("ID_CDROM_MO=1\n");
+		if (cd_mrw)
+			printf("ID_CDROM_MRW=1\n");
+		if (cd_mrw_w)
+			printf("ID_CDROM_MRW_W=1\n");
+
+	}
+exit:
+	if (fd >= 0)
+		close(fd);
+	udev_unref(udev);
+	logging_close();
+	return rc;
+}
+
-- 
1.6.2.2


-- 
Ian Campbell

Consultation, n.:
	Medical term meaning "to share the wealth."

Attachment: signature.asc
Description: This is a digitally signed message part


[Index of Archives]     [Linux Kernel]     [Linux DVB]     [Asterisk Internet PBX]     [DCCP]     [Netdev]     [X.org]     [Util Linux NG]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux