From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ian Campbell Date: Thu, 16 Apr 2009 18:37:27 +0000 Subject: [PATCH] support identification of Xen virtual block devices Message-Id: <1239907047.15147.95.camel@localhost.localdomain> MIME-Version: 1 Content-Type: multipart/mixed; boundary="=-3PgMJvVGiaRRzR30/Srs" List-Id: To: linux-hotplug@vger.kernel.org --=-3PgMJvVGiaRRzR30/Srs Content-Type: text/plain Content-Transfer-Encoding: quoted-printable * 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_C= DROM (such as the Debian Installer) can correctly identify the disks. Signed-off-by: Ian Campbell --- 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 =20 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 =3D \ 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=3D0 } =20 +handle_xen () { + local DEV=3D$1 + cd -P $1 + vbd_id=3D${DEV##*/} + host_dev_path=3D$DEV + while [ ! -z "$host_dev_path" ] ; do + case "$host_dev_path" in + */vbd*) + host_dev_path=3D${host_dev_path%/*} + ;; + *) + break + ;; + esac + done + if [ "$d" ]; then + d=3D"xen-$vbd_id-$d" + else + d=3D"xen-$vbd_id" + fi + D=3D"$host_dev_path" + RESULT=3D0 +} + handle_serio () { local DEV=3D$1 cd -P $1 @@ -532,6 +556,9 @@ handle_device () { */platform/*) handle_platform "$D" ;; + */vbd-[0-9]*) + handle_xen "$D" + ;; */devices) D=3D ;; 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-xenv= bd_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=3D=3D"add|change", KERNEL=3D=3D"xvd*[!0-9]", DRIVERS=3D=3D"vbd", IM= PORT{program}=3D"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 =3D $(udev_prefix)/lib/udev +udevhome_PROGRAMS =3D \ + xenvbd_id + +udevrulesdir =3D $(udev_prefix)/lib/udev/rules.d +dist_udevrules_DATA =3D \ + 60-xenvbd_id.rules + +xenvbd_id_SOURCES =3D \ + xenvbd_id.c \ + ../../udev/lib/libudev.h \ + ../../udev/lib/libudev.c \ + ../../udev/lib/libudev-list.c \ + ../../udev/lib/libudev-util.c + +dist_man_MANS =3D \ + 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 t= his +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 based on cdrom_id by Kay Si= evers . + 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 + * Copyright (C) 2008 Kay Sievers + * + * 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 . + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 =3D 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 =3D 1; + if (capabilty & CDC_CD_RW) + cd_cd_rw =3D 1; + if (capabilty & CDC_DVD) + cd_dvd_rom =3D 1; + if (capabilty & CDC_DVD_R) + cd_dvd_r =3D 1; + if (capabilty & CDC_DVD_RAM) + cd_dvd_ram =3D 1; + if (capabilty & CDC_MRW) + cd_mrw =3D 1; + if (capabilty & CDC_MRW_W) + cd_mrw_w =3D 1; + return 0; +} + +int main(int argc, char *argv[]) +{ + struct udev *udev; + static const struct option options[] =3D { + { "export", no_argument, NULL, 'x' }, + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + {} + }; + const char *node =3D NULL; + int export =3D 0; + int fd =3D -1; + int rc =3D 0; + + udev =3D udev_new(); + if (udev =3D=3D NULL) + goto exit; + + logging_init("xenvbd_id"); + udev_set_log_fn(udev, log_fn); + + while (1) { + int option; + + option =3D getopt_long(argc, argv, "dxh", options, NULL); + if (option =3D=3D -1) + break; + + switch (option) { + case 'd': + debug =3D 1; + if (udev_get_log_priority(udev) < LOG_INFO) + udev_set_log_priority(udev, LOG_INFO); + break; + case 'x': + export =3D 1; + break; + case 'h': + printf("Usage: xenvbd_id [options] \n" + " --export export key/value pairs\n" + " --debug debug to stderr\n" + " --help print this help text\n\n"); + goto exit; + default: + rc =3D 1; + goto exit; + } + } + + node =3D argv[optind]; + if (!node) { + err(udev, "no device\n"); + fprintf(stderr, "no device\n"); + rc =3D 1; + goto exit; + } + + fd =3D open(node, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + info(udev, "unable to open '%s'\n", node); + rc =3D 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=3Ddisk\n"); + } else { + printf("ID_TYPE=3Dcd\n"); + printf("ID_CDROM=3D1\n"); + + if (cd_cd_rom) + printf("ID_CDROM_CD=3D1\n"); + if (cd_cd_r) + printf("ID_CDROM_CD_R=3D1\n"); + if (cd_cd_rw) + printf("ID_CDROM_CD_RW=3D1\n"); + if (cd_dvd_rom) + printf("ID_CDROM_DVD=3D1\n"); + if (cd_dvd_r) + printf("ID_CDROM_DVD_R=3D1\n"); + if (cd_dvd_rw) + printf("ID_CDROM_DVD_RW=3D1\n"); + if (cd_dvd_ram) + printf("ID_CDROM_DVD_RAM=3D1\n"); + if (cd_dvd_plus_r) + printf("ID_CDROM_DVD_PLUS_R=3D1\n"); + if (cd_dvd_plus_rw) + printf("ID_CDROM_DVD_PLUS_RW=3D1\n"); + if (cd_dvd_plus_r_dl) + printf("ID_CDROM_DVD_PLUS_R_DL=3D1\n"); + if (cd_dvd_plus_rw_dl) + printf("ID_CDROM_DVD_PLUS_RW_DL=3D1\n"); + if (cd_bd) + printf("ID_CDROM_BD=3D1\n"); + if (cd_bd_r) + printf("ID_CDROM_BD_R=3D1\n"); + if (cd_bd_re) + printf("ID_CDROM_BD_RE=3D1\n"); + if (cd_hddvd) + printf("ID_CDROM_HDDVD=3D1\n"); + if (cd_hddvd_r) + printf("ID_CDROM_HDDVD_R=3D1\n"); + if (cd_hddvd_rw) + printf("ID_CDROM_HDDVD_RW=3D1\n"); + if (cd_mo) + printf("ID_CDROM_MO=3D1\n"); + if (cd_mrw) + printf("ID_CDROM_MRW=3D1\n"); + if (cd_mrw_w) + printf("ID_CDROM_MRW_W=3D1\n"); + + } +exit: + if (fd >=3D 0) + close(fd); + udev_unref(udev); + logging_close(); + return rc; +} + --=20 1.6.2.2 --=20 Ian Campbell Consultation, n.: Medical term meaning "to share the wealth." --=-3PgMJvVGiaRRzR30/Srs Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEABECAAYFAknneuIACgkQM0+0qS9rzVkTWQCgkYe8j8mvq9skRTFWEkYBJUaS rlAAoNIBfUb6KcwPjBTFN5AeU2J8p8O3 =dCGq -----END PGP SIGNATURE----- --=-3PgMJvVGiaRRzR30/Srs--