From a3943792ea54cec61140e38d6819da311acaa1e5 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Fri, 23 Jan 2004 14:37:45 +0000 Subject: [PATCH] Userspace support for LIST_VERSIONS ioctl. --- VERSION | 2 +- dmsetup/dmsetup.c | 37 ++++++++++++++++++++++++++++++++++++- kernel/ioctl/dm-ioctl.h | 3 +++ lib/.export.sym | 1 + lib/ioctl/libdevmapper.c | 11 +++++++++++ lib/ioctl/libdm-compat.h | 33 +++++++++++++++++---------------- lib/libdevmapper.h | 12 +++++++++++- 7 files changed, 80 insertions(+), 19 deletions(-) diff --git a/VERSION b/VERSION index 812bd23..01d78c2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.00.07-cvs (2003-11-21) +1.00.07-cvs (2004-01-23) diff --git a/dmsetup/dmsetup.c b/dmsetup/dmsetup.c index b8ed05d..a51dac3 100644 --- a/dmsetup/dmsetup.c +++ b/dmsetup/dmsetup.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Sistina Software (UK) Limited. + * Copyright (C) 2001-2003 Sistina Software (UK) Limited. * * This file is released under the GPL. */ @@ -462,6 +462,40 @@ static int _status(int argc, char **argv, void *data) } +/* Show target names and their version numbers */ +static int _targets(int argc, char **argv, void *data) +{ + int r = 0; + struct dm_task *dmt; + struct dm_versions *target; + struct dm_versions *last_target; + + if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS))) + return 0; + + if (!dm_task_run(dmt)) + goto out; + + target = dm_task_get_versions(dmt); + + /* Fetch targets and print 'em */ + do { + last_target = target; + + printf("%-16s v%d.%d.%d\n", target->name, target->version[0], + target->version[1], target->version[2]); + + target = (void *) target + target->next; + } while (last_target != target); + + r = 1; + + out: + dm_task_destroy(dmt); + return r; + +} + static int _info(int argc, char **argv, void *data) { int r = 0; @@ -611,6 +645,7 @@ static struct command _commands[] = { {"status", "[]", 0, 1, _status}, {"table", "[]", 0, 1, _status}, {"wait", " []", 1, 2, _wait}, + {"targets", "", 0, 0, _targets}, {"version", "", 0, 0, _version}, {NULL, NULL, 0, 0, NULL} }; diff --git a/kernel/ioctl/dm-ioctl.h b/kernel/ioctl/dm-ioctl.h index 7487d36..0dc85fc 100644 --- a/kernel/ioctl/dm-ioctl.h +++ b/kernel/ioctl/dm-ioctl.h @@ -185,6 +185,8 @@ enum { DM_TABLE_CLEAR_CMD, DM_TABLE_DEPS_CMD, DM_TABLE_STATUS_CMD, + + DM_LIST_VERSIONS_CMD, }; #define DM_IOCTL 0xfd @@ -192,6 +194,7 @@ enum { #define DM_VERSION _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl) #define DM_REMOVE_ALL _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, struct dm_ioctl) #define DM_LIST_DEVICES _IOWR(DM_IOCTL, DM_LIST_DEVICES_CMD, struct dm_ioctl) +#define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl) #define DM_DEV_CREATE _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, struct dm_ioctl) #define DM_DEV_REMOVE _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, struct dm_ioctl) diff --git a/lib/.export.sym b/lib/.export.sym index 0399e6e..1c5b956 100644 --- a/lib/.export.sym +++ b/lib/.export.sym @@ -12,6 +12,7 @@ Base { dm_task_get_deps; dm_task_get_name; dm_task_get_names; + dm_task_get_versions; dm_task_get_uuid; dm_task_set_ro; dm_task_set_newname; diff --git a/lib/ioctl/libdevmapper.c b/lib/ioctl/libdevmapper.c index ac7ba0c..10bcba6 100644 --- a/lib/ioctl/libdevmapper.c +++ b/lib/ioctl/libdevmapper.c @@ -80,6 +80,7 @@ static struct cmd_data _cmd_data_v4[] = { {"names", DM_LIST_DEVICES, {4, 0, 0}}, {"clear", DM_TABLE_CLEAR, {4, 0, 0}}, {"mknodes", DM_DEV_STATUS, {4, 0, 0}}, + {"versions", DM_LIST_VERSIONS, {4, 1, 0}}, }; /* *INDENT-ON* */ @@ -384,6 +385,10 @@ static int _dm_names_v1(struct dm_ioctl_v1 *dmi) struct stat buf; char path[PATH_MAX]; + log_print("Warning: Device list may be incomplete with interface " + "version 1."); + log_print("Please upgrade your kernel device-mapper driver."); + if (!(d = opendir(dev_dir))) { log_error("%s: opendir failed: %s", dev_dir, strerror(errno)); return 0; @@ -736,6 +741,12 @@ struct dm_names *dm_task_get_names(struct dm_task *dmt) dmt->dmi.v4->data_start); } +struct dm_versions *dm_task_get_versions(struct dm_task *dmt) +{ + return (struct dm_versions *) (((void *) dmt->dmi.v4) + + dmt->dmi.v4->data_start); +} + int dm_task_set_ro(struct dm_task *dmt) { dmt->read_only = 1; diff --git a/lib/ioctl/libdm-compat.h b/lib/ioctl/libdm-compat.h index af7a9f1..bf16bb8 100644 --- a/lib/ioctl/libdm-compat.h +++ b/lib/ioctl/libdm-compat.h @@ -89,22 +89,23 @@ enum { /* *INDENT-OFF* */ static struct cmd_data _cmd_data_v1[] = { - { "create", DM_DEV_CREATE_V1, {1, 0, 0} }, - { "reload", DM_DEV_RELOAD_V1, {1, 0, 0} }, - { "remove", DM_DEV_REMOVE_V1, {1, 0, 0} }, - { "remove_all", DM_REMOVE_ALL_V1, {1, 0, 0} }, - { "suspend", DM_DEV_SUSPEND_V1, {1, 0, 0} }, - { "resume", DM_DEV_SUSPEND_V1, {1, 0, 0} }, - { "info", DM_DEV_STATUS_V1, {1, 0, 0} }, - { "deps", DM_DEV_DEPS_V1, {1, 0, 0} }, - { "rename", DM_DEV_RENAME_V1, {1, 0, 0} }, - { "version", DM_VERSION_V1, {1, 0, 0} }, - { "status", DM_TARGET_STATUS_V1, {1, 0, 0} }, - { "table", DM_TARGET_STATUS_V1, {1, 0, 0} }, - { "waitevent", DM_TARGET_WAIT_V1, {1, 0, 0} }, - { "names", 0, {4, 0, 0} }, - { "clear", 0, {4, 0, 0} }, - { "mknodes", 0, {4, 0, 0} }, + { "create", DM_DEV_CREATE_V1, {1, 0, 0} }, + { "reload", DM_DEV_RELOAD_V1, {1, 0, 0} }, + { "remove", DM_DEV_REMOVE_V1, {1, 0, 0} }, + { "remove_all", DM_REMOVE_ALL_V1, {1, 0, 0} }, + { "suspend", DM_DEV_SUSPEND_V1, {1, 0, 0} }, + { "resume", DM_DEV_SUSPEND_V1, {1, 0, 0} }, + { "info", DM_DEV_STATUS_V1, {1, 0, 0} }, + { "deps", DM_DEV_DEPS_V1, {1, 0, 0} }, + { "rename", DM_DEV_RENAME_V1, {1, 0, 0} }, + { "version", DM_VERSION_V1, {1, 0, 0} }, + { "status", DM_TARGET_STATUS_V1, {1, 0, 0} }, + { "table", DM_TARGET_STATUS_V1, {1, 0, 0} }, + { "waitevent", DM_TARGET_WAIT_V1, {1, 0, 0} }, + { "names", 0, {4, 0, 0} }, + { "clear", 0, {4, 0, 0} }, + { "mknodes", 0, {4, 0, 0} }, + { "versions", 0, {4, 1, 0} }, }; /* *INDENT-ON* */ diff --git a/lib/libdevmapper.h b/lib/libdevmapper.h index 42ef16a..87038c3 100644 --- a/lib/libdevmapper.h +++ b/lib/libdevmapper.h @@ -57,7 +57,9 @@ enum { DM_DEVICE_CLEAR, - DM_DEVICE_MKNODES + DM_DEVICE_MKNODES, + + DM_DEVICE_LIST_VERSIONS }; struct dm_task; @@ -97,6 +99,13 @@ struct dm_names { char name[0]; }; +struct dm_versions { + uint32_t next; /* Offset to next struct from start of this struct */ + uint32_t version[3]; + + char name[0]; +}; + int dm_get_library_version(char *version, size_t size); int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size); int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi); @@ -105,6 +114,7 @@ const char *dm_task_get_uuid(struct dm_task *dmt); struct dm_deps *dm_task_get_deps(struct dm_task *dmt); struct dm_names *dm_task_get_names(struct dm_task *dmt); +struct dm_versions *dm_task_get_versions(struct dm_task *dmt); int dm_task_set_ro(struct dm_task *dmt); int dm_task_set_newname(struct dm_task *dmt, const char *newname); -- 2.43.5