summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--WHATS_NEW_DM1
-rw-r--r--libdm/.exported_symbols1
-rw-r--r--libdm/ioctl/libdm-compat.h1
-rw-r--r--libdm/ioctl/libdm-iface.c41
-rw-r--r--libdm/ioctl/libdm-targets.h1
-rw-r--r--libdm/libdevmapper.h5
-rw-r--r--libdm/libdm-common.c1
-rw-r--r--tools/dmsetup.c34
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}
};