From 4c6b8e41e85ee2884ff643501115b8e824910f9e Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Mon, 20 Feb 2006 23:55:57 +0000 Subject: [PATCH] A setgeometry implementation. [untested] --- WHATS_NEW | 1 + dmsetup/dmsetup.c | 34 ++++++++++++++++ kernel/ioctl/dm-ioctl.h | 82 +++++++++++++++++++++++---------------- lib/.exported_symbols | 1 + lib/ioctl/libdm-compat.h | 1 + lib/ioctl/libdm-iface.c | 41 ++++++++++++++++++++ lib/ioctl/libdm-targets.h | 1 + lib/libdevmapper.h | 5 ++- lib/libdm-common.c | 1 + 9 files changed, 132 insertions(+), 35 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 53634e3..a1695b2 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 1.02.04 - ============================ + Add setgeometry. Version 1.02.03 - 7 Feb 2006 ============================ diff --git a/dmsetup/dmsetup.c b/dmsetup/dmsetup.c index 60421f8..7d37c3c 100644 --- a/dmsetup/dmsetup.c +++ b/dmsetup/dmsetup.c @@ -508,6 +508,39 @@ static int _message(int argc, char **argv, void *data) return r; } +static int _setgeometry(int argc, char **argv, void *data) +{ + int r = 0; + struct dm_task *dmt; + + if (!(dmt = dm_task_create(DM_DEVICE_SET_GEOMETRY))) + return 0; + + if (_switches[UUID_ARG] || _switches[MAJOR_ARG]) { + if (!_set_task_device(dmt, NULL, 0)) + goto out; + } else { + if (!_set_task_device(dmt, argv[1], 0)) + goto out; + argc--; + argv++; + } + + if (!dm_task_set_geometry(dmt, argv[1], argv[2], argv[3], argv[4])) + goto out; + + /* run the task */ + if (!dm_task_run(dmt)) + goto out; + + r = 1; + + out: + dm_task_destroy(dmt); + + return r; +} + static int _version(int argc, char **argv, void *data) { char version[80]; @@ -1326,6 +1359,7 @@ static struct command _commands[] = { {"mknodes", "[]", 0, 1, _mknodes}, {"targets", "", 0, 0, _targets}, {"version", "", 0, 0, _version}, + {"setgeometry", " ", 5, 5, _setgeometry}, {NULL, NULL, 0, 0, NULL} }; diff --git a/kernel/ioctl/dm-ioctl.h b/kernel/ioctl/dm-ioctl.h index 0d5bdab..472893b 100644 --- a/kernel/ioctl/dm-ioctl.h +++ b/kernel/ioctl/dm-ioctl.h @@ -82,6 +82,17 @@ * * DM_TARGET_MSG: * Pass a message string to the target at a specific offset of a device. + * + * DM_DEV_SET_GEOMETRY: + * Set the geometry of a device by passing in a string. The + * string should have this format: + * + * "cylinders heads sectors_per_track start_sector" + * + * Beware that CHS geometry is nearly obsolete and only provided + * for compatibility with dm devices that can be booted by a PC + * BIOS. See struct hd_geometry for range limits. Also note that + * the geometry is erased if the device size changes. */ /* @@ -220,6 +231,7 @@ enum { /* Added later */ DM_LIST_VERSIONS_CMD, DM_TARGET_MSG_CMD, + DM_DEV_SET_GEOMETRY_CMD }; /* @@ -232,51 +244,53 @@ enum { */ #ifdef CONFIG_COMPAT typedef char ioctl_struct[308]; -#define DM_VERSION_32 _IOWR(DM_IOCTL, DM_VERSION_CMD, ioctl_struct) -#define DM_REMOVE_ALL_32 _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, ioctl_struct) -#define DM_LIST_DEVICES_32 _IOWR(DM_IOCTL, DM_LIST_DEVICES_CMD, ioctl_struct) - -#define DM_DEV_CREATE_32 _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, ioctl_struct) -#define DM_DEV_REMOVE_32 _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, ioctl_struct) -#define DM_DEV_RENAME_32 _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, ioctl_struct) -#define DM_DEV_SUSPEND_32 _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, ioctl_struct) -#define DM_DEV_STATUS_32 _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, ioctl_struct) -#define DM_DEV_WAIT_32 _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, ioctl_struct) - -#define DM_TABLE_LOAD_32 _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, ioctl_struct) -#define DM_TABLE_CLEAR_32 _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, ioctl_struct) -#define DM_TABLE_DEPS_32 _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, ioctl_struct) -#define DM_TABLE_STATUS_32 _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, ioctl_struct) -#define DM_LIST_VERSIONS_32 _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, ioctl_struct) -#define DM_TARGET_MSG_32 _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, ioctl_struct) +#define DM_VERSION_32 _IOWR(DM_IOCTL, DM_VERSION_CMD, ioctl_struct) +#define DM_REMOVE_ALL_32 _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, ioctl_struct) +#define DM_LIST_DEVICES_32 _IOWR(DM_IOCTL, DM_LIST_DEVICES_CMD, ioctl_struct) + +#define DM_DEV_CREATE_32 _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, ioctl_struct) +#define DM_DEV_REMOVE_32 _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, ioctl_struct) +#define DM_DEV_RENAME_32 _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, ioctl_struct) +#define DM_DEV_SUSPEND_32 _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, ioctl_struct) +#define DM_DEV_STATUS_32 _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, ioctl_struct) +#define DM_DEV_WAIT_32 _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, ioctl_struct) + +#define DM_TABLE_LOAD_32 _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, ioctl_struct) +#define DM_TABLE_CLEAR_32 _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, ioctl_struct) +#define DM_TABLE_DEPS_32 _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, ioctl_struct) +#define DM_TABLE_STATUS_32 _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, ioctl_struct) +#define DM_LIST_VERSIONS_32 _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, ioctl_struct) +#define DM_TARGET_MSG_32 _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, ioctl_struct) +#define DM_DEV_SET_GEOMETRY_32 _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, ioctl_struct) #endif #define DM_IOCTL 0xfd -#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_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_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) -#define DM_DEV_RENAME _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl) -#define DM_DEV_SUSPEND _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl) -#define DM_DEV_STATUS _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl) -#define DM_DEV_WAIT _IOWR(DM_IOCTL, DM_DEV_WAIT_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) +#define DM_DEV_RENAME _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl) +#define DM_DEV_SUSPEND _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl) +#define DM_DEV_STATUS _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl) +#define DM_DEV_WAIT _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, struct dm_ioctl) -#define DM_TABLE_LOAD _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl) -#define DM_TABLE_CLEAR _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl) -#define DM_TABLE_DEPS _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl) -#define DM_TABLE_STATUS _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, struct dm_ioctl) +#define DM_TABLE_LOAD _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl) +#define DM_TABLE_CLEAR _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl) +#define DM_TABLE_DEPS _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl) +#define DM_TABLE_STATUS _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, struct dm_ioctl) -#define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl) +#define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl) -#define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl) +#define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl) +#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) #define DM_VERSION_MAJOR 4 -#define DM_VERSION_MINOR 5 +#define DM_VERSION_MINOR 6 #define DM_VERSION_PATCHLEVEL 0 -#define DM_VERSION_EXTRA "-ioctl (2005-10-04)" +#define DM_VERSION_EXTRA "-ioctl (2006-02-17)" /* Status bits */ #define DM_READONLY_FLAG (1 << 0) /* In/Out */ diff --git a/lib/.exported_symbols b/lib/.exported_symbols index 9b398f2..2407f0a 100644 --- a/lib/.exported_symbols +++ b/lib/.exported_symbols @@ -108,3 +108,4 @@ dm_hash_get_data dm_hash_get_first dm_hash_get_next dm_set_selinux_context +dm_task_set_geometry diff --git a/lib/ioctl/libdm-compat.h b/lib/ioctl/libdm-compat.h index 4c06e7f..7a7e752 100644 --- a/lib/ioctl/libdm-compat.h +++ b/lib/ioctl/libdm-compat.h @@ -116,6 +116,7 @@ static struct cmd_data _cmd_data_v1[] = { { "mknodes", 0, {4, 0, 0} }, { "versions", 0, {4, 1, 0} }, { "message", 0, {4, 2, 0} }, + { "setgeometry",0, {4, 6, 0} }, }; /* *INDENT-ON* */ diff --git a/lib/ioctl/libdm-iface.c b/lib/ioctl/libdm-iface.c index 31359b9..4cb49a6 100644 --- a/lib/ioctl/libdm-iface.c +++ b/lib/ioctl/libdm-iface.c @@ -103,6 +103,9 @@ static struct cmd_data _cmd_data_v4[] = { #ifdef DM_TARGET_MSG {"message", DM_TARGET_MSG, {4, 2, 0}}, #endif +#ifdef DM_DEV_SET_GEOMETRY + {"setgeometry", DM_DEV_SET_GEOMETRY, {4, 6, 0}}, +#endif }; /* *INDENT-ON* */ @@ -1001,6 +1004,23 @@ int dm_task_set_sector(struct dm_task *dmt, uint64_t sector) return 1; } +int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads, const char *sectors, const char *start) +{ + size_t len = strlen(cylinders) + 1 + strlen(heads) + 1 + strlen(sectors) + 1 + strlen(start) + 1; + + if (!(dmt->geometry = dm_malloc(len))) { + log_error("dm_task_set_geometry: dm_malloc failed"); + return 0; + } + + if (sprintf(dmt->geometry, "%s %s %s %s", cylinders, heads, sectors, start) < 0) { + log_error("dm_task_set_geometry: sprintf failed"); + return 0; + } + + return 1; +} + int dm_task_no_open_count(struct dm_task *dmt) { dmt->no_open_count = 1; @@ -1123,11 +1143,26 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count) return NULL; } + if (count && dmt->geometry) { + log_error("targets and geometry are incompatible"); + return NULL; + } + if (dmt->newname && (dmt->sector || dmt->message)) { log_error("message and newname are incompatible"); return NULL; } + if (dmt->newname && dmt->geometry) { + log_error("geometry and newname are incompatible"); + return NULL; + } + + if (dmt->geometry && (dmt->sector || dmt->message)) { + log_error("geometry and message are incompatible"); + return NULL; + } + if (dmt->sector && !dmt->message) { log_error("message is required with sector"); return NULL; @@ -1139,6 +1174,9 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count) if (dmt->message) len += sizeof(struct dm_target_msg) + strlen(dmt->message) + 1; + if (dmt->geometry) + len += strlen(dmt->geometry) + 1; + /* * Give len a minimum size so that we have space to store * dependencies or status information. @@ -1205,6 +1243,9 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count) strcpy(tmsg->message, dmt->message); } + if (dmt->geometry) + strcpy(b, dmt->geometry); + return dmi; bad: diff --git a/lib/ioctl/libdm-targets.h b/lib/ioctl/libdm-targets.h index 4eea595..b850d99 100644 --- a/lib/ioctl/libdm-targets.h +++ b/lib/ioctl/libdm-targets.h @@ -50,6 +50,7 @@ struct dm_task { } dmi; char *newname; char *message; + char *geometry; uint64_t sector; int no_open_count; int skip_lockfs; diff --git a/lib/libdevmapper.h b/lib/libdevmapper.h index 543cb7d..68359a4 100644 --- a/lib/libdevmapper.h +++ b/lib/libdevmapper.h @@ -80,7 +80,9 @@ enum { DM_DEVICE_LIST_VERSIONS, - DM_DEVICE_TARGET_MSG + DM_DEVICE_TARGET_MSG, + + DM_DEVICE_SET_GEOMETRY }; struct dm_task; @@ -145,6 +147,7 @@ int dm_task_set_uid(struct dm_task *dmt, uid_t uid); int dm_task_set_gid(struct dm_task *dmt, gid_t gid); int dm_task_set_mode(struct dm_task *dmt, mode_t mode); int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr); +int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads, const char *sectors, const char *start); int dm_task_set_message(struct dm_task *dmt, const char *message); int dm_task_set_sector(struct dm_task *dmt, uint64_t sector); int dm_task_no_open_count(struct dm_task *dmt); diff --git a/lib/libdm-common.c b/lib/libdm-common.c index c27c077..0b2e3c2 100644 --- a/lib/libdm-common.c +++ b/lib/libdm-common.c @@ -510,3 +510,4 @@ out: dm_task_destroy(dmt); return r; } + -- 2.43.5