master - libdm: update DM_ABORT_ON_INTERNAL_ERRORS
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=16c1dacb6e98c8...
Commit: 16c1dacb6e98c8b49462a7ca9f98687c0affe498
Parent: 139a62fc0bbe45318c7ca25cd8ee2dc990c95a9d
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Aug 6 15:22:26 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Aug 6 16:19:31 2013 +0200
libdm: update DM_ABORT_ON_INTERNAL_ERRORS
Update behavior to disable aborting when macro is unset
or its set to 0. In other cases it will abort.
i.e. set to anything....
---
libdm/libdm-common.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c
index de4b747..2e068dc 100644
--- a/libdm/libdm-common.c
+++ b/libdm/libdm-common.c
@@ -127,9 +127,9 @@ static void _default_log_line(int level,
}
if (_abort_on_internal_errors < 0)
- /* Set when env DM_ABORT_ON_INTERNAL_ERRORS is 1 */
+ /* Set when env DM_ABORT_ON_INTERNAL_ERRORS is not "0" */
_abort_on_internal_errors =
- !strcmp(getenv("DM_ABORT_ON_INTERNAL_ERRORS") ? : "0", "1");
+ strcmp(getenv("DM_ABORT_ON_INTERNAL_ERRORS") ? : "0", "0");
if (_abort_on_internal_errors &&
!strncmp(f, INTERNAL_ERROR, sizeof(INTERNAL_ERROR) - 1))
10 years, 8 months
master - thin: use pipe_open instead of popen
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=139a62fc0bbe45...
Commit: 139a62fc0bbe45318c7ca25cd8ee2dc990c95a9d
Parent: f6dd5a294b9beaf1d3ef68385eeeb8d55ec3a344
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Aug 6 15:21:42 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Aug 6 16:19:31 2013 +0200
thin: use pipe_open instead of popen
Use new function to directly exec command and read its output.
---
tools/lvconvert.c | 24 +++++++++++++++---------
1 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index f008954..5d796e7 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -1968,6 +1968,7 @@ static int _lvconvert_thinpool_repair(struct cmd_context *cmd,
uint64_t trans_id;
struct logical_volume *pmslv;
struct logical_volume *mlv = first_seg(pool_lv)->metadata_lv;
+ struct pipe_data pdata;
FILE *f;
if (!thin_repair[0]) {
@@ -1975,11 +1976,17 @@ static int _lvconvert_thinpool_repair(struct cmd_context *cmd,
return 0; /* Checking disabled */
}
+ pmslv = pool_lv->vg->pool_metadata_spare_lv;
+
/* Check we have pool metadata spare LV */
if (!handle_pool_metadata_spare(pool_lv->vg, 0, NULL, 1))
return_0;
- pmslv = pool_lv->vg->pool_metadata_spare_lv;
+ if (pmslv != pool_lv->vg->pool_metadata_spare_lv) {
+ if (!vg_write(pool_lv->vg) || !vg_commit(pool_lv->vg))
+ return_0;
+ pmslv = pool_lv->vg->pool_metadata_spare_lv;
+ }
if (!(dm_name = dm_build_dm_name(cmd->mem, mlv->vg->name,
mlv->name, NULL)) ||
@@ -2050,13 +2057,12 @@ static int _lvconvert_thinpool_repair(struct cmd_context *cmd,
}
if (thin_dump[0]) {
- if (dm_snprintf(meta_path, sizeof(meta_path), "%s %s", thin_dump, pms_path) < 0) {
- log_error("Command cannot fit into buffer.");
- goto deactivate_mlv;
- }
+ argv[0] = thin_dump;
+ argv[1] = pms_path;
+ argv[2] = NULL;
- if (!(f = popen(meta_path, "r")))
- log_warn("WARNING: Cannot read output from %s.", meta_path);
+ if (!(f = pipe_open(cmd, argv, 0, &pdata)))
+ log_warn("WARNING: Cannot read output from %s %s.", thin_dump, pms_path);
else {
/*
* Scan only the 1st. line for transation id.
@@ -2073,8 +2079,8 @@ static int _lvconvert_thinpool_repair(struct cmd_context *cmd,
first_seg(pool_lv)->transaction_id,
pool_lv->vg->name, pool_lv->name, trans_id,
pms_path);
- if (pclose(f))
- log_sys_error("popen", thin_dump);
+
+ (void) pipe_close(&pdata); /* killing pipe */
}
}
10 years, 8 months
master - exec: pipe open
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f6dd5a294b9bea...
Commit: f6dd5a294b9beaf1d3ef68385eeeb8d55ec3a344
Parent: b6437a61806bdec29951eb80616db121c4ec4eff
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Aug 6 14:27:37 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Aug 6 16:18:43 2013 +0200
exec: pipe open
Function replaces popen() system and avoids shell execution
and argument parsing (no surprices).
---
WHATS_NEW | 1 +
lib/misc/lvm-exec.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++
lib/misc/lvm-exec.h | 30 +++++++++++++++
3 files changed, 130 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 5baa00d..5284145 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.100 -
================================
+ Add pipe_open/close() to replace less secure popen() glibc call.
Fix metadata area offset/size overflow if it's >= 4g and while using lvmetad.
Inherit and apply any profile attached to a VG if creating new thin pool.
Add initial support thin pool lvconvert --repair.
diff --git a/lib/misc/lvm-exec.c b/lib/misc/lvm-exec.c
index 2f0f5ca..4cecfa3 100644
--- a/lib/misc/lvm-exec.c
+++ b/lib/misc/lvm-exec.c
@@ -107,3 +107,102 @@ int exec_cmd(struct cmd_context *cmd, const char *const argv[],
return 1;
}
+
+static int _reopen_fd_to_null(int fd)
+{
+ int null_fd;
+
+ if ((null_fd = open("/dev/null", O_RDWR)) == -1) {
+ log_sys_error("open", "/dev/null");
+ return 0;
+ }
+
+ if (close(fd)) {
+ log_sys_error("close", "");
+ return 0;
+ }
+
+ if (dup2(null_fd, fd) == -1) {
+ log_sys_error("dup2", "");
+ return 0;
+ }
+
+ if (close(null_fd)) {
+ log_sys_error("dup2", "");
+ return 0;
+ }
+
+ return 1;
+}
+
+FILE *pipe_open(struct cmd_context *cmd, const char *const argv[],
+ int sync_needed, struct pipe_data *pdata)
+{
+ int pipefd[2];
+ char buf[PATH_MAX * 2];
+
+ if (sync_needed)
+ if (!sync_local_dev_names(cmd)) /* Flush ops and reset dm cookie */
+ return_0;
+
+ if (pipe(pipefd)) {
+ log_sys_error("pipe", "");
+ return 0;
+ }
+
+ log_verbose("Piping:%s", _verbose_args(argv, buf, sizeof(buf)));
+
+ if ((pdata->pid = fork()) == -1) {
+ log_sys_error("pipe", "");
+ return 0;
+ }
+
+ if (pdata->pid == 0) {
+ /* Child -> writer, convert pipe[0] to STDOUT */
+ if (!_reopen_fd_to_null(STDIN_FILENO))
+ stack;
+ else if (close(pipefd[0 /*read*/]))
+ log_sys_error("close", "pipe[0]");
+ else if (close(STDOUT_FILENO))
+ log_sys_error("close", "STDOUT");
+ else if (dup2(pipefd[1 /*write*/], STDOUT_FILENO) == -1)
+ log_sys_error("dup2", "STDOUT");
+ else if (close(pipefd[1]))
+ log_sys_error("close", "pipe[1]");
+ else if (argv[0]) {
+ execvp(argv[0], (char **) argv);
+ log_sys_error("execvp", argv[0]);
+ }
+ _exit(errno);
+ }
+
+ /* Parent -> reader */
+ if (close(pipefd[1 /*write*/])) {
+ log_sys_error("close", "STDOUT");
+ return NULL;
+ }
+
+ if (!(pdata->fp = fdopen(pipefd[0 /*read*/], "r"))) {
+ log_sys_error("fdopen", "STDIN");
+ if (close(pipefd[0]))
+ log_sys_error("close", "STDIN");
+ return NULL; /* FIXME: kill */
+ }
+
+ return pdata->fp;
+}
+
+int pipe_close(struct pipe_data *pdata)
+{
+ int status;
+
+ if (fclose(pdata->fp))
+ log_sys_error("fclose", "STDIN");
+
+ if (waitpid(pdata->pid, &status, 0) != pdata->pid) {
+ log_sys_error("waitpid", "");
+ return 0;
+ }
+
+ return (status == 0) ? 1 : 0;
+}
diff --git a/lib/misc/lvm-exec.h b/lib/misc/lvm-exec.h
index 3ad4af1..c73d4c4 100644
--- a/lib/misc/lvm-exec.h
+++ b/lib/misc/lvm-exec.h
@@ -37,4 +37,34 @@ struct cmd_context;
int exec_cmd(struct cmd_context *cmd, const char *const argv[],
int *rstatus, int sync_needed);
+
+struct FILE;
+struct pipe_data {
+ FILE *fp;
+ pid_t pid;
+};
+
+/**
+ * popen() like function to read-only output from executed command
+ * without running shell.
+ *
+ * \param argv
+ * Arguments for execvp.
+ *
+ * \param sync_needed
+ * Bool specifying whether local devices needs to be synchronized
+ * before executing command.
+ * Note: You cannot synchronize devices within activation context.
+ *
+ * \param pdata
+ * Arguments to store data needed for pclose_exec().
+ *
+ * \return
+ * 1 (success) or 0 (failure).
+ */
+FILE *pipe_open(struct cmd_context *cmd, const char *const argv[],
+ int sync_needed, struct pipe_data *pdata);
+
+int pipe_close(struct pipe_data *pdata);
+
#endif
10 years, 8 months
master - cleanup: update exec_cmd comment and error
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b6437a61806bde...
Commit: b6437a61806bdec29951eb80616db121c4ec4eff
Parent: 61e7dc833cbcc07453d0e919d52d92290d3ab541
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Aug 6 14:26:00 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Aug 6 16:16:57 2013 +0200
cleanup: update exec_cmd comment and error
Use log_sys_error for reporting error of system call.
Fix comment for return value.
---
lib/misc/lvm-exec.c | 2 +-
lib/misc/lvm-exec.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/misc/lvm-exec.c b/lib/misc/lvm-exec.c
index 1b69635..2f0f5ca 100644
--- a/lib/misc/lvm-exec.c
+++ b/lib/misc/lvm-exec.c
@@ -64,7 +64,7 @@ int exec_cmd(struct cmd_context *cmd, const char *const argv[],
log_verbose("Executing:%s", _verbose_args(argv, buf, sizeof(buf)));
if ((pid = fork()) == -1) {
- log_error("fork failed: %s", strerror(errno));
+ log_sys_error("fork", "");
return 0;
}
diff --git a/lib/misc/lvm-exec.h b/lib/misc/lvm-exec.h
index c91ffaf..3ad4af1 100644
--- a/lib/misc/lvm-exec.h
+++ b/lib/misc/lvm-exec.h
@@ -32,7 +32,7 @@ struct cmd_context;
* Note: You cannot synchronize devices within activation context.
*
* \return
- * 0 (success) or -1 (failure).
+ * 1 (success) or 0 (failure).
*/
int exec_cmd(struct cmd_context *cmd, const char *const argv[],
int *rstatus, int sync_needed);
10 years, 8 months
master - WHATS_NEW: previous commit
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=61e7dc833cbcc0...
Commit: 61e7dc833cbcc07453d0e919d52d92290d3ab541
Parent: 34d207d9b37edc2499dfff2c4809fecf72926416
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Aug 6 14:03:43 2013 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Aug 6 14:03:43 2013 +0200
WHATS_NEW: previous commit
---
WHATS_NEW | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index b289bf2..5baa00d 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.100 -
================================
+ Fix metadata area offset/size overflow if it's >= 4g and while using lvmetad.
Inherit and apply any profile attached to a VG if creating new thin pool.
Add initial support thin pool lvconvert --repair.
Add --with-thin-repair and --with-thin-dump configure options.
10 years, 8 months
master - lvmetad: fix mda offset/size overflow if >= 4g (32bit)
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=34d207d9b37edc...
Commit: 34d207d9b37edc2499dfff2c4809fecf72926416
Parent: 41e64b72ab50153494fd2925fbb760331014fd70
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Aug 6 13:37:42 2013 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Aug 6 13:37:42 2013 +0200
lvmetad: fix mda offset/size overflow if >= 4g (32bit)
When reading an info about MDAs from lvmetad, we need to use 64 bit
int to read the value of the offset/size, otherwise the value is
overflows and then it's used throughout!
This is dangerous if we're trying to write such metadata area then,
mostly visible if we're using 2 mdas where the 2nd one is at the end
of the underlying device and hence the value of the mda offset is
high enough to cause problems:
(the offset trimmed to value of 0 instead of 4096m, so we write
at the very start of the disk (or elsewhere if the offset has
some other value!)
[1] raw/~ # lvcreate -s -l 100%FREE vg --virtualsize 4097m
Logical volume "lvol0" created
[1] raw/~ # pvcreate --metadatacopies 2 /dev/vg/lvol0
Physical volume "/dev/vg/lvol0" successfully created
[1] raw/~ # hexdump -n 512 /dev/vg/lvol0
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
0000200
[1] raw/~ # pvchange -u /dev/vg/lvol0
Physical volume "/dev/vg/lvol0" changed
1 physical volume changed / 0 physical volumes not changed
[1] raw/~ # hexdump -n 512 /dev/vg/lvol0
0000000 d43e d2a5 4c20 4d56 2032 5b78 4135 7225
0000010 4e30 3e2a 0001 0000 0000 0000 0000 0000
0000020 0000 0010 0000 0000 0000 0000 0000 0000
0000030 0000 0000 0000 0000 0000 0000 0000 0000
*
0000200
=======
(the offset overflows to undefined values which is far behind
the end of the disk)
[1] raw/~ # lvcreate -s -l 100%FREE vg --virtualsize 100g
Logical volume "lvol0" created
[1] raw/~ # pvcreate --metadatacopies 2 /dev/vg/lvol0
Physical volume "/dev/vg/lvol0" successfully created
[1] raw/~ # pvchange -u /dev/vg/lvol0
/dev/vg/lvol0: lseek 18446744073708503040 failed: Invalid argument
/dev/vg/lvol0: lseek 18446744073708503040 failed: Invalid argument
Failed to store physical volume "/dev/vg/lvol0"
0 physical volumes changed / 1 physical volume not changed
---
lib/format_text/format-text.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index b210603..950e0d5 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -1688,12 +1688,12 @@ static int _mda_import_text_raw(struct lvmcache_info *info, const struct dm_conf
cn = cn->child;
device = lvmcache_device(info);
- size = dm_config_find_int(cn, "size", 0);
+ size = dm_config_find_int64(cn, "size", 0);
if (!device || !size)
return 0;
- offset = dm_config_find_int(cn, "start", 0);
+ offset = dm_config_find_int64(cn, "start", 0);
ignore = dm_config_find_int(cn, "ignore", 0);
lvmcache_add_mda(info, device, offset, size, ignore);
10 years, 8 months
master - thin: chunk_size check already part of get_profilable_pool_params fn
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=41e64b72ab5015...
Commit: 41e64b72ab50153494fd2925fbb760331014fd70
Parent: e195b5227e624cb125b070b4a10e24efdab16d53
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Aug 6 11:46:48 2013 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Aug 6 11:46:48 2013 +0200
thin: chunk_size check already part of get_profilable_pool_params fn
---
tools/toollib.c | 8 --------
1 files changed, 0 insertions(+), 8 deletions(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index 7944d23..befd3b8 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1577,14 +1577,6 @@ int get_pool_params(struct cmd_context *cmd,
chunk_size, discards, zero))
return_0;
- if ((*chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) ||
- (*chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)) {
- log_error("Chunk size must be in the range %s to %s.",
- display_size(cmd, DM_THIN_MIN_DATA_BLOCK_SIZE),
- display_size(cmd, DM_THIN_MAX_DATA_BLOCK_SIZE));
- return 0;
- }
-
if (arg_count(cmd, poolmetadatasize_ARG)) {
if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) {
log_error("Negative pool metadata size is invalid.");
10 years, 8 months
master - thin: apply VG profile if creating a new thin pool
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e195b5227e624c...
Commit: e195b5227e624cb125b070b4a10e24efdab16d53
Parent: 1cdd563b6cb238d63f3f9a7f2448ef3c4d1368ae
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Aug 6 11:42:40 2013 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Aug 6 11:42:40 2013 +0200
thin: apply VG profile if creating a new thin pool
When creating a new thin pool and there's no profile requested
via "lvcreate --profile ...", inherit any VG profile if it's attached.
Currently this applies to these settings:
allocation/thin_pool_chunk_size
allocation/thin_pool_discards
allocation/thin_pool_zero
---
WHATS_NEW | 1 +
lib/metadata/metadata-exported.h | 7 +++++--
lib/metadata/thin_manip.c | 38 ++++++++++++++++++++++++++++++++++++--
tools/lvconvert.c | 8 ++++----
tools/lvcreate.c | 4 ++--
tools/toollib.c | 16 ++++++----------
6 files changed, 54 insertions(+), 20 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 69a8275..b289bf2 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.100 -
================================
+ Inherit and apply any profile attached to a VG if creating new thin pool.
Add initial support thin pool lvconvert --repair.
Add --with-thin-repair and --with-thin-dump configure options.
Add lvm.conf thin_repair/dump_executable and thin_repair_options.
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 67dc7f7..d214fd2 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -656,10 +656,13 @@ struct logical_volume *find_pool_lv(struct logical_volume *lv);
int pool_is_active(const struct logical_volume *pool_lv);
int pool_can_resize_metadata(const struct logical_volume *pool_lv);
int update_pool_lv(struct logical_volume *lv, int activate);
-int update_pool_params(struct cmd_context *cmd, unsigned attr, int passed_args,
+int update_profilable_pool_params(struct cmd_context *cmd, struct profile *profile,
+ int passed_args, uint32_t *chunk_size,
+ thin_discards_t *discards, int *zero);
+int update_pool_params(struct volume_group *vg, unsigned attr, int passed_args,
uint32_t data_extents, uint32_t extent_size,
uint32_t *chunk_size, thin_discards_t *discards,
- uint64_t *pool_metadata_size);
+ uint64_t *pool_metadata_size, int *zero);
int get_pool_discards(const char *str, thin_discards_t *discards);
const char *get_pool_discards_name(thin_discards_t discards);
struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv,
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index 6851b3f..36cd6c4 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -569,12 +569,46 @@ int update_pool_lv(struct logical_volume *lv, int activate)
return 1;
}
-int update_pool_params(struct cmd_context *cmd, unsigned attr, int passed_args,
+int update_profilable_pool_params(struct cmd_context *cmd, struct profile *profile,
+ int passed_args, uint32_t *chunk_size,
+ thin_discards_t *discards, int *zero)
+{
+ const char *dstr;
+
+ if (!(passed_args & PASS_ARG_CHUNK_SIZE)) {
+ *chunk_size = find_config_tree_int(cmd, allocation_thin_pool_chunk_size_CFG, profile) * 2;
+ if ((*chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) ||
+ (*chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)) {
+ log_error("Chunk size must be in the range %s to %s.",
+ display_size(cmd, DM_THIN_MIN_DATA_BLOCK_SIZE),
+ display_size(cmd, DM_THIN_MAX_DATA_BLOCK_SIZE));
+ return 0;
+ }
+ }
+
+ if (!(passed_args & PASS_ARG_DISCARDS)) {
+ dstr = find_config_tree_str(cmd, allocation_thin_pool_discards_CFG, profile);
+ if (!get_pool_discards(dstr, discards))
+ return_0;
+ }
+
+ if (!(passed_args & PASS_ARG_ZERO))
+ *zero = find_config_tree_bool(cmd, allocation_thin_pool_zero_CFG, profile);
+
+ return 1;
+}
+
+int update_pool_params(struct volume_group *vg, unsigned attr, int passed_args,
uint32_t data_extents, uint32_t extent_size,
uint32_t *chunk_size, thin_discards_t *discards,
- uint64_t *pool_metadata_size)
+ uint64_t *pool_metadata_size, int *zero)
{
size_t estimate_chunk_size;
+ struct cmd_context *cmd = vg->cmd;
+
+ if (!update_profilable_pool_params(cmd, vg->profile, passed_args,
+ chunk_size, discards, zero))
+ return_0;
if (!(attr & THIN_FEATURE_BLOCK_SIZE) &&
(*chunk_size & (*chunk_size - 1))) {
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 88e0119..f008954 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2293,10 +2293,10 @@ static int _lvconvert_thinpool(struct cmd_context *cmd,
}
if (!lp->pool_metadata_lv_name) {
- if (!update_pool_params(cmd, lp->target_attr, lp->passed_args,
+ if (!update_pool_params(pool_lv->vg, lp->target_attr, lp->passed_args,
pool_lv->le_count, pool_lv->vg->extent_size,
&lp->chunk_size, &lp->discards,
- &lp->poolmetadata_size))
+ &lp->poolmetadata_size, &lp->zero))
return_0;
if (!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size))
@@ -2399,10 +2399,10 @@ static int _lvconvert_thinpool(struct cmd_context *cmd,
display_size(cmd, 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE));
return 0;
}
- if (!update_pool_params(cmd, lp->target_attr, lp->passed_args,
+ if (!update_pool_params(pool_lv->vg, lp->target_attr, lp->passed_args,
pool_lv->le_count, pool_lv->vg->extent_size,
&lp->chunk_size, &lp->discards,
- &lp->poolmetadata_size))
+ &lp->poolmetadata_size, &lp->zero))
return_0;
}
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 8564613..095adbb 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -334,10 +334,10 @@ static int _update_extents_params(struct volume_group *vg,
}
if (lp->create_thin_pool) {
- if (!update_pool_params(vg->cmd, lp->target_attr, lp->passed_args,
+ if (!update_pool_params(vg, lp->target_attr, lp->passed_args,
lp->extents, vg->extent_size,
&lp->chunk_size, &lp->discards,
- &lp->poolmetadatasize))
+ &lp->poolmetadatasize, &lp->zero))
return_0;
if (!(lp->poolmetadataextents =
diff --git a/tools/toollib.c b/tools/toollib.c
index ce449e7..7944d23 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1547,25 +1547,18 @@ int get_pool_params(struct cmd_context *cmd,
uint64_t *pool_metadata_size,
int *zero)
{
- const char *dstr;
-
*passed_args = 0;
if (arg_count(cmd, zero_ARG)) {
*passed_args |= PASS_ARG_ZERO;
*zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n");
log_very_verbose("Setting pool zeroing: %u", *zero);
- } else
- *zero = find_config_tree_bool(cmd, allocation_thin_pool_zero_CFG, profile);
+ }
if (arg_count(cmd, discards_ARG)) {
*passed_args |= PASS_ARG_DISCARDS;
*discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, 0);
log_very_verbose("Setting pool discards: %s",
get_pool_discards_name(*discards));
- } else {
- dstr = find_config_tree_str(cmd, allocation_thin_pool_discards_CFG, profile);
- if (!get_pool_discards(dstr, discards))
- return_0;
}
if (arg_count(cmd, chunksize_ARG)) {
@@ -1578,8 +1571,11 @@ int get_pool_params(struct cmd_context *cmd,
DM_THIN_MIN_DATA_BLOCK_SIZE);
log_very_verbose("Setting pool chunk size: %s",
display_size(cmd, *chunk_size));
- } else
- *chunk_size = find_config_tree_int(cmd, allocation_thin_pool_chunk_size_CFG, profile) * 2;
+ }
+
+ if (!update_profilable_pool_params(cmd, profile, *passed_args,
+ chunk_size, discards, zero))
+ return_0;
if ((*chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) ||
(*chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)) {
10 years, 8 months
master - WHATS_NEW: move line to WHATS_NEW_DM
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1cdd563b6cb238...
Commit: 1cdd563b6cb238d63f3f9a7f2448ef3c4d1368ae
Parent: 19baf84290186a550b212260144523266350252b
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Aug 6 11:42:01 2013 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Aug 6 11:42:01 2013 +0200
WHATS_NEW: move line to WHATS_NEW_DM
---
WHATS_NEW | 1 -
WHATS_NEW_DM | 1 +
2 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index c76dc68..69a8275 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,6 +1,5 @@
Version 2.02.100 -
================================
- Create dmeventd timeout threads as "detached" so exit status is freed.
Add initial support thin pool lvconvert --repair.
Add --with-thin-repair and --with-thin-dump configure options.
Add lvm.conf thin_repair/dump_executable and thin_repair_options.
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index ffee9a3..43eb4d8 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.79 -
================================
+ Create dmeventd timeout threads as "detached" so exit status is freed.
Add DM_ABORT_ON_INTERNAL_ERRORS env var support to abort on internal errors.
Version 1.02.78 - 24th July 2013
10 years, 8 months
master - clvmd: verify messages before processing
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=19baf84290186a...
Commit: 19baf84290186a550b212260144523266350252b
Parent: 5ca54c4f0b27125bc385d55ea0b44853fc7744dd
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jul 30 14:12:33 2013 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Aug 2 09:55:54 2013 -0500
clvmd: verify messages before processing
Check that fields in clvm_header are valid when
local or remote messages are received. If not,
log an error, dump the message data and ignore
the message.
---
daemons/clvmd/clvmd.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 109 insertions(+), 0 deletions(-)
diff --git a/daemons/clvmd/clvmd.c b/daemons/clvmd/clvmd.c
index a276cbc..f05776f 100644
--- a/daemons/clvmd/clvmd.c
+++ b/daemons/clvmd/clvmd.c
@@ -21,6 +21,7 @@
#include <pthread.h>
#include <getopt.h>
+#include <ctype.h>
#include "clvmd-comms.h"
#include "clvm.h"
@@ -1088,7 +1089,90 @@ static void be_daemon(int timeout)
log_error("Error setting current directory to /: %m");
exit(6);
}
+}
+
+static int verify_message(char *buf, int len)
+{
+ struct clvm_header *h = (struct clvm_header *)buf;
+
+ if (len < sizeof(struct clvm_header)) {
+ log_error("verify_message short len %d", len);
+ return -1;
+ }
+
+ switch (h->cmd) {
+ case CLVMD_CMD_REPLY:
+ case CLVMD_CMD_VERSION:
+ case CLVMD_CMD_GOAWAY:
+ case CLVMD_CMD_TEST:
+ case CLVMD_CMD_LOCK:
+ case CLVMD_CMD_UNLOCK:
+ case CLVMD_CMD_LOCK_LV:
+ case CLVMD_CMD_LOCK_VG:
+ case CLVMD_CMD_LOCK_QUERY:
+ case CLVMD_CMD_REFRESH:
+ case CLVMD_CMD_GET_CLUSTERNAME:
+ case CLVMD_CMD_SET_DEBUG:
+ case CLVMD_CMD_VG_BACKUP:
+ case CLVMD_CMD_RESTART:
+ case CLVMD_CMD_SYNC_NAMES:
+ break;
+ default:
+ log_error("verify_message bad cmd %x", h->cmd);
+ return -1;
+ };
+
+ /* TODO: we may be able to narrow len/flags/clientid/arglen checks based on cmd */
+
+ if (h->flags & ~(CLVMD_FLAG_LOCAL | CLVMD_FLAG_SYSTEMLV | CLVMD_FLAG_NODEERRS)) {
+ log_error("verify_message bad flags %x", h->flags);
+ return -1;
+ }
+ if (h->clientid < 0) {
+ log_error("verify_message bad clientid %x", h->clientid);
+ return -1;
+ }
+
+ if (h->arglen > max_cluster_message) {
+ log_error("verify_message bad arglen %x max %d", h->arglen, max_cluster_message);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void dump_message(char *buf, int len)
+{
+ unsigned char row[8];
+ char str[9];
+ int i, j, pos;
+
+ if (len > 128)
+ len = 128;
+
+ pos = 0;
+ memset(row, 0, sizeof(row));
+
+ for (i = 0; i < len; i++) {
+ row[pos++] = buf[i];
+
+ if ((pos == 8) || (i + 1 == len)) {
+ memset(str, 0, sizeof(str));
+
+ for (j = 0; j < 8; j++) {
+ if (isprint(row[j]))
+ str[j] = row[j];
+ else
+ str[j] = ' ';
+ }
+
+ log_error("%02x %02x %02x %02x %02x %02x %02x %02x [%s]",
+ row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], str);
+ pos = 0;
+ memset(row, 0, sizeof(row));
+ }
+ }
}
/* Called when we have a read from the local socket.
@@ -1100,12 +1184,25 @@ static int read_from_local_sock(struct local_client *thisfd)
int missing_len;
char buffer[PIPE_BUF + 1];
+ memset(buffer, 0, sizeof(buffer));
+
len = read(thisfd->fd, buffer, sizeof(buffer) - 1);
if (len == -1 && errno == EINTR)
return 1;
DEBUGLOG("Read on local socket %d, len = %d\n", thisfd->fd, len);
+ if (len) {
+ int rv = verify_message(buffer, len);
+ if (rv < 0) {
+ log_error("read_from_local_sock from %d len %d bad verify",
+ thisfd->fd, len);
+ dump_message(buffer, len);
+ /* force error handling below */
+ len = 0;
+ }
+ }
+
/* EOF or error on socket */
if (len <= 0) {
int *status;
@@ -2189,10 +2286,22 @@ error:
void process_message(struct local_client *client, char *buf, int len,
const char *csid)
{
+ char nodename[max_cluster_member_name_len];
struct clvm_header *inheader;
+ int rv;
inheader = (struct clvm_header *) buf;
ntoh_clvm(inheader); /* Byteswap fields */
+
+ rv = verify_message(buf, len);
+ if (rv < 0) {
+ memset(nodename, 0, sizeof(nodename));
+ clops->name_from_csid(csid, nodename);
+ log_error("process_message from %s len %d bad verify", nodename, len);
+ dump_message(buf, len);
+ return;
+ }
+
if (inheader->cmd == CLVMD_CMD_REPLY)
process_reply(inheader, len, csid);
else
10 years, 8 months