diff options
-rw-r--r-- | WHATS_NEW_DM | 1 | ||||
-rw-r--r-- | libdm/.exported_symbols | 1 | ||||
-rw-r--r-- | libdm/ioctl/libdm-compat.h | 1 | ||||
-rw-r--r-- | libdm/ioctl/libdm-iface.c | 41 | ||||
-rw-r--r-- | libdm/ioctl/libdm-targets.h | 1 | ||||
-rw-r--r-- | libdm/libdevmapper.h | 5 | ||||
-rw-r--r-- | libdm/libdm-common.c | 1 | ||||
-rw-r--r-- | tools/dmsetup.c | 34 |
8 files changed, 84 insertions, 1 deletions
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index 53634e3ad..a1695b2f3 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -1,5 +1,6 @@ Version 1.02.04 - ============================ + Add setgeometry. Version 1.02.03 - 7 Feb 2006 ============================ diff --git a/libdm/.exported_symbols b/libdm/.exported_symbols index 9b398f207..2407f0ab6 100644 --- a/libdm/.exported_symbols +++ b/libdm/.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/libdm/ioctl/libdm-compat.h b/libdm/ioctl/libdm-compat.h index 4c06e7f3a..7a7e75237 100644 --- a/libdm/ioctl/libdm-compat.h +++ b/libdm/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/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c index 31359b976..4cb49a682 100644 --- a/libdm/ioctl/libdm-iface.c +++ b/libdm/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/libdm/ioctl/libdm-targets.h b/libdm/ioctl/libdm-targets.h index 4eea595d4..b850d9971 100644 --- a/libdm/ioctl/libdm-targets.h +++ b/libdm/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/libdm/libdevmapper.h b/libdm/libdevmapper.h index 543cb7d43..68359a4fe 100644 --- a/libdm/libdevmapper.h +++ b/libdm/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/libdm/libdm-common.c b/libdm/libdm-common.c index c27c077e9..0b2e3c24a 100644 --- a/libdm/libdm-common.c +++ b/libdm/libdm-common.c @@ -510,3 +510,4 @@ out: dm_task_destroy(dmt); return r; } + diff --git a/tools/dmsetup.c b/tools/dmsetup.c index 60421f868..7d37c3c9d 100644 --- a/tools/dmsetup.c +++ b/tools/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", "[<device>]", 0, 1, _mknodes}, {"targets", "", 0, 0, _targets}, {"version", "", 0, 0, _version}, + {"setgeometry", "<device> <cyl> <head> <sect> <start>", 5, 5, _setgeometry}, {NULL, NULL, 0, 0, NULL} }; |