From 5be55e0ba1919349bd5542a084318eee35ccad46 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Thu, 10 Jan 2002 23:29:14 +0000 Subject: [PATCH] Support the renaming of active mapped devices (ioctl interface only). --- VERSION | 2 +- kernel/common/dm.c.in | 32 +++++++++++++++++++++++++++++++- kernel/common/dm.h | 5 ++++- kernel/ioctl/dm-ioctl.c | 32 ++++++++++++++++++++++++++++---- kernel/ioctl/dm-ioctl.h.in | 1 + lib/ioctl/libdevmapper.c | 28 ++++++++++++++++++++++++++++ lib/ioctl/libdm-targets.h | 1 + lib/libdevmapper.h | 3 +++ 8 files changed, 97 insertions(+), 7 deletions(-) diff --git a/VERSION b/VERSION index c3d0f82..6f835a0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.91.02-cvs (2002-01-04) +0.92.00-cvs (2002-01-10) diff --git a/kernel/common/dm.c.in b/kernel/common/dm.c.in index 4cc4ece..59541aa 100644 --- a/kernel/common/dm.c.in +++ b/kernel/common/dm.c.in @@ -731,7 +731,7 @@ static struct mapped_device *__get_by_name(const char *name) static int __check_name(const char *name) { - if (strchr(name, '/')) { + if (strchr(name, '/') || strlen(name) > DM_NAME_LEN) { DMWARN("invalid device name"); return -1; } @@ -845,6 +845,36 @@ void dm_set_ro(struct mapped_device *md, int ro) dm_unlock_w(); } +/* + * Renames the device + */ +int dm_set_name(struct mapped_device *md, const char *newname) +{ + int r; + + dm_lock_w(); + + if (__check_name(newname) < 0) { + r = -EINVAL; + goto err; + } + + r = unregister_device(md); + if (r) + goto err; + + strcpy(md->name, newname); + + r = register_device(md); + if (r) + goto err; + + err: + dm_unlock_w(); + return r; +} + + /* * Requeue the deferred buffer_heads by calling generic_make_request. */ diff --git a/kernel/common/dm.h b/kernel/common/dm.h index 190ecd3..9882269 100644 --- a/kernel/common/dm.h +++ b/kernel/common/dm.h @@ -9,6 +9,7 @@ #ifndef DM_INTERNAL_H #define DM_INTERNAL_H + #include #include #include @@ -122,6 +123,7 @@ int dm_create(const char *name, int minor, struct dm_table *table, struct mapped_device **result); int dm_destroy(struct mapped_device *md); void dm_set_ro(struct mapped_device *md, int ro); +int dm_set_name(struct mapped_device *md, const char *newname); /* * The device must be suspended before calling this method. @@ -173,10 +175,11 @@ void dm_interface_exit(void); /* * Targets for linear and striped mappings */ + int dm_linear_init(void); void dm_linear_exit(void); + int dm_stripe_init(void); void dm_stripe_exit(void); - #endif diff --git a/kernel/ioctl/dm-ioctl.c b/kernel/ioctl/dm-ioctl.c index 7b2cd67..7fe167c 100644 --- a/kernel/ioctl/dm-ioctl.c +++ b/kernel/ioctl/dm-ioctl.c @@ -33,8 +33,9 @@ static int copy_params(struct dm_ioctl *user, struct dm_ioctl **result) } /* - * check a string doesn't overrun the chunk of + * Check a string doesn't overrun the chunk of * memory we copied from userland. + * Returns 1 if OK. */ static int valid_str(char *str, void *begin, void *end) { @@ -50,7 +51,7 @@ static int first_target(struct dm_ioctl *a, void *begin, void *end, *spec = (struct dm_target_spec *) (a + 1); *params = (char *) (*spec + 1); - return valid_str(*params, begin, end); + return !valid_str(*params, begin, end); } static int next_target(struct dm_target_spec *last, void *begin, void *end, @@ -60,7 +61,7 @@ static int next_target(struct dm_target_spec *last, void *begin, void *end, (((unsigned char *) last) + last->next); *params = (char *) (*spec + 1); - return valid_str(*params, begin, end); + return !valid_str(*params, begin, end); } void dm_error(const char *message) @@ -107,7 +108,7 @@ static int populate_table(struct dm_table *table, struct dm_ioctl *args) r = first ? first_target(args, begin, end, &spec, ¶ms) : next_target(spec, begin, end, &spec, ¶ms); - if (!r) + if (r) PARSE_ERROR("unable to find target"); /* Look up the target type */ @@ -259,6 +260,25 @@ static int reload(struct dm_ioctl *param) return r; } +static int rename(struct dm_ioctl *param) +{ + char *newname = (char *) (param + 1); + struct mapped_device *md = dm_get(param->name); + + if (!md) + return -ENXIO; + + if (!valid_str(newname, (void *)param, + (void *)param + param->data_size) || + dm_set_name(md, newname)) { + dm_error("Invalid new logical volume name supplied."); + return -EINVAL; + } + + dm_put(md); + return 0; +} + static int ctl_open(struct inode *inode, struct file *file) { /* only root can open this */ @@ -312,6 +332,10 @@ static int ctl_ioctl(struct inode *inode, struct file *file, r = info(p->name, (struct dm_ioctl *) a); break; + case DM_RENAME: + r = rename(p); + break; + default: DMWARN("dm_ctl_ioctl: unknown command 0x%x", command); r = -EINVAL; diff --git a/kernel/ioctl/dm-ioctl.h.in b/kernel/ioctl/dm-ioctl.h.in index b3b4c87..20ebcae 100644 --- a/kernel/ioctl/dm-ioctl.h.in +++ b/kernel/ioctl/dm-ioctl.h.in @@ -52,6 +52,7 @@ struct dm_ioctl { #define DM_SUSPEND _IOW(DM_IOCTL, 0x02, struct dm_ioctl) #define DM_RELOAD _IOWR(DM_IOCTL, 0x03, struct dm_ioctl) #define DM_INFO _IOWR(DM_IOCTL, 0x04, struct dm_ioctl) +#define DM_RENAME _IOWR(DM_IOCTL, 0x05, struct dm_ioctl) #define DM_IOCTL_VERSION @DM_IOCTL_VERSION@ diff --git a/lib/ioctl/libdevmapper.c b/lib/ioctl/libdevmapper.c index ad00554..0d39c93 100644 --- a/lib/ioctl/libdevmapper.c +++ b/lib/ioctl/libdevmapper.c @@ -35,6 +35,9 @@ void dm_task_destroy(struct dm_task *dmt) free(t); } + if (dmt->newname) + free(dmt->newname); + if (dmt->dmi) free(dmt->dmi); @@ -62,6 +65,16 @@ int dm_task_set_ro(struct dm_task *dmt) return 1; } +int dm_task_set_newname(struct dm_task *dmt, const char *newname) +{ + if (!(dmt->newname = strdup(newname))) { + log("dm_task_set_newname: strdup(%s) failed", newname); + return 0; + } + + return 1; +} + struct target *create_target(uint64_t start, uint64_t len, const char *type, const char *params) @@ -154,6 +167,14 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt) count++; } + if (count && dmt->newname) { + log("targets and newname are incompatible"); + return NULL; + } + + if (dmt->newname) + len += strlen(dmt->newname) + 1; + if (!(dmi = malloc(len))) return NULL; @@ -176,6 +197,9 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt) if (!(b = _add_target(t, b, e))) goto bad; + if (dmt->newname) + strcpy(b, dmt->newname); + return dmi; bad: @@ -227,6 +251,10 @@ int dm_task_run(struct dm_task *dmt) command = DM_INFO; break; + case DM_DEVICE_RENAME: + command = DM_RENAME; + break; + default: log("Internal error: unknown device-mapper task %d", dmt->type); diff --git a/lib/ioctl/libdm-targets.h b/lib/ioctl/libdm-targets.h index 72906c3..9243366 100644 --- a/lib/ioctl/libdm-targets.h +++ b/lib/ioctl/libdm-targets.h @@ -21,5 +21,6 @@ struct dm_task { int read_only; struct dm_ioctl *dmi; + char *newname; }; diff --git a/lib/libdevmapper.h b/lib/libdevmapper.h index a8dd6c7..67ddba8 100644 --- a/lib/libdevmapper.h +++ b/lib/libdevmapper.h @@ -38,6 +38,7 @@ enum { DM_DEVICE_RESUME, DM_DEVICE_INFO, + DM_DEVICE_RENAME, }; @@ -66,6 +67,8 @@ int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi); int dm_task_set_ro(struct dm_task *dmt); +int dm_task_set_newname(struct dm_task *dmt, const char *newname); + /* * Use these to prepare for a create or reload. */ -- 2.43.5