From prajnoha@sourceware.org Mon Nov 1 13:31:00 2010 From: prajnoha@sourceware.org (prajnoha@sourceware.org) Date: Mon, 01 Nov 2010 13:31:00 -0000 Subject: LVM2 ./WHATS_NEW_DM libdm/libdm-report.c Message-ID: <20101101133156.18419.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: prajnoha@sourceware.org 2010-11-01 13:31:55 Modified files: . : WHATS_NEW_DM libdm : libdm-report.c Log message: Allocate buffer for reporting functions dynamically to support long outputs. Fix memory leak of field_id in _output_field function. There's been a patch added recently to use dynamic allocation for metadata tags buffer to remove the 4k limit (for writing metadata out). However, when using reporting commands like vgs and lvs, we still need to fix libdm reporting functions themselves to support such long outputs. So the buffer used in those reporting functions is dynamic now. The patch also includes a fix for field_id memory leak which was found in the _output_field function. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW_DM.diff?cvsroot=lvm2&r1=1.420&r2=1.421 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-report.c.diff?cvsroot=lvm2&r1=1.37&r2=1.38 --- LVM2/WHATS_NEW_DM 2010/10/25 16:38:20 1.420 +++ LVM2/WHATS_NEW_DM 2010/11/01 13:31:55 1.421 @@ -1,5 +1,7 @@ Version 1.02.57 =================================== + Fix memory leak of field_id in _output_field function. + Allocate buffer for reporting functions dynamically to support long outputs. Version 1.02.56 - 25th October 2010 =================================== --- LVM2/libdm/libdm-report.c 2010/09/30 21:06:52 1.37 +++ LVM2/libdm/libdm-report.c 2010/11/01 13:31:55 1.38 @@ -757,7 +757,8 @@ { struct field_properties *fp; const char *heading; - char buf[1024]; + char *buf = NULL; + size_t buf_size = 0; if (rh->flags & RH_HEADINGS_PRINTED) return 1; @@ -773,6 +774,18 @@ return 0; } + dm_list_iterate_items(fp, &rh->field_props) { + if (buf_size < fp->width) + buf_size = fp->width; + } + /* Including trailing '\0'! */ + buf_size++; + + if (!(buf = dm_malloc(buf_size))) { + log_error("dm_report: Could not allocate memory for heading buffer."); + goto bad; + } + /* First heading line */ dm_list_iterate_items(fp, &rh->field_props) { if (fp->flags & FLD_HIDDEN) @@ -780,7 +793,7 @@ heading = rh->fields[fp->field_num].heading; if (rh->flags & DM_REPORT_OUTPUT_ALIGNED) { - if (dm_snprintf(buf, sizeof(buf), "%-*.*s", + if (dm_snprintf(buf, buf_size, "%-*.*s", fp->width, fp->width, heading) < 0) { log_error("dm_report: snprintf heading failed"); goto bad; @@ -806,9 +819,12 @@ } log_print("%s", (char *) dm_pool_end_object(rh->mem)); + dm_free(buf); + return 1; bad: + dm_free(buf); dm_pool_abandon_object(rh->mem); return 0; } @@ -892,7 +908,8 @@ int32_t width; uint32_t align; const char *repstr; - char buf[4096]; + char *buf = NULL; + size_t buf_size = 0; if (rh->flags & DM_REPORT_OUTPUT_FIELD_NAME_PREFIX) { if (!(field_id = strdup(rh->fields[field->props->field_num].id))) { @@ -902,11 +919,13 @@ if (!dm_pool_grow_object(rh->mem, rh->output_field_name_prefix, 0)) { log_error("dm_report: Unable to extend output line"); + free(field_id); return 0; } if (!dm_pool_grow_object(rh->mem, _toupperstr(field_id), 0)) { log_error("dm_report: Unable to extend output line"); + free(field_id); return 0; } @@ -935,25 +954,33 @@ if (!(align = field->props->flags & DM_REPORT_FIELD_ALIGN_MASK)) align = (field->props->flags & DM_REPORT_FIELD_TYPE_NUMBER) ? DM_REPORT_FIELD_ALIGN_RIGHT : DM_REPORT_FIELD_ALIGN_LEFT; + + /* Including trailing '\0'! */ + buf_size = width + 1; + if (!(buf = dm_malloc(buf_size))) { + log_error("dm_report: Could not allocate memory for output line buffer."); + return 0; + } + if (align & DM_REPORT_FIELD_ALIGN_LEFT) { - if (dm_snprintf(buf, sizeof(buf), "%-*.*s", + if (dm_snprintf(buf, buf_size, "%-*.*s", width, width, repstr) < 0) { log_error("dm_report: left-aligned snprintf() failed"); - return 0; + goto bad; } if (!dm_pool_grow_object(rh->mem, buf, width)) { log_error("dm_report: Unable to extend output line"); - return 0; + goto bad; } } else if (align & DM_REPORT_FIELD_ALIGN_RIGHT) { - if (dm_snprintf(buf, sizeof(buf), "%*.*s", + if (dm_snprintf(buf, buf_size, "%*.*s", width, width, repstr) < 0) { log_error("dm_report: right-aligned snprintf() failed"); - return 0; + goto bad; } if (!dm_pool_grow_object(rh->mem, buf, width)) { log_error("dm_report: Unable to extend output line"); - return 0; + goto bad; } } } @@ -962,10 +989,15 @@ !(rh->flags & DM_REPORT_OUTPUT_FIELD_UNQUOTED)) if (!dm_pool_grow_object(rh->mem, "\'", 1)) { log_error("dm_report: Unable to extend output line"); - return 0; + goto bad; } + dm_free(buf); return 1; + +bad: + dm_free(buf); + return 0; } static int _output_as_rows(struct dm_report *rh) From prajnoha@sourceware.org Mon Nov 1 13:50:00 2010 From: prajnoha@sourceware.org (prajnoha@sourceware.org) Date: Mon, 01 Nov 2010 13:50:00 -0000 Subject: LVM2/libdm libdm-report.c Message-ID: <20101101135052.8570.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: prajnoha@sourceware.org 2010-11-01 13:50:51 Modified files: libdm : libdm-report.c Log message: Use dm_strdup/dm_free instead of strdup/free. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-report.c.diff?cvsroot=lvm2&r1=1.38&r2=1.39 --- LVM2/libdm/libdm-report.c 2010/11/01 13:31:55 1.38 +++ LVM2/libdm/libdm-report.c 2010/11/01 13:50:51 1.39 @@ -912,20 +912,20 @@ size_t buf_size = 0; if (rh->flags & DM_REPORT_OUTPUT_FIELD_NAME_PREFIX) { - if (!(field_id = strdup(rh->fields[field->props->field_num].id))) { + if (!(field_id = dm_strdup(rh->fields[field->props->field_num].id))) { log_error("dm_report: Failed to copy field name"); return 0; } if (!dm_pool_grow_object(rh->mem, rh->output_field_name_prefix, 0)) { log_error("dm_report: Unable to extend output line"); - free(field_id); + dm_free(field_id); return 0; } if (!dm_pool_grow_object(rh->mem, _toupperstr(field_id), 0)) { log_error("dm_report: Unable to extend output line"); - free(field_id); + dm_free(field_id); return 0; } From zkabelac@sourceware.org Mon Nov 1 14:08:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 01 Nov 2010 14:08:00 -0000 Subject: LVM2 ./WHATS_NEW scripts/fsadm.sh Message-ID: <20101101140854.13044.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-01 14:08:52 Modified files: . : WHATS_NEW scripts : fsadm.sh Log message: Return different status code for fsadm check of mounted filesystem Return status code 3 for fsadm check of mounted filesystem - used later with lvresize update patch to better support online filesystem resize. Also makes a more consistent user interruption and returns status code 2 in this case. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1783&r2=1.1784 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/scripts/fsadm.sh.diff?cvsroot=lvm2&r1=1.20&r2=1.21 --- LVM2/WHATS_NEW 2010/10/29 21:15:23 1.1783 +++ LVM2/WHATS_NEW 2010/11/01 14:08:51 1.1784 @@ -1,5 +1,6 @@ Version 2.02.76 - =================================== + Modify fsadm to return different status code for check of mounted filesystem. Update VG metadata only once in vgchange when making multiple changes. Allow independent vgchange arguments to be used together. Automatically unmount invalidated snapshots in dmeventd. --- LVM2/scripts/fsadm.sh 2010/10/08 15:02:05 1.20 +++ LVM2/scripts/fsadm.sh 2010/11/01 14:08:52 1.21 @@ -23,6 +23,11 @@ # reiserfs: resize_reiserfs, reiserfstune # xfs: xfs_growfs, xfs_info # +# Return values: +# 0 success +# 1 error +# 2 break detected +# 3 unsupported online filesystem check for given mounted fs TOOL=fsadm @@ -126,6 +131,8 @@ IFS=$IFS_OLD trap 2 + test "$1" -eq 2 && verbose "Break detected" + if [ "$DO_LVRESIZE" -eq 2 ]; then # start LVRESIZE with the filesystem modification flag # and allow recursive call of fsadm @@ -349,7 +356,6 @@ # if the size parameter is missing use device size #if [ -n "$NEWSIZE" -a $NEWSIZE < test -z "$NEWSIZE" && NEWSIZE=${DEVSIZE}b - trap cleanup 2 IFS=$NL case "$FSTYPE" in "ext3"|"ext2"|"ext4") resize_ext $NEWSIZE ;; @@ -365,7 +371,10 @@ ################### check() { detect_fs "$1" - detect_mounted && error "Cannot fsck device \"$VOLUME\", filesystem is mounted on $MOUNTED" + if detect_mounted ; then + verbose "Skipping filesystem check for device \"$VOLUME\" as the filesystem is mounted on $MOUNTED"; + cleanup 3 + fi case "$FSTYPE" in "xfs") dry $XFS_CHECK "$VOLUME" ;; *) # check if executed from interactive shell environment @@ -380,6 +389,7 @@ # start point of this script # - parsing parameters ############################# +trap "cleanup 2" 2 # test if we are not invoked recursively test -n "$FSADM_RUNNING" && exit 0 From zkabelac@sourceware.org Mon Nov 1 14:10:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 01 Nov 2010 14:10:00 -0000 Subject: LVM2 ./WHATS_NEW man/fsadm.8.in Message-ID: <20101101141047.14026.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-01 14:10:47 Modified files: . : WHATS_NEW man : fsadm.8.in Log message: Add DIAGNOSTICS section to fsadm man page. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1784&r2=1.1785 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/man/fsadm.8.in.diff?cvsroot=lvm2&r1=1.3&r2=1.4 --- LVM2/WHATS_NEW 2010/11/01 14:08:51 1.1784 +++ LVM2/WHATS_NEW 2010/11/01 14:10:46 1.1785 @@ -1,5 +1,6 @@ Version 2.02.76 - =================================== + Add DIAGNOSTICS section to fsadm man page. Modify fsadm to return different status code for check of mounted filesystem. Update VG metadata only once in vgchange when making multiple changes. Allow independent vgchange arguments to be used together. --- LVM2/man/fsadm.8.in 2010/01/07 09:42:51 1.3 +++ LVM2/man/fsadm.8.in 2010/11/01 14:10:46 1.4 @@ -37,6 +37,13 @@ or an absolute size using a suffix (in powers of 1024). If new_size is not supplied, the whole device is used. +.SH "DIAGNOSTICS" +On successful completion, the status code is 0. +A status code of 2 indicates the operation was interrupted by the user. +A status code of 3 indicates the requested check operation could not be performed +because the filesystem is mounted and does not support an online fsck. +A status code of 1 is used for other failures. + .SH "EXAMPLES" "fsadm \-e \-y resize /dev/vg/test 1000M" tries to resize the filesystem on logical volume /dev/vg/test. If /dev/vg/test contains ext2/ext3/ext4 From zkabelac@sourceware.org Mon Nov 1 14:17:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 01 Nov 2010 14:17:00 -0000 Subject: LVM2 ./WHATS_NEW lib/activate/activate.c lib/m ... Message-ID: <20101101141737.16847.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-01 14:17:36 Modified files: . : WHATS_NEW lib/activate : activate.c lib/misc : lvm-exec.c lvm-exec.h tools : lvresize.c Log message: Use new status code from fsadm check Patch updates exec_cmd() and adds 3rd parameter with pointer for status value, so caller might examine returned status code. If the passed pointer is NULL, behavior is unmodified. Patch allows to confinue with lvresize if the failure from fsadm check is caused by mounted filesystem as many of filesystem resize tools do support online filesystem resize. (originally user had to use flag '-n' to bypass this filesystem check) Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1785&r2=1.1786 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/activate.c.diff?cvsroot=lvm2&r1=1.177&r2=1.178 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-exec.c.diff?cvsroot=lvm2&r1=1.7&r2=1.8 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-exec.h.diff?cvsroot=lvm2&r1=1.5&r2=1.6 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvresize.c.diff?cvsroot=lvm2&r1=1.124&r2=1.125 --- LVM2/WHATS_NEW 2010/11/01 14:10:46 1.1785 +++ LVM2/WHATS_NEW 2010/11/01 14:17:35 1.1786 @@ -1,5 +1,6 @@ Version 2.02.76 - =================================== + Fix handling of online filesystem resize (using new fsadm return code). Add DIAGNOSTICS section to fsadm man page. Modify fsadm to return different status code for check of mounted filesystem. Update VG metadata only once in vgchange when making multiple changes. --- LVM2/lib/activate/activate.c 2010/08/17 16:25:32 1.177 +++ LVM2/lib/activate/activate.c 2010/11/01 14:17:35 1.178 @@ -425,7 +425,7 @@ argv[1] = module; argv[2] = NULL; - ret = exec_cmd(cmd, argv); + ret = exec_cmd(cmd, argv, NULL); #endif return ret; } --- LVM2/lib/misc/lvm-exec.c 2009/07/13 21:26:41 1.7 +++ LVM2/lib/misc/lvm-exec.c 2010/11/01 14:17:36 1.8 @@ -46,7 +46,7 @@ /* * Execute and wait for external command */ -int exec_cmd(struct cmd_context *cmd, const char *const argv[]) +int exec_cmd(struct cmd_context *cmd, const char *const argv[], int *rstatus) { pid_t pid; int status; @@ -71,6 +71,9 @@ _exit(errno); } + if (rstatus) + *rstatus = -1; + /* Parent */ if (wait4(pid, &status, 0, NULL) != pid) { log_error("wait4 child process %u failed: %s", pid, @@ -84,9 +87,16 @@ } if (WEXITSTATUS(status)) { - log_error("%s failed: %u", argv[0], WEXITSTATUS(status)); + if (rstatus) { + *rstatus = WEXITSTATUS(status); + log_verbose("%s failed: %u", argv[0], *rstatus); + } else + log_error("%s failed: %u", argv[0], WEXITSTATUS(status)); return 0; } + if (rstatus) + *rstatus = 0; + return 1; } --- LVM2/lib/misc/lvm-exec.h 2009/02/28 00:54:06 1.5 +++ LVM2/lib/misc/lvm-exec.h 2010/11/01 14:17:36 1.6 @@ -1,6 +1,6 @@ /* * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved. * * This file is part of LVM2. * @@ -19,6 +19,6 @@ #include "lib.h" struct cmd_context; -int exec_cmd(struct cmd_context *cmd, const char *const argv[]); +int exec_cmd(struct cmd_context *cmd, const char *const argv[], int *rstatus); #endif --- LVM2/tools/lvresize.c 2010/10/15 16:28:16 1.124 +++ LVM2/tools/lvresize.c 2010/11/01 14:17:36 1.125 @@ -129,6 +129,7 @@ enum fsadm_cmd_e { FSADM_CMD_CHECK, FSADM_CMD_RESIZE }; #define FSADM_CMD "fsadm" #define FSADM_CMD_MAX_ARGS 6 +#define FSADM_CHECK_FAILS_FOR_MOUNTED 3 /* shell exist status code */ /* * FSADM_CMD --dry-run --verbose --force check lv_path @@ -137,7 +138,8 @@ static int _fsadm_cmd(struct cmd_context *cmd, const struct volume_group *vg, const struct lvresize_params *lp, - enum fsadm_cmd_e fcmd) + enum fsadm_cmd_e fcmd, + int *status) { char lv_path[PATH_MAX]; char size_buf[SIZE_BUF]; @@ -177,7 +179,7 @@ argv[i] = NULL; - return exec_cmd(cmd, argv); + return exec_cmd(cmd, argv, status); } static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv, @@ -321,6 +323,7 @@ struct lv_segment *seg, *uninitialized_var(mirr_seg); uint32_t seg_extents; uint32_t sz, str; + int status; struct dm_list *pvh = NULL; int use_policy = arg_count(cmd, use_policies_ARG); @@ -637,13 +640,16 @@ if (lp->resizefs) { if (!lp->nofsck && - !_fsadm_cmd(cmd, vg, lp, FSADM_CMD_CHECK)) { - stack; - return ECMD_FAILED; + !_fsadm_cmd(cmd, vg, lp, FSADM_CMD_CHECK, &status)) { + if (status != FSADM_CHECK_FAILS_FOR_MOUNTED) { + stack; + return ECMD_FAILED; + } + /* some filesystems supports online resize */ } if ((lp->resize == LV_REDUCE) && - !_fsadm_cmd(cmd, vg, lp, FSADM_CMD_RESIZE)) { + !_fsadm_cmd(cmd, vg, lp, FSADM_CMD_RESIZE, NULL)) { stack; return ECMD_FAILED; } @@ -711,7 +717,7 @@ log_print("Logical volume %s successfully resized", lp->lv_name); if (lp->resizefs && (lp->resize == LV_EXTEND) && - !_fsadm_cmd(cmd, vg, lp, FSADM_CMD_RESIZE)) { + !_fsadm_cmd(cmd, vg, lp, FSADM_CMD_RESIZE, NULL)) { stack; return ECMD_FAILED; } From agk@sourceware.org Tue Nov 2 19:56:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Tue, 02 Nov 2010 19:56:00 -0000 Subject: LVM2 ./WHATS_NEW libdm/regex/parse_rx.c Message-ID: <20101102195634.18032.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-02 19:56:33 Modified files: . : WHATS_NEW libdm/regex : parse_rx.c Log message: Fix regex optimiser not to ignore RHS of OR nodes in _find_leftmost_common. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1786&r2=1.1787 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/regex/parse_rx.c.diff?cvsroot=lvm2&r1=1.13&r2=1.14 --- LVM2/WHATS_NEW 2010/11/01 14:17:35 1.1786 +++ LVM2/WHATS_NEW 2010/11/02 19:56:33 1.1787 @@ -1,5 +1,6 @@ Version 2.02.76 - =================================== + Fix regex optimiser not to ignore RHS of OR nodes in _find_leftmost_common. Fix handling of online filesystem resize (using new fsadm return code). Add DIAGNOSTICS section to fsadm man page. Modify fsadm to return different status code for check of mounted filesystem. --- LVM2/libdm/regex/parse_rx.c 2010/08/09 10:29:42 1.13 +++ LVM2/libdm/regex/parse_rx.c 2010/11/02 19:56:33 1.14 @@ -473,16 +473,19 @@ unsigned left_depth = _depth(left, leftmost); unsigned right_depth = _depth(right, leftmost); - while (left_depth > right_depth) { + while (left_depth > right_depth && left->type != OR) { left = LEFT(left); left_depth--; } - while (right_depth > left_depth) { + while (right_depth > left_depth && right->type != OR) { right = LEFT(right); right_depth--; } + if (left_depth != right_depth) + return 0; + while (left_depth) { if (left->type == CAT && right->type == CAT) { if (_nodes_equal(LEFT(left), LEFT(right))) { @@ -491,6 +494,8 @@ return 1; } } + if (left->type == OR || right->type == OR) + break; left = LEFT(left); right = LEFT(right); left_depth--; @@ -568,7 +573,6 @@ case QUEST: if (!(r->left = _pass(mem, r->left, changed))) return_NULL; - break; case OR: /* It's important we optimise sub nodes first */ @@ -577,7 +581,6 @@ if (!(r->right = _pass(mem, r->right, changed))) return_NULL; - /* * If rotate_ors changes the tree, left and right are stale, * so just set 'changed' to repeat the search. From agk@sourceware.org Tue Nov 2 20:10:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Tue, 02 Nov 2010 20:10:00 -0000 Subject: LVM2/libdm/regex parse_rx.c Message-ID: <20101102201036.25035.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-02 20:10:35 Modified files: libdm/regex : parse_rx.c Log message: lost line Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/regex/parse_rx.c.diff?cvsroot=lvm2&r1=1.14&r2=1.15 --- LVM2/libdm/regex/parse_rx.c 2010/11/02 19:56:33 1.14 +++ LVM2/libdm/regex/parse_rx.c 2010/11/02 20:10:35 1.15 @@ -574,6 +574,7 @@ if (!(r->left = _pass(mem, r->left, changed))) return_NULL; + break; case OR: /* It's important we optimise sub nodes first */ if (!(r->left = _pass(mem, r->left, changed))) From zkabelac@sourceware.org Fri Nov 5 16:10:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Fri, 05 Nov 2010 16:10:00 -0000 Subject: LVM2/include Makefile.in Message-ID: <20101105161010.17169.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-05 16:10:08 Modified files: include : Makefile.in Log message: Use include make.tmpl Makes easier to use recursive targets and simplifies Makefile. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/include/Makefile.in.diff?cvsroot=lvm2&r1=1.14&r2=1.15 --- LVM2/include/Makefile.in 2010/08/02 13:17:04 1.14 +++ LVM2/include/Makefile.in 2010/11/05 16:10:08 1.15 @@ -1,6 +1,6 @@ # # Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. -# Copyright (C) 2004 Red Hat, Inc. All rights reserved. +# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved. # # This file is part of LVM2. # @@ -12,15 +12,11 @@ # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -SHELL = /bin/sh - srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ -LN_S = @LN_S@ - -.PHONY: clean distclean all install pofile install_cluster install_device-mapper +include $(top_builddir)/make.tmpl all: .symlinks_created @@ -37,14 +33,4 @@ device-mapper: all -clean: - -install: - -install_cluster: - -install_device-mapper: - -install_lvm2: - cflow: all From zkabelac@sourceware.org Fri Nov 5 16:13:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Fri, 05 Nov 2010 16:13:00 -0000 Subject: LVM2 ./make.tmpl.in scripts/Makefile.in Message-ID: <20101105161319.18965.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-05 16:13:19 Modified files: . : make.tmpl.in scripts : Makefile.in Log message: Add given user prefix to make target install_initscripts Avoid files to be written into the live system if lvm was configured with different --prefix. Use initdir for install target path. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/make.tmpl.in.diff?cvsroot=lvm2&r1=1.112&r2=1.113 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/scripts/Makefile.in.diff?cvsroot=lvm2&r1=1.18&r2=1.19 --- LVM2/make.tmpl.in 2010/10/07 16:33:35 1.112 +++ LVM2/make.tmpl.in 2010/11/05 16:13:18 1.113 @@ -64,6 +64,8 @@ staticdir = $(DESTDIR)@STATICDIR@ udevdir = $(DESTDIR)@udevdir@ pkgconfigdir = $(usrlibdir)/pkgconfig +initdir = $(DESTDIR)@sysconfdir@/rc.d/init.d + USRLIB_RELPATH = $(shell echo $(abspath $(usrlibdir) $(libdir)) | \ $(AWK) -f $(top_srcdir)/scripts/relpath.awk) --- LVM2/scripts/Makefile.in 2010/05/20 14:45:17 1.18 +++ LVM2/scripts/Makefile.in 2010/11/05 16:13:19 1.19 @@ -33,13 +33,13 @@ # FIXME Customise for other distributions install_initscripts: - $(INSTALL_DIR) $(DESTDIR)/etc/rc.d/init.d - $(INSTALL_SCRIPT) lvm2_monitoring_init_red_hat $(DESTDIR)/etc/rc.d/init.d/lvm2-monitor + $(INSTALL_DIR) $(initdir) + $(INSTALL_SCRIPT) lvm2_monitoring_init_red_hat $(initdir)/lvm2-monitor ifneq ("@CLVMD@", "none") - $(INSTALL_SCRIPT) clvmd_init_red_hat $(DESTDIR)/etc/rc.d/init.d/clvmd + $(INSTALL_SCRIPT) clvmd_init_red_hat $(initdir)/clvmd endif ifeq ("@BUILD_CMIRRORD@", "yes") - $(INSTALL_SCRIPT) cmirrord_init_red_hat $(DESTDIR)/etc/rc.d/init.d/cmirrord + $(INSTALL_SCRIPT) cmirrord_init_red_hat $(initdir)/cmirrord endif DISTCLEAN_TARGETS += clvmd_init_red_hat cmirrord_init_red_hat lvm2_monitoring_init_red_hat From zkabelac@sourceware.org Fri Nov 5 16:18:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Fri, 05 Nov 2010 16:18:00 -0000 Subject: LVM2 ./WHATS_NEW ./configure.in ./make.tmpl.in ... Message-ID: <20101105161839.20705.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-05 16:18:38 Modified files: . : WHATS_NEW configure.in make.tmpl.in scripts : Makefile.in Added files: scripts : VolumeGroup.ocf Log message: Add OCF support Updated patch from Florian Haas from Linux-HA project. User needs to 'configure --enable-ocf' to get file installed by 'make install' target by default. User can also use 'make install_ocf' to get only ocf files installed. With disabled (default) ocf support - no ocf files are installed. FIXME: ocf installation path needs to be kept in sync with pacemaker. find better way and possible also better location. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1787&r2=1.1788 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/configure.in.diff?cvsroot=lvm2&r1=1.156&r2=1.157 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/make.tmpl.in.diff?cvsroot=lvm2&r1=1.113&r2=1.114 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/scripts/VolumeGroup.ocf.diff?cvsroot=lvm2&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/scripts/Makefile.in.diff?cvsroot=lvm2&r1=1.19&r2=1.20 --- LVM2/WHATS_NEW 2010/11/02 19:56:33 1.1787 +++ LVM2/WHATS_NEW 2010/11/05 16:18:38 1.1788 @@ -1,5 +1,6 @@ Version 2.02.76 - =================================== + Add initial script VolumeGroup.ocf for pacemaker support. Fix regex optimiser not to ignore RHS of OR nodes in _find_leftmost_common. Fix handling of online filesystem resize (using new fsadm return code). Add DIAGNOSTICS section to fsadm man page. --- LVM2/configure.in 2010/10/13 12:18:53 1.156 +++ LVM2/configure.in 2010/11/05 16:18:38 1.157 @@ -361,6 +361,15 @@ AC_MSG_RESULT($REALTIME) ################################################################################ +dnl -- disable OCF resource agents +AC_MSG_CHECKING(whether to enable OCF resource agents) +AC_ARG_ENABLE(ocf, + AC_HELP_STRING([--enable-ocf], + [enable Open Cluster Framework (OCF) compliant resource agents]), + OCF=$enableval, OCF=no) +AC_MSG_RESULT($OCF) + +################################################################################ dnl -- Init pkg-config with dummy invokation: dnl -- this is required because PKG_CHECK_MODULES macro is expanded dnl -- to initialize the pkg-config environment only at the first invokation, @@ -1317,6 +1326,7 @@ AC_SUBST(LVM_RELEASE) AC_SUBST(LVM_RELEASE_DATE) AC_SUBST(MIRRORS) +AC_SUBST(OCF) AC_SUBST(REPLICATORS) AC_SUBST(MSGFMT) AC_SUBST(PKGCONFIG) --- LVM2/make.tmpl.in 2010/11/05 16:13:18 1.113 +++ LVM2/make.tmpl.in 2010/11/05 16:18:38 1.114 @@ -1,7 +1,7 @@ # @configure_input@ # # Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. -# Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved. +# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved. # # This file is part of LVM2. # @@ -65,6 +65,7 @@ udevdir = $(DESTDIR)@udevdir@ pkgconfigdir = $(usrlibdir)/pkgconfig initdir = $(DESTDIR)@sysconfdir@/rc.d/init.d +ocf_scriptdir = $(DESTDIR)@prefix@/usr/lib/ocf/resource.d/lvm2 USRLIB_RELPATH = $(shell echo $(abspath $(usrlibdir) $(libdir)) | \ $(AWK) -f $(top_srcdir)/scripts/relpath.awk) @@ -177,6 +178,7 @@ .PHONY: all pofile distclean clean cleandir cflow device-mapper .PHONY: install install_cluster install_device-mapper install_lvm2 .PHONY: install_lib_shared install_dm_plugin install_lvm2_plugin +.PHONY: install_ocf .PHONY: $(SUBDIRS) $(SUBDIRS.install) $(SUBDIRS.clean) $(SUBDIRS.distclean) .PHONY: $(SUBDIRS.pofile) $(SUBDIRS.install_cluster) $(SUBDIRS.cflow) .PHONY: $(SUBDIRS.device-mapper) $(SUBDIRS.install-device-mapper) @@ -186,6 +188,7 @@ SUBDIRS.install_cluster := $(SUBDIRS:=.install_cluster) SUBDIRS.install_device-mapper := $(SUBDIRS:=.install_device-mapper) SUBDIRS.install_lvm2 := $(SUBDIRS:=.install_lvm2) +SUBDIRS.install_ocf := $(SUBDIRS:=.install_ocf) SUBDIRS.pofile := $(SUBDIRS:=.pofile) SUBDIRS.cflow := $(SUBDIRS:=.cflow) SUBDIRS.clean := $(SUBDIRS:=.clean) @@ -199,6 +202,7 @@ install_cluster: all $(SUBDIRS.install_cluster) install_device-mapper: $(SUBDIRS.install_device-mapper) install_lvm2: $(SUBDIRS.install_lvm2) +install_ocf: $(SUBDIRS.install_ocf) cflow: $(SUBDIRS.cflow) $(SUBDIRS): $(SUBDIRS.device-mapper) @@ -219,6 +223,9 @@ $(SUBDIRS.install_lvm2): $(SUBDIRS) $(MAKE) -C $(@:.install_lvm2=) install_lvm2 +$(SUBDIRS.install_ocf): + $(MAKE) -C $(@:.install_ocf=) install_ocf + $(SUBDIRS.clean): -$(MAKE) -C $(@:.clean=) clean /cvs/lvm2/LVM2/scripts/VolumeGroup.ocf,v --> standard output revision 1.1 --- LVM2/scripts/VolumeGroup.ocf +++ - 2010-11-05 16:18:39.554362000 +0000 @@ -0,0 +1,279 @@ +#!/bin/sh +# +# VolumeGroup +# +# Description: Manages an LVM2 volume group as an HA resource in +# an OCF-compliant cluster +# +# +# Authors: Alan Robertson, Lars Marowsky-Bree, Florian Haas, +# and others from the Linux-HA project +# License: GNU General Public License (GPL) +# Copyright: (C) 2002 - 2005 International Business Machines, Inc. +# (C) 2010 LINBIT HA-Solutions GmbH +# +# This code significantly inspired by the LVM resource +# in FailSafe by Lars Marowsky-Bree +# +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat} +. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs + +####################################################################### + + +usage() { + methods=`VolumeGroup_methods` + methods=`echo $methods | tr ' ' '|'` + cat < + + +1.0 + + +Resource script for an LVM Volume Group. + +Controls the availability of an LVM Volume Group + + + + +The name of volume group. + +Volume group name + + + + +If set, the volume group will be activated exclusively. + +Exclusive activation + + + + + + + + + + + + + + +EOF +} + +# +# methods: What methods/operations do we support? +# +VolumeGroup_methods() { + cat <&1` || exit $OCF_ERR_GENERIC + echo "$VGOUT" | grep -i 'Status[ \t]*available' >/dev/null + rc=$? + + if [ $rc -eq 0 ]; then + ocf_log debug "LVM Volume Group $OCF_RESKEY_volgrpname is available (started)" + else + ocf_log debug "LVM Volume Group $OCF_RESKEY_volgrpname is not available (stopped)" + return $OCF_NOT_RUNNING + fi + + if echo "$VGOUT" | grep -i 'Access.*read/write' >/dev/null; then + ocf_log debug "Volume $OCF_RESKEY_volgrpname is available read/write (running)" + else + ocf_log debug "Volume $OCF_RESKEY_volgrpname is available read-only (running)" + fi + + return $OCF_SUCCESS +} + +# +# Monitor the volume - does it really seem to be working? May report +# $OCF_SUCCESS or $OCF_NOT_RUNNING like VolumeGroup_status, plus +# $OCF_ERR_GENERIC in case vgck reports an error. +# +VolumeGroup_monitor() { + if ! VolumeGroup_status $OCF_RESKEY_volgrpname; then + ocf_log info "LVM Volume Group $OCF_RESKEY_volgrpname is offline" + return $OCF_NOT_RUNNING + fi + + ocf_run vgck $OCF_RESKEY_volgrpname || exit $OCF_ERR_GENERIC + + return $OCF_SUCCESS +} + +# +# Activate the volume group, either locally (if $OCF_RESKEY_exclusive +# is false or unset), or exclusively (if $OCF_RESKEY_exclusive is +# true). +# Either returns successfully, or exits with $OCF_ERR_GENERIC. +# +VolumeGroup_start() { + + ocf_log info "Activating volume group $OCF_RESKEY_volgrpname" + ocf_run vgscan + + local active_mode + active_mode="ly" + if ocf_is_true "$OCF_RESKEY_exclusive" ; then + active_mode="ey" + fi + + ocf_run vgchange -a $active_mode $OCF_RESKEY_volgrpname || exit $OCF_ERR_GENERIC + + if ! VolumeGroup_status $OCF_RESKEY_volgrpname; then + ocf_log err "LVM: $OCF_RESKEY_volgrpname did not activate correctly" + exit $OCF_ERR_GENERIC + fi + + return $OCF_SUCCESS +} + +# +# Deactivate the volume group. +# Either returns successfully, or exits with $OCF_ERR_GENERIC. +# +VolumeGroup_stop() { + if ! VolumeGroup_status; then + ocf_log debug "Volume Group $OCF_RESKEY_volgrpname already stopped" + return $OCF_SUCCESS + fi + + ocf_log info "Deactivating volume group $OCF_RESKEY_volgrpname" + ocf_run vgchange -a ln $OCF_RESKEY_volgrpname || exit $OCF_ERR_GENERIC + + if VolumeGroup_status; then + ocf_log err "LVM: $OCF_RESKEY_volgrpname did not stop correctly" + exit $OCF_ERR_GENERIC + fi + + return $OCF_SUCCESS +} + +# +# Check whether the OCF instance parameters are valid. +# Either returns successfully, or exits with +# $OCF_ERR_CONFIGURED if required parameters are missing; +# $OCF_ERR_INSTALLED if required binaries are missing; +# $OCF_ERR_GENERIC in case of any other error. +# +VolumeGroup_validate_all() { + + if [ -z $OCF_RESKEY_volgrpname ]; then + ocf_log err 'Missing required parameter "volgrpname"!' + exit $OCF_ERR_CONFIGURED + fi + + check_binary vgchange + check_binary vgck + check_binary vgdisplay + + # Run the following tests only if we're not invoked by a probe + # operation + if ! ocf_is_probe; then + # Off-the-shelf tests... + vgck "$OCF_RESKEY_volgrpname" >/dev/null 2>&1 + if [ $? -ne 0 ]; then + ocf_log err "Volume group $OCF_RESKEY_volgrpname does not exist or contains error!" + exit $OCF_ERR_GENERIC + fi + + # Double-check + vgdisplay -v "$OCF_RESKEY_volgrpname" >/dev/null 2>&1 + if [ $? -ne 0 ]; then + ocf_log err "Volume group $OCF_RESKEY_volgrpname does not exist or contains error!" + exit $OCF_ERR_GENERIC + fi + fi + + return $OCF_SUCCESS +} + +# +# 'main' starts here... +# +if [ $# -ne 1 ]; then + usage + exit $OCF_ERR_ARGS +fi + +case $1 in + meta-data) meta_data + exit $OCF_SUCCESS;; + + methods) VolumeGroup_methods + exit $OCF_SUCCESS;; + + usage) usage + exit $OCF_SUCCESS;; + *) ;; +esac + +# Everything except usage and meta-data must pass the validate test +VolumeGroup_validate_all + +# What kind of method was invoked? +case "$1" in + start) + VolumeGroup_start + ;; + stop) + VolumeGroup_stop + ;; + status) + VolumeGroup_status + ;; + monitor) + VolumeGroup_monitor + ;; + validate-all) + ;; + notify|promote|demote|migrate_from|migrate_to) + usage + exit $OCF_ERR_UNIMPLEMENTED + ;; + *) usage + exit $OCF_ERR_ARGS + ;; +esac + +exit $? --- LVM2/scripts/Makefile.in 2010/11/05 16:13:19 1.19 +++ LVM2/scripts/Makefile.in 2010/11/05 16:18:38 1.20 @@ -22,14 +22,25 @@ SCRIPTS += fsadm.sh endif +OCF_SCRIPTS = +ifeq ("@OCF@", "yes") + OCF_SCRIPTS += VolumeGroup.ocf +endif + vpath %.sh $(srcdir) %_install: %.sh $(INSTALL_PROGRAM) -D $< $(sbindir)/$(basename $( CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: prajnoha@sourceware.org 2010-11-05 18:18:12 Modified files: . : WHATS_NEW lib/activate : activate.c lib/metadata : lv_manip.c Log message: Clarify error messages when activation fails due to activation filter use. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1788&r2=1.1789 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/activate.c.diff?cvsroot=lvm2&r1=1.178&r2=1.179 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_manip.c.diff?cvsroot=lvm2&r1=1.234&r2=1.235 --- LVM2/WHATS_NEW 2010/11/05 16:18:38 1.1788 +++ LVM2/WHATS_NEW 2010/11/05 18:18:11 1.1789 @@ -1,5 +1,6 @@ Version 2.02.76 - =================================== + Clarify error messages when activation fails due to activation filter use. Add initial script VolumeGroup.ocf for pacemaker support. Fix regex optimiser not to ignore RHS of OR nodes in _find_leftmost_common. Fix handling of online filesystem resize (using new fsadm return code). --- LVM2/lib/activate/activate.c 2010/11/01 14:17:35 1.178 +++ LVM2/lib/activate/activate.c 2010/11/05 18:18:12 1.179 @@ -285,12 +285,12 @@ /* Don't activate */ return 0; } - - for (cv = cn->v; cv; cv = cv->next) { + else log_verbose("activation/volume_list configuration setting " "defined, checking the list to match %s/%s", lv->vg->name, lv->name); + for (cv = cn->v; cv; cv = cv->next) { if (cv->type != CFG_STRING) { log_error("Ignoring invalid string in config file " "activation/volume_list"); @@ -303,6 +303,7 @@ continue; } + /* Tag? */ if (*str == '@') { str++; @@ -1239,8 +1240,8 @@ goto out; if (!_passes_activation_filter(cmd, lv)) { - log_verbose("Not activating %s/%s due to config file settings", - lv->vg->name, lv->name); + log_verbose("Not activating %s/%s since it does not pass " + "activation filter.", lv->vg->name, lv->name); *activate_lv = 0; } else *activate_lv = 1; @@ -1266,8 +1267,8 @@ goto out; if (filter && !_passes_activation_filter(cmd, lv)) { - log_verbose("Not activating %s/%s due to config file settings", - lv->vg->name, lv->name); + log_error("Not activating %s/%s since it does not pass " + "activation filter.", lv->vg->name, lv->name); goto out; } --- LVM2/lib/metadata/lv_manip.c 2010/10/14 20:03:12 1.234 +++ LVM2/lib/metadata/lv_manip.c 2010/11/05 18:18:12 1.235 @@ -3240,12 +3240,9 @@ goto revert_new_lv; } } else if (!activate_lv(cmd, lv)) { - if (lp->zero) { - log_error("Aborting. Failed to activate new LV to wipe " - "the start of it."); - goto deactivate_and_revert_new_lv; - } log_error("Failed to activate new LV."); + if (lp->zero) + goto deactivate_and_revert_new_lv; return 0; } From zkabelac@sourceware.org Mon Nov 8 14:19:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 08 Nov 2010 14:19:00 -0000 Subject: LVM2/include Makefile.in Message-ID: <20101108141948.28165.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-08 14:19:48 Modified files: include : Makefile.in Log message: Fix include commit and switch to use DISTCLEAN_TARGETS Fixing warning introduced by 'include make.tmpl' commit. Produced this warning: Makefile:29: warning: overriding commands for target `distclean' ../make.tmpl:366: warning: ignoring old commands for target `distclean' Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/include/Makefile.in.diff?cvsroot=lvm2&r1=1.15&r2=1.16 --- LVM2/include/Makefile.in 2010/11/05 16:10:08 1.15 +++ LVM2/include/Makefile.in 2010/11/08 14:19:48 1.16 @@ -25,12 +25,11 @@ for i in `cat $<`; do $(LN_S) $$i ; done touch $@ -distclean: - find . -maxdepth 1 -type l -exec $(RM) \{\} \; - $(RM) Makefile .include_symlinks .symlinks_created .symlinks - pofile: all device-mapper: all cflow: all + +DISTCLEAN_TARGETS += $(shell find . -maxdepth 1 -type l) +DISTCLEAN_TARGETS += .include_symlinks .symlinks_created .symlinks From agk@sourceware.org Mon Nov 8 19:37:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Mon, 08 Nov 2010 19:37:00 -0000 Subject: LVM2 ./VERSION ./VERSION_DM ./WHATS_NEW ./WHAT ... Message-ID: <20101108193742.21585.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-08 19:37:41 Modified files: . : VERSION VERSION_DM WHATS_NEW WHATS_NEW_DM daemons/clvmd : clvmd.c Log message: pre-release Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/VERSION.diff?cvsroot=lvm2&r1=1.258&r2=1.259 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/VERSION_DM.diff?cvsroot=lvm2&r1=1.67&r2=1.68 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1789&r2=1.1790 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW_DM.diff?cvsroot=lvm2&r1=1.421&r2=1.422 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/clvmd/clvmd.c.diff?cvsroot=lvm2&r1=1.82&r2=1.83 --- LVM2/VERSION 2010/10/25 16:38:20 1.258 +++ LVM2/VERSION 2010/11/08 19:37:40 1.259 @@ -1 +1 @@ -2.02.76(2)-cvs (2010-10-25) +2.02.76(2)-cvs (2010-11-08) --- LVM2/VERSION_DM 2010/10/25 16:38:20 1.67 +++ LVM2/VERSION_DM 2010/11/08 19:37:40 1.68 @@ -1 +1 @@ -1.02.57-cvs (2010-10-25) +1.02.57-cvs (2010-11-08) --- LVM2/WHATS_NEW 2010/11/05 18:18:11 1.1789 +++ LVM2/WHATS_NEW 2010/11/08 19:37:40 1.1790 @@ -1,16 +1,16 @@ -Version 2.02.76 - +Version 2.02.76 - 8th November 2010 =================================== Clarify error messages when activation fails due to activation filter use. - Add initial script VolumeGroup.ocf for pacemaker support. - Fix regex optimiser not to ignore RHS of OR nodes in _find_leftmost_common. + Add pacemaker script VolumeGroup.ocf with configure --enable-ocf. + Import make.tmpl into include/ Makefile. Fix handling of online filesystem resize (using new fsadm return code). Add DIAGNOSTICS section to fsadm man page. Modify fsadm to return different status code for check of mounted filesystem. Update VG metadata only once in vgchange when making multiple changes. Allow independent vgchange arguments to be used together. Automatically unmount invalidated snapshots in dmeventd. + Suppress some superfluous messages from clang static analysis. Fix a deadlock caused by double close in clvmd. - Add dmeventd -R to restart dmeventd without losing monitoring state. (2.02.75) Fix NULL pointer dereference on too-large MDA error path in _vg_read_raw_area. Use static for internal _align_chunk() and _new_chunk() from pool-fast.c. Fix vgchange to process -a, --refresh, --monitor and --poll like lvchange. --- LVM2/WHATS_NEW_DM 2010/11/01 13:31:55 1.421 +++ LVM2/WHATS_NEW_DM 2010/11/08 19:37:40 1.422 @@ -1,5 +1,7 @@ -Version 1.02.57 +Version 1.02.57 - 8th November 2010 =================================== + Fix regex optimiser not to ignore RHS of OR nodes in _find_leftmost_common. + Add dmeventd -R to restart dmeventd without losing monitoring state. (1.02.56) Fix memory leak of field_id in _output_field function. Allocate buffer for reporting functions dynamically to support long outputs. --- LVM2/daemons/clvmd/clvmd.c 2010/10/27 11:40:14 1.82 +++ LVM2/daemons/clvmd/clvmd.c 2010/11/08 19:37:41 1.83 @@ -184,8 +184,12 @@ write(child_pipe[1], &status, sizeof(status)); close(child_pipe[1]); } - if (status) - exit(status); +} + +static __attribute__((noreturn)) void child_init_signal_and_exit(int status) +{ + child_init_signal(status); + exit(status); } static void safe_close(int *fd) @@ -420,8 +424,10 @@ potential clients will block rather than error if we are running but the cluster is not ready yet */ local_sock = open_local_sock(); - if (local_sock < 0) - child_init_signal(DFAIL_LOCAL_SOCK); + if (local_sock < 0) { + child_init_signal_and_exit(DFAIL_LOCAL_SOCK); + /* NOTREACHED */ + } /* Set up signal handlers, USR1 is for cluster change notifications (in cman) USR2 causes child threads to exit. @@ -498,10 +504,8 @@ if (!clops) { DEBUGLOG("Can't initialise cluster interface\n"); log_error("Can't initialise cluster interface\n"); - child_init_signal(DFAIL_CLUSTER_IF); -#ifdef __clang__ - __builtin_unreachable(); -#endif + child_init_signal_and_exit(DFAIL_CLUSTER_IF); + /* NOTREACHED */ } DEBUGLOG("Cluster ready, doing some more initialisation\n"); @@ -517,10 +521,8 @@ /* Add the local socket to the list */ newfd = malloc(sizeof(struct local_client)); if (!newfd) { - child_init_signal(DFAIL_MALLOC); -#ifdef __clang__ - __builtin_unreachable(); -#endif + child_init_signal_and_exit(DFAIL_MALLOC); + /* NOTREACHED */ } newfd->fd = local_sock; From agk@sourceware.org Tue Nov 9 02:58:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Tue, 09 Nov 2010 02:58:00 -0000 Subject: LVM2 WHATS_NEW WHATS_NEW_DM VERSION VERSION_DM Message-ID: <20101109025808.8908.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-09 02:58:06 Modified files: . : WHATS_NEW WHATS_NEW_DM VERSION VERSION_DM Log message: post-release Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1790&r2=1.1791 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW_DM.diff?cvsroot=lvm2&r1=1.422&r2=1.423 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/VERSION.diff?cvsroot=lvm2&r1=1.259&r2=1.260 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/VERSION_DM.diff?cvsroot=lvm2&r1=1.68&r2=1.69 --- LVM2/WHATS_NEW 2010/11/08 19:37:40 1.1790 +++ LVM2/WHATS_NEW 2010/11/09 02:58:06 1.1791 @@ -1,3 +1,6 @@ +Version 2.02.77 - +=================================== + Version 2.02.76 - 8th November 2010 =================================== Clarify error messages when activation fails due to activation filter use. --- LVM2/WHATS_NEW_DM 2010/11/08 19:37:40 1.422 +++ LVM2/WHATS_NEW_DM 2010/11/09 02:58:06 1.423 @@ -1,3 +1,6 @@ +Version 1.02.58 - +=================================== + Version 1.02.57 - 8th November 2010 =================================== Fix regex optimiser not to ignore RHS of OR nodes in _find_leftmost_common. --- LVM2/VERSION 2010/11/08 19:37:40 1.259 +++ LVM2/VERSION 2010/11/09 02:58:06 1.260 @@ -1 +1 @@ -2.02.76(2)-cvs (2010-11-08) +2.02.77(2)-cvs (2010-11-08) --- LVM2/VERSION_DM 2010/11/08 19:37:40 1.68 +++ LVM2/VERSION_DM 2010/11/09 02:58:06 1.69 @@ -1 +1 @@ -1.02.57-cvs (2010-11-08) +1.02.58-cvs (2010-11-08) From agk@sourceware.org Tue Nov 9 11:14:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Tue, 09 Nov 2010 11:14:00 -0000 Subject: LVM2 configure Message-ID: <20101109111412.12215.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-09 11:14:09 Modified files: . : configure Log message: forgotten to regenerate last time configure.in was updated Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/configure.diff?cvsroot=lvm2&r1=1.141&r2=1.142 --- LVM2/configure 2010/08/23 13:44:31 1.141 +++ LVM2/configure 2010/11/09 11:14:06 1.142 @@ -662,6 +662,7 @@ POOL PKGCONFIG REPLICATORS +OCF MIRRORS LVM_RELEASE_DATE LVM_RELEASE @@ -835,6 +836,7 @@ with_replicators enable_readline enable_realtime +enable_ocf with_clvmd with_clvmd_pidfile enable_cmirrord @@ -1539,6 +1541,8 @@ device-mapper is missing from the kernel --disable-readline disable readline support --enable-realtime enable realtime clock support + --enable-ocf enable Open Cluster Framework (OCF) compliant + resource agents --enable-cmirrord enable the cluster mirror log daemon --enable-debug enable debugging --enable-profiling gather gcov profiling data @@ -7892,96 +7896,8 @@ ################################################################################ -{ $as_echo "$as_me:$LINENO: checking for library containing floor" >&5 -$as_echo_n "checking for library containing floor... " >&6; } -if test "${ac_cv_search_floor+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char floor (); -int -main () -{ -return floor (); - ; - return 0; -} -_ACEOF -for ac_lib in '' m; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_search_floor=$ac_res -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_floor+set}" = set; then - break -fi -done -if test "${ac_cv_search_floor+set}" = set; then - : -else - ac_cv_search_floor=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_search_floor" >&5 -$as_echo "$ac_cv_search_floor" >&6; } -ac_res=$ac_cv_search_floor -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" -else - { { $as_echo "$as_me:$LINENO: error: bailing out" >&5 -$as_echo "$as_me: error: bailing out" >&2;} - { (exit 1); exit 1; }; } -fi @@ -8004,11 +7920,7 @@ - - - - -for ac_func in floor ftruncate gethostname getpagesize \ +for ac_func in ftruncate gethostname getpagesize \ gettimeofday memset mkdir mkfifo rmdir munmap nl_langinfo setenv setlocale \ strcasecmp strchr strcspn strspn strdup strncasecmp strerror strrchr \ strstr strtol strtoul uname @@ -11423,6 +11335,19 @@ $as_echo "$REALTIME" >&6; } ################################################################################ +{ $as_echo "$as_me:$LINENO: checking whether to enable OCF resource agents" >&5 +$as_echo_n "checking whether to enable OCF resource agents... " >&6; } +# Check whether --enable-ocf was given. +if test "${enable_ocf+set}" = set; then + enableval=$enable_ocf; OCF=$enableval +else + OCF=no +fi + +{ $as_echo "$as_me:$LINENO: result: $OCF" >&5 +$as_echo "$OCF" >&6; } + +################################################################################ pkg_config_init() { @@ -18264,6 +18189,7 @@ + ################################################################################ ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile doc/Makefile doc/example.conf include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/snapshot/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/lvm2_monitoring_init_red_hat scripts/Makefile test/Makefile test/api/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile" From agk@sourceware.org Tue Nov 9 11:15:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Tue, 09 Nov 2010 11:15:00 -0000 Subject: LVM2 WHATS_NEW Message-ID: <20101109111540.12805.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-09 11:15:37 Modified files: . : WHATS_NEW Log message: Regenerate configure with 'autoreconf' for --enable-ocf. (2.02.76) Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1791&r2=1.1792 --- LVM2/WHATS_NEW 2010/11/09 02:58:06 1.1791 +++ LVM2/WHATS_NEW 2010/11/09 11:15:34 1.1792 @@ -1,5 +1,6 @@ Version 2.02.77 - =================================== + Regenerate configure with 'autoreconf' for --enable-ocf. (2.02.76) Version 2.02.76 - 8th November 2010 =================================== From agk@sourceware.org Tue Nov 9 12:34:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Tue, 09 Nov 2010 12:34:00 -0000 Subject: LVM2 ./WHATS_NEW doc/example.conf.in lib/activ ... Message-ID: <20101109123453.7567.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-09 12:34:44 Modified files: . : WHATS_NEW doc : example.conf.in lib/activate : activate.c lib/datastruct : str_list.c str_list.h lib/display : display.c lib/metadata : lv_manip.c metadata.c mirror.c vg.h man : lvm.conf.5.in tools : toollib.c Log message: Extend cling allocation policy to recognise PV tags (cling_by_tags). Add allocation/cling_tag_list to lvm.conf. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1792&r2=1.1793 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/doc/example.conf.in.diff?cvsroot=lvm2&r1=1.16&r2=1.17 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/activate.c.diff?cvsroot=lvm2&r1=1.179&r2=1.180 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/datastruct/str_list.c.diff?cvsroot=lvm2&r1=1.12&r2=1.13 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/datastruct/str_list.h.diff?cvsroot=lvm2&r1=1.9&r2=1.10 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/display/display.c.diff?cvsroot=lvm2&r1=1.113&r2=1.114 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_manip.c.diff?cvsroot=lvm2&r1=1.235&r2=1.236 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.c.diff?cvsroot=lvm2&r1=1.408&r2=1.409 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/mirror.c.diff?cvsroot=lvm2&r1=1.136&r2=1.137 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/vg.h.diff?cvsroot=lvm2&r1=1.7&r2=1.8 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/man/lvm.conf.5.in.diff?cvsroot=lvm2&r1=1.15&r2=1.16 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/toollib.c.diff?cvsroot=lvm2&r1=1.210&r2=1.211 --- LVM2/WHATS_NEW 2010/11/09 11:15:34 1.1792 +++ LVM2/WHATS_NEW 2010/11/09 12:34:40 1.1793 @@ -1,5 +1,7 @@ Version 2.02.77 - =================================== + Extend cling allocation policy to recognise PV tags (cling_by_tags). + Add allocation/cling_tag_list to lvm.conf. Regenerate configure with 'autoreconf' for --enable-ocf. (2.02.76) Version 2.02.76 - 8th November 2010 --- LVM2/doc/example.conf.in 2010/10/25 11:20:55 1.16 +++ LVM2/doc/example.conf.in 2010/11/09 12:34:41 1.17 @@ -146,6 +146,25 @@ require_restorefile_with_uuid = 1 } +# This section allows you to configure the way in which LVM selects +# free space for its Logical Volumes. +#allocation { +# When searching for free space to extend an LV, the "cling" +# allocation policy will choose space on the same PVs as the last +# segment of the existing LV. If there is insufficient space and a +# list of tags is defined here, it will check whether any of them are +# attached to the PVs concerned and then seek to match those PV tags +# between existing extents and new extents. +# Use the special tag "@*" as a wildcard to match any PV tag. +# +# Example: LVs are mirrored between two sites within a single VG. +# PVs are tagged with either @site1 or @site2 to indicate where +# they are situated. +# +# cling_tag_list = [ "@site1", "@site2" ] +# cling_tag_list = [ "@*" ] +#} + # This section that allows you to configure the nature of the # information that LVM2 reports. log { --- LVM2/lib/activate/activate.c 2010/11/05 18:18:12 1.179 +++ LVM2/lib/activate/activate.c 2010/11/09 12:34:41 1.180 @@ -275,8 +275,8 @@ return 1; /* If any host tag matches any LV or VG tag, activate */ - if (str_list_match_list(&cmd->tags, &lv->tags) || - str_list_match_list(&cmd->tags, &lv->vg->tags)) + if (str_list_match_list(&cmd->tags, &lv->tags, NULL) || + str_list_match_list(&cmd->tags, &lv->vg->tags, NULL)) return 1; log_verbose("No host tag matches %s/%s", @@ -314,9 +314,9 @@ } /* If any host tag matches any LV or VG tag, activate */ if (!strcmp(str, "*")) { - if (str_list_match_list(&cmd->tags, &lv->tags) + if (str_list_match_list(&cmd->tags, &lv->tags, NULL) || str_list_match_list(&cmd->tags, - &lv->vg->tags)) + &lv->vg->tags, NULL)) return 1; else continue; --- LVM2/lib/datastruct/str_list.c 2009/07/27 11:00:18 1.12 +++ LVM2/lib/datastruct/str_list.c 2010/11/09 12:34:41 1.13 @@ -93,14 +93,18 @@ /* * Is at least one item on both lists? + * If tag_matched is non-NULL, it is set to the tag that matched. */ -int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2) +int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, char **tag_matched) { struct str_list *sl; dm_list_iterate_items(sl, sll) - if (str_list_match_item(sll2, sl->str)) - return 1; + if (str_list_match_item(sll2, sl->str)) { + if (tag_matched) + *tag_matched = sl->str; + return 1; + } return 0; } --- LVM2/lib/datastruct/str_list.h 2008/11/03 22:14:27 1.9 +++ LVM2/lib/datastruct/str_list.h 2010/11/09 12:34:42 1.10 @@ -20,7 +20,7 @@ int str_list_add(struct dm_pool *mem, struct dm_list *sll, const char *str); int str_list_del(struct dm_list *sll, const char *str); int str_list_match_item(const struct dm_list *sll, const char *str); -int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2); +int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, char **tag_matched); int str_list_lists_equal(const struct dm_list *sll, const struct dm_list *sll2); int str_list_dup(struct dm_pool *mem, struct dm_list *sllnew, const struct dm_list *sllold); --- LVM2/lib/display/display.c 2010/10/25 13:54:29 1.113 +++ LVM2/lib/display/display.c 2010/11/09 12:34:42 1.114 @@ -26,12 +26,13 @@ static const struct { alloc_policy_t alloc; - const char str[12]; /* must be changed when size extends 11 chars */ + const char str[14]; /* must be changed when size extends 13 chars */ const char repchar; } _policies[] = { { ALLOC_CONTIGUOUS, "contiguous", 'c'}, { ALLOC_CLING, "cling", 'l'}, { + ALLOC_CLING_BY_TAGS, "cling_by_tags", 't'}, { /* Only used in log mesgs */ ALLOC_NORMAL, "normal", 'n'}, { ALLOC_ANYWHERE, "anywhere", 'a'}, { ALLOC_INHERIT, "inherit", 'i'} @@ -147,12 +148,16 @@ { int i; + /* cling_by_tags is part of cling */ + if (!strcmp("cling_by_tags", str)) + return ALLOC_CLING; + for (i = 0; i < _num_policies; i++) if (!strcmp(_policies[i].str, str)) return _policies[i].alloc; /* Special case for old metadata */ - if(!strcmp("next free", str)) + if (!strcmp("next free", str)) return ALLOC_NORMAL; log_error("Unrecognised allocation policy %s", str); --- LVM2/lib/metadata/lv_manip.c 2010/11/05 18:18:12 1.235 +++ LVM2/lib/metadata/lv_manip.c 2010/11/09 12:34:42 1.236 @@ -526,6 +526,8 @@ uint32_t region_size; /* Mirror region size */ uint32_t total_area_len; /* Total number of parallel extents */ + const struct config_node *cling_tag_list_cn; + struct dm_list *parallel_areas; /* PVs to avoid */ /* @@ -640,6 +642,8 @@ ah->parallel_areas = parallel_areas; + ah->cling_tag_list_cn = find_config_tree_node(cmd, "allocation/cling_tag_list"); + return ah; } @@ -927,18 +931,19 @@ * Search for pvseg that matches condition */ struct pv_match { - int (*condition)(struct pv_segment *pvseg, struct pv_area *pva); + int (*condition)(struct pv_match *pvmatch, struct pv_segment *pvseg, struct pv_area *pva); struct pv_area_used *areas; struct pv_area *pva; uint32_t areas_size; + const struct config_node *cling_tag_list_cn; int s; /* Area index of match */ }; /* * Is PV area on the same PV? */ -static int _is_same_pv(struct pv_segment *pvseg, struct pv_area *pva) +static int _is_same_pv(struct pv_match *pvmatch __attribute((unused)), struct pv_segment *pvseg, struct pv_area *pva) { if (pvseg->pv != pva->map->pv) return 0; @@ -947,9 +952,70 @@ } /* + * Does PV area have a tag listed in allocation/cling_tag_list that + * matches a tag of the PV of the existing segment? + */ +static int _has_matching_pv_tag(struct pv_match *pvmatch, struct pv_segment *pvseg, struct pv_area *pva) +{ + struct config_value *cv; + char *str; + char *tag_matched; + + for (cv = pvmatch->cling_tag_list_cn->v; cv; cv = cv->next) { + if (cv->type != CFG_STRING) { + log_error("Ignoring invalid string in config file entry " + "allocation/cling_tag_list"); + continue; + } + str = cv->v.str; + if (!*str) { + log_error("Ignoring empty string in config file entry " + "allocation/cling_tag_list"); + continue; + } + + if (*str != '@') { + log_error("Ignoring string not starting with @ in config file entry " + "allocation/cling_tag_list: %s", str); + continue; + } + + str++; + + if (!*str) { + log_error("Ignoring empty tag in config file entry " + "allocation/cling_tag_list"); + continue; + } + + /* Wildcard matches any tag against any tag. */ + if (!strcmp(str, "*")) { + if (!str_list_match_list(&pvseg->pv->tags, &pva->map->pv->tags, &tag_matched)) + continue; + else { + log_debug("Matched allocation PV tag %s on existing %s with free space on %s.", + tag_matched, pv_dev_name(pvseg->pv), pv_dev_name(pva->map->pv)); + return 1; + } + } + + if (!str_list_match_item(&pvseg->pv->tags, str) || + !str_list_match_item(&pva->map->pv->tags, str)) + continue; + else { + log_debug("Matched allocation PV tag %s on existing %s with free space on %s.", + str, pv_dev_name(pvseg->pv), pv_dev_name(pva->map->pv)); + return 1; + } + } + + return 0; +} + +/* * Is PV area contiguous to PV segment? */ -static int _is_contiguous(struct pv_segment *pvseg, struct pv_area *pva) +static int _is_contiguous(struct pv_match *pvmatch __attribute((unused)), struct pv_segment *pvseg, struct pv_area *pva) { if (pvseg->pv != pva->map->pv) return 0; @@ -966,7 +1032,7 @@ { struct pv_match *pvmatch = data; - if (!pvmatch->condition(pvseg, pvmatch->pva)) + if (!pvmatch->condition(pvmatch, pvseg, pvmatch->pva)) return 1; /* Continue */ if (s >= pvmatch->areas_size) @@ -991,16 +1057,18 @@ * Is pva on same PV as any existing areas? */ static int _check_cling(struct cmd_context *cmd, + const struct config_node *cling_tag_list_cn, struct lv_segment *prev_lvseg, struct pv_area *pva, struct pv_area_used *areas, uint32_t areas_size) { struct pv_match pvmatch; int r; - pvmatch.condition = _is_same_pv; + pvmatch.condition = cling_tag_list_cn ? _has_matching_pv_tag : _is_same_pv; pvmatch.areas = areas; pvmatch.areas_size = areas_size; pvmatch.pva = pva; + pvmatch.cling_tag_list_cn = cling_tag_list_cn; /* FIXME Cope with stacks by flattening */ if (!(r = _for_each_pv(cmd, prev_lvseg->lv, @@ -1029,6 +1097,7 @@ pvmatch.areas = areas; pvmatch.areas_size = areas_size; pvmatch.pva = pva; + pvmatch.cling_tag_list_cn = NULL; /* FIXME Cope with stacks by flattening */ if (!(r = _for_each_pv(cmd, prev_lvseg->lv, @@ -1056,7 +1125,7 @@ struct pv_area *pva; struct pv_list *pvl; unsigned already_found_one = 0; - unsigned contiguous = 0, cling = 0, preferred_count = 0; + unsigned contiguous = 0, cling = 0, use_cling_tags = 0, preferred_count = 0; unsigned ix, last_ix; unsigned ix_offset = 0; /* Offset for non-preferred allocations */ unsigned ix_log_offset; /* Offset to start of areas to use for log */ @@ -1089,7 +1158,10 @@ contiguous = 1; else if ((alloc == ALLOC_CLING)) cling = 1; - else + else if ((alloc == ALLOC_CLING_BY_TAGS)) { + cling = 1; + use_cling_tags = 1; + } else ix_offset = 0; } @@ -1176,9 +1248,10 @@ if (cling) { if (prev_lvseg && _check_cling(ah->cmd, - prev_lvseg, - pva, *areas_ptr, - *areas_size_ptr)) { + use_cling_tags ? ah->cling_tag_list_cn : NULL, + prev_lvseg, + pva, *areas_ptr, + *areas_size_ptr)) { preferred_count++; } goto next_pv; @@ -1361,8 +1434,18 @@ return 0; } + /* + * cling includes implicit cling_by_tags + * but it does nothing unless the lvm.conf setting is present. + */ + if (ah->alloc == ALLOC_CLING) + ah->alloc = ALLOC_CLING_BY_TAGS; + /* Attempt each defined allocation policy in turn */ for (alloc = ALLOC_CONTIGUOUS; alloc < ALLOC_INHERIT; alloc++) { + /* Skip cling_by_tags if no list defined */ + if (alloc == ALLOC_CLING_BY_TAGS && !ah->cling_tag_list_cn) + continue; old_allocated = allocated; log_debug("Trying allocation using %s policy. " "Need %" PRIu32 " extents for %" PRIu32 " parallel areas and %" PRIu32 " log areas of %" PRIu32 " extents. " @@ -1829,8 +1912,8 @@ /* * Compose a new name for sub lv: * e.g. new name is "lvol1_mlog" - * if the sub LV is "lvol0_mlog" and - * a new name for main LV is "lvol1" + * if the sub LV is "lvol0_mlog" and + * a new name for main LV is "lvol1" */ len = strlen(lv_name_new) + strlen(suffix) + 1; new_name = dm_pool_alloc(cmd->mem, len); @@ -2339,7 +2422,7 @@ } } - return lv_remove_single(cmd, lv, force); + return lv_remove_single(cmd, lv, force); } /* --- LVM2/lib/metadata/metadata.c 2010/10/25 13:54:29 1.408 +++ LVM2/lib/metadata/metadata.c 2010/11/09 12:34:42 1.409 @@ -2164,6 +2164,12 @@ uint32_t num_snapshots = 0; uint32_t loop_counter1, loop_counter2; + if (vg->alloc == ALLOC_CLING_BY_TAGS) { + log_error(INTERNAL_ERROR "VG %s allocation policy set to invalid cling_by_tags.", + vg->name); + r = 0; + } + /* FIXME Also check there's no data/metadata overlap */ dm_list_iterate_items(pvl, &vg->pvs) { if (++pv_count > vg->pv_count) { @@ -2233,6 +2239,12 @@ r = 0; } + if (lvl->lv->alloc == ALLOC_CLING_BY_TAGS) { + log_error(INTERNAL_ERROR "LV %s allocation policy set to invalid cling_by_tags.", + lvl->lv->name); + r = 0; + } + if (lvl->lv->status & VISIBLE_LV) continue; --- LVM2/lib/metadata/mirror.c 2010/10/14 20:03:13 1.136 +++ LVM2/lib/metadata/mirror.c 2010/11/09 12:34:43 1.137 @@ -400,7 +400,7 @@ struct str_list *sl; /* Inherit tags - maybe needed for activation */ - if (!str_list_match_list(&mirror_lv->tags, &lv->tags)) { + if (!str_list_match_list(&mirror_lv->tags, &lv->tags, NULL)) { dm_list_iterate_items(sl, &mirror_lv->tags) if (!str_list_add(cmd->mem, &lv->tags, sl->str)) { log_error("Aborting. Unable to tag."); --- LVM2/lib/metadata/vg.h 2010/10/25 12:01:59 1.7 +++ LVM2/lib/metadata/vg.h 2010/11/09 12:34:43 1.8 @@ -25,6 +25,7 @@ ALLOC_INVALID, ALLOC_CONTIGUOUS, ALLOC_CLING, + ALLOC_CLING_BY_TAGS, /* Internal - never written or displayed. */ ALLOC_NORMAL, ALLOC_ANYWHERE, ALLOC_INHERIT --- LVM2/man/lvm.conf.5.in 2010/10/15 16:24:01 1.15 +++ LVM2/man/lvm.conf.5.in 2010/11/09 12:34:43 1.16 @@ -172,6 +172,28 @@ the respective operation. Setting the parameter to 0 disables the counters altogether. .TP +\fBallocation\fP \(em Space allocation policies +.IP +\fBcling_tag_list\fP \(em List of PV tags matched by the \fBcling\fP allocation policy. +.IP +When searching for free space to extend an LV, the \fBcling\fP +allocation policy will choose space on the same PVs as the last +segment of the existing LV. If there is insufficient space and a +list of tags is defined here, it will check whether any of them are +attached to the PVs concerned and then seek to match those PV tags +between existing extents and new extents. +.IP +The @ prefix for tags is required. +Use the special tag "@*" as a wildcard to match any PV tag and so use +all PV tags for this purpose. +.IP +For example, LVs are mirrored between two sites within a single VG. +PVs are tagged with either @site1 or @site2 to indicate where +they are situated and these two PV tags are selected for use with this +allocation policy: +.IP +cling_tag_list = [ "@site1", "@site2" ] +.TP \fBlog\fP \(em Default log settings .IP \fBfile\fP \(em Location of log file. If this entry is not present, no --- LVM2/tools/toollib.c 2010/10/25 12:08:15 1.210 +++ LVM2/tools/toollib.c 2010/11/09 12:34:43 1.211 @@ -115,7 +115,7 @@ /* Or if VG tags match */ if (!process_lv && tags_supplied && - str_list_match_list(tags, &vg->tags)) { + str_list_match_list(tags, &vg->tags, NULL)) { process_all = 1; } @@ -141,7 +141,7 @@ /* LV tag match? */ if (!process_lv && tags_supplied && - str_list_match_list(tags, &lvl->lv->tags)) { + str_list_match_list(tags, &lvl->lv->tags, NULL)) { process_lv = 1; } @@ -487,7 +487,7 @@ if (!dm_list_empty(tags) && /* Only process if a tag matches or it's on arg_vgnames */ !str_list_match_item(arg_vgnames, vg_name) && - !str_list_match_list(tags, &cvl_vg->vg->tags)) + !str_list_match_list(tags, &cvl_vg->vg->tags, NULL)) break; ret = process_single_vg(cmd, vg_name, cvl_vg->vg, handle); @@ -606,7 +606,7 @@ dm_list_iterate_items(pvl, &vg->pvs) { if (tags && !dm_list_empty(tags) && - !str_list_match_list(tags, &pvl->pv->tags)) { + !str_list_match_list(tags, &pvl->pv->tags, NULL)) { continue; } if ((ret = process_single_pv(cmd, vg, pvl->pv, handle)) > ret_max) From zkabelac@sourceware.org Wed Nov 10 10:03:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Wed, 10 Nov 2010 10:03:00 -0000 Subject: LVM2/scripts fsadm.sh Message-ID: <20101110100307.3127.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-10 10:03:07 Modified files: scripts : fsadm.sh Log message: Scan also 'mount' output for mounted filesystem. As util-linux package seems to give all the time different names, try harder to figure out, where is the given lv possible mounted and scan /proc/mounts and if not found there, test also 'mount' output. /dev/dm-xxx /dev/mapper/vg-lv /dev/vg/lv All of them could be used different combination in /proc/mount and mount output. Patch fixes regression for older systems where new detection code failed to find valid combination. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/scripts/fsadm.sh.diff?cvsroot=lvm2&r1=1.21&r2=1.22 --- LVM2/scripts/fsadm.sh 2010/11/01 14:08:52 1.21 +++ LVM2/scripts/fsadm.sh 2010/11/10 10:03:07 1.22 @@ -199,6 +199,10 @@ # for empty string try again with real volume name test -z "$MOUNTED" && MOUNTED=$($GREP ^"$RVOLUME" $PROCMOUNTS) + # for systems with different device names - check also mount output + test -z "$MOUNTED" && MOUNTED=$($MOUNT | $GREP ^"$VOLUME") + test -z "$MOUNTED" && MOUNTED=$($MOUNT | $GREP ^"$RVOLUME") + # cut device name prefix and trim everything past mountpoint # echo translates \040 to spaces MOUNTED=${MOUNTED#* } From zkabelac@sourceware.org Wed Nov 10 10:05:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Wed, 10 Nov 2010 10:05:00 -0000 Subject: LVM2 WHATS_NEW Message-ID: <20101110100527.4817.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-10 10:05:27 Modified files: . : WHATS_NEW Log message: Update fsadm regresion Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1793&r2=1.1794 --- LVM2/WHATS_NEW 2010/11/09 12:34:40 1.1793 +++ LVM2/WHATS_NEW 2010/11/10 10:05:27 1.1794 @@ -1,5 +1,6 @@ Version 2.02.77 - =================================== + Fix regression in detection of mounted filesystem for older systems (2.0.75). Extend cling allocation policy to recognise PV tags (cling_by_tags). Add allocation/cling_tag_list to lvm.conf. Regenerate configure with 'autoreconf' for --enable-ocf. (2.02.76) From zkabelac@sourceware.org Wed Nov 10 16:14:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Wed, 10 Nov 2010 16:14:00 -0000 Subject: LVM2 ./WHATS_NEW scripts/fsadm.sh Message-ID: <20101110161405.12477.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-10 16:14:03 Modified files: . : WHATS_NEW scripts : fsadm.sh Log message: fsadm fix for downsize of unmounted fs Fix for the last commit as $MOUNTED is not only used as bool flag, but also store mounted location for remount - so parsing output from mount differently then from /proc/mounts. Prefix calls of 'tunefs' tools with LANG=C to be sure we always do get some nonlocalized strings. Avoid using forced 'resize2fs' for cleanly unmounted filesystems and run regular fsck -f for this case as required by resize2fs. 'fsadm check' uses date difference for extX filesystems between the last mount and last check of 'fsck -f' execution and if the mount was later run 'fsck' with -f so resize2fs is happy and user does not need to pass '-f' flag. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1794&r2=1.1795 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/scripts/fsadm.sh.diff?cvsroot=lvm2&r1=1.22&r2=1.23 --- LVM2/WHATS_NEW 2010/11/10 10:05:27 1.1794 +++ LVM2/WHATS_NEW 2010/11/10 16:14:02 1.1795 @@ -1,6 +1,7 @@ Version 2.02.77 - =================================== - Fix regression in detection of mounted filesystem for older systems (2.0.75). + Fix fsadm need of using '-f' for downsize of unmounted filesystem. + Fix fsadm regression in detection of mounted filesystem for older systems (2.0.75). Extend cling allocation policy to recognise PV tags (cling_by_tags). Add allocation/cling_tag_list to lvm.conf. Regenerate configure with 'autoreconf' for --enable-ocf. (2.02.76) --- LVM2/scripts/fsadm.sh 2010/11/10 10:03:07 1.22 +++ LVM2/scripts/fsadm.sh 2010/11/10 16:14:03 1.23 @@ -199,14 +199,19 @@ # for empty string try again with real volume name test -z "$MOUNTED" && MOUNTED=$($GREP ^"$RVOLUME" $PROCMOUNTS) - # for systems with different device names - check also mount output - test -z "$MOUNTED" && MOUNTED=$($MOUNT | $GREP ^"$VOLUME") - test -z "$MOUNTED" && MOUNTED=$($MOUNT | $GREP ^"$RVOLUME") - # cut device name prefix and trim everything past mountpoint # echo translates \040 to spaces MOUNTED=${MOUNTED#* } MOUNTED=$(echo -n -e ${MOUNTED%% *}) + + # for systems with different device names - check also mount output + if test -z "$MOUNTED" ; then + MOUNTED=$(LANG=C $MOUNT | $GREP ^"$VOLUME") + test -z "$MOUNTED" && MOUNTED=$(LANG=C $MOUNT | $GREP ^"$RVOLUME") + MOUNTED=${MOUNTED##* on } + MOUNTED=${MOUNTED% type *} # allow type in the mount name + fi + test -n "$MOUNTED" } @@ -271,7 +276,7 @@ #################################### resize_ext() { verbose "Parsing $TUNE_EXT -l \"$VOLUME\"" - for i in $($TUNE_EXT -l "$VOLUME"); do + for i in $(LANG=C $TUNE_EXT -l "$VOLUME"); do case "$i" in "Block size"*) BLOCKSIZE=${i##* } ;; "Block count"*) BLOCKCOUNT=${i##* } ;; @@ -284,8 +289,13 @@ if [ "$NEWBLOCKCOUNT" -lt "$BLOCKCOUNT" -o "$EXTOFF" -eq 1 ]; then detect_mounted && verbose "$RESIZE_EXT needs unmounted filesystem" && try_umount REMOUNT=$MOUNTED - # CHECKME: after umount resize2fs requires fsck or -f flag. - FSFORCE="-f" + if test -n "$MOUNTED" ; then + # Forced fsck -f for umounted extX filesystem. + case "$-" in + *i*) dry $FSCK $YES -f "$VOLUME" ;; + *) dry $FSCK -f -p "$VOLUME" ;; + esac + fi fi verbose "Resizing filesystem on device \"$VOLUME\" to $NEWSIZE bytes ($BLOCKCOUNT -> $NEWBLOCKCOUNT blocks of $BLOCKSIZE bytes)" @@ -301,7 +311,7 @@ detect_mounted && verbose "ReiserFS resizes only unmounted filesystem" && try_umount REMOUNT=$MOUNTED verbose "Parsing $TUNE_REISER \"$VOLUME\"" - for i in $($TUNE_REISER "$VOLUME"); do + for i in $(LANG=C $TUNE_REISER "$VOLUME"); do case "$i" in "Blocksize"*) BLOCKSIZE=${i##*: } ;; "Count of blocks"*) BLOCKCOUNT=${i##*: } ;; @@ -330,7 +340,7 @@ temp_mount || error "Cannot mount Xfs filesystem" fi verbose "Parsing $TUNE_XFS \"$MOUNTPOINT\"" - for i in $($TUNE_XFS "$MOUNTPOINT"); do + for i in $(LANG=C $TUNE_XFS "$MOUNTPOINT"); do case "$i" in "data"*) BLOCKSIZE=${i##*bsize=} ; BLOCKCOUNT=${i##*blocks=} ;; esac @@ -370,6 +380,15 @@ cleanup 0 } +#################################### +# Calclulate diff between two dates +# LANG=C input is expected the +# only one supported +#################################### +diff_dates() { + echo $(( $(date -u -d"$1" +%s 2>/dev/null) - $(date -u -d"$2" +%s 2>/dev/null) )) +} + ################### # Check filesystem ################### @@ -379,6 +398,30 @@ verbose "Skipping filesystem check for device \"$VOLUME\" as the filesystem is mounted on $MOUNTED"; cleanup 3 fi + + case "$FSTYPE" in + "ext2"|"ext3"|"ext4") + IFS_CHECK=$IFS + IFS=$NL + for i in $(LANG=C $TUNE_EXT -l "$VOLUME"); do + case "$i" in + "Last mount"*) LASTMOUNT=${i##*: } ;; + "Last checked"*) LASTCHECKED=${i##*: } ;; + esac + done + case "$LASTMOUNT" in + *"n/a") ;; # nothing to do - system was not mounted yet + *) + LASTDIFF=$(diff_dates $LASTMOUNT $LASTCHECKED) + if test "$LASTDIFF" -gt 0 ; then + verbose "Filesystem has not been checked after the last mount, using fsck -f" + FORCE="-f" + fi + ;; + esac + IFS=$IFS_CHECK + esac + case "$FSTYPE" in "xfs") dry $XFS_CHECK "$VOLUME" ;; *) # check if executed from interactive shell environment From zkabelac@sourceware.org Thu Nov 11 12:17:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Thu, 11 Nov 2010 12:17:00 -0000 Subject: LVM2/scripts fsadm.sh Message-ID: <20101111121716.12701.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-11 12:17:15 Modified files: scripts : fsadm.sh Log message: Add date configurable variable DATE Follow the rule to run every command through variable dereference. Add a runtime check of translated date to seconds. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/scripts/fsadm.sh.diff?cvsroot=lvm2&r1=1.23&r2=1.24 --- LVM2/scripts/fsadm.sh 2010/11/10 16:14:03 1.23 +++ LVM2/scripts/fsadm.sh 2010/11/11 12:17:15 1.24 @@ -47,6 +47,7 @@ RMDIR=rmdir BLOCKDEV=blockdev BLKID=blkid +DATE=date GREP=grep READLINK=readlink READLINK_E="-e" @@ -386,7 +387,7 @@ # only one supported #################################### diff_dates() { - echo $(( $(date -u -d"$1" +%s 2>/dev/null) - $(date -u -d"$2" +%s 2>/dev/null) )) + echo $(( $($DATE -u -d"$1" +%s 2>/dev/null) - $($DATE -u -d"$2" +%s 2>/dev/null) )) } ################### @@ -445,7 +446,7 @@ test -n "$TUNE_EXT" -a -n "$RESIZE_EXT" -a -n "$TUNE_REISER" -a -n "$RESIZE_REISER" \ -a -n "$TUNE_XFS" -a -n "$RESIZE_XFS" -a -n "$MOUNT" -a -n "$UMOUNT" -a -n "$MKDIR" \ -a -n "$RMDIR" -a -n "$BLOCKDEV" -a -n "$BLKID" -a -n "$GREP" -a -n "$READLINK" \ - -a -n "$FSCK" -a -n "$XFS_CHECK" -a -n "LVM" \ + -a -n "$DATE" -a -n "$FSCK" -a -n "$XFS_CHECK" -a -n "LVM" \ || error "Required command definitions in the script are missing!" $LVM version >/dev/null 2>&1 || error "Could not run lvm binary '$LVM'" @@ -453,6 +454,7 @@ TEST64BIT=$(( 1000 * 1000000000000 )) test $TEST64BIT -eq 1000000000000000 || error "Shell does not handle 64bit arithmetic" $(echo Y | $GREP Y >/dev/null) || error "Grep does not work properly" +test $($DATE -u -d"Jan 01 00:00:01 1970" +%s) -eq 1 || error "Date translation does not work" if [ "$#" -eq 0 ] ; then From zkabelac@sourceware.org Thu Nov 11 12:32:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Thu, 11 Nov 2010 12:32:00 -0000 Subject: LVM2/lib datastruct/str_list.c datastruct/str_ ... Message-ID: <20101111123235.18232.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-11 12:32:34 Modified files: lib/datastruct : str_list.c str_list.h lib/metadata : lv_manip.c Log message: Preserve const for char pointer Keep char pointers 'const' (introduced with cling commit). Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/datastruct/str_list.c.diff?cvsroot=lvm2&r1=1.13&r2=1.14 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/datastruct/str_list.h.diff?cvsroot=lvm2&r1=1.10&r2=1.11 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_manip.c.diff?cvsroot=lvm2&r1=1.236&r2=1.237 --- LVM2/lib/datastruct/str_list.c 2010/11/09 12:34:41 1.13 +++ LVM2/lib/datastruct/str_list.c 2010/11/11 12:32:33 1.14 @@ -95,7 +95,7 @@ * Is at least one item on both lists? * If tag_matched is non-NULL, it is set to the tag that matched. */ -int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, char **tag_matched) +int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, const char **tag_matched) { struct str_list *sl; --- LVM2/lib/datastruct/str_list.h 2010/11/09 12:34:42 1.10 +++ LVM2/lib/datastruct/str_list.h 2010/11/11 12:32:33 1.11 @@ -20,7 +20,7 @@ int str_list_add(struct dm_pool *mem, struct dm_list *sll, const char *str); int str_list_del(struct dm_list *sll, const char *str); int str_list_match_item(const struct dm_list *sll, const char *str); -int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, char **tag_matched); +int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, const char **tag_matched); int str_list_lists_equal(const struct dm_list *sll, const struct dm_list *sll2); int str_list_dup(struct dm_pool *mem, struct dm_list *sllnew, const struct dm_list *sllold); --- LVM2/lib/metadata/lv_manip.c 2010/11/09 12:34:42 1.236 +++ LVM2/lib/metadata/lv_manip.c 2010/11/11 12:32:34 1.237 @@ -959,7 +959,7 @@ { struct config_value *cv; char *str; - char *tag_matched; + const char *tag_matched; for (cv = pvmatch->cling_tag_list_cn->v; cv; cv = cv->next) { if (cv->type != CFG_STRING) { From agk@sourceware.org Thu Nov 11 17:29:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Thu, 11 Nov 2010 17:29:00 -0000 Subject: LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ... Message-ID: <20101111172909.22001.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-11 17:29:06 Modified files: . : WHATS_NEW lib/commands : toolcontext.c toolcontext.h lib/metadata : lv_manip.c metadata-exported.h liblvm : lvm_lv.c tools : args.h lvchange.c lvcreate.c lvm.c lvm2cmdline.h lvmcmdline.c pvchange.c tools.h vgchange.c vgcreate.c Log message: Support repetition of --addtag and --deltag arguments. Add infrastructure for specific cmdline arguments to be repeated in groups. Split the_args cmdline arguments and values into arg_props and arg_values. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1795&r2=1.1796 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.107&r2=1.108 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.h.diff?cvsroot=lvm2&r1=1.40&r2=1.41 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_manip.c.diff?cvsroot=lvm2&r1=1.237&r2=1.238 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata-exported.h.diff?cvsroot=lvm2&r1=1.169&r2=1.170 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_lv.c.diff?cvsroot=lvm2&r1=1.27&r2=1.28 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/args.h.diff?cvsroot=lvm2&r1=1.80&r2=1.81 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvchange.c.diff?cvsroot=lvm2&r1=1.126&r2=1.127 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvcreate.c.diff?cvsroot=lvm2&r1=1.224&r2=1.225 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvm.c.diff?cvsroot=lvm2&r1=1.114&r2=1.115 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvm2cmdline.h.diff?cvsroot=lvm2&r1=1.9&r2=1.10 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvmcmdline.c.diff?cvsroot=lvm2&r1=1.129&r2=1.130 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/pvchange.c.diff?cvsroot=lvm2&r1=1.84&r2=1.85 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/tools.h.diff?cvsroot=lvm2&r1=1.72&r2=1.73 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/vgchange.c.diff?cvsroot=lvm2&r1=1.116&r2=1.117 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/vgcreate.c.diff?cvsroot=lvm2&r1=1.80&r2=1.81 --- LVM2/WHATS_NEW 2010/11/10 16:14:02 1.1795 +++ LVM2/WHATS_NEW 2010/11/11 17:29:05 1.1796 @@ -1,7 +1,10 @@ Version 2.02.77 - =================================== - Fix fsadm need of using '-f' for downsize of unmounted filesystem. - Fix fsadm regression in detection of mounted filesystem for older systems (2.0.75). + Support repetition of --addtag and --deltag arguments. + Add infrastructure for specific cmdline arguments to be repeated in groups. + Split the_args cmdline arguments and values into arg_props and arg_values. +FIXME??? Fix fsadm need of using '-f' for downsize of unmounted filesystem. + Fix fsadm to detect mounted filesystems on older systems. (2.0.75) Extend cling allocation policy to recognise PV tags (cling_by_tags). Add allocation/cling_tag_list to lvm.conf. Regenerate configure with 'autoreconf' for --enable-ocf. (2.02.76) --- LVM2/lib/commands/toolcontext.c 2010/10/25 11:20:55 1.107 +++ LVM2/lib/commands/toolcontext.c 2010/11/11 17:29:05 1.108 @@ -1136,6 +1136,7 @@ cmd->handles_missing_pvs = 0; cmd->handles_unknown_segments = 0; cmd->hosttags = 0; + dm_list_init(&cmd->arg_value_groups); dm_list_init(&cmd->formats); dm_list_init(&cmd->segtypes); dm_list_init(&cmd->tags); --- LVM2/lib/commands/toolcontext.h 2010/10/25 11:20:55 1.40 +++ LVM2/lib/commands/toolcontext.h 2010/11/11 17:29:06 1.41 @@ -49,6 +49,7 @@ struct config_tree; struct archive_params; struct backup_params; +struct arg_values; /* FIXME Split into tool & library contexts */ /* command-instance-related variables needed by library */ @@ -68,6 +69,8 @@ const char *cmd_line; struct command *command; char **argv; + struct arg_values *arg_values; + struct dm_list arg_value_groups; unsigned is_long_lived:1; /* Optimises persistent_filter handling */ unsigned handles_missing_pvs:1; unsigned handles_unknown_segments:1; --- LVM2/lib/metadata/lv_manip.c 2010/11/11 12:32:34 1.237 +++ LVM2/lib/metadata/lv_manip.c 2010/11/11 17:29:06 1.238 @@ -3248,7 +3248,7 @@ if (!archive(vg)) return 0; - if (lp->tag) { + if (!dm_list_empty(&lp->tags)) { if (!(vg->fid->fmt->features & FMT_TAGS)) { log_error("Volume group %s does not support tags", vg->name); @@ -3283,11 +3283,8 @@ lv->minor); } - if (lp->tag && !str_list_add(cmd->mem, &lv->tags, lp->tag)) { - log_error("Failed to add tag %s to %s/%s", - lp->tag, lv->vg->name, lv->name); - return 0; - } + if (!dm_list_empty(&lp->tags)) + dm_list_splice(&lv->tags, &lp->tags); if (!lv_extend(lv, lp->segtype, lp->stripes, lp->stripe_size, 1, lp->extents, NULL, 0u, 0u, lp->pvh, lp->alloc)) --- LVM2/lib/metadata/metadata-exported.h 2010/10/12 16:41:17 1.169 +++ LVM2/lib/metadata/metadata-exported.h 2010/11/11 17:29:06 1.170 @@ -516,7 +516,7 @@ uint32_t read_ahead; /* all */ alloc_policy_t alloc; /* all */ - const char *tag; /* all */ + struct dm_list tags; /* all */ }; int lv_create_single(struct volume_group *vg, --- LVM2/liblvm/lvm_lv.c 2010/10/25 14:09:08 1.27 +++ LVM2/liblvm/lvm_lv.c 2010/11/11 17:29:06 1.28 @@ -113,7 +113,7 @@ lp->permission = LVM_READ | LVM_WRITE; lp->read_ahead = DM_READ_AHEAD_NONE; lp->alloc = ALLOC_INHERIT; - lp->tag = NULL; + dm_list_init(&lp->tags); } /* Set default for linear segment specific LV parameters */ --- LVM2/tools/args.h 2010/10/13 10:34:32 1.80 +++ LVM2/tools/args.h 2010/11/11 17:29:06 1.81 @@ -40,8 +40,8 @@ arg(removemissing_ARG, '\0', "removemissing", NULL, 0) arg(restoremissing_ARG, '\0', "restoremissing", NULL, 0) arg(abort_ARG, '\0', "abort", NULL, 0) -arg(addtag_ARG, '\0', "addtag", tag_arg, 0) -arg(deltag_ARG, '\0', "deltag", tag_arg, 0) +arg(addtag_ARG, '\0', "addtag", tag_arg, ARG_GROUPABLE) +arg(deltag_ARG, '\0', "deltag", tag_arg, ARG_GROUPABLE) arg(refresh_ARG, '\0', "refresh", NULL, 0) arg(mknodes_ARG, '\0', "mknodes", NULL, 0) arg(minor_ARG, '\0', "minor", minor_arg, 0) @@ -90,11 +90,11 @@ arg(colon_ARG, 'c', "colon", NULL, 0) arg(columns_ARG, 'C', "columns", NULL, 0) arg(contiguous_ARG, 'C', "contiguous", yes_no_arg, 0) -arg(debug_ARG, 'd', "debug", NULL, ARG_REPEATABLE) +arg(debug_ARG, 'd', "debug", NULL, ARG_COUNTABLE) arg(exported_ARG, 'e', "exported", NULL, 0) arg(physicalextent_ARG, 'E', "physicalextent", NULL, 0) arg(file_ARG, 'f', "file", string_arg, 0) -arg(force_ARG, 'f', "force", NULL, ARG_REPEATABLE) +arg(force_ARG, 'f', "force", NULL, ARG_COUNTABLE) arg(full_ARG, 'f', "full", NULL, 0) arg(help_ARG, 'h', "help", NULL, 0) arg(help2_ARG, '?', "", NULL, 0) @@ -137,7 +137,7 @@ arg(uuid_ARG, 'u', "uuid", NULL, 0) arg(uuidstr_ARG, 'u', "uuid", string_arg, 0) arg(uuidlist_ARG, 'U', "uuidlist", NULL, 0) -arg(verbose_ARG, 'v', "verbose", NULL, ARG_REPEATABLE) +arg(verbose_ARG, 'v', "verbose", NULL, ARG_COUNTABLE) arg(volumegroup_ARG, 'V', "volumegroup", NULL, 0) arg(allocatable_ARG, 'x', "allocatable", yes_no_arg, 0) arg(resizeable_ARG, 'x', "resizeable", yes_no_arg, 0) --- LVM2/tools/lvchange.c 2010/10/26 01:37:59 1.126 +++ LVM2/tools/lvchange.c 2010/11/11 17:29:06 1.127 @@ -495,14 +495,20 @@ int arg) { const char *tag; + struct arg_value_group_list *current_group; - if (!(tag = arg_str_value(cmd, arg, NULL))) { - log_error("Failed to get tag"); - return 0; - } + dm_list_iterate_items(current_group, &cmd->arg_value_groups) { + if (!grouped_arg_is_set(current_group->arg_values, arg)) + continue; - if (!lv_change_tag(lv, tag, arg == addtag_ARG)) - return_0; + if (!(tag = grouped_arg_str_value(current_group->arg_values, arg, NULL))) { + log_error("Failed to get tag"); + return 0; + } + + if (!lv_change_tag(lv, tag, arg == addtag_ARG)) + return_0; + } log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name); --- LVM2/tools/lvcreate.c 2010/10/25 12:05:46 1.224 +++ LVM2/tools/lvcreate.c 2010/11/11 17:29:06 1.225 @@ -327,9 +327,12 @@ { int contiguous; unsigned pagesize; + struct arg_value_group_list *current_group; + const char *tag; memset(lp, 0, sizeof(*lp)); memset(lcp, 0, sizeof(*lcp)); + dm_list_init(&lp->tags); /* * Check selected options are compatible and determine segtype @@ -507,7 +510,20 @@ return 0; } - lp->tag = arg_str_value(cmd, addtag_ARG, NULL); + dm_list_iterate_items(current_group, &cmd->arg_value_groups) { + if (!grouped_arg_is_set(current_group->arg_values, addtag_ARG)) + continue; + + if (!(tag = grouped_arg_str_value(current_group->arg_values, addtag_ARG, NULL))) { + log_error("Failed to get tag"); + return 0; + } + + if (!str_list_add(cmd->mem, &lp->tags, tag)) { + log_error("Unable to allocate memory for tag %s", tag); + return 0; + } + } lcp->pv_count = argc; lcp->pvs = argv; --- LVM2/tools/lvm.c 2010/10/25 12:57:00 1.114 +++ LVM2/tools/lvm.c 2010/11/11 17:29:06 1.115 @@ -95,7 +95,7 @@ while (match_no < com->num_args) { char s[3]; char c; - if (!(c = (_cmdline->the_args + + if (!(c = (_cmdline->arg_props + com->valid_args[match_no++])->short_arg)) continue; @@ -111,7 +111,7 @@ while (match_no - com->num_args < com->num_args) { const char *l; - l = (_cmdline->the_args + + l = (_cmdline->arg_props + com->valid_args[match_no++ - com->num_args])->long_arg; if (*(l + 2) && !strncmp(text, l, len)) return strdup(l); --- LVM2/tools/lvm2cmdline.h 2010/01/11 19:19:17 1.9 +++ LVM2/tools/lvm2cmdline.h 2010/11/11 17:29:06 1.10 @@ -19,7 +19,7 @@ struct cmd_context; struct cmdline_context { - struct arg *the_args; + struct arg_props *arg_props; struct command *commands; int num_commands; int commands_size; --- LVM2/tools/lvmcmdline.c 2010/10/25 11:20:56 1.129 +++ LVM2/tools/lvmcmdline.c 2010/11/11 17:29:06 1.130 @@ -50,8 +50,8 @@ /* * Table of valid switches */ -static struct arg _the_args[ARG_COUNT + 1] = { -#define arg(a, b, c, d, e) {b, "", "--" c, d, e, 0, NULL, 0, 0, INT64_C(0), UINT64_C(0), SIGN_NONE, PERCENT_NONE}, +static struct arg_props _arg_props[ARG_COUNT + 1] = { +#define arg(a, b, c, d, e) {b, "", "--" c, d, e}, #include "args.h" #undef arg }; @@ -59,10 +59,14 @@ static struct cmdline_context _cmdline; /* Command line args */ -/* FIXME: Move static _the_args into cmd? */ -unsigned arg_count(const struct cmd_context *cmd __attribute__((unused)), int a) +unsigned arg_count(const struct cmd_context *cmd, int a) { - return _the_args[a].count; + return cmd->arg_values[a].count; +} + +unsigned grouped_arg_count(const struct arg_values *av, int a) +{ + return av[a].count; } unsigned arg_is_set(const struct cmd_context *cmd, int a) @@ -70,71 +74,81 @@ return arg_count(cmd, a) ? 1 : 0; } -const char *arg_value(struct cmd_context *cmd __attribute__((unused)), int a) +unsigned grouped_arg_is_set(const struct arg_values *av, int a) +{ + return grouped_arg_count(av, a) ? 1 : 0; +} + +const char *arg_value(struct cmd_context *cmd, int a) { - return _the_args[a].value; + return cmd->arg_values[a].value; } const char *arg_str_value(struct cmd_context *cmd, int a, const char *def) { - return arg_count(cmd, a) ? _the_args[a].value : def; + return arg_count(cmd, a) ? cmd->arg_values[a].value : def; +} + +const char *grouped_arg_str_value(const struct arg_values *av, int a, const char *def) +{ + return grouped_arg_count(av, a) ? av[a].value : def; } int32_t arg_int_value(struct cmd_context *cmd, int a, const int32_t def) { - return arg_count(cmd, a) ? _the_args[a].i_value : def; + return arg_count(cmd, a) ? cmd->arg_values[a].i_value : def; } uint32_t arg_uint_value(struct cmd_context *cmd, int a, const uint32_t def) { - return arg_count(cmd, a) ? _the_args[a].ui_value : def; + return arg_count(cmd, a) ? cmd->arg_values[a].ui_value : def; } int64_t arg_int64_value(struct cmd_context *cmd, int a, const int64_t def) { - return arg_count(cmd, a) ? _the_args[a].i64_value : def; + return arg_count(cmd, a) ? cmd->arg_values[a].i64_value : def; } uint64_t arg_uint64_value(struct cmd_context *cmd, int a, const uint64_t def) { - return arg_count(cmd, a) ? _the_args[a].ui64_value : def; + return arg_count(cmd, a) ? cmd->arg_values[a].ui64_value : def; } /* No longer used. const void *arg_ptr_value(struct cmd_context *cmd, int a, const void *def) { - return arg_count(cmd, a) ? _the_args[a].ptr : def; + return arg_count(cmd, a) ? cmd->arg_values[a].ptr : def; } */ sign_t arg_sign_value(struct cmd_context *cmd, int a, const sign_t def) { - return arg_count(cmd, a) ? _the_args[a].sign : def; + return arg_count(cmd, a) ? cmd->arg_values[a].sign : def; } percent_t arg_percent_value(struct cmd_context *cmd, int a, const percent_t def) { - return arg_count(cmd, a) ? _the_args[a].percent : def; + return arg_count(cmd, a) ? cmd->arg_values[a].percent : def; } -int arg_count_increment(struct cmd_context *cmd __attribute__((unused)), int a) +int arg_count_increment(struct cmd_context *cmd, int a) { - return _the_args[a].count++; + return cmd->arg_values[a].count++; } -int yes_no_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a) +int yes_no_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av) { - a->sign = SIGN_NONE; - a->percent = PERCENT_NONE; + av->sign = SIGN_NONE; + av->percent = PERCENT_NONE; - if (!strcmp(a->value, "y")) { - a->i_value = 1; - a->ui_value = 1; + if (!strcmp(av->value, "y")) { + av->i_value = 1; + av->ui_value = 1; } - else if (!strcmp(a->value, "n")) { - a->i_value = 0; - a->ui_value = 0; + else if (!strcmp(av->value, "n")) { + av->i_value = 0; + av->ui_value = 0; } else @@ -143,37 +157,36 @@ return 1; } -int yes_no_excl_arg(struct cmd_context *cmd __attribute__((unused)), - struct arg *a) +int yes_no_excl_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av) { - a->sign = SIGN_NONE; - a->percent = PERCENT_NONE; + av->sign = SIGN_NONE; + av->percent = PERCENT_NONE; - if (!strcmp(a->value, "e") || !strcmp(a->value, "ey") || - !strcmp(a->value, "ye")) { - a->i_value = CHANGE_AE; - a->ui_value = CHANGE_AE; + if (!strcmp(av->value, "e") || !strcmp(av->value, "ey") || + !strcmp(av->value, "ye")) { + av->i_value = CHANGE_AE; + av->ui_value = CHANGE_AE; } - else if (!strcmp(a->value, "y")) { - a->i_value = CHANGE_AY; - a->ui_value = CHANGE_AY; + else if (!strcmp(av->value, "y")) { + av->i_value = CHANGE_AY; + av->ui_value = CHANGE_AY; } - else if (!strcmp(a->value, "n") || !strcmp(a->value, "en") || - !strcmp(a->value, "ne")) { - a->i_value = CHANGE_AN; - a->ui_value = CHANGE_AN; + else if (!strcmp(av->value, "n") || !strcmp(av->value, "en") || + !strcmp(av->value, "ne")) { + av->i_value = CHANGE_AN; + av->ui_value = CHANGE_AN; } - else if (!strcmp(a->value, "ln") || !strcmp(a->value, "nl")) { - a->i_value = CHANGE_ALN; - a->ui_value = CHANGE_ALN; + else if (!strcmp(av->value, "ln") || !strcmp(av->value, "nl")) { + av->i_value = CHANGE_ALN; + av->ui_value = CHANGE_ALN; } - else if (!strcmp(a->value, "ly") || !strcmp(a->value, "yl")) { - a->i_value = CHANGE_ALY; - a->ui_value = CHANGE_ALY; + else if (!strcmp(av->value, "ly") || !strcmp(av->value, "yl")) { + av->i_value = CHANGE_ALY; + av->ui_value = CHANGE_ALY; } else @@ -182,30 +195,30 @@ return 1; } -int metadatatype_arg(struct cmd_context *cmd, struct arg *a) +int metadatatype_arg(struct cmd_context *cmd, struct arg_values *av) { - return get_format_by_name(cmd, a->value) ? 1 : 0; + return get_format_by_name(cmd, av->value) ? 1 : 0; } -static int _get_int_arg(struct arg *a, char **ptr) +static int _get_int_arg(struct arg_values *av, char **ptr) { char *val; long v; - a->percent = PERCENT_NONE; + av->percent = PERCENT_NONE; - val = a->value; + val = av->value; switch (*val) { case '+': - a->sign = SIGN_PLUS; + av->sign = SIGN_PLUS; val++; break; case '-': - a->sign = SIGN_MINUS; + av->sign = SIGN_MINUS; val++; break; default: - a->sign = SIGN_NONE; + av->sign = SIGN_NONE; } if (!isdigit(*val)) @@ -216,16 +229,16 @@ if (*ptr == val) return 0; - a->i_value = (int32_t) v; - a->ui_value = (uint32_t) v; - a->i64_value = (int64_t) v; - a->ui64_value = (uint64_t) v; + av->i_value = (int32_t) v; + av->ui_value = (uint32_t) v; + av->i64_value = (int64_t) v; + av->ui64_value = (uint64_t) v; return 1; } /* Size stored in sectors */ -static int _size_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a, int factor) +static int _size_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av, int factor) { char *ptr; int i; @@ -234,20 +247,20 @@ double v; uint64_t v_tmp, adjustment; - a->percent = PERCENT_NONE; + av->percent = PERCENT_NONE; - val = a->value; + val = av->value; switch (*val) { case '+': - a->sign = SIGN_PLUS; + av->sign = SIGN_PLUS; val++; break; case '-': - a->sign = SIGN_MINUS; + av->sign = SIGN_MINUS; val++; break; default: - a->sign = SIGN_NONE; + av->sign = SIGN_NONE; } if (!isdigit(*val)) @@ -289,50 +302,50 @@ } else v *= factor; - a->i_value = (int32_t) v; - a->ui_value = (uint32_t) v; - a->i64_value = (int64_t) v; - a->ui64_value = (uint64_t) v; + av->i_value = (int32_t) v; + av->ui_value = (uint32_t) v; + av->i64_value = (int64_t) v; + av->ui64_value = (uint64_t) v; return 1; } -int size_kb_arg(struct cmd_context *cmd, struct arg *a) +int size_kb_arg(struct cmd_context *cmd, struct arg_values *av) { - return _size_arg(cmd, a, 2); + return _size_arg(cmd, av, 2); } -int size_mb_arg(struct cmd_context *cmd, struct arg *a) +int size_mb_arg(struct cmd_context *cmd, struct arg_values *av) { - return _size_arg(cmd, a, 2048); + return _size_arg(cmd, av, 2048); } -int int_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a) +int int_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av) { char *ptr; - if (!_get_int_arg(a, &ptr) || (*ptr) || (a->sign == SIGN_MINUS)) + if (!_get_int_arg(av, &ptr) || (*ptr) || (av->sign == SIGN_MINUS)) return 0; return 1; } -int int_arg_with_sign(struct cmd_context *cmd __attribute__((unused)), struct arg *a) +int int_arg_with_sign(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av) { char *ptr; - if (!_get_int_arg(a, &ptr) || (*ptr)) + if (!_get_int_arg(av, &ptr) || (*ptr)) return 0; return 1; } int int_arg_with_sign_and_percent(struct cmd_context *cmd __attribute__((unused)), - struct arg *a) + struct arg_values *av) { char *ptr; - if (!_get_int_arg(a, &ptr)) + if (!_get_int_arg(av, &ptr)) return 0; if (!*ptr) @@ -342,32 +355,32 @@ return 0; if (!strcasecmp(ptr, "V") || !strcasecmp(ptr, "VG")) - a->percent = PERCENT_VG; + av->percent = PERCENT_VG; else if (!strcasecmp(ptr, "L") || !strcasecmp(ptr, "LV")) - a->percent = PERCENT_LV; + av->percent = PERCENT_LV; else if (!strcasecmp(ptr, "P") || !strcasecmp(ptr, "PV") || !strcasecmp(ptr, "PVS")) - a->percent = PERCENT_PVS; + av->percent = PERCENT_PVS; else if (!strcasecmp(ptr, "F") || !strcasecmp(ptr, "FR") || !strcasecmp(ptr, "FREE")) - a->percent = PERCENT_FREE; + av->percent = PERCENT_FREE; else if (!strcasecmp(ptr, "O") || !strcasecmp(ptr, "OR") || !strcasecmp(ptr, "ORIGIN")) - a->percent = PERCENT_ORIGIN; + av->percent = PERCENT_ORIGIN; else return 0; return 1; } -int minor_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a) +int minor_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av) { char *ptr; - if (!_get_int_arg(a, &ptr) || (*ptr) || (a->sign == SIGN_MINUS)) + if (!_get_int_arg(av, &ptr) || (*ptr) || (av->sign == SIGN_MINUS)) return 0; - if (a->i_value > 255) { + if (av->i_value > 255) { log_error("Minor number outside range 0-255"); return 0; } @@ -375,14 +388,14 @@ return 1; } -int major_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a) +int major_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av) { char *ptr; - if (!_get_int_arg(a, &ptr) || (*ptr) || (a->sign == SIGN_MINUS)) + if (!_get_int_arg(av, &ptr) || (*ptr) || (av->sign == SIGN_MINUS)) return 0; - if (a->i_value > 255) { + if (av->i_value > 255) { log_error("Major number outside range 0-255"); return 0; } @@ -393,14 +406,14 @@ } int string_arg(struct cmd_context *cmd __attribute__((unused)), - struct arg *a __attribute__((unused))) + struct arg_values *av __attribute__((unused))) { return 1; } -int tag_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a) +int tag_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av) { - char *pos = a->value; + char *pos = av->value; if (*pos == '@') pos++; @@ -408,20 +421,20 @@ if (!validate_name(pos)) return 0; - a->value = pos; + av->value = pos; return 1; } -int permission_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a) +int permission_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av) { - a->sign = SIGN_NONE; + av->sign = SIGN_NONE; - if ((!strcmp(a->value, "rw")) || (!strcmp(a->value, "wr"))) - a->ui_value = LVM_READ | LVM_WRITE; + if ((!strcmp(av->value, "rw")) || (!strcmp(av->value, "wr"))) + av->ui_value = LVM_READ | LVM_WRITE; - else if (!strcmp(a->value, "r")) - a->ui_value = LVM_READ; + else if (!strcmp(av->value, "r")) + av->ui_value = LVM_READ; else return 0; @@ -429,45 +442,45 @@ return 1; } -int alloc_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a) +int alloc_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av) { alloc_policy_t alloc; - a->sign = SIGN_NONE; + av->sign = SIGN_NONE; - alloc = get_alloc_from_string(a->value); + alloc = get_alloc_from_string(av->value); if (alloc == ALLOC_INVALID) return 0; - a->ui_value = (uint32_t) alloc; + av->ui_value = (uint32_t) alloc; return 1; } -int segtype_arg(struct cmd_context *cmd, struct arg *a) +int segtype_arg(struct cmd_context *cmd, struct arg_values *av) { - return get_segtype_from_string(cmd, a->value) ? 1 : 0; + return get_segtype_from_string(cmd, av->value) ? 1 : 0; } /* * Positive integer, zero or "auto". */ -int readahead_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a) +int readahead_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av) { - if (!strcasecmp(a->value, "auto")) { - a->ui_value = DM_READ_AHEAD_AUTO; + if (!strcasecmp(av->value, "auto")) { + av->ui_value = DM_READ_AHEAD_AUTO; return 1; } - if (!strcasecmp(a->value, "none")) { - a->ui_value = DM_READ_AHEAD_NONE; + if (!strcasecmp(av->value, "none")) { + av->ui_value = DM_READ_AHEAD_NONE; return 1; } - if (!_size_arg(cmd, a, 1)) + if (!_size_arg(cmd, av, 1)) return 0; - if (a->sign == SIGN_MINUS) + if (av->sign == SIGN_MINUS) return 0; return 1; @@ -476,22 +489,21 @@ /* * Non-zero, positive integer, "all", or "unmanaged" */ -int metadatacopies_arg(struct cmd_context *cmd __attribute__((unused)), - struct arg *a) +int metadatacopies_arg(struct cmd_context *cmd, struct arg_values *av) { if (!strncmp(cmd->command->name, "vg", 2)) { - if (!strcasecmp(a->value, "all")) { - a->ui_value = VGMETADATACOPIES_ALL; + if (!strcasecmp(av->value, "all")) { + av->ui_value = VGMETADATACOPIES_ALL; return 1; } - if (!strcasecmp(a->value, "unmanaged")) { - a->ui_value = VGMETADATACOPIES_UNMANAGED; + if (!strcasecmp(av->value, "unmanaged")) { + av->ui_value = VGMETADATACOPIES_UNMANAGED; return 1; } } - return int_arg(cmd, a); + return int_arg(cmd, av); } static void __alloc(int size) @@ -618,7 +630,7 @@ */ static void _add_getopt_arg(int arg, char **ptr, struct option **o) { - struct arg *a = _cmdline.the_args + arg; + struct arg_props *a = _cmdline.arg_props + arg; if (a->short_arg) { *(*ptr)++ = a->short_arg; @@ -640,14 +652,14 @@ #endif } -static struct arg *_find_arg(struct command *com, int opt) +static int _find_arg(struct command *com, int opt) { - struct arg *a; + struct arg_props *a; int i, arg; for (i = 0; i < com->num_args; i++) { arg = com->valid_args[i]; - a = _cmdline.the_args + arg; + a = _cmdline.arg_props + arg; /* * opt should equal either the @@ -656,30 +668,25 @@ */ if ((a->short_arg && (opt == a->short_arg)) || (!a->short_arg && (opt == arg))) - return a; + return arg; } - return 0; + return -1; } static int _process_command_line(struct cmd_context *cmd, int *argc, char ***argv) { - int i, opt; + int i, opt, arg; char str[((ARG_COUNT + 1) * 2) + 1], *ptr = str; struct option opts[ARG_COUNT + 1], *o = opts; - struct arg *a; - - for (i = 0; i < ARG_COUNT; i++) { - a = _cmdline.the_args + i; + struct arg_props *a; + struct arg_values *av; + struct arg_value_group_list *current_group = NULL; - /* zero the count and arg */ - a->count = 0; - a->value = 0; - a->i_value = 0; - a->ui_value = 0; - a->i64_value = 0; - a->ui64_value = 0; + if (!(cmd->arg_values = dm_pool_zalloc(cmd->mem, sizeof(*cmd->arg_values) * ARG_COUNT))) { + log_fatal("Unable to allocate memory for command line arguments."); + return 0; } /* fill in the short and long opts */ @@ -697,15 +704,33 @@ if (opt == '?') return 0; - a = _find_arg(cmd->command, opt); - - if (!a) { + if ((arg = _find_arg(cmd->command, opt)) < 0) { log_fatal("Unrecognised option."); return 0; } - if (a->count && !(a->flags & ARG_REPEATABLE)) { - log_error("Option%s%c%s%s may not be repeated", + a = _cmdline.arg_props + arg; + + av = &cmd->arg_values[arg]; + + if (a->flags & ARG_GROUPABLE) { + /* Start a new group of arguments the first time or if a non-countable argument is repeated. */ + if (!current_group || (current_group->arg_values[arg].count && !(a->flags & ARG_COUNTABLE))) { + /* FIXME Reduce size including only groupable args */ + if (!(current_group = dm_pool_zalloc(cmd->mem, sizeof(struct arg_value_group_list) + sizeof(*cmd->arg_values) * ARG_COUNT))) { + log_fatal("Unable to allocate memory for command line arguments."); + return 0; + } + + dm_list_add(&cmd->arg_value_groups, ¤t_group->list); + } + /* Maintain total argument count as well as count within each group */ + av->count++; + av = ¤t_group->arg_values[arg]; + } + + if (av->count && !(a->flags & ARG_COUNTABLE)) { + log_error("Option%s%c%s%s may not be repeated.", a->short_arg ? " -" : "", a->short_arg ? : ' ', (a->short_arg && a->long_arg) ? @@ -719,15 +744,15 @@ return 0; } - a->value = optarg; + av->value = optarg; - if (!a->fn(cmd, a)) { - log_error("Invalid argument %s", optarg); + if (!a->fn(cmd, av)) { + log_error("Invalid argument for %s: %s", a->long_arg, optarg); return 0; } } - a->count++; + av->count++; } *argc -= optind; @@ -737,20 +762,20 @@ static int _merge_synonym(struct cmd_context *cmd, int oldarg, int newarg) { - const struct arg *old; - struct arg *new; + const struct arg_values *old; + struct arg_values *new; if (arg_count(cmd, oldarg) && arg_count(cmd, newarg)) { log_error("%s and %s are synonyms. Please only supply one.", - _cmdline.the_args[oldarg].long_arg, _cmdline.the_args[newarg].long_arg); + _cmdline.arg_props[oldarg].long_arg, _cmdline.arg_props[newarg].long_arg); return 0; } if (!arg_count(cmd, oldarg)) return 1; - old = _cmdline.the_args + oldarg; - new = _cmdline.the_args + newarg; + old = cmd->arg_values + oldarg; + new = cmd->arg_values + newarg; new->count = old->count; new->value = old->value; @@ -1120,6 +1145,7 @@ /* * free off any memory the command used. */ + dm_list_init(&cmd->arg_value_groups); dm_pool_empty(cmd->mem); reset_lvm_errno(1); @@ -1250,11 +1276,11 @@ { struct cmd_context *cmd; - _cmdline.the_args = &_the_args[0]; - if (!(cmd = create_toolcontext(0, NULL))) return_NULL; + _cmdline.arg_props = &_arg_props[0]; + if (stored_errno()) { destroy_toolcontext(cmd); return_NULL; --- LVM2/tools/pvchange.c 2010/09/23 12:02:34 1.84 +++ LVM2/tools/pvchange.c 2010/11/11 17:29:06 1.85 @@ -36,6 +36,8 @@ int r = 0; int mda_ignore = 0; + struct arg_value_group_list *current_group; + if (arg_count(cmd, addtag_ARG)) tagarg = addtag_ARG; else if (arg_count(cmd, deltag_ARG)) @@ -47,10 +49,6 @@ if (arg_count(cmd, metadataignore_ARG)) mda_ignore = !strcmp(arg_str_value(cmd, metadataignore_ARG, "n"), "y"); - else if (tagarg && !(tag = arg_str_value(cmd, tagarg, NULL))) { - log_error("Failed to get tag"); - return 0; - } /* If in a VG, must change using volume group. */ if (!is_orphan(pv)) { @@ -108,16 +106,25 @@ } } else if (tagarg) { /* tag or deltag */ - if ((tagarg == addtag_ARG)) { - if (!str_list_add(cmd->mem, &pv->tags, tag)) { - log_error("Failed to add tag %s to physical " - "volume %s", tag, pv_name); + + dm_list_iterate_items(current_group, &cmd->arg_value_groups) { + if (!grouped_arg_is_set(current_group->arg_values, tagarg)) + continue; + + if (!(tag = grouped_arg_str_value(current_group->arg_values, tagarg, NULL))) { + log_error("Failed to get tag"); goto out; } - } else { - if (!str_list_del(&pv->tags, tag)) { + + if ((tagarg == addtag_ARG)) { + if (!str_list_add(cmd->mem, &pv->tags, tag)) { + log_error("Failed to add tag %s to physical " + "volume %s", tag, pv_name); + goto out; + } + } else if (!str_list_del(&pv->tags, tag)) { log_error("Failed to remove tag %s from " - "physical volume" "%s", tag, pv_name); + "physical volume" "%s", tag, pv_name); goto out; } } @@ -202,8 +209,8 @@ struct dm_list *vgnames; struct str_list *sll; - if (arg_count(cmd, allocatable_ARG) + arg_count(cmd, addtag_ARG) + - arg_count(cmd, deltag_ARG) + arg_count(cmd, uuid_ARG) + + if (arg_count(cmd, allocatable_ARG) + arg_is_set(cmd, addtag_ARG) + + arg_is_set(cmd, deltag_ARG) + arg_count(cmd, uuid_ARG) + arg_count(cmd, metadataignore_ARG) != 1) { log_error("Please give exactly one option of -x, -uuid, " "--addtag or --deltag"); --- LVM2/tools/tools.h 2010/10/25 11:20:56 1.72 +++ LVM2/tools/tools.h 2010/11/11 17:29:06 1.73 @@ -95,17 +95,10 @@ CHANGE_ALN = 4 }; -#define ARG_REPEATABLE 0x00000001 - -/* a global table of possible arguments */ -struct arg { - const char short_arg; - char _padding[7]; - const char *long_arg; - - int (*fn) (struct cmd_context * cmd, struct arg * a); - uint32_t flags; +#define ARG_COUNTABLE 0x00000001 /* E.g. -vvvv */ +#define ARG_GROUPABLE 0x00000002 /* E.g. --addtag */ +struct arg_values { unsigned count; char *value; int32_t i_value; @@ -117,6 +110,21 @@ /* void *ptr; // Currently not used. */ }; +/* a global table of possible arguments */ +struct arg_props { + const char short_arg; + char _padding[7]; + const char *long_arg; + + int (*fn) (struct cmd_context *cmd, struct arg_values *av); + uint32_t flags; +}; + +struct arg_value_group_list { + struct dm_list list; + struct arg_values arg_values[0]; +}; + #define CACHE_VGMETADATA 0x00000001 #define PERMITTED_READ_ONLY 0x00000002 @@ -136,24 +144,24 @@ void usage(const char *name); /* the argument verify/normalise functions */ -int yes_no_arg(struct cmd_context *cmd, struct arg *a); -int yes_no_excl_arg(struct cmd_context *cmd, struct arg *a); -int size_kb_arg(struct cmd_context *cmd, struct arg *a); -int size_mb_arg(struct cmd_context *cmd, struct arg *a); -int int_arg(struct cmd_context *cmd, struct arg *a); -int int_arg_with_sign(struct cmd_context *cmd, struct arg *a); -int int_arg_with_sign_and_percent(struct cmd_context *cmd, struct arg *a); -int major_arg(struct cmd_context *cmd, struct arg *a); -int minor_arg(struct cmd_context *cmd, struct arg *a); -int string_arg(struct cmd_context *cmd, struct arg *a); -int tag_arg(struct cmd_context *cmd, struct arg *a); -int permission_arg(struct cmd_context *cmd, struct arg *a); -int metadatatype_arg(struct cmd_context *cmd, struct arg *a); -int units_arg(struct cmd_context *cmd, struct arg *a); -int segtype_arg(struct cmd_context *cmd, struct arg *a); -int alloc_arg(struct cmd_context *cmd, struct arg *a); -int readahead_arg(struct cmd_context *cmd, struct arg *a); -int metadatacopies_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a); +int yes_no_arg(struct cmd_context *cmd, struct arg_values *av); +int yes_no_excl_arg(struct cmd_context *cmd, struct arg_values *av); +int size_kb_arg(struct cmd_context *cmd, struct arg_values *av); +int size_mb_arg(struct cmd_context *cmd, struct arg_values *av); +int int_arg(struct cmd_context *cmd, struct arg_values *av); +int int_arg_with_sign(struct cmd_context *cmd, struct arg_values *av); +int int_arg_with_sign_and_percent(struct cmd_context *cmd, struct arg_values *av); +int major_arg(struct cmd_context *cmd, struct arg_values *av); +int minor_arg(struct cmd_context *cmd, struct arg_values *av); +int string_arg(struct cmd_context *cmd, struct arg_values *av); +int tag_arg(struct cmd_context *cmd, struct arg_values *av); +int permission_arg(struct cmd_context *cmd, struct arg_values *av); +int metadatatype_arg(struct cmd_context *cmd, struct arg_values *av); +int units_arg(struct cmd_context *cmd, struct arg_values *av); +int segtype_arg(struct cmd_context *cmd, struct arg_values *av); +int alloc_arg(struct cmd_context *cmd, struct arg_values *av); +int readahead_arg(struct cmd_context *cmd, struct arg_values *av); +int metadatacopies_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av); /* we use the enums to access the switches */ unsigned arg_count(const struct cmd_context *cmd, int a); @@ -169,6 +177,10 @@ percent_t arg_percent_value(struct cmd_context *cmd, int a, const percent_t def); int arg_count_increment(struct cmd_context *cmd, int a); +unsigned grouped_arg_count(const struct arg_values *av, int a); +unsigned grouped_arg_is_set(const struct arg_values *av, int a); +const char *grouped_arg_str_value(const struct arg_values *av, int a, const char *def); + const char *command_name(struct cmd_context *cmd); int pvmove_poll(struct cmd_context *cmd, const char *pv, unsigned background); --- LVM2/tools/vgchange.c 2010/10/29 21:15:23 1.116 +++ LVM2/tools/vgchange.c 2010/11/11 17:29:06 1.117 @@ -364,14 +364,21 @@ int arg) { const char *tag; + struct arg_value_group_list *current_group; - if (!(tag = arg_str_value(cmd, arg, NULL))) { - log_error("Failed to get tag"); - return 0; - } + dm_list_iterate_items(current_group, &cmd->arg_value_groups) { + if (!grouped_arg_is_set(current_group->arg_values, arg)) + continue; + + if (!(tag = grouped_arg_str_value(current_group->arg_values, arg, NULL))) { + log_error("Failed to get tag"); + return 0; + } - if (!vg_change_tag(vg, tag, arg == addtag_ARG)) - return_0; + if (!vg_change_tag(vg, tag, arg == addtag_ARG)) + return_0; + + } return 1; } --- LVM2/tools/vgcreate.c 2010/06/30 20:03:53 1.80 +++ LVM2/tools/vgcreate.c 2010/11/11 17:29:06 1.81 @@ -24,6 +24,7 @@ const char *clustered_message = ""; char *vg_name; struct pvcreate_params pp; + struct arg_value_group_list *current_group; if (!argc) { log_error("Please provide volume group name and " @@ -85,21 +86,24 @@ "(0 means unlimited)", vg->max_pv); if (arg_count(cmd, addtag_ARG)) { - if (!(tag = arg_str_value(cmd, addtag_ARG, NULL))) { - log_error("Failed to get tag"); - goto bad; - } + dm_list_iterate_items(current_group, &cmd->arg_value_groups) { + if (!grouped_arg_is_set(current_group->arg_values, addtag_ARG)) + continue; + + if (!(tag = grouped_arg_str_value(current_group->arg_values, addtag_ARG, NULL))) { + log_error("Failed to get tag"); + goto bad; + } - if (!vg_change_tag(vg, tag, 1)) - goto_bad; + if (!vg_change_tag(vg, tag, 1)) + goto_bad; + } } - if (vg_is_clustered(vg)) { + if (vg_is_clustered(vg)) clustered_message = "Clustered "; - } else { - if (locking_is_clustered()) - clustered_message = "Non-clustered "; - } + else if (locking_is_clustered()) + clustered_message = "Non-clustered "; if (!archive(vg)) goto_bad; From prajnoha@sourceware.org Fri Nov 12 16:04:00 2010 From: prajnoha@sourceware.org (prajnoha@sourceware.org) Date: Fri, 12 Nov 2010 16:04:00 -0000 Subject: LVM2 WHATS_NEW Message-ID: <20101112160454.29731.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: prajnoha@sourceware.org 2010-11-12 16:04:53 Modified files: . : WHATS_NEW Log message: WHATS_NEW FIXME Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1796&r2=1.1797 --- LVM2/WHATS_NEW 2010/11/11 17:29:05 1.1796 +++ LVM2/WHATS_NEW 2010/11/12 16:04:52 1.1797 @@ -3,7 +3,7 @@ Support repetition of --addtag and --deltag arguments. Add infrastructure for specific cmdline arguments to be repeated in groups. Split the_args cmdline arguments and values into arg_props and arg_values. -FIXME??? Fix fsadm need of using '-f' for downsize of unmounted filesystem. + Fix fsadm to not require '-f' for resize of unmounted filesystem. Fix fsadm to detect mounted filesystems on older systems. (2.0.75) Extend cling allocation policy to recognise PV tags (cling_by_tags). Add allocation/cling_tag_list to lvm.conf. From agk@sourceware.org Wed Nov 17 10:19:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Wed, 17 Nov 2010 10:19:00 -0000 Subject: LVM2 ./WHATS_NEW lib/misc/lvm-string.c lib/mis ... Message-ID: <20101117101931.20959.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-17 10:19:30 Modified files: . : WHATS_NEW lib/misc : lvm-string.c lvm-string.h man : lvm.8.in tools : lvmcmdline.c toollib.c Log message: Remove tag length restriction and allow / = ! : # & characters. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1797&r2=1.1798 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-string.c.diff?cvsroot=lvm2&r1=1.23&r2=1.24 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-string.h.diff?cvsroot=lvm2&r1=1.21&r2=1.22 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/man/lvm.8.in.diff?cvsroot=lvm2&r1=1.5&r2=1.6 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvmcmdline.c.diff?cvsroot=lvm2&r1=1.130&r2=1.131 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/toollib.c.diff?cvsroot=lvm2&r1=1.211&r2=1.212 --- LVM2/WHATS_NEW 2010/11/12 16:04:52 1.1797 +++ LVM2/WHATS_NEW 2010/11/17 10:19:29 1.1798 @@ -1,5 +1,6 @@ Version 2.02.77 - =================================== + Remove tag length restriction and allow / = ! : # & characters. Support repetition of --addtag and --deltag arguments. Add infrastructure for specific cmdline arguments to be repeated in groups. Split the_args cmdline arguments and values into arg_props and arg_values. --- LVM2/lib/misc/lvm-string.c 2010/09/28 01:29:07 1.23 +++ LVM2/lib/misc/lvm-string.c 2010/11/17 10:19:30 1.24 @@ -286,6 +286,25 @@ } /* + * A-Za-z0-9._-+/=!:&# + */ +int validate_tag(const char *n) +{ + register char c; + register int len = 0; + + if (!n || !*n) + return 0; + + while ((len++, c = *n++)) + if (!isalnum(c) && c != '.' && c != '_' && c != '-' && c != '+' && c != '/' + && c != '=' && c != '!' && c != ':' && c != '&' && c != '#') + return 0; + + return 1; +} + +/* * Device layer names are all of the form --, any * other hyphens that appear in these names are quoted with yet * another hyphen. The top layer of any device has no layer --- LVM2/lib/misc/lvm-string.h 2010/09/23 12:02:34 1.21 +++ LVM2/lib/misc/lvm-string.h 2010/11/17 10:19:30 1.22 @@ -33,6 +33,7 @@ const char *layer); int validate_name(const char *n); +int validate_tag(const char *n); int apply_lvname_restrictions(const char *name); int is_reserved_lvname(const char *name); --- LVM2/man/lvm.8.in 2010/05/20 13:47:22 1.5 +++ LVM2/man/lvm.8.in 2010/11/17 10:19:30 1.6 @@ -205,6 +205,7 @@ .TP \fB--addtag tag\fP Add the tag \fBtag\fP to a PV, VG or LV. +Supply this argument multiple times to add more than one tag at once. A tag is a word that can be used to group LVM2 objects of the same type together. Tags can be given on the command line in place of PV, VG or LV @@ -221,10 +222,13 @@ LVM1 metadata format cannot be tagged because the on-disk format does not support it. Snapshots cannot be tagged. -Characters allowed in tags are: A-Z a-z 0-9 _ + . - +Characters allowed in tags are: A-Z a-z 0-9 _ + . - and +as of version 2.02.78 the following characters are also +accepted: / = ! : # & .TP \fB--deltag tag\fP Delete the tag \fBtag\fP from a PV, VG or LV, if it's present. +Supply this argument multiple times to remove more than one tag at once. .TP \fB--alloc AllocationPolicy\fP The allocation policy to use: \fBcontiguous\fP, \fBcling\fP, \fBnormal\fP, \fBanywhere\fP or \fBinherit\fP. --- LVM2/tools/lvmcmdline.c 2010/11/11 17:29:06 1.130 +++ LVM2/tools/lvmcmdline.c 2010/11/17 10:19:30 1.131 @@ -418,7 +418,7 @@ if (*pos == '@') pos++; - if (!validate_name(pos)) + if (!validate_tag(pos)) return 0; av->value = pos; --- LVM2/tools/toollib.c 2010/11/09 12:34:43 1.211 +++ LVM2/tools/toollib.c 2010/11/17 10:19:30 1.212 @@ -222,7 +222,7 @@ vgname = lv_name; if (*vgname == '@') { - if (!validate_name(vgname + 1)) { + if (!validate_tag(vgname + 1)) { log_error("Skipping invalid tag %s", vgname); continue; @@ -528,7 +528,7 @@ for (; opt < argc; opt++) { vg_name = argv[opt]; if (*vg_name == '@') { - if (!validate_name(vg_name + 1)) { + if (!validate_tag(vg_name + 1)) { log_error("Skipping invalid tag %s", vg_name); if (ret_max < EINVALID_CMD_LINE) @@ -698,7 +698,7 @@ if (at_sign && (at_sign == argv[opt])) { tagname = at_sign + 1; - if (!validate_name(tagname)) { + if (!validate_tag(tagname)) { log_error("Skipping invalid tag %s", tagname); if (ret_max < EINVALID_CMD_LINE) @@ -1113,7 +1113,7 @@ if (at_sign && (at_sign == argv[i])) { tagname = at_sign + 1; - if (!validate_name(tagname)) { + if (!validate_tag(tagname)) { log_error("Skipping invalid tag %s", tagname); continue; } From mornfall@sourceware.org Wed Nov 17 19:15:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Wed, 17 Nov 2010 19:15:00 -0000 Subject: LVM2/lib/report columns.h properties.c propert ... Message-ID: <20101117191512.26108.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-17 19:15:11 Modified files: lib/report : columns.h properties.c properties.h Log message: Add generic infrastructure to internal library to 'set' a property. Similar to 'get' property internal functions. Add specific 'set' function for vg_mda_copies. Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/columns.h.diff?cvsroot=lvm2&r1=1.45&r2=1.46 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/properties.c.diff?cvsroot=lvm2&r1=1.22&r2=1.23 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/properties.h.diff?cvsroot=lvm2&r1=1.5&r2=1.6 --- LVM2/lib/report/columns.h 2010/09/30 13:52:57 1.45 +++ LVM2/lib/report/columns.h 2010/11/17 19:15:10 1.46 @@ -121,7 +121,7 @@ FIELD(VGS, vg, NUM, "#VMdaUse", cmd, 8, vgmdasused, vg_mda_used_count, "Number of metadata areas in use on this VG.", 0) FIELD(VGS, vg, NUM, "VMdaFree", cmd, 9, vgmdafree, vg_mda_free, "Free metadata area space for this VG in current units.", 0) FIELD(VGS, vg, NUM, "VMdaSize", cmd, 9, vgmdasize, vg_mda_size, "Size of smallest metadata area for this VG in current units.", 0) -FIELD(VGS, vg, NUM, "#VMdaCps", cmd, 8, vgmdacopies, vg_mda_copies, "Target number of in use metadata areas in the VG.", 0) +FIELD(VGS, vg, NUM, "#VMdaCps", cmd, 8, vgmdacopies, vg_mda_copies, "Target number of in use metadata areas in the VG.", 1) FIELD(SEGS, seg, STR, "Type", list, 4, segtype, segtype, "Type of LV segment.", 0) FIELD(SEGS, seg, NUM, "#Str", area_count, 4, uint32, stripes, "Number of stripes or mirror legs.", 0) --- LVM2/lib/report/properties.c 2010/10/25 14:08:32 1.22 +++ LVM2/lib/report/properties.c 2010/11/17 19:15:11 1.23 @@ -35,6 +35,21 @@ #define GET_LV_NUM_PROPERTY_FN(NAME, VALUE) \ GET_NUM_PROPERTY_FN(NAME, VALUE, logical_volume, lv) +#define SET_NUM_PROPERTY_FN(NAME, SETFN, TYPE, VAR) \ +static int _ ## NAME ## _set (void *obj, struct lvm_property_type *prop) \ +{ \ + struct TYPE *VAR = (struct TYPE *)obj; \ +\ + SETFN(VAR, prop->value.integer); \ + return 1; \ +} +#define SET_VG_NUM_PROPERTY_FN(NAME, SETFN) \ + SET_NUM_PROPERTY_FN(NAME, SETFN, volume_group, vg) +#define SET_PV_NUM_PROPERTY_FN(NAME, SETFN) \ + SET_NUM_PROPERTY_FN(NAME, SETFN, physical_volume, pv) +#define SET_LV_NUM_PROPERTY_FN(NAME, SETFN) \ + SET_NUM_PROPERTY_FN(NAME, SETFN, logical_volume, lv) + #define GET_STR_PROPERTY_FN(NAME, VALUE, TYPE, VAR) \ static int _ ## NAME ## _get (const void *obj, struct lvm_property_type *prop) \ { \ @@ -184,7 +199,7 @@ GET_VG_NUM_PROPERTY_FN(vg_mda_size, (SECTOR_SIZE * vg_mda_size(vg))) #define _vg_mda_size_set _not_implemented_set GET_VG_NUM_PROPERTY_FN(vg_mda_copies, (vg_mda_copies(vg))) -#define _vg_mda_copies_set _not_implemented_set +SET_VG_NUM_PROPERTY_FN(vg_mda_copies, vg_set_mda_copies) /* LVSEG */ #define _segtype_get _not_implemented_get @@ -267,6 +282,42 @@ return 1; } +static int _set_property(void *obj, struct lvm_property_type *prop, + report_type_t type) +{ + struct lvm_property_type *p; + + p = _properties; + while (p->id[0]) { + if (!strcmp(p->id, prop->id)) + break; + p++; + } + if (!p->id[0]) { + log_errno(EINVAL, "Invalid property name %s", prop->id); + return 0; + } + if (!p->is_settable) { + log_errno(EINVAL, "Unable to set read-only property %s", + prop->id); + return 0; + } + if (!(p->type & type)) { + log_errno(EINVAL, "Property name %s does not match type %d", + prop->id, p->type); + return 0; + } + + if (p->is_string) + p->value.string = prop->value.string; + else + p->value.integer = prop->value.integer; + if (!p->set(obj, p)) { + return 0; + } + return 1; +} + int lv_get_property(const struct logical_volume *lv, struct lvm_property_type *prop) { @@ -284,3 +335,21 @@ { return _get_property(pv, prop, PVS | LABEL); } + +int lv_set_property(struct logical_volume *lv, + struct lvm_property_type *prop) +{ + return _set_property(lv, prop, LVS); +} + +int vg_set_property(struct volume_group *vg, + struct lvm_property_type *prop) +{ + return _set_property(vg, prop, VGS); +} + +int pv_set_property(struct physical_volume *pv, + struct lvm_property_type *prop) +{ + return _set_property(pv, prop, PVS | LABEL); +} --- LVM2/lib/report/properties.h 2010/10/25 14:08:32 1.5 +++ LVM2/lib/report/properties.h 2010/11/17 19:15:11 1.6 @@ -39,5 +39,11 @@ struct lvm_property_type *prop); int pv_get_property(const struct physical_volume *pv, struct lvm_property_type *prop); +int lv_set_property(struct logical_volume *lv, + struct lvm_property_type *prop); +int vg_set_property(struct volume_group *vg, + struct lvm_property_type *prop); +int pv_set_property(struct physical_volume *pv, + struct lvm_property_type *prop); #endif From mornfall@sourceware.org Wed Nov 17 19:16:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Wed, 17 Nov 2010 19:16:00 -0000 Subject: LVM2/liblvm lvm2app.h lvm_misc.c lvm_misc.h lv ... Message-ID: <20101117191606.26685.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-17 19:16:05 Modified files: liblvm : lvm2app.h lvm_misc.c lvm_misc.h lvm_vg.c Log message: Implement lvm_vg_set_property() by calling internal 'set' property function. Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm2app.h.diff?cvsroot=lvm2&r1=1.23&r2=1.24 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_misc.c.diff?cvsroot=lvm2&r1=1.3&r2=1.4 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_misc.h.diff?cvsroot=lvm2&r1=1.3&r2=1.4 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_vg.c.diff?cvsroot=lvm2&r1=1.45&r2=1.46 --- LVM2/liblvm/lvm2app.h 2010/10/25 14:09:08 1.23 +++ LVM2/liblvm/lvm2app.h 2010/11/17 19:16:05 1.24 @@ -911,6 +911,36 @@ */ struct lvm_property_value lvm_vg_get_property(const vg_t vg, const char *name); +/** + * Set the value of a VG property. Note that the property must be + * a 'settable' property, as evidenced by the 'is_settable' flag + * when querying the property. + * + * \memberof vg_t + * + * The memory allocated for a string property value is tied to the vg_t + * handle and will be released when lvm_vg_close() is called. + * + * Example (integer): + * lvm_property_value copies; + * + * if (lvm_vg_get_property(vg, "vg_mda_copies", &copies) < 0) { + * // Error - unable to query property + * } + * if (!copies.is_settable) { + * // Error - property not settable + * } + * copies.value.integer = 2; + * if (lvm_vg_set_property(vg, "vg_mda_copies", &copies) < 0) { + * // handle error + * } + * + * \return + * 0 (success) or -1 (failure). + */ +int lvm_vg_set_property(const vg_t vg, const char *name, + struct lvm_property_value *value); + /************************** logical volume handling *************************/ /** --- LVM2/liblvm/lvm_misc.c 2010/10/25 14:08:43 1.3 +++ LVM2/liblvm/lvm_misc.c 2010/11/17 19:16:05 1.4 @@ -78,3 +78,33 @@ v.is_valid = 1; return v; } + + +int set_property(const pv_t pv, const vg_t vg, const lv_t lv, + const char *name, struct lvm_property_value *v) +{ + struct lvm_property_type prop; + + prop.id = name; + if (v->is_string) + prop.value.string = v->value.string; + else + prop.value.integer = v->value.integer; + if (pv) { + if (!pv_set_property(pv, &prop)) { + v->is_valid = 0; + return -1; + } + } else if (vg) { + if (!vg_set_property(vg, &prop)) { + v->is_valid = 0; + return -1; + } + } else if (lv) { + if (!lv_set_property(lv, &prop)) { + v->is_valid = 0; + return -1; + } + } + return 0; +} --- LVM2/liblvm/lvm_misc.h 2010/10/25 14:08:43 1.3 +++ LVM2/liblvm/lvm_misc.h 2010/11/17 19:16:05 1.4 @@ -19,5 +19,7 @@ struct dm_list *tag_list_copy(struct dm_pool *p, struct dm_list *tag_list); struct lvm_property_value get_property(const pv_t pv, const vg_t vg, const lv_t lv, const char *name); +int set_property(const pv_t pv, const vg_t vg, const lv_t lv, + const char *name, struct lvm_property_value *value); #endif --- LVM2/liblvm/lvm_vg.c 2010/10/25 14:08:43 1.45 +++ LVM2/liblvm/lvm_vg.c 2010/11/17 19:16:05 1.46 @@ -341,6 +341,12 @@ return get_property(NULL, vg, NULL, name); } +int lvm_vg_set_property(const vg_t vg, const char *name, + struct lvm_property_value *value) +{ + return set_property(NULL, vg, NULL, name, value); +} + struct dm_list *lvm_list_vg_names(lvm_t libh) { return get_vgnames((struct cmd_context *)libh, 0); From mornfall@sourceware.org Wed Nov 17 19:17:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Wed, 17 Nov 2010 19:17:00 -0000 Subject: LVM2/test/api test.c Message-ID: <20101117191708.26936.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-17 19:17:07 Modified files: test/api : test.c Log message: Add vg_set_property to the interactive lvm2app test program. Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/api/test.c.diff?cvsroot=lvm2&r1=1.31&r2=1.32 --- LVM2/test/api/test.c 2010/10/25 14:09:19 1.31 +++ LVM2/test/api/test.c 2010/11/17 19:17:07 1.32 @@ -97,6 +97,8 @@ "Display the value of VG property\n"); printf("'pv_get_property pvname property_name': " "Display the value of PV property\n"); + printf("'vg_set_property vgname property_name': " + "Set the value of VG property\n"); printf("'lv_get_tags vgname lvname': " "List the tags of a LV\n"); printf("'vg_{add|remove}_tag vgname tag': " @@ -652,6 +654,36 @@ _print_property_value(v); } +static void _vg_set_property(char **argv, int argc) +{ + vg_t vg; + struct lvm_property_value value; + int rc; + + if (argc < 4) { + printf("Please enter vgname, field_id, value\n"); + return; + } + if (!(vg = _lookup_vg_by_name(argv, argc))) + return; + value = lvm_vg_get_property(vg, argv[2]); + if (!value.is_valid) { + printf("Error obtaining property value\n"); + return; + } + if (value.is_string) + value.value.string = argv[3]; + else + value.value.integer = atoi(argv[3]); + rc = lvm_vg_set_property(vg, argv[2], &value); + if (rc) + printf("Error "); + else + printf("Success "); + printf("setting value of property %s in VG %s\n", + argv[2], argv[1]); +} + static void _lv_get_tags(char **argv, int argc) { lv_t lv; @@ -908,6 +940,8 @@ _vg_get_property(argv, argc); } else if (!strcmp(argv[0], "pv_get_property")) { _pv_get_property(argv, argc); + } else if (!strcmp(argv[0], "vg_set_property")) { + _vg_set_property(argv, argc); } else if (!strcmp(argv[0], "lv_add_tag")) { _lv_tag(argv, argc, 1); } else if (!strcmp(argv[0], "lv_remove_tag")) { From mornfall@sourceware.org Wed Nov 17 19:50:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Wed, 17 Nov 2010 19:50:00 -0000 Subject: LVM2/lib/report properties.h Message-ID: <20101117195016.30014.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-17 19:50:15 Modified files: lib/report : properties.h Log message: Make value.string const char *, in properties.h, to fix a warning introduced by the previous patch set. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/properties.h.diff?cvsroot=lvm2&r1=1.6&r2=1.7 --- LVM2/lib/report/properties.h 2010/11/17 19:15:11 1.6 +++ LVM2/lib/report/properties.h 2010/11/17 19:50:15 1.7 @@ -26,7 +26,7 @@ unsigned is_string:1; unsigned is_integer:1; union { - char *string; + const char *string; uint64_t integer; } value; int (*get) (const void *obj, struct lvm_property_type *prop); From mornfall@sourceware.org Wed Nov 17 20:07:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Wed, 17 Nov 2010 20:07:00 -0000 Subject: LVM2/liblvm lvm2app.h lvm_lv.c Message-ID: <20101117200702.6896.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-17 20:07:01 Modified files: liblvm : lvm2app.h lvm_lv.c Log message: Add a new type and function to lvm2app to enumerate lvsegs. Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm2app.h.diff?cvsroot=lvm2&r1=1.24&r2=1.25 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_lv.c.diff?cvsroot=lvm2&r1=1.28&r2=1.29 --- LVM2/liblvm/lvm2app.h 2010/11/17 19:16:05 1.24 +++ LVM2/liblvm/lvm2app.h 2010/11/17 20:07:01 1.25 @@ -95,6 +95,7 @@ struct physical_volume; struct volume_group; struct logical_volume; +struct lv_segment; /** * \class lvm_t @@ -137,6 +138,13 @@ typedef struct physical_volume *pv_t; /** + * \class lvseg_t + * + * This lv segment object is bound to a lv_t. + */ +typedef struct lv_segment *lvseg_t; + +/** * Logical Volume object list. * * Lists of these structures are returned by lvm_vg_list_lvs(). @@ -147,6 +155,16 @@ } lv_list_t; /** + * Logical Volume Segment object list. + * + * Lists of these structures are returned by lvm_lv_list_lvsegs(). + */ +typedef struct lvm_lvseg_list { + struct dm_list list; + lvseg_t lvseg; +} lvseg_list_t; + +/** * Physical volume object list. * * Lists of these structures are returned by lvm_vg_list_pvs(). @@ -966,6 +984,19 @@ lv_t lvm_vg_create_lv_linear(vg_t vg, const char *name, uint64_t size); /** + * Return a list of lvseg handles for a given LV handle. + * + * \memberof lv_t + * + * \param lv + * Logical volume handle. + * + * \return + * A list of lvm_lvseg_list structures containing lvseg handles for this lv. + */ +struct dm_list *lvm_lv_list_lvsegs(lv_t lv); + +/** * Activate a logical volume. * * \memberof lv_t --- LVM2/liblvm/lvm_lv.c 2010/11/11 17:29:06 1.28 +++ LVM2/liblvm/lvm_lv.c 2010/11/17 20:07:01 1.29 @@ -216,6 +216,33 @@ return 0; } +struct dm_list *lvm_lv_list_lvsegs(lv_t lv) +{ + struct dm_list *list; + lvseg_list_t *lvseg; + struct lv_segment *lvl; + + if (dm_list_empty(&lv->segments)) + return NULL; + + if (!(list = dm_pool_zalloc(lv->vg->vgmem, sizeof(*list)))) { + log_errno(ENOMEM, "Memory allocation fail for dm_list."); + return NULL; + } + dm_list_init(list); + + dm_list_iterate_items(lvl, &lv->segments) { + if (!(lvseg = dm_pool_zalloc(lv->vg->vgmem, sizeof(*lvseg)))) { + log_errno(ENOMEM, + "Memory allocation fail for lvm_lvseg_list."); + return NULL; + } + lvseg->lvseg = lvl; + dm_list_add(list, &lvseg->list); + } + return list; +} + int lvm_lv_resize(const lv_t lv, uint64_t new_size) { /* FIXME: add lv resize code here */ From mornfall@sourceware.org Wed Nov 17 20:08:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Wed, 17 Nov 2010 20:08:00 -0000 Subject: LVM2/lib metadata/lv.c metadata/lv.h report/pr ... Message-ID: <20101117200816.7553.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-17 20:08:14 Modified files: lib/metadata : lv.c lv.h lib/report : properties.c properties.h report.c Log message: Add the macro and specific 'get' functions for lvsegs. Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv.c.diff?cvsroot=lvm2&r1=1.18&r2=1.19 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv.h.diff?cvsroot=lvm2&r1=1.16&r2=1.17 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/properties.c.diff?cvsroot=lvm2&r1=1.23&r2=1.24 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/properties.h.diff?cvsroot=lvm2&r1=1.7&r2=1.8 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/report.c.diff?cvsroot=lvm2&r1=1.139&r2=1.140 --- LVM2/lib/metadata/lv.c 2010/10/25 13:54:29 1.18 +++ LVM2/lib/metadata/lv.c 2010/11/17 20:08:14 1.19 @@ -21,6 +21,41 @@ #include "segtype.h" #include "str_list.h" +char *lvseg_tags_dup(const struct lv_segment *seg) +{ + return tags_format_and_copy(seg->lv->vg->vgmem, &seg->tags); +} + +char *lvseg_segtype_dup(const struct lv_segment *seg) +{ + if (seg->area_count == 1) { + return (char *)"linear"; + } + + return dm_pool_strdup(seg->lv->vg->vgmem, seg->segtype->ops->name(seg)); +} + +uint64_t lvseg_chunksize(const struct lv_segment *seg) +{ + uint64_t size; + + if (lv_is_cow(seg->lv)) + size = (uint64_t) find_cow(seg->lv)->chunk_size; + else + size = UINT64_C(0); + return size; +} + +uint64_t lvseg_start(const struct lv_segment *seg) +{ + return (uint64_t) seg->le * seg->lv->vg->extent_size; +} + +uint64_t lvseg_size(const struct lv_segment *seg) +{ + return (uint64_t) seg->len * seg->lv->vg->extent_size; +} + uint32_t lv_kernel_read_ahead(const struct logical_volume *lv) { struct lvinfo info; --- LVM2/lib/metadata/lv.h 2010/10/25 12:01:59 1.16 +++ LVM2/lib/metadata/lv.h 2010/11/17 20:08:14 1.17 @@ -63,5 +63,10 @@ char *lv_name_dup(struct dm_pool *mem, const struct logical_volume *lv); char *lv_origin_dup(struct dm_pool *mem, const struct logical_volume *lv); uint32_t lv_kernel_read_ahead(const struct logical_volume *lv); +uint64_t lvseg_start(const struct lv_segment *seg); +uint64_t lvseg_size(const struct lv_segment *seg); +uint64_t lvseg_chunksize(const struct lv_segment *seg); +char *lvseg_segtype_dup(const struct lv_segment *seg); +char *lvseg_tags_dup(const struct lv_segment *seg); #endif /* _LVM_LV_H */ --- LVM2/lib/report/properties.c 2010/11/17 19:15:11 1.23 +++ LVM2/lib/report/properties.c 2010/11/17 20:08:14 1.24 @@ -34,6 +34,8 @@ GET_NUM_PROPERTY_FN(NAME, VALUE, physical_volume, pv) #define GET_LV_NUM_PROPERTY_FN(NAME, VALUE) \ GET_NUM_PROPERTY_FN(NAME, VALUE, logical_volume, lv) +#define GET_LVSEG_NUM_PROPERTY_FN(NAME, VALUE) \ + GET_NUM_PROPERTY_FN(NAME, VALUE, lv_segment, lvseg) #define SET_NUM_PROPERTY_FN(NAME, SETFN, TYPE, VAR) \ static int _ ## NAME ## _set (void *obj, struct lvm_property_type *prop) \ @@ -64,6 +66,8 @@ GET_STR_PROPERTY_FN(NAME, VALUE, physical_volume, pv) #define GET_LV_STR_PROPERTY_FN(NAME, VALUE) \ GET_STR_PROPERTY_FN(NAME, VALUE, logical_volume, lv) +#define GET_LVSEG_STR_PROPERTY_FN(NAME, VALUE) \ + GET_STR_PROPERTY_FN(NAME, VALUE, lv_segment, lvseg) static int _not_implemented_get(const void *obj, struct lvm_property_type *prop) { @@ -202,29 +206,29 @@ SET_VG_NUM_PROPERTY_FN(vg_mda_copies, vg_set_mda_copies) /* LVSEG */ -#define _segtype_get _not_implemented_get +GET_LVSEG_STR_PROPERTY_FN(segtype, lvseg_segtype_dup(lvseg)) #define _segtype_set _not_implemented_set -#define _stripes_get _not_implemented_get +GET_LVSEG_NUM_PROPERTY_FN(stripes, lvseg->area_count) #define _stripes_set _not_implemented_set -#define _stripesize_get _not_implemented_get +GET_LVSEG_NUM_PROPERTY_FN(stripesize, lvseg->stripe_size) #define _stripesize_set _not_implemented_set -#define _stripe_size_get _not_implemented_get +GET_LVSEG_NUM_PROPERTY_FN(stripe_size, lvseg->stripe_size) #define _stripe_size_set _not_implemented_set -#define _regionsize_get _not_implemented_get +GET_LVSEG_NUM_PROPERTY_FN(regionsize, lvseg->region_size) #define _regionsize_set _not_implemented_set -#define _region_size_get _not_implemented_get +GET_LVSEG_NUM_PROPERTY_FN(region_size, lvseg->region_size) #define _region_size_set _not_implemented_set -#define _chunksize_get _not_implemented_get +GET_LVSEG_NUM_PROPERTY_FN(chunksize, lvseg_chunksize(lvseg)) #define _chunksize_set _not_implemented_set -#define _chunk_size_get _not_implemented_get +GET_LVSEG_NUM_PROPERTY_FN(chunk_size, lvseg_chunksize(lvseg)) #define _chunk_size_set _not_implemented_set -#define _seg_start_get _not_implemented_get +GET_LVSEG_NUM_PROPERTY_FN(seg_start, lvseg_start(lvseg)) #define _seg_start_set _not_implemented_set -#define _seg_start_pe_get _not_implemented_get +GET_LVSEG_NUM_PROPERTY_FN(seg_start_pe, lvseg->le) #define _seg_start_pe_set _not_implemented_set -#define _seg_size_get _not_implemented_get +GET_LVSEG_NUM_PROPERTY_FN(seg_size, lvseg_size(lvseg)) #define _seg_size_set _not_implemented_set -#define _seg_tags_get _not_implemented_get +GET_LVSEG_STR_PROPERTY_FN(seg_tags, lvseg_tags_dup(lvseg)) #define _seg_tags_set _not_implemented_set #define _seg_pe_ranges_get _not_implemented_get #define _seg_pe_ranges_set _not_implemented_set @@ -318,6 +322,12 @@ return 1; } +int lvseg_get_property(const struct lv_segment *lvseg, + struct lvm_property_type *prop) +{ + return _get_property(lvseg, prop, SEGS); +} + int lv_get_property(const struct logical_volume *lv, struct lvm_property_type *prop) { --- LVM2/lib/report/properties.h 2010/11/17 19:50:15 1.7 +++ LVM2/lib/report/properties.h 2010/11/17 20:08:14 1.8 @@ -33,6 +33,8 @@ int (*set) (void *obj, struct lvm_property_type *prop); }; +int lvseg_get_property(const struct lv_segment *lvseg, + struct lvm_property_type *prop); int lv_get_property(const struct logical_volume *lv, struct lvm_property_type *prop); int vg_get_property(const struct volume_group *vg, --- LVM2/lib/report/report.c 2010/10/21 14:49:31 1.139 +++ LVM2/lib/report/report.c 2010/11/17 20:08:14 1.140 @@ -279,12 +279,9 @@ { const struct lv_segment *seg = (const struct lv_segment *) data; - if (seg->area_count == 1) { - dm_report_field_set_value(field, "linear", NULL); - return 1; - } - - dm_report_field_set_value(field, seg->segtype->ops->name(seg), NULL); + char *name; + name = lvseg_segtype_dup(seg); + dm_report_field_set_value(field, name, NULL); return 1; } @@ -496,7 +493,7 @@ const struct lv_segment *seg = (const struct lv_segment *) data; uint64_t start; - start = (uint64_t) seg->le * seg->lv->vg->extent_size; + start = lvseg_start(seg); return _size64_disp(rh, mem, field, &start, private); } @@ -519,7 +516,7 @@ const struct lv_segment *seg = (const struct lv_segment *) data; uint64_t size; - size = (uint64_t) seg->len * seg->lv->vg->extent_size; + size = lvseg_size(seg); return _size64_disp(rh, mem, field, &size, private); } @@ -531,10 +528,7 @@ const struct lv_segment *seg = (const struct lv_segment *) data; uint64_t size; - if (lv_is_cow(seg->lv)) - size = (uint64_t) find_cow(seg->lv)->chunk_size; - else - size = UINT64_C(0); + size = lvseg_chunksize(seg); return _size64_disp(rh, mem, field, &size, private); } From mornfall@sourceware.org Wed Nov 17 20:09:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Wed, 17 Nov 2010 20:09:00 -0000 Subject: LVM2/liblvm lvm2app.h lvm_lv.c lvm_misc.c lvm_ ... Message-ID: <20101117200943.7917.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-17 20:09:42 Modified files: liblvm : lvm2app.h lvm_lv.c lvm_misc.c lvm_misc.h lvm_pv.c lvm_vg.c Log message: Add lvm2app function to query lvseg properties. Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm2app.h.diff?cvsroot=lvm2&r1=1.25&r2=1.26 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_lv.c.diff?cvsroot=lvm2&r1=1.29&r2=1.30 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_misc.c.diff?cvsroot=lvm2&r1=1.4&r2=1.5 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_misc.h.diff?cvsroot=lvm2&r1=1.4&r2=1.5 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_pv.c.diff?cvsroot=lvm2&r1=1.14&r2=1.15 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_vg.c.diff?cvsroot=lvm2&r1=1.46&r2=1.47 --- LVM2/liblvm/lvm2app.h 2010/11/17 20:07:01 1.25 +++ LVM2/liblvm/lvm2app.h 2010/11/17 20:09:42 1.26 @@ -1132,6 +1132,45 @@ struct lvm_property_value lvm_lv_get_property(const lv_t lv, const char *name); /** + * Get the value of a LV segment property + * + * \memberof lv_t + * + * \param lvseg + * Logical volume segment handle. + * + * \param name + * Name of property to query. See lvs man page for full list of properties + * that may be queried. + * + * The memory allocated for a string property value is tied to the vg_t + * handle and will be released when lvm_vg_close() is called. + * + * Example: + * lvm_property_value v; + * char *prop_name = "seg_start_pe"; + * + * v = lvm_lvseg_get_property(lvseg, prop_name); + * if (lvm_errno(libh) || !v.is_valid) { + * // handle error + * printf("Invalid property name or unable to query" + * "'%s'.\n", prop_name); + * return; + * } + * if (v.is_string) + * printf(", value = %s\n", v.value.string); + * else + * printf(", value = %"PRIu64"\n", v.value.integer); + * + * \return + * lvm_property_value structure that will contain the current + * value of the property. Caller should check lvm_errno() as well + * as 'is_valid' flag before using the value. + */ +struct lvm_property_value lvm_lvseg_get_property(const lvseg_t lvseg, + const char *name); + +/** * Get the current activation state of a logical volume. * * \memberof lv_t --- LVM2/liblvm/lvm_lv.c 2010/11/17 20:07:01 1.29 +++ LVM2/liblvm/lvm_lv.c 2010/11/17 20:09:42 1.30 @@ -50,7 +50,13 @@ struct lvm_property_value lvm_lv_get_property(const lv_t lv, const char *name) { - return get_property(NULL, NULL, lv, name); + return get_property(NULL, NULL, lv, NULL, name); +} + +struct lvm_property_value lvm_lvseg_get_property(const lvseg_t lvseg, + const char *name) +{ + return get_property(NULL, NULL, NULL, lvseg, name); } uint64_t lvm_lv_is_active(const lv_t lv) --- LVM2/liblvm/lvm_misc.c 2010/11/17 19:16:05 1.4 +++ LVM2/liblvm/lvm_misc.c 2010/11/17 20:09:42 1.5 @@ -46,7 +46,8 @@ } struct lvm_property_value get_property(const pv_t pv, const vg_t vg, - const lv_t lv, const char *name) + const lv_t lv, const lvseg_t lvseg, + const char *name) { struct lvm_property_type prop; struct lvm_property_value v; @@ -67,6 +68,11 @@ v.is_valid = 0; return v; } + } else if (lvseg) { + if (!lvseg_get_property(lvseg, &prop)) { + v.is_valid = 0; + return v; + } } v.is_settable = prop.is_settable; v.is_string = prop.is_string; --- LVM2/liblvm/lvm_misc.h 2010/11/17 19:16:05 1.4 +++ LVM2/liblvm/lvm_misc.h 2010/11/17 20:09:42 1.5 @@ -18,7 +18,8 @@ struct dm_list *tag_list_copy(struct dm_pool *p, struct dm_list *tag_list); struct lvm_property_value get_property(const pv_t pv, const vg_t vg, - const lv_t lv, const char *name); + const lv_t lv, const lvseg_t lvseg, + const char *name); int set_property(const pv_t pv, const vg_t vg, const lv_t lv, const char *name, struct lvm_property_value *value); --- LVM2/liblvm/lvm_pv.c 2010/10/25 14:08:55 1.14 +++ LVM2/liblvm/lvm_pv.c 2010/11/17 20:09:42 1.15 @@ -51,7 +51,7 @@ struct lvm_property_value lvm_pv_get_property(const pv_t pv, const char *name) { - return get_property(pv, NULL, NULL, name); + return get_property(pv, NULL, NULL, NULL, name); } int lvm_pv_resize(const pv_t pv, uint64_t new_size) --- LVM2/liblvm/lvm_vg.c 2010/11/17 19:16:05 1.46 +++ LVM2/liblvm/lvm_vg.c 2010/11/17 20:09:42 1.47 @@ -338,7 +338,7 @@ struct lvm_property_value lvm_vg_get_property(const vg_t vg, const char *name) { - return get_property(NULL, vg, NULL, name); + return get_property(NULL, vg, NULL, NULL, name); } int lvm_vg_set_property(const vg_t vg, const char *name, From mornfall@sourceware.org Wed Nov 17 20:10:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Wed, 17 Nov 2010 20:10:00 -0000 Subject: LVM2/liblvm lvm2app.h lvm_pv.c Message-ID: <20101117201043.8200.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-17 20:10:42 Modified files: liblvm : lvm2app.h lvm_pv.c Log message: Add a new type and function to lvm2app to enumerate pvsegs. Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm2app.h.diff?cvsroot=lvm2&r1=1.26&r2=1.27 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_pv.c.diff?cvsroot=lvm2&r1=1.15&r2=1.16 --- LVM2/liblvm/lvm2app.h 2010/11/17 20:09:42 1.26 +++ LVM2/liblvm/lvm2app.h 2010/11/17 20:10:42 1.27 @@ -96,6 +96,7 @@ struct volume_group; struct logical_volume; struct lv_segment; +struct pv_segment; /** * \class lvm_t @@ -145,6 +146,13 @@ typedef struct lv_segment *lvseg_t; /** + * \class pvseg_t + * + * This pv segment object is bound to a pv_t. + */ +typedef struct pv_segment *pvseg_t; + +/** * Logical Volume object list. * * Lists of these structures are returned by lvm_vg_list_lvs(). @@ -175,6 +183,16 @@ } pv_list_t; /** + * Physical Volume Segment object list. + * + * Lists of these structures are returned by lvm_pv_list_pvsegs(). + */ +typedef struct lvm_pvseg_list { + struct dm_list list; + pvseg_t pvseg; +} pvseg_list_t; + +/** * String list. * * This string list contains read-only strings. @@ -1419,6 +1437,19 @@ struct lvm_property_value lvm_pv_get_property(const pv_t pv, const char *name); /** + * Return a list of pvseg handles for a given PV handle. + * + * \memberof pv_t + * + * \param pv + * Physical volume handle. + * + * \return + * A list of lvm_pvseg_list structures containing pvseg handles for this pv. + */ +struct dm_list *lvm_pv_list_pvsegs(pv_t pv); + +/** * Resize physical volume to new_size bytes. * * \memberof pv_t --- LVM2/liblvm/lvm_pv.c 2010/11/17 20:09:42 1.15 +++ LVM2/liblvm/lvm_pv.c 2010/11/17 20:10:42 1.16 @@ -54,6 +54,33 @@ return get_property(pv, NULL, NULL, NULL, name); } +struct dm_list *lvm_pv_list_pvsegs(pv_t pv) +{ + struct dm_list *list; + pvseg_list_t *pvseg; + struct pv_segment *pvl; + + if (dm_list_empty(&pv->segments)) + return NULL; + + if (!(list = dm_pool_zalloc(pv->vg->vgmem, sizeof(*list)))) { + log_errno(ENOMEM, "Memory allocation fail for dm_list."); + return NULL; + } + dm_list_init(list); + + dm_list_iterate_items(pvl, &pv->segments) { + if (!(pvseg = dm_pool_zalloc(pv->vg->vgmem, sizeof(*pvseg)))) { + log_errno(ENOMEM, + "Memory allocation fail for lvm_pvseg_list."); + return NULL; + } + pvseg->pvseg = pvl; + dm_list_add(list, &pvseg->list); + } + return list; +} + int lvm_pv_resize(const pv_t pv, uint64_t new_size) { /* FIXME: add pv resize code here */ From mornfall@sourceware.org Wed Nov 17 20:11:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Wed, 17 Nov 2010 20:11:00 -0000 Subject: LVM2/lib/report properties.c properties.h Message-ID: <20101117201129.8427.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-17 20:11:28 Modified files: lib/report : properties.c properties.h Log message: Add the macro and specific 'get' functions for pvsegs. Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/properties.c.diff?cvsroot=lvm2&r1=1.24&r2=1.25 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/properties.h.diff?cvsroot=lvm2&r1=1.8&r2=1.9 --- LVM2/lib/report/properties.c 2010/11/17 20:08:14 1.24 +++ LVM2/lib/report/properties.c 2010/11/17 20:11:27 1.25 @@ -36,6 +36,8 @@ GET_NUM_PROPERTY_FN(NAME, VALUE, logical_volume, lv) #define GET_LVSEG_NUM_PROPERTY_FN(NAME, VALUE) \ GET_NUM_PROPERTY_FN(NAME, VALUE, lv_segment, lvseg) +#define GET_PVSEG_NUM_PROPERTY_FN(NAME, VALUE) \ + GET_NUM_PROPERTY_FN(NAME, VALUE, pv_segment, pvseg) #define SET_NUM_PROPERTY_FN(NAME, SETFN, TYPE, VAR) \ static int _ ## NAME ## _set (void *obj, struct lvm_property_type *prop) \ @@ -68,6 +70,8 @@ GET_STR_PROPERTY_FN(NAME, VALUE, logical_volume, lv) #define GET_LVSEG_STR_PROPERTY_FN(NAME, VALUE) \ GET_STR_PROPERTY_FN(NAME, VALUE, lv_segment, lvseg) +#define GET_PVSEG_STR_PROPERTY_FN(NAME, VALUE) \ + GET_STR_PROPERTY_FN(NAME, VALUE, pv_segment, pvseg) static int _not_implemented_get(const void *obj, struct lvm_property_type *prop) { @@ -237,9 +241,9 @@ /* PVSEG */ -#define _pvseg_start_get _not_implemented_get +GET_PVSEG_NUM_PROPERTY_FN(pvseg_start, pvseg->pe) #define _pvseg_start_set _not_implemented_set -#define _pvseg_size_get _not_implemented_get +GET_PVSEG_NUM_PROPERTY_FN(pvseg_size, pvseg->len) #define _pvseg_size_set _not_implemented_set @@ -340,6 +344,12 @@ return _get_property(vg, prop, VGS); } +int pvseg_get_property(const struct pv_segment *pvseg, + struct lvm_property_type *prop) +{ + return _get_property(pvseg, prop, PVSEGS); +} + int pv_get_property(const struct physical_volume *pv, struct lvm_property_type *prop) { --- LVM2/lib/report/properties.h 2010/11/17 20:08:14 1.8 +++ LVM2/lib/report/properties.h 2010/11/17 20:11:28 1.9 @@ -39,6 +39,8 @@ struct lvm_property_type *prop); int vg_get_property(const struct volume_group *vg, struct lvm_property_type *prop); +int pvseg_get_property(const struct pv_segment *pvseg, + struct lvm_property_type *prop); int pv_get_property(const struct physical_volume *pv, struct lvm_property_type *prop); int lv_set_property(struct logical_volume *lv, From mornfall@sourceware.org Wed Nov 17 20:12:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Wed, 17 Nov 2010 20:12:00 -0000 Subject: LVM2/liblvm lvm2app.h lvm_lv.c lvm_misc.c lvm_ ... Message-ID: <20101117201241.8715.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-17 20:12:40 Modified files: liblvm : lvm2app.h lvm_lv.c lvm_misc.c lvm_misc.h lvm_pv.c lvm_vg.c Log message: Add lvm2app function to query pvseg properties. Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm2app.h.diff?cvsroot=lvm2&r1=1.27&r2=1.28 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_lv.c.diff?cvsroot=lvm2&r1=1.30&r2=1.31 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_misc.c.diff?cvsroot=lvm2&r1=1.5&r2=1.6 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_misc.h.diff?cvsroot=lvm2&r1=1.5&r2=1.6 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_pv.c.diff?cvsroot=lvm2&r1=1.16&r2=1.17 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_vg.c.diff?cvsroot=lvm2&r1=1.47&r2=1.48 --- LVM2/liblvm/lvm2app.h 2010/11/17 20:10:42 1.27 +++ LVM2/liblvm/lvm2app.h 2010/11/17 20:12:39 1.28 @@ -1437,6 +1437,45 @@ struct lvm_property_value lvm_pv_get_property(const pv_t pv, const char *name); /** + * Get the value of a PV segment property + * + * \memberof pv_t + * + * \param pvseg + * Physical volume segment handle. + * + * \param name + * Name of property to query. See pvs man page for full list of properties + * that may be queried. + * + * The memory allocated for a string property value is tied to the vg_t + * handle and will be released when lvm_vg_close() is called. + * + * Example: + * lvm_property_value v; + * char *prop_name = "pvseg_start"; + * + * v = lvm_pvseg_get_property(pvseg, prop_name); + * if (lvm_errno(libh) || !v.is_valid) { + * // handle error + * printf("Invalid property name or unable to query" + * "'%s'.\n", prop_name); + * return; + * } + * if (v.is_string) + * printf(", value = %s\n", v.value.string); + * else + * printf(", value = %"PRIu64"\n", v.value.integer); + * + * \return + * lvm_property_value structure that will contain the current + * value of the property. Caller should check lvm_errno() as well + * as 'is_valid' flag before using the value. + */ +struct lvm_property_value lvm_pvseg_get_property(const pvseg_t pvseg, + const char *name); + +/** * Return a list of pvseg handles for a given PV handle. * * \memberof pv_t --- LVM2/liblvm/lvm_lv.c 2010/11/17 20:09:42 1.30 +++ LVM2/liblvm/lvm_lv.c 2010/11/17 20:12:39 1.31 @@ -50,13 +50,13 @@ struct lvm_property_value lvm_lv_get_property(const lv_t lv, const char *name) { - return get_property(NULL, NULL, lv, NULL, name); + return get_property(NULL, NULL, lv, NULL, NULL, name); } struct lvm_property_value lvm_lvseg_get_property(const lvseg_t lvseg, const char *name) { - return get_property(NULL, NULL, NULL, lvseg, name); + return get_property(NULL, NULL, NULL, lvseg, NULL, name); } uint64_t lvm_lv_is_active(const lv_t lv) --- LVM2/liblvm/lvm_misc.c 2010/11/17 20:09:42 1.5 +++ LVM2/liblvm/lvm_misc.c 2010/11/17 20:12:40 1.6 @@ -47,7 +47,7 @@ struct lvm_property_value get_property(const pv_t pv, const vg_t vg, const lv_t lv, const lvseg_t lvseg, - const char *name) + const pvseg_t pvseg, const char *name) { struct lvm_property_type prop; struct lvm_property_value v; @@ -73,6 +73,11 @@ v.is_valid = 0; return v; } + } else if (pvseg) { + if (!pvseg_get_property(pvseg, &prop)) { + v.is_valid = 0; + return v; + } } v.is_settable = prop.is_settable; v.is_string = prop.is_string; --- LVM2/liblvm/lvm_misc.h 2010/11/17 20:09:42 1.5 +++ LVM2/liblvm/lvm_misc.h 2010/11/17 20:12:40 1.6 @@ -19,7 +19,7 @@ struct dm_list *tag_list_copy(struct dm_pool *p, struct dm_list *tag_list); struct lvm_property_value get_property(const pv_t pv, const vg_t vg, const lv_t lv, const lvseg_t lvseg, - const char *name); + const pvseg_t pvseg, const char *name); int set_property(const pv_t pv, const vg_t vg, const lv_t lv, const char *name, struct lvm_property_value *value); --- LVM2/liblvm/lvm_pv.c 2010/11/17 20:10:42 1.16 +++ LVM2/liblvm/lvm_pv.c 2010/11/17 20:12:40 1.17 @@ -51,7 +51,13 @@ struct lvm_property_value lvm_pv_get_property(const pv_t pv, const char *name) { - return get_property(pv, NULL, NULL, NULL, name); + return get_property(pv, NULL, NULL, NULL, NULL, name); +} + +struct lvm_property_value lvm_pvseg_get_property(const pvseg_t pvseg, + const char *name) +{ + return get_property(NULL, NULL, NULL, NULL, pvseg, name); } struct dm_list *lvm_pv_list_pvsegs(pv_t pv) --- LVM2/liblvm/lvm_vg.c 2010/11/17 20:09:42 1.47 +++ LVM2/liblvm/lvm_vg.c 2010/11/17 20:12:40 1.48 @@ -338,7 +338,7 @@ struct lvm_property_value lvm_vg_get_property(const vg_t vg, const char *name) { - return get_property(NULL, vg, NULL, NULL, name); + return get_property(NULL, vg, NULL, NULL, NULL, name); } int lvm_vg_set_property(const vg_t vg, const char *name, From mornfall@sourceware.org Wed Nov 17 20:13:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Wed, 17 Nov 2010 20:13:00 -0000 Subject: LVM2/test/api test.c Message-ID: <20101117201351.9009.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-17 20:13:51 Modified files: test/api : test.c Log message: Update interactive tests for lvm2app lvseg and pvseg apis. Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/api/test.c.diff?cvsroot=lvm2&r1=1.32&r2=1.33 --- LVM2/test/api/test.c 2010/11/17 19:17:07 1.32 +++ LVM2/test/api/test.c 2010/11/17 20:13:51 1.33 @@ -67,8 +67,12 @@ "List the uuids of the VGs that exist in the system\n"); printf("'vg_list_pvs vgname': " "List the PVs that exist in VG vgname\n"); + printf("'pv_list_pvsegs pvname': " + "List the PV segments that exist in PV pvname\n"); printf("'vg_list_lvs vgname': " "List the LVs that exist in VG vgname\n"); + printf("'lv_list_lvsegs vgname lvname': " + "List the LV segments that exist in LV vgname/lvname\n"); printf("'vgs_open': " "List the VGs that are currently open\n"); printf("'vgs': " @@ -189,17 +193,13 @@ return vg; } -static pv_t _lookup_pv_by_name(char **argv, int argc) +static pv_t _lookup_pv_by_name(const char *name) { pv_t pv; - if (argc < 2) { - printf ("Please enter vg_name\n"); - return NULL; - } - if (!(pv = dm_hash_lookup(_pvname_hash, argv[1]))) { + if (!(pv = dm_hash_lookup(_pvname_hash, name))) { printf ("Can't find %s in open PVs - run vg_open first\n", - argv[1]); + name); return NULL; } return pv; @@ -238,6 +238,7 @@ dm_hash_insert(_pvname_hash, name, pvl->pv); } } + static void _vg_reduce(char **argv, int argc, lvm_t libh) { vg_t vg; @@ -496,6 +497,40 @@ } } +static void _print_property_value(const char *name, + struct lvm_property_value v) +{ + if (!v.is_valid) + printf("%s = INVALID\n", name); + else if (v.is_string) + printf("%s = %s\n", name, v.value.string); + else + printf("%s = %"PRIu64"\n", name, v.value.integer); +} + +static void _pvsegs_in_pv(char **argv, int argc) +{ + struct dm_list *pvsegs; + struct lvm_pvseg_list *pvl; + pv_t pv; + + if (!(pv = _lookup_pv_by_name(argv[1]))) + return; + pvsegs = lvm_pv_list_pvsegs(pv); + if (!pvsegs || dm_list_empty(pvsegs)) { + printf("No PV segments in pv %s\n", argv[1]); + return; + } + printf("PV segments in pv %s:\n", argv[1]); + dm_list_iterate_items(pvl, pvsegs) { + struct lvm_property_value v; + v = lvm_pvseg_get_property(pvl->pvseg, "pvseg_start"); + _print_property_value("pvseg_start", v); + v = lvm_pvseg_get_property(pvl->pvseg, "pvseg_size"); + _print_property_value("pvseg_size", v); + } +} + static void _scan_vgs(lvm_t libh) { lvm_scan(libh); @@ -571,14 +606,6 @@ add ? "adding":"removing", argv[2], argv[1]); } -static void _print_property_value(struct lvm_property_value value) -{ - if (value.is_string) - printf(", value = %s\n", value.value.string); - else - printf(", value = %"PRIu64"\n", value.value.integer); -} - static void _pv_get_property(char **argv, int argc) { pv_t pv; @@ -588,20 +615,10 @@ printf("Please enter pvname, field_id\n"); return; } - if (!(pv = _lookup_pv_by_name(argv, argc))) + if (!(pv = _lookup_pv_by_name(argv[1]))) return; v = lvm_pv_get_property(pv, argv[2]); - if (!v.is_valid) - printf("Error "); - else - printf("Success "); - printf("obtaining value of property %s in PV %s", - argv[2], argv[1]); - if (!v.is_valid) { - printf("\n"); - return; - } - _print_property_value(v); + _print_property_value(argv[2], v); } static void _vg_get_property(char **argv, int argc) @@ -616,17 +633,7 @@ if (!(vg = _lookup_vg_by_name(argv, argc))) return; v = lvm_vg_get_property(vg, argv[2]); - if (!v.is_valid) - printf("Error "); - else - printf("Success "); - printf("obtaining value of property %s in VG %s", - argv[2], argv[1]); - if (!v.is_valid) { - printf("\n"); - return; - } - _print_property_value(v); + _print_property_value(argv[2], v); } static void _lv_get_property(char **argv, int argc) @@ -641,17 +648,7 @@ if (!(lv = _lookup_lv_by_name(argv[2]))) return; v = lvm_lv_get_property(lv, argv[3]); - if (!v.is_valid) - printf("Error "); - else - printf("Success "); - printf("obtaining value of property %s in LV %s", - argv[3], argv[2]); - if (!v.is_valid) { - printf("\n"); - return; - } - _print_property_value(v); + _print_property_value(argv[3], v); } static void _vg_set_property(char **argv, int argc) @@ -774,6 +771,31 @@ } } +static void _lvsegs_in_lv(char **argv, int argc) +{ + struct dm_list *lvsegs; + struct lvm_lvseg_list *lvl; + lv_t lv; + + if (!(lv = _lookup_lv_by_name(argv[2]))) + return; + lvsegs = lvm_lv_list_lvsegs(lv); + if (!lvsegs || dm_list_empty(lvsegs)) { + printf("No LV segments in lv %s\n", lvm_lv_get_name(lv)); + return; + } + printf("LV segments in lv %s:\n", lvm_lv_get_name(lv)); + dm_list_iterate_items(lvl, lvsegs) { + struct lvm_property_value v; + v = lvm_lvseg_get_property(lvl->lvseg, "segtype"); + _print_property_value("segtype", v); + v = lvm_lvseg_get_property(lvl->lvseg, "seg_start_pe"); + _print_property_value("seg_start_pe", v); + v = lvm_lvseg_get_property(lvl->lvseg, "seg_size"); + _print_property_value("seg_size", v); + } +} + static void _lv_deactivate(char **argv, int argc) { lv_t lv; @@ -918,8 +940,12 @@ _list_open_vgs(); } else if (!strcmp(argv[0], "vg_list_pvs")) { _pvs_in_vg(argv, argc); + } else if (!strcmp(argv[0], "pv_list_pvsegs")) { + _pvsegs_in_pv(argv, argc); } else if (!strcmp(argv[0], "vg_list_lvs")) { _lvs_in_vg(argv, argc); + } else if (!strcmp(argv[0], "lv_list_lvsegs")) { + _lvsegs_in_lv(argv, argc); } else if (!strcmp(argv[0], "list_vg_names")) { _list_vg_names(libh); } else if (!strcmp(argv[0], "list_vg_ids")) { From mornfall@sourceware.org Wed Nov 17 22:26:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Wed, 17 Nov 2010 22:26:00 -0000 Subject: LVM2/tools reporter.c Message-ID: <20101117222643.16641.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-17 22:26:43 Modified files: tools : reporter.c Log message: The _free_vg that is created as a placeholder when reporting segments in pvs was lacking the (vgmem) pool. We now create that pool. There is at least one more such VG (_dummy_vg) which is pool-less. I am not sure what is the right way to go about this, but this is currently necessary to fix a segfault introduced by using vgmem in the reporter in Dave's lvseg lvm2app patches. Signed-off-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/reporter.c.diff?cvsroot=lvm2&r1=1.62&r2=1.63 --- LVM2/tools/reporter.c 2010/07/09 15:34:48 1.62 +++ LVM2/tools/reporter.c 2010/11/17 22:26:42 1.63 @@ -64,6 +64,9 @@ .name = (char *)"", }; + if (!(_free_vg.vgmem = dm_pool_create("_free_vg", 10240))) + return ECMD_FAILED; + struct logical_volume _free_logical_volume = { .vg = vg ?: &_free_vg, .name = (char *) "", @@ -103,10 +106,11 @@ if (!report_object(handle, vg, seg ? seg->lv : &_free_logical_volume, pvseg->pv, seg ? : &_free_lv_segment, pvseg)) { - stack; ret = ECMD_FAILED; + goto_out; } - + out: + dm_pool_destroy(_free_vg.vgmem); return ret; } From agk@sourceware.org Fri Nov 19 13:17:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Fri, 19 Nov 2010 13:17:00 -0000 Subject: LVM2 ./WHATS_NEW_DM libdm/libdm-report.c Message-ID: <20101119131728.5314.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-19 13:17:28 Modified files: . : WHATS_NEW_DM libdm : libdm-report.c Log message: Fix _output_field crash from field_id free with DEBUG_MEM. (Phillip Susi) Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW_DM.diff?cvsroot=lvm2&r1=1.423&r2=1.424 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-report.c.diff?cvsroot=lvm2&r1=1.39&r2=1.40 --- LVM2/WHATS_NEW_DM 2010/11/09 02:58:06 1.423 +++ LVM2/WHATS_NEW_DM 2010/11/19 13:17:27 1.424 @@ -1,5 +1,6 @@ Version 1.02.58 - =================================== + Fix _output_field crash from field_id free with DEBUG_MEM. (1.02.57) Version 1.02.57 - 8th November 2010 =================================== --- LVM2/libdm/libdm-report.c 2010/11/01 13:50:51 1.39 +++ LVM2/libdm/libdm-report.c 2010/11/19 13:17:27 1.40 @@ -929,7 +929,7 @@ return 0; } - free(field_id); + dm_free(field_id); if (!dm_pool_grow_object(rh->mem, "=", 1)) { log_error("dm_report: Unable to extend output line"); From agk@sourceware.org Mon Nov 22 14:26:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Mon, 22 Nov 2010 14:26:00 -0000 Subject: LVM2 VERSION VERSION_DM WHATS_NEW WHATS_NEW_DM Message-ID: <20101122142612.7823.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-22 14:25:22 Modified files: . : VERSION VERSION_DM WHATS_NEW WHATS_NEW_DM Log message: pre-release Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/VERSION.diff?cvsroot=lvm2&r1=1.260&r2=1.261 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/VERSION_DM.diff?cvsroot=lvm2&r1=1.69&r2=1.70 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1798&r2=1.1799 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW_DM.diff?cvsroot=lvm2&r1=1.424&r2=1.425 --- LVM2/VERSION 2010/11/09 02:58:06 1.260 +++ LVM2/VERSION 2010/11/22 14:25:22 1.261 @@ -1 +1 @@ -2.02.77(2)-cvs (2010-11-08) +2.02.77(2)-cvs (2010-11-22) --- LVM2/VERSION_DM 2010/11/09 02:58:06 1.69 +++ LVM2/VERSION_DM 2010/11/22 14:25:22 1.70 @@ -1 +1 @@ -1.02.58-cvs (2010-11-08) +1.02.58-cvs (2010-11-22) --- LVM2/WHATS_NEW 2010/11/17 10:19:29 1.1798 +++ LVM2/WHATS_NEW 2010/11/22 14:25:22 1.1799 @@ -1,10 +1,13 @@ -Version 2.02.77 - -=================================== +Version 2.02.77 - 22nd November 2010 +==================================== + Allocate a pool for dummy VG in _pvsegs_sub_single. + Add PV and LV segment types and functions to liblvm. + Add set_property functions to liblvm. Remove tag length restriction and allow / = ! : # & characters. Support repetition of --addtag and --deltag arguments. Add infrastructure for specific cmdline arguments to be repeated in groups. Split the_args cmdline arguments and values into arg_props and arg_values. - Fix fsadm to not require '-f' for resize of unmounted filesystem. + Fix fsadm no longer to require '-f' to resize an unmounted filesystem. Fix fsadm to detect mounted filesystems on older systems. (2.0.75) Extend cling allocation policy to recognise PV tags (cling_by_tags). Add allocation/cling_tag_list to lvm.conf. --- LVM2/WHATS_NEW_DM 2010/11/19 13:17:27 1.424 +++ LVM2/WHATS_NEW_DM 2010/11/22 14:25:22 1.425 @@ -1,5 +1,5 @@ -Version 1.02.58 - -=================================== +Version 1.02.58 - 22nd November 2010 +==================================== Fix _output_field crash from field_id free with DEBUG_MEM. (1.02.57) Version 1.02.57 - 8th November 2010 From agk@sourceware.org Mon Nov 22 18:38:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Mon, 22 Nov 2010 18:38:00 -0000 Subject: LVM2 VERSION VERSION_DM WHATS_NEW WHATS_NEW_DM Message-ID: <20101122183801.17147.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-22 18:37:57 Modified files: . : VERSION VERSION_DM WHATS_NEW WHATS_NEW_DM Log message: post-release Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/VERSION.diff?cvsroot=lvm2&r1=1.261&r2=1.262 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/VERSION_DM.diff?cvsroot=lvm2&r1=1.70&r2=1.71 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1799&r2=1.1800 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW_DM.diff?cvsroot=lvm2&r1=1.425&r2=1.426 --- LVM2/VERSION 2010/11/22 14:25:22 1.261 +++ LVM2/VERSION 2010/11/22 18:37:56 1.262 @@ -1 +1 @@ -2.02.77(2)-cvs (2010-11-22) +2.02.78(2)-cvs (2010-11-22) --- LVM2/VERSION_DM 2010/11/22 14:25:22 1.70 +++ LVM2/VERSION_DM 2010/11/22 18:37:56 1.71 @@ -1 +1 @@ -1.02.58-cvs (2010-11-22) +1.02.59-cvs (2010-11-22) --- LVM2/WHATS_NEW 2010/11/22 14:25:22 1.1799 +++ LVM2/WHATS_NEW 2010/11/22 18:37:56 1.1800 @@ -1,3 +1,6 @@ +Version 2.02.78 - +==================================== + Version 2.02.77 - 22nd November 2010 ==================================== Allocate a pool for dummy VG in _pvsegs_sub_single. --- LVM2/WHATS_NEW_DM 2010/11/22 14:25:22 1.425 +++ LVM2/WHATS_NEW_DM 2010/11/22 18:37:56 1.426 @@ -1,3 +1,6 @@ +Version 1.02.59 - +==================================== + Version 1.02.58 - 22nd November 2010 ==================================== Fix _output_field crash from field_id free with DEBUG_MEM. (1.02.57) From agk@sourceware.org Mon Nov 22 21:39:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Mon, 22 Nov 2010 21:39:00 -0000 Subject: LVM2 Makefile.in WHATS_NEW Message-ID: <20101122213948.11757.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-22 21:39:47 Modified files: . : Makefile.in WHATS_NEW Log message: Fix default /etc/lvm permissions to be 0755. (2.02.66) Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/Makefile.in.diff?cvsroot=lvm2&r1=1.62&r2=1.63 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1800&r2=1.1801 --- LVM2/Makefile.in 2010/08/09 10:56:01 1.62 +++ LVM2/Makefile.in 2010/11/22 21:39:47 1.63 @@ -81,7 +81,7 @@ $(MAKE) -C test $(@) install_system_dirs: - $(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_SYS_DIR) + $(INSTALL_DIR) $(DESTDIR)$(DEFAULT_SYS_DIR) $(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_ARCHIVE_DIR) $(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_BACKUP_DIR) $(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_CACHE_DIR) --- LVM2/WHATS_NEW 2010/11/22 18:37:56 1.1800 +++ LVM2/WHATS_NEW 2010/11/22 21:39:47 1.1801 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Fix default /etc/lvm permissions to be 0755. (2.02.66) Version 2.02.77 - 22nd November 2010 ==================================== From agk@sourceware.org Tue Nov 23 01:56:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Tue, 23 Nov 2010 01:56:00 -0000 Subject: LVM2 ./WHATS_NEW daemons/clvmd/lvm-functions.c ... Message-ID: <20101123015618.11963.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-23 01:56:02 Modified files: . : WHATS_NEW daemons/clvmd : lvm-functions.c lib/metadata : metadata-exported.h metadata.c tools : pvremove.c toollib.c Log message: Suppress 'No PV label' message when removing several PVs without mdas. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1801&r2=1.1802 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/clvmd/lvm-functions.c.diff?cvsroot=lvm2&r1=1.99&r2=1.100 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata-exported.h.diff?cvsroot=lvm2&r1=1.170&r2=1.171 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.c.diff?cvsroot=lvm2&r1=1.409&r2=1.410 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/pvremove.c.diff?cvsroot=lvm2&r1=1.30&r2=1.31 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/toollib.c.diff?cvsroot=lvm2&r1=1.212&r2=1.213 --- LVM2/WHATS_NEW 2010/11/22 21:39:47 1.1801 +++ LVM2/WHATS_NEW 2010/11/23 01:55:53 1.1802 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Suppress 'No PV label' message when removing several PVs without mdas. Fix default /etc/lvm permissions to be 0755. (2.02.66) Version 2.02.77 - 22nd November 2010 --- LVM2/daemons/clvmd/lvm-functions.c 2010/08/17 19:25:05 1.99 +++ LVM2/daemons/clvmd/lvm-functions.c 2010/11/23 01:55:58 1.100 @@ -848,7 +848,7 @@ pthread_mutex_lock(&lvm_lock); - vg = vg_read_internal(cmd, vgname, NULL /*vgid*/, &consistent); + vg = vg_read_internal(cmd, vgname, NULL /*vgid*/, 1, &consistent); if (vg && consistent) check_current_backup(vg); --- LVM2/lib/metadata/metadata-exported.h 2010/11/11 17:29:06 1.170 +++ LVM2/lib/metadata/metadata-exported.h 2010/11/23 01:55:59 1.171 @@ -341,7 +341,7 @@ int vg_commit(struct volume_group *vg); int vg_revert(struct volume_group *vg); struct volume_group *vg_read_internal(struct cmd_context *cmd, const char *vg_name, - const char *vgid, int *consistent); + const char *vgid, int warnings, int *consistent); struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name, struct dm_list *mdas, uint64_t *label_sector, int warnings, int scan_label_only); @@ -357,7 +357,7 @@ struct dm_list *get_vgnames(struct cmd_context *cmd, int include_internal); struct dm_list *get_vgids(struct cmd_context *cmd, int include_internal); -int scan_vgs_for_pvs(struct cmd_context *cmd); +int scan_vgs_for_pvs(struct cmd_context *cmd, int warnings); int pv_write(struct cmd_context *cmd, struct physical_volume *pv, struct dm_list *mdas, int64_t label_sector); --- LVM2/lib/metadata/metadata.c 2010/11/09 12:34:42 1.409 +++ LVM2/lib/metadata/metadata.c 2010/11/23 01:55:59 1.410 @@ -344,7 +344,7 @@ struct pv_list *pvl; int r = 0, consistent = 0; - if (!(vg = vg_read_internal(fmt->cmd, vg_name, vgid, &consistent))) { + if (!(vg = vg_read_internal(fmt->cmd, vg_name, vgid, 1, &consistent))) { log_error("get_pv_from_vg_by_id: vg_read_internal failed to read VG %s", vg_name); return 0; @@ -918,7 +918,7 @@ /* FIXME: Is this vg_read_internal necessary? Move it inside vg_lock_newname? */ /* is this vg name already in use ? */ - if ((vg = vg_read_internal(cmd, vg_name, NULL, &consistent))) { + if ((vg = vg_read_internal(cmd, vg_name, NULL, 1, &consistent))) { log_error("A volume group called '%s' already exists.", vg_name); unlock_and_release_vg(cmd, vg, vg_name); return _vg_make_handle(cmd, NULL, FAILED_EXIST); @@ -1343,7 +1343,7 @@ * system. */ if (pv && is_orphan(pv) && mdas_empty_or_ignored(&mdas)) { - if (!scan_vgs_for_pvs(cmd)) + if (!scan_vgs_for_pvs(cmd, 0)) return_0; pv = pv_read(cmd, name, NULL, NULL, 0, 0); } @@ -1812,7 +1812,7 @@ if (is_orphan_vg(pv->vg_name) && mdas_empty_or_ignored(&mdas)) { /* If a PV has no MDAs - need to search all VGs for it */ - if (!scan_vgs_for_pvs(cmd)) + if (!scan_vgs_for_pvs(cmd, 1)) return_NULL; if (!(pv = _pv_read(cmd, cmd->mem, pv_name, NULL, NULL, 1, 0))) { log_error("Physical volume %s not found", pv_name); @@ -2513,6 +2513,7 @@ /* Make orphan PVs look like a VG */ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd, + int warnings, const char *orphan_vgname) { struct lvmcache_vginfo *vginfo; @@ -2554,7 +2555,7 @@ } dm_list_iterate_items(info, &vginfo->infos) { - if (!(pv = _pv_read(cmd, mem, dev_name(info->dev), NULL, NULL, 1, 0))) { + if (!(pv = _pv_read(cmd, mem, dev_name(info->dev), NULL, NULL, warnings, 0))) { continue; } if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl)))) { @@ -2641,6 +2642,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd, const char *vgname, const char *vgid, + int warnings, int *consistent, unsigned precommitted) { struct format_instance *fid; @@ -2667,7 +2669,7 @@ return NULL; } *consistent = 1; - return _vg_read_orphans(cmd, vgname); + return _vg_read_orphans(cmd, warnings, vgname); } /* @@ -3035,12 +3037,12 @@ } struct volume_group *vg_read_internal(struct cmd_context *cmd, const char *vgname, - const char *vgid, int *consistent) + const char *vgid, int warnings, int *consistent) { struct volume_group *vg; struct lv_list *lvl; - if (!(vg = _vg_read(cmd, vgname, vgid, consistent, 0))) + if (!(vg = _vg_read(cmd, vgname, vgid, warnings, consistent, 0))) return NULL; if (!check_pv_segments(vg)) { @@ -3104,7 +3106,7 @@ /* Is corresponding vgname already cached? */ if ((vginfo = vginfo_from_vgid(vgid)) && vginfo->vgname && !is_orphan_vg(vginfo->vgname)) { - if ((vg = _vg_read(cmd, NULL, vgid, + if ((vg = _vg_read(cmd, NULL, vgid, 1, &consistent, precommitted)) && !strncmp((char *)vg->id.uuid, vgid, ID_LEN)) { @@ -3137,7 +3139,7 @@ if (!vgname) continue; // FIXME Unnecessary? consistent = 0; - if ((vg = _vg_read(cmd, vgname, vgid, &consistent, + if ((vg = _vg_read(cmd, vgname, vgid, 1, &consistent, precommitted)) && !strncmp((char *)vg->id.uuid, vgid, ID_LEN)) { @@ -3208,7 +3210,7 @@ * every PV on the system. */ if (mdas_empty_or_ignored(&info->mdas)) { - if (!scan_vgs_for_pvs(cmd)) { + if (!scan_vgs_for_pvs(cmd, 1)) { log_error("Rescan for PVs without " "metadata areas failed."); return NULL; @@ -3323,7 +3325,7 @@ return lvmcache_get_vgids(cmd, include_internal); } -static int _get_pvs(struct cmd_context *cmd, struct dm_list **pvslist) +static int _get_pvs(struct cmd_context *cmd, int warnings, struct dm_list **pvslist) { struct str_list *strl; struct dm_list * uninitialized_var(results); @@ -3364,7 +3366,7 @@ stack; continue; } - if (!(vg = vg_read_internal(cmd, vgname, vgid, &consistent))) { + if (!(vg = vg_read_internal(cmd, vgname, vgid, warnings, &consistent))) { stack; continue; } @@ -3398,15 +3400,15 @@ { struct dm_list *results; - if (!_get_pvs(cmd, &results)) + if (!_get_pvs(cmd, 1, &results)) return NULL; return results; } -int scan_vgs_for_pvs(struct cmd_context *cmd) +int scan_vgs_for_pvs(struct cmd_context *cmd, int warnings) { - return _get_pvs(cmd, NULL); + return _get_pvs(cmd, warnings, NULL); } int pv_write(struct cmd_context *cmd __attribute__((unused)), @@ -3581,7 +3583,7 @@ if (!lock_vol(cmd, vg_name, LCK_VG_WRITE)) return_NULL; - if (!(vg = vg_read_internal(cmd, vg_name, vgid, &consistent))) + if (!(vg = vg_read_internal(cmd, vg_name, vgid, 1, &consistent))) return_NULL; if (!consistent) { @@ -3636,7 +3638,7 @@ consistent_in = consistent; /* If consistent == 1, we get NULL here if correction fails. */ - if (!(vg = vg_read_internal(cmd, vg_name, vgid, &consistent))) { + if (!(vg = vg_read_internal(cmd, vg_name, vgid, 1, &consistent))) { if (consistent_in && !consistent) { log_error("Volume group \"%s\" inconsistent.", vg_name); failure |= FAILED_INCONSISTENT; --- LVM2/tools/pvremove.c 2010/09/23 12:02:34 1.30 +++ LVM2/tools/pvremove.c 2010/11/23 01:56:02 1.31 @@ -48,7 +48,7 @@ * PV on the system. */ if (is_orphan(pv) && !dm_list_size(&mdas)) { - if (!scan_vgs_for_pvs(cmd)) { + if (!scan_vgs_for_pvs(cmd, 0)) { log_error("Rescan for PVs without metadata areas " "failed."); return 0; --- LVM2/tools/toollib.c 2010/11/17 10:19:30 1.212 +++ LVM2/tools/toollib.c 2010/11/23 01:56:02 1.213 @@ -629,7 +629,7 @@ int ret_max = ECMD_PROCESSED; int ret = 0; - if (!scan_vgs_for_pvs(cmd)) { + if (!scan_vgs_for_pvs(cmd, 1)) { stack; return ECMD_FAILED; } @@ -744,7 +744,7 @@ if (!scanned && is_orphan(pv) && !dm_list_size(&mdas)) { if (!scan_label_only && - !scan_vgs_for_pvs(cmd)) { + !scan_vgs_for_pvs(cmd, 1)) { stack; ret_max = ECMD_FAILED; continue; From zkabelac@sourceware.org Tue Nov 23 15:00:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 23 Nov 2010 15:00:00 -0000 Subject: LVM2/libdm libdm-string.c Message-ID: <20101123150053.24357.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-23 15:00:52 Modified files: libdm : libdm-string.c Log message: Move va_end(ap) so we do not leave with return -1 without calling it. Remove unneeded ';' Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-string.c.diff?cvsroot=lvm2&r1=1.13&r2=1.14 --- LVM2/libdm/libdm-string.c 2010/10/25 13:13:53 1.13 +++ LVM2/libdm/libdm-string.c 2010/11/23 15:00:52 1.14 @@ -144,6 +144,8 @@ while (!ok) { va_start(ap, format); n = vsnprintf(buf, size, format, ap); + va_end(ap); + if (0 <= n && n < size) ok = 1; else { @@ -152,8 +154,7 @@ buf = dm_malloc(size); if (!buf) return -1; - }; - va_end(ap); + } } *result = dm_strdup(buf); From zkabelac@sourceware.org Tue Nov 23 15:09:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 23 Nov 2010 15:09:00 -0000 Subject: LVM2/lib/config config.c Message-ID: <20101123150902.29444.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-23 15:08:58 Modified files: lib/config : config.c Log message: Move va_end() so it is also used before error path return Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/config/config.c.diff?cvsroot=lvm2&r1=1.82&r2=1.83 --- LVM2/lib/config/config.c 2010/09/30 21:06:51 1.82 +++ LVM2/lib/config/config.c 2010/11/23 15:08:57 1.83 @@ -381,11 +381,12 @@ va_start(ap, fmt); n = vsnprintf(&buf[0], sizeof buf - 1, fmt, ap); + va_end(ap); + if (n < 0 || n > (int) sizeof buf - 1) { log_error("vsnprintf failed for config line"); return 0; } - va_end(ap); if (!dm_pool_grow_object(outline->mem, &buf[0], strlen(buf))) { log_error("dm_pool_grow_object failed for config line"); From zkabelac@sourceware.org Tue Nov 23 15:28:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 23 Nov 2010 15:28:00 -0000 Subject: LVM2 lib/activate/fs.c ./WHATS_NEW Message-ID: <20101123152855.12264.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-23 15:28:55 Modified files: lib/activate : fs.c . : WHATS_NEW Log message: Add missing closedir() - fixes resource leak Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/fs.c.diff?cvsroot=lvm2&r1=1.51&r2=1.52 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1802&r2=1.1803 --- LVM2/lib/activate/fs.c 2010/01/11 15:40:03 1.51 +++ LVM2/lib/activate/fs.c 2010/11/23 15:28:54 1.52 @@ -105,6 +105,9 @@ log_sys_error("unlink", path); } } + + if (closedir(d)) + log_sys_error("closedir", dir); } static int _mk_link(const char *dev_dir, const char *vg_name, --- LVM2/WHATS_NEW 2010/11/23 01:55:53 1.1802 +++ LVM2/WHATS_NEW 2010/11/23 15:28:55 1.1803 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Fix resource leak in _rm_blks(). Suppress 'No PV label' message when removing several PVs without mdas. Fix default /etc/lvm permissions to be 0755. (2.02.66) From zkabelac@sourceware.org Tue Nov 23 18:29:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 23 Nov 2010 18:29:00 -0000 Subject: LVM2 ./WHATS_NEW libdm/libdm-deptree.c Message-ID: <20101123182907.29349.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-23 18:29:06 Modified files: . : WHATS_NEW libdm : libdm-deptree.c Log message: Do not call dm_task_destroy with NULL Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1803&r2=1.1804 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-deptree.c.diff?cvsroot=lvm2&r1=1.86&r2=1.87 --- LVM2/WHATS_NEW 2010/11/23 15:28:55 1.1803 +++ LVM2/WHATS_NEW 2010/11/23 18:29:06 1.1804 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Fix dm_task_destroy(NULL) call in _node_clear_table() error path. Fix resource leak in _rm_blks(). Suppress 'No PV label' message when removing several PVs without mdas. Fix default /etc/lvm permissions to be 0755. (2.02.66) --- LVM2/libdm/libdm-deptree.c 2010/09/30 21:06:52 1.86 +++ LVM2/libdm/libdm-deptree.c 2010/11/23 18:29:06 1.87 @@ -580,7 +580,6 @@ name, info->major, info->minor); if (!(dmt = dm_task_create(DM_DEVICE_CLEAR))) { - dm_task_destroy(dmt); log_error("Table clear dm_task creation failed for %s", name); return 0; } From zkabelac@sourceware.org Tue Nov 23 20:39:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 23 Nov 2010 20:39:00 -0000 Subject: LVM2 ./WHATS_NEW tools/toollib.c Message-ID: <20101123203915.11523.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-23 20:39:14 Modified files: . : WHATS_NEW tools : toollib.c Log message: Move arg_vgnames from local scope As gcc puts probably all vars on stack this bug was not noticed in runtime. Patch fixes referencing local scope list variable. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1804&r2=1.1805 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/toollib.c.diff?cvsroot=lvm2&r1=1.213&r2=1.214 --- LVM2/WHATS_NEW 2010/11/23 18:29:06 1.1804 +++ LVM2/WHATS_NEW 2010/11/23 20:39:13 1.1805 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Fix out-of-scope variable usage in process_each_lv(). Fix dm_task_destroy(NULL) call in _node_clear_table() error path. Fix resource leak in _rm_blks(). Suppress 'No PV label' message when removing several PVs without mdas. --- LVM2/tools/toollib.c 2010/11/23 01:56:02 1.213 +++ LVM2/tools/toollib.c 2010/11/23 20:39:14 1.214 @@ -198,6 +198,7 @@ struct dm_list failed_lvnames; struct dm_list tags, lvnames; struct dm_list arg_lvnames; /* Cmdline vgname or vgname/lvname */ + struct dm_list arg_vgnames; char *vglv; size_t vglv_sz; @@ -208,8 +209,6 @@ dm_list_init(&failed_lvnames); if (argc) { - struct dm_list arg_vgnames; - log_verbose("Using logical volume(s) on command line"); dm_list_init(&arg_vgnames); From zkabelac@sourceware.org Tue Nov 23 21:19:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 23 Nov 2010 21:19:00 -0000 Subject: LVM2 ./WHATS_NEW daemons/dmeventd/plugins/snap ... Message-ID: <20101123211947.29382.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-23 21:19:46 Modified files: . : WHATS_NEW daemons/dmeventd/plugins/snapshot: dmeventd_snapshot.c Log message: Add missing fclose Fixing resource leak in _umount(). CHECKME: mountpoints with spaces need to be checked Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1805&r2=1.1806 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c.diff?cvsroot=lvm2&r1=1.12&r2=1.13 --- LVM2/WHATS_NEW 2010/11/23 20:39:13 1.1805 +++ LVM2/WHATS_NEW 2010/11/23 21:19:45 1.1806 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Fix missing fclose for _umount() in dmeventd snapshot plugin. Fix out-of-scope variable usage in process_each_lv(). Fix dm_task_destroy(NULL) call in _node_clear_table() error path. Fix resource leak in _rm_blks(). --- LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c 2010/10/29 16:43:51 1.12 +++ LVM2/daemons/dmeventd/plugins/snapshot/dmeventd_snapshot.c 2010/11/23 21:19:45 1.13 @@ -170,6 +170,9 @@ device, words[1], strerror(errno)); } } + + if (fclose(mounts)) + syslog(LOG_ERR, "Failed to close /proc/mounts.\n"); } void process_event(struct dm_task *dmt, From zkabelac@sourceware.org Wed Nov 24 09:34:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Wed, 24 Nov 2010 09:34:00 -0000 Subject: LVM2 ./WHATS_NEW lib/commands/toolcontext.c Message-ID: <20101124093435.4218.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-24 09:34:35 Modified files: . : WHATS_NEW lib/commands : toolcontext.c Log message: Fix resource leak of dlopened pointer Add missing dlclose in _init_formats() error path. Use return_0 to print stack trace from the call. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1806&r2=1.1807 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.108&r2=1.109 --- LVM2/WHATS_NEW 2010/11/23 21:19:45 1.1806 +++ LVM2/WHATS_NEW 2010/11/24 09:34:34 1.1807 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Fix missing dlclose in _init_formats() error path from init_format call. Fix missing fclose for _umount() in dmeventd snapshot plugin. Fix out-of-scope variable usage in process_each_lv(). Fix dm_task_destroy(NULL) call in _node_clear_table() error path. --- LVM2/lib/commands/toolcontext.c 2010/11/11 17:29:05 1.108 +++ LVM2/lib/commands/toolcontext.c 2010/11/24 09:34:35 1.109 @@ -814,8 +814,11 @@ return 0; } - if (!(fmt = init_format_fn(cmd))) - return 0; + if (!(fmt = init_format_fn(cmd))) { + dlclose(lib); + return_0; + } + fmt->library = lib; dm_list_add(&cmd->formats, &fmt->list); } From zkabelac@sourceware.org Wed Nov 24 09:43:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Wed, 24 Nov 2010 09:43:00 -0000 Subject: LVM2 ./WHATS_NEW tools/dmsetup.c Message-ID: <20101124094320.20204.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-24 09:43:19 Modified files: . : WHATS_NEW tools : dmsetup.c Log message: Fix memory leak in error path Release allocated path buffer in error path. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1807&r2=1.1808 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/dmsetup.c.diff?cvsroot=lvm2&r1=1.147&r2=1.148 --- LVM2/WHATS_NEW 2010/11/24 09:34:34 1.1807 +++ LVM2/WHATS_NEW 2010/11/24 09:43:18 1.1808 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Fix memory leak in error path of parse_loop_device_name() from dmsetup. Fix missing dlclose in _init_formats() error path from init_format call. Fix missing fclose for _umount() in dmeventd snapshot plugin. Fix out-of-scope variable usage in process_each_lv(). --- LVM2/tools/dmsetup.c 2010/10/25 13:36:57 1.147 +++ LVM2/tools/dmsetup.c 2010/11/24 09:43:18 1.148 @@ -2904,6 +2904,7 @@ return buf; error: + dm_free(buf); return NULL; } From zkabelac@sourceware.org Wed Nov 24 09:53:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Wed, 24 Nov 2010 09:53:00 -0000 Subject: LVM2 ./WHATS_NEW tools/lvmcmdline.c Message-ID: <20101124095332.24720.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-24 09:53:31 Modified files: . : WHATS_NEW tools : lvmcmdline.c Log message: Add missing destrustion of cmd_context Lvm1 fallback code missed to destroy cmd_context in error path. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1808&r2=1.1809 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvmcmdline.c.diff?cvsroot=lvm2&r1=1.131&r2=1.132 --- LVM2/WHATS_NEW 2010/11/24 09:43:18 1.1808 +++ LVM2/WHATS_NEW 2010/11/24 09:53:31 1.1809 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Fix missing context desctruction in err path of lvm1 fallback in lvm2_main(). Fix memory leak in error path of parse_loop_device_name() from dmsetup. Fix missing dlclose in _init_formats() error path from init_format call. Fix missing fclose for _umount() in dmeventd snapshot plugin. --- LVM2/tools/lvmcmdline.c 2010/11/17 10:19:30 1.131 +++ LVM2/tools/lvmcmdline.c 2010/11/24 09:53:31 1.132 @@ -1447,10 +1447,12 @@ if (!argc) { log_error("Falling back to LVM1 tools, but no " "command specified."); - return ECMD_FAILED; + ret = ECMD_FAILED; + goto out; } _exec_lvm1_command(argv); - return ECMD_FAILED; + ret = ECMD_FAILED; + goto out; } #ifdef READLINE_SUPPORT if (!alias && argc == 1) { From mornfall@sourceware.org Thu Nov 25 14:33:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Thu, 25 Nov 2010 14:33:00 -0000 Subject: LVM2/liblvm lvm2app.h lvm_lv.c lvm_pv.c Message-ID: <20101125143352.8667.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-25 14:33:45 Modified files: liblvm : lvm2app.h lvm_lv.c lvm_pv.c Log message: This patch adds helpers to allow users to lookup a lv or pv handle by name (given a vg_t of course). Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm2app.h.diff?cvsroot=lvm2&r1=1.28&r2=1.29 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_lv.c.diff?cvsroot=lvm2&r1=1.31&r2=1.32 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_pv.c.diff?cvsroot=lvm2&r1=1.17&r2=1.18 --- LVM2/liblvm/lvm2app.h 2010/11/17 20:12:39 1.28 +++ LVM2/liblvm/lvm2app.h 2010/11/25 14:33:44 1.29 @@ -1015,6 +1015,23 @@ struct dm_list *lvm_lv_list_lvsegs(lv_t lv); /** + * Lookup an LV handle in a VG by the LV name. + * + * \memberof lv_t + * + * \param vg + * VG handle obtained from lvm_vg_create() or lvm_vg_open(). + * + * \param name + * Name of LV to lookup. + * + * \return + * non-NULL handle to the LV 'name' attached to the VG. + * NULL is returned if the LV name is not associated with the VG handle. + */ +lv_t lvm_lv_from_name(vg_t vg, const char *name); + +/** * Activate a logical volume. * * \memberof lv_t @@ -1489,6 +1506,23 @@ struct dm_list *lvm_pv_list_pvsegs(pv_t pv); /** + * Lookup an PV handle in a VG by the PV name. + * + * \memberof pv_t + * + * \param vg + * VG handle obtained from lvm_vg_create() or lvm_vg_open(). + * + * \param name + * Name of PV to lookup. + * + * \return + * non-NULL handle to the PV 'name' attached to the VG. + * NULL is returned if the PV name is not associated with the VG handle. + */ +pv_t lvm_pv_from_name(vg_t vg, const char *name); + +/** * Resize physical volume to new_size bytes. * * \memberof pv_t --- LVM2/liblvm/lvm_lv.c 2010/11/17 20:12:39 1.31 +++ LVM2/liblvm/lvm_lv.c 2010/11/25 14:33:44 1.32 @@ -249,6 +249,17 @@ return list; } +lv_t lvm_lv_from_name(vg_t vg, const char *name) +{ + struct lv_list *lvl; + + dm_list_iterate_items(lvl, &vg->lvs) { + if (!strcmp(name, lvl->lv->name)) + return lvl->lv; + } + return NULL; +} + int lvm_lv_resize(const lv_t lv, uint64_t new_size) { /* FIXME: add lv resize code here */ --- LVM2/liblvm/lvm_pv.c 2010/11/17 20:12:40 1.17 +++ LVM2/liblvm/lvm_pv.c 2010/11/25 14:33:44 1.18 @@ -87,6 +87,18 @@ return list; } +pv_t lvm_pv_from_name(vg_t vg, const char *name) +{ + struct pv_list *pvl; + + dm_list_iterate_items(pvl, &vg->pvs) { + if (!strcmp(name, pv_dev_name(pvl->pv))) + return pvl->pv; + } + return NULL; +} + + int lvm_pv_resize(const pv_t pv, uint64_t new_size) { /* FIXME: add pv resize code here */ From mornfall@sourceware.org Thu Nov 25 14:34:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Thu, 25 Nov 2010 14:34:00 -0000 Subject: LVM2/liblvm lvm2app.h lvm_lv.c lvm_pv.c Message-ID: <20101125143456.10117.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-25 14:34:52 Modified files: liblvm : lvm2app.h lvm_lv.c lvm_pv.c Log message: This patch adds helpers to allow users to lookup a lv or pv handle by uuid (given a vg_t of course). Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm2app.h.diff?cvsroot=lvm2&r1=1.29&r2=1.30 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_lv.c.diff?cvsroot=lvm2&r1=1.32&r2=1.33 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_pv.c.diff?cvsroot=lvm2&r1=1.18&r2=1.19 --- LVM2/liblvm/lvm2app.h 2010/11/25 14:33:44 1.29 +++ LVM2/liblvm/lvm2app.h 2010/11/25 14:34:51 1.30 @@ -1032,6 +1032,25 @@ lv_t lvm_lv_from_name(vg_t vg, const char *name); /** + * Lookup an LV handle in a VG by the LV uuid. + * The form of the uuid may be either the formatted, human-readable form, + * or the non-formatted form. + * + * \memberof lv_t + * + * \param vg + * VG handle obtained from lvm_vg_create() or lvm_vg_open(). + * + * \param uuid + * UUID of LV to lookup. + * + * \return + * non-NULL handle to the LV with 'uuid' attached to the VG. + * NULL is returned if the LV uuid is not associated with the VG handle. + */ +lv_t lvm_lv_from_uuid(vg_t vg, const char *uuid); + +/** * Activate a logical volume. * * \memberof lv_t @@ -1523,6 +1542,25 @@ pv_t lvm_pv_from_name(vg_t vg, const char *name); /** + * Lookup an PV handle in a VG by the PV uuid. + * The form of the uuid may be either the formatted, human-readable form, + * or the non-formatted form. + * + * \memberof pv_t + * + * \param vg + * VG handle obtained from lvm_vg_create() or lvm_vg_open(). + * + * \param uuid + * UUID of PV to lookup. + * + * \return + * non-NULL handle to the PV with 'uuid' attached to the VG. + * NULL is returned if the PV uuid is not associated with the VG handle. + */ +pv_t lvm_pv_from_uuid(vg_t vg, const char *uuid); + +/** * Resize physical volume to new_size bytes. * * \memberof pv_t --- LVM2/liblvm/lvm_lv.c 2010/11/25 14:33:44 1.32 +++ LVM2/liblvm/lvm_lv.c 2010/11/25 14:34:51 1.33 @@ -260,6 +260,28 @@ return NULL; } +lv_t lvm_lv_from_uuid(vg_t vg, const char *uuid) +{ + struct lv_list *lvl; + struct id id; + + if (strlen(uuid) < ID_LEN) { + log_errno (EINVAL, "Invalid UUID string length"); + return NULL; + } + if (strlen(uuid) >= ID_LEN) { + if (!id_read_format(&id, uuid)) { + log_errno(EINVAL, "Invalid UUID format"); + return NULL; + } + } + dm_list_iterate_items(lvl, &vg->lvs) { + if (id_equal(&vg->id, &lvl->lv->lvid.id[0]) && + id_equal(&id, &lvl->lv->lvid.id[1])) + return lvl->lv; + } + return NULL; +} int lvm_lv_resize(const lv_t lv, uint64_t new_size) { /* FIXME: add lv resize code here */ --- LVM2/liblvm/lvm_pv.c 2010/11/25 14:33:44 1.18 +++ LVM2/liblvm/lvm_pv.c 2010/11/25 14:34:51 1.19 @@ -98,6 +98,28 @@ return NULL; } +pv_t lvm_pv_from_uuid(vg_t vg, const char *uuid) +{ + struct pv_list *pvl; + struct id id; + + if (strlen(uuid) < ID_LEN) { + log_errno (EINVAL, "Invalid UUID string length"); + return NULL; + } + if (strlen(uuid) >= ID_LEN) { + if (!id_read_format(&id, uuid)) { + log_errno(EINVAL, "Invalid UUID format"); + return NULL; + } + } + dm_list_iterate_items(pvl, &vg->pvs) { + if (id_equal(&id, &pvl->pv->id)) + return pvl->pv; + } + return NULL; +} + int lvm_pv_resize(const pv_t pv, uint64_t new_size) { From mornfall@sourceware.org Thu Nov 25 14:35:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Thu, 25 Nov 2010 14:35:00 -0000 Subject: LVM2/test/api test.c Message-ID: <20101125143548.12407.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-25 14:35:47 Modified files: test/api : test.c Log message: Add interactive tests for functions to lookup a pv|lv by name|uuid. Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/api/test.c.diff?cvsroot=lvm2&r1=1.33&r2=1.34 --- LVM2/test/api/test.c 2010/11/17 20:13:51 1.33 +++ LVM2/test/api/test.c 2010/11/25 14:35:46 1.34 @@ -113,6 +113,14 @@ "Lookup a vgname from a device name\n"); printf("'vgname_from_pvid pvid': " "Lookup a vgname from a pvid\n"); + printf("'lv_from_uuid vgname lvuuid': " + "Lookup an LV from an LV uuid\n"); + printf("'lv_from_name vgname lvname': " + "Lookup an LV from an LV name\n"); + printf("'pv_from_uuid vgname pvuuid': " + "Lookup an LV from an LV uuid\n"); + printf("'pv_from_name vgname pvname': " + "Lookup an LV from an LV name\n"); printf("'quit': exit the program\n"); } @@ -468,6 +476,30 @@ lvm_vg_get_pv_count(vg), lvm_vg_get_seqno(vg)); } +static void _print_pv(pv_t pv) +{ + if (!pv) + return; + printf("%s (%s): size=%"PRIu64", free=%"PRIu64 + ", dev_size=%"PRIu64", mda_count=%"PRIu64"\n", + lvm_pv_get_name(pv), lvm_pv_get_uuid(pv), + lvm_pv_get_size(pv), lvm_pv_get_free(pv), + lvm_pv_get_dev_size(pv), + lvm_pv_get_mda_count(pv)); +} + +static void _print_lv(vg_t vg, lv_t lv) +{ + if (!lv) + return; + printf("%s/%s (%s): size=%"PRIu64", %sACTIVE / %sSUSPENDED\n", + lvm_vg_get_name(vg), + lvm_lv_get_name(lv), lvm_lv_get_uuid(lv), + lvm_lv_get_size(lv), + lvm_lv_is_active(lv) ? "" : "IN", + lvm_lv_is_suspended(lv) ? "" : "NOT "); +} + static void _list_open_vgs(void) { dm_hash_iter(_vgid_hash, (dm_hash_iterate_fn) _show_one_vg); @@ -488,12 +520,7 @@ } printf("PVs in VG %s:\n", lvm_vg_get_name(vg)); dm_list_iterate_items(pvl, pvs) { - printf("%s (%s): size=%"PRIu64", free=%"PRIu64 - ", dev_size=%"PRIu64", mda_count=%"PRIu64"\n", - lvm_pv_get_name(pvl->pv), lvm_pv_get_uuid(pvl->pv), - lvm_pv_get_size(pvl->pv), lvm_pv_get_free(pvl->pv), - lvm_pv_get_dev_size(pvl->pv), - lvm_pv_get_mda_count(pvl->pv)); + _print_pv(pvl->pv); } } @@ -715,6 +742,59 @@ printf("%s tag %s to LV %s\n", add ? "adding":"removing", argv[3], argv[2]); } + +static void _lv_from_uuid(char **argv, int argc) +{ + vg_t vg; + + if (argc < 3) { + printf("Please enter vgname, lv_uuid\n"); + return; + } + if (!(vg = _lookup_vg_by_name(argv, argc))) + return; + _print_lv(vg, lvm_lv_from_uuid(vg, argv[2])); +} + +static void _lv_from_name(char **argv, int argc) +{ + vg_t vg; + + if (argc < 3) { + printf("Please enter vgname, lv_uuid\n"); + return; + } + if (!(vg = _lookup_vg_by_name(argv, argc))) + return; + _print_lv(vg, lvm_lv_from_name(vg, argv[2])); +} + +static void _pv_from_uuid(char **argv, int argc) +{ + vg_t vg; + + if (argc < 3) { + printf("Please enter vgname, pv_uuid\n"); + return; + } + if (!(vg = _lookup_vg_by_name(argv, argc))) + return; + _print_pv(lvm_pv_from_uuid(vg, argv[2])); +} + +static void _pv_from_name(char **argv, int argc) +{ + vg_t vg; + + if (argc < 3) { + printf("Please enter vgname, pv_uuid\n"); + return; + } + if (!(vg = _lookup_vg_by_name(argv, argc))) + return; + _print_pv(lvm_pv_from_name(vg, argv[2])); +} + static void _vgname_from_pvid(char **argv, int argc, lvm_t libh) { const char *vgname; @@ -762,12 +842,7 @@ } printf("LVs in VG %s:\n", lvm_vg_get_name(vg)); dm_list_iterate_items(lvl, lvs) { - printf("%s/%s (%s): size=%"PRIu64", %sACTIVE / %sSUSPENDED\n", - lvm_vg_get_name(vg), - lvm_lv_get_name(lvl->lv), lvm_lv_get_uuid(lvl->lv), - lvm_lv_get_size(lvl->lv), - lvm_lv_is_active(lvl->lv) ? "" : "IN", - lvm_lv_is_suspended(lvl->lv) ? "" : "NOT "); + _print_lv(vg, lvl->lv); } } @@ -978,6 +1053,14 @@ _vgname_from_devname(argv, argc, libh); } else if (!strcmp(argv[0], "vgname_from_pvid")) { _vgname_from_pvid(argv, argc, libh); + } else if (!strcmp(argv[0], "lv_from_uuid")) { + _lv_from_uuid(argv, argc); + } else if (!strcmp(argv[0], "lv_from_name")) { + _lv_from_name(argv, argc); + } else if (!strcmp(argv[0], "pv_from_uuid")) { + _pv_from_uuid(argv, argc); + } else if (!strcmp(argv[0], "pv_from_name")) { + _pv_from_name(argv, argc); } else { printf ("Unrecognized command %s\n", argv[0]); } From mornfall@sourceware.org Thu Nov 25 14:39:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Thu, 25 Nov 2010 14:39:00 -0000 Subject: LVM2/lib/report properties.c Message-ID: <20101125143906.21013.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-25 14:39:04 Modified files: lib/report : properties.c Log message: All 'size' values of lvm2app properties should be in bytes. Fix 'seg_size' to return bytes. Signed-off-by: Dave Wysochanski Reviewed-by: Petr Rockai Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/properties.c.diff?cvsroot=lvm2&r1=1.25&r2=1.26 --- LVM2/lib/report/properties.c 2010/11/17 20:11:27 1.25 +++ LVM2/lib/report/properties.c 2010/11/25 14:39:02 1.26 @@ -230,7 +230,7 @@ #define _seg_start_set _not_implemented_set GET_LVSEG_NUM_PROPERTY_FN(seg_start_pe, lvseg->le) #define _seg_start_pe_set _not_implemented_set -GET_LVSEG_NUM_PROPERTY_FN(seg_size, lvseg_size(lvseg)) +GET_LVSEG_NUM_PROPERTY_FN(seg_size, (SECTOR_SIZE * lvseg_size(lvseg))) #define _seg_size_set _not_implemented_set GET_LVSEG_STR_PROPERTY_FN(seg_tags, lvseg_tags_dup(lvseg)) #define _seg_tags_set _not_implemented_set From mornfall@sourceware.org Thu Nov 25 17:15:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Thu, 25 Nov 2010 17:15:00 -0000 Subject: LVM2 tools/lvconvert.c test/t-lvconvert-twostep.sh Message-ID: <20101125171554.6287.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-25 17:15:48 Modified files: tools : lvconvert.c Added files: test : t-lvconvert-twostep.sh Log message: Disallow certain lvconvert operations that need to both allocate and free extents, while physical volumes are specified. Fixes BZ 640051. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/t-lvconvert-twostep.sh.diff?cvsroot=lvm2&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvconvert.c.diff?cvsroot=lvm2&r1=1.148&r2=1.149 /cvs/lvm2/LVM2/test/t-lvconvert-twostep.sh,v --> standard output revision 1.1 --- LVM2/test/t-lvconvert-twostep.sh +++ - 2010-11-25 17:15:51.043330000 +0000 @@ -0,0 +1,21 @@ +#!/bin/bash +# Copyright (C) 2010 Red Hat, Inc. All rights reserved. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions +# of the GNU General Public License v.2. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +. ./test-utils.sh + +aux prepare_vg 4 +lvcreate -m 1 --mirrorlog disk --ig -L 1 -n mirror $vg +not lvconvert -m 2 --mirrorlog core $vg/mirror $dev3 2>&1 | tee errs +grep "two steps" errs +lvconvert -m 2 $vg/mirror $dev3 +lvconvert --mirrorlog core $vg/mirror +not lvconvert -m 1 --mirrorlog disk $vg/mirror $dev3 2>&1 | tee errs +grep "two steps" errs --- LVM2/tools/lvconvert.c 2010/10/13 21:26:38 1.148 +++ LVM2/tools/lvconvert.c 2010/11/25 17:15:47 1.149 @@ -1345,6 +1345,15 @@ &new_mimage_count, &new_log_count)) return 0; + if (((old_mimage_count < new_mimage_count && old_log_count > new_log_count) || + (old_mimage_count > new_mimage_count && old_log_count < new_log_count)) && + lp->pv_count) { + log_error("Cannot both allocate and free extents when specifying physical" + " volumes to use."); + log_error("Please specify the operation in two steps."); + return 0; + } + /* Nothing to do? (Probably finishing collapse.) */ if ((old_mimage_count == new_mimage_count) && (old_log_count == new_log_count) && !repair) From mornfall@sourceware.org Thu Nov 25 17:16:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Thu, 25 Nov 2010 17:16:00 -0000 Subject: LVM2 WHATS_NEW Message-ID: <20101125171642.6544.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-25 17:16:41 Modified files: . : WHATS_NEW Log message: Update WHATS_NEW. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1809&r2=1.1810 --- LVM2/WHATS_NEW 2010/11/24 09:53:31 1.1809 +++ LVM2/WHATS_NEW 2010/11/25 17:16:41 1.1810 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Certain lvconvert invocations are now required to be done in two steps. Fix missing context desctruction in err path of lvm1 fallback in lvm2_main(). Fix memory leak in error path of parse_loop_device_name() from dmsetup. Fix missing dlclose in _init_formats() error path from init_format call. From snitzer@sourceware.org Sun Nov 28 18:37:00 2010 From: snitzer@sourceware.org (snitzer@sourceware.org) Date: Sun, 28 Nov 2010 18:37:00 -0000 Subject: LVM2/tools lvconvert.c Message-ID: <20101128183734.4011.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: snitzer@sourceware.org 2010-11-28 18:37:34 Modified files: tools : lvconvert.c Log message: Fix "it's" typo to be "its" in lvconvert error message. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvconvert.c.diff?cvsroot=lvm2&r1=1.149&r2=1.150 --- LVM2/tools/lvconvert.c 2010/11/25 17:15:47 1.149 +++ LVM2/tools/lvconvert.c 2010/11/28 18:37:33 1.150 @@ -1572,7 +1572,7 @@ return ECMD_FAILED; } if (!lvconvert_merge(cmd, lv, lp)) { - log_error("Unable to merge LV \"%s\" into it's origin.", lv->name); + log_error("Unable to merge LV \"%s\" into its origin.", lv->name); return ECMD_FAILED; } } else if (lp->snapshot) { From zkabelac@sourceware.org Mon Nov 29 10:11:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 10:11:00 -0000 Subject: LVM2/libdm libdm-common.c Message-ID: <20101129101152.29135.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 10:11:51 Modified files: libdm : libdm-common.c Log message: Cleanup remove test for NULL dm_free is testing NULL itself Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-common.c.diff?cvsroot=lvm2&r1=1.101&r2=1.102 --- LVM2/libdm/libdm-common.c 2010/10/15 01:10:28 1.101 +++ LVM2/libdm/libdm-common.c 2010/11/29 10:11:50 1.102 @@ -250,10 +250,8 @@ char path[PATH_MAX]; struct stat st1, st2; - if (dmt->dev_name) { - dm_free(dmt->dev_name); - dmt->dev_name = NULL; - } + dm_free(dmt->dev_name); + dmt->dev_name = NULL; /* * Path supplied for existing device? @@ -292,8 +290,7 @@ if (strlen(name) >= DM_NAME_LEN) { log_error("Name \"%s\" too long", name); - if (new_name) - dm_free(new_name); + dm_free(new_name); return 0; } @@ -309,10 +306,7 @@ int dm_task_set_uuid(struct dm_task *dmt, const char *uuid) { - if (dmt->uuid) { - dm_free(dmt->uuid); - dmt->uuid = NULL; - } + dm_free(dmt->uuid); if (!(dmt->uuid = dm_strdup(uuid))) { log_error("dm_task_set_uuid: strdup(%s) failed", uuid); From zkabelac@sourceware.org Mon Nov 29 10:58:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 10:58:00 -0000 Subject: LVM2 lib/commands/toolcontext.c ./WHATS_NEW Message-ID: <20101129105833.5420.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 10:58:33 Modified files: lib/commands : toolcontext.c . : WHATS_NEW Log message: Fix check for empty system_dir Fixing check for zero length system_dir string. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.109&r2=1.110 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1810&r2=1.1811 --- LVM2/lib/commands/toolcontext.c 2010/11/24 09:34:35 1.109 +++ LVM2/lib/commands/toolcontext.c 2010/11/29 10:58:32 1.110 @@ -1036,7 +1036,7 @@ char default_dir[PATH_MAX]; const char *dir; - if (!cmd->system_dir) { + if (!cmd->system_dir[0]) { log_warn("WARNING: Metadata changes will NOT be backed up"); backup_init(cmd, "", 0); archive_init(cmd, "", 0, 0, 0); --- LVM2/WHATS_NEW 2010/11/25 17:16:41 1.1810 +++ LVM2/WHATS_NEW 2010/11/29 10:58:33 1.1811 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Fix test for empty system_dir string in _init_backup(). Certain lvconvert invocations are now required to be done in two steps. Fix missing context desctruction in err path of lvm1 fallback in lvm2_main(). Fix memory leak in error path of parse_loop_device_name() from dmsetup. From zkabelac@sourceware.org Mon Nov 29 11:05:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 11:05:00 -0000 Subject: LVM2/daemons/clvmd lvm-functions.c Message-ID: <20101129110515.8572.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 11:05:15 Modified files: daemons/clvmd : lvm-functions.c Log message: Remove printing of LCK_CACHE LCK_CACHE is defined as 0x100 so it cannot be passed through unsigned char parameter - remove it from the sprintf code. If the LCK_CLUSTER should be printed here - lot of code need to be reworked - so adding FIXME comment. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/clvmd/lvm-functions.c.diff?cvsroot=lvm2&r1=1.100&r2=1.101 --- LVM2/daemons/clvmd/lvm-functions.c 2010/11/23 01:55:58 1.100 +++ LVM2/daemons/clvmd/lvm-functions.c 2010/11/29 11:05:15 1.101 @@ -44,6 +44,10 @@ int lock_mode; }; +/* + * FIXME: 8bit value passed here - + * so only LCK_XXX defines < 0x100 can be decoded + */ static const char *decode_locking_cmd(unsigned char cmdl) { static char buf[128]; @@ -109,12 +113,11 @@ break; } - sprintf(buf, "0x%x %s (%s|%s%s%s%s%s%s)", cmdl, command, type, scope, + sprintf(buf, "0x%x %s (%s|%s%s%s%s%s)", cmdl, command, type, scope, cmdl & LCK_NONBLOCK ? "|NONBLOCK" : "", cmdl & LCK_HOLD ? "|HOLD" : "", cmdl & LCK_LOCAL ? "|LOCAL" : "", - cmdl & LCK_CLUSTER_VG ? "|CLUSTER_VG" : "", - cmdl & LCK_CACHE ? "|CACHE" : ""); + cmdl & LCK_CLUSTER_VG ? "|CLUSTER_VG" : ""); return buf; } From zkabelac@sourceware.org Mon Nov 29 11:08:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 11:08:00 -0000 Subject: LVM2 ./WHATS_NEW lib/metadata/metadata.c Message-ID: <20101129110814.10141.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 11:08:14 Modified files: . : WHATS_NEW lib/metadata : metadata.c Log message: Reset vg pointer after release Set vg to NULL after releasing it as the following memlock() test may lead to goto for the second call of vg_release() with the already released vg pointer. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1811&r2=1.1812 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.c.diff?cvsroot=lvm2&r1=1.410&r2=1.411 --- LVM2/WHATS_NEW 2010/11/29 10:58:33 1.1811 +++ LVM2/WHATS_NEW 2010/11/29 11:08:14 1.1812 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Fix missing reset of vg pointer after vg_release() in _vg_read_by_vgid(). Fix test for empty system_dir string in _init_backup(). Certain lvconvert invocations are now required to be done in two steps. Fix missing context desctruction in err path of lvm1 fallback in lvm2_main(). --- LVM2/lib/metadata/metadata.c 2010/11/23 01:55:59 1.410 +++ LVM2/lib/metadata/metadata.c 2010/11/29 11:08:14 1.411 @@ -3117,6 +3117,7 @@ return vg; } vg_release(vg); + vg = NULL; /* reset so memlock goto out is safe */ } /* Mustn't scan if memory locked: ensure cache gets pre-populated! */ From zkabelac@sourceware.org Mon Nov 29 11:13:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 11:13:00 -0000 Subject: LVM2/lib/locking cluster_locking.c Message-ID: <20101129111313.12761.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 11:13:12 Modified files: lib/locking : cluster_locking.c Log message: Remove dead assignment in _lock_for_cluster 'saved_errno' is not read from this initialization and before its usage is assigned again before _cluster_free_request() call. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/locking/cluster_locking.c.diff?cvsroot=lvm2&r1=1.46&r2=1.47 --- LVM2/lib/locking/cluster_locking.c 2010/08/17 19:25:05 1.46 +++ LVM2/lib/locking/cluster_locking.c 2010/11/29 11:13:12 1.47 @@ -308,7 +308,7 @@ const char *node = ""; int len; int dmeventd_mode; - int saved_errno = errno; + int saved_errno; lvm_response_t *response = NULL; int num_responses; From zkabelac@sourceware.org Mon Nov 29 11:14:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 11:14:00 -0000 Subject: LVM2/tools lvmcmdline.c Message-ID: <20101129111433.13650.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 11:14:33 Modified files: tools : lvmcmdline.c Log message: Remove dead assignment in lvm2_main 'alias' is not read again in this code path. Also 'alias' is already equal to 0 in this place. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvmcmdline.c.diff?cvsroot=lvm2&r1=1.132&r2=1.133 --- LVM2/tools/lvmcmdline.c 2010/11/24 09:53:31 1.132 +++ LVM2/tools/lvmcmdline.c 2010/11/29 11:14:33 1.133 @@ -1442,7 +1442,6 @@ if (!alias) { argv++; argc--; - alias = 0; } if (!argc) { log_error("Falling back to LVM1 tools, but no " From zkabelac@sourceware.org Mon Nov 29 11:16:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 11:16:00 -0000 Subject: LVM2/lib/format_text format-text.c Message-ID: <20101129111658.15250.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 11:16:58 Modified files: lib/format_text: format-text.c Log message: Remove unused 'i' in _pv_analyze_mda_raw 'i' is unused in the function - remove it. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/format-text.c.diff?cvsroot=lvm2&r1=1.148&r2=1.149 --- LVM2/lib/format_text/format-text.c 2010/10/26 09:13:13 1.148 +++ LVM2/lib/format_text/format-text.c 2010/11/29 11:16:58 1.149 @@ -173,7 +173,6 @@ uint64_t area_size; uint64_t prev_sector, prev_sector2; uint64_t latest_mrec_offset; - int i; uint64_t offset; uint64_t offset2; size_t size; @@ -214,7 +213,7 @@ offset = prev_sector; size = SECTOR_SIZE; offset2 = size2 = 0; - i = 0; + while (prev_sector != latest_mrec_offset) { prev_sector2 = prev_sector; prev_sector = _get_prev_sector_circular(area_start, area_size, From zkabelac@sourceware.org Mon Nov 29 11:23:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 11:23:00 -0000 Subject: LVM2/daemons/dmeventd dmeventd.c Message-ID: <20101129112314.17136.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 11:23:14 Modified files: daemons/dmeventd: dmeventd.c Log message: Remove dead assignment in 'main' 'ret' is never read anywhere - remove it. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/dmeventd/dmeventd.c.diff?cvsroot=lvm2&r1=1.69&r2=1.70 --- LVM2/daemons/dmeventd/dmeventd.c 2010/10/26 08:54:37 1.69 +++ LVM2/daemons/dmeventd/dmeventd.c 2010/11/29 11:23:14 1.70 @@ -1761,7 +1761,6 @@ int main(int argc, char *argv[]) { - int ret; signed char opt; struct dm_event_fifos fifos; //struct sys_log logdata = {DAEMON_NAME, LOG_DAEMON}; @@ -1835,7 +1834,7 @@ pthread_mutex_init(&_global_mutex, NULL); - if ((ret = _open_fifos(&fifos))) + if (_open_fifos(&fifos)) exit(EXIT_FIFO_FAILURE); /* Signal parent, letting them know we are ready to go. */ From zkabelac@sourceware.org Mon Nov 29 11:26:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 11:26:00 -0000 Subject: LVM2/libdm libdm-deptree.c Message-ID: <20101129112600.18695.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 11:26:00 Modified files: libdm : libdm-deptree.c Log message: Remove dead assignment in dm_tree_node_add_mirror_target_log 'seg' is never used - remove it. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-deptree.c.diff?cvsroot=lvm2&r1=1.87&r2=1.88 --- LVM2/libdm/libdm-deptree.c 2010/11/23 18:29:06 1.87 +++ LVM2/libdm/libdm-deptree.c 2010/11/29 11:26:00 1.88 @@ -2199,9 +2199,7 @@ int dm_tree_node_add_mirror_target(struct dm_tree_node *node, uint64_t size) { - struct load_segment *seg; - - if (!(seg = _add_segment(node, SEG_MIRRORED, size))) + if (!_add_segment(node, SEG_MIRRORED, size)) return_0; return 1; From zkabelac@sourceware.org Mon Nov 29 12:15:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 12:15:00 -0000 Subject: LVM2/daemons/dmeventd dmeventd.c Message-ID: <20101129121542.27148.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 12:15:42 Modified files: daemons/dmeventd: dmeventd.c Log message: Use one fprintf call for usage print Replace multiple fprintf calls with multiline one. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/dmeventd/dmeventd.c.diff?cvsroot=lvm2&r1=1.70&r2=1.71 --- LVM2/daemons/dmeventd/dmeventd.c 2010/11/29 11:23:14 1.70 +++ LVM2/daemons/dmeventd/dmeventd.c 2010/11/29 12:15:41 1.71 @@ -1749,14 +1749,12 @@ static void usage(char *prog, FILE *file) { - fprintf(file, "Usage:\n"); - fprintf(file, "%s [-V] [-h] [-d] [-d] [-d] [-f]\n", prog); - fprintf(file, "\n"); - fprintf(file, " -V Show version of dmeventd\n"); - fprintf(file, " -h Show this help information\n"); - fprintf(file, " -d Log debug messages to syslog (-d, -dd, -ddd)\n"); - fprintf(file, " -f Don't fork, run in the foreground\n"); - fprintf(file, "\n"); + fprintf(file, "Usage:\n" + "%s [-V] [-h] [-d] [-d] [-d] [-f]\n\n" + " -V Show version of dmeventd\n" + " -h Show this help information\n" + " -d Log debug messages to syslog (-d, -dd, -ddd)\n" + " -f Don't fork, run in the foreground\n\n", prog); } int main(int argc, char *argv[]) From zkabelac@sourceware.org Mon Nov 29 12:20:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 12:20:00 -0000 Subject: LVM2 ./WHATS_NEW lib/format_text/export.c Message-ID: <20101129121959.28053.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 12:19:58 Modified files: . : WHATS_NEW lib/format_text: export.c Log message: Fix memory leak in error path Nicely hidden memory leak in outf macro error path. This macro is using out_text() and does automagical return_0. That would leak tag_buffer allocated memory. As there was same code for tags output - create _out_tags() function. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1812&r2=1.1813 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/export.c.diff?cvsroot=lvm2&r1=1.79&r2=1.80 --- LVM2/WHATS_NEW 2010/11/29 11:08:14 1.1812 +++ LVM2/WHATS_NEW 2010/11/29 12:19:58 1.1813 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Fix memory leak in outf macro error path of _print_vg/lv/pvs/segment(). Fix missing reset of vg pointer after vg_release() in _vg_read_by_vgid(). Fix test for empty system_dir string in _init_backup(). Certain lvconvert invocations are now required to be done in two steps. --- LVM2/lib/format_text/export.c 2010/09/30 21:06:51 1.79 +++ LVM2/lib/format_text/export.c 2010/11/29 12:19:58 1.80 @@ -363,10 +363,27 @@ return 1; } + +static int _out_tags(struct formatter *f, struct dm_list *tags) +{ + char *tag_buffer; + + if (!dm_list_empty(tags)) { + if (!(tag_buffer = alloc_printed_tags(tags))) + return_0; + if (!out_text(f, "tags = %s", tag_buffer)) { + dm_free(tag_buffer); + return_0; + } + dm_free(tag_buffer); + } + + return 1; +} + static int _print_vg(struct formatter *f, struct volume_group *vg) { char buffer[4096]; - char *tag_buffer = NULL; if (!id_write_format(&vg->id, buffer, sizeof(buffer))) return_0; @@ -378,12 +395,8 @@ if (!_print_flag_config(f, vg->status, VG_FLAGS)) return_0; - if (!dm_list_empty(&vg->tags)) { - if (!(tag_buffer = alloc_printed_tags(&vg->tags))) - return_0; - outf(f, "tags = %s", tag_buffer); - dm_free(tag_buffer); - } + if (!_out_tags(f, &vg->tags)) + return_0; if (vg->system_id && *vg->system_id) outf(f, "system_id = \"%s\"", vg->system_id); @@ -428,7 +441,7 @@ struct pv_list *pvl; struct physical_volume *pv; char buffer[4096]; - char *buf, *tag_buffer = NULL; + char *buf; const char *name; outf(f, "physical_volumes {"); @@ -462,12 +475,8 @@ if (!_print_flag_config(f, pv->status, PV_FLAGS)) return_0; - if (!dm_list_empty(&pv->tags)) { - if (!(tag_buffer = alloc_printed_tags(&pv->tags))) - return_0; - outf(f, "tags = %s", tag_buffer); - dm_free(tag_buffer); - } + if (!_out_tags(f, &pv->tags)) + return_0; outsize(f, pv->size, "dev_size = %" PRIu64, pv->size); @@ -487,8 +496,6 @@ static int _print_segment(struct formatter *f, struct volume_group *vg, int count, struct lv_segment *seg) { - char *tag_buffer = NULL; - outf(f, "segment%u {", count); _inc_indent(f); @@ -499,12 +506,8 @@ outnl(f); outf(f, "type = \"%s\"", seg->segtype->name); - if (!dm_list_empty(&seg->tags)) { - if (!(tag_buffer = alloc_printed_tags(&seg->tags))) - return_0; - outf(f, "tags = %s", tag_buffer); - dm_free(tag_buffer); - } + if (!_out_tags(f, &seg->tags)) + return_0; if (seg->segtype->ops->text_export && !seg->segtype->ops->text_export(seg, f)) @@ -557,7 +560,6 @@ { struct lv_segment *seg; char buffer[4096]; - char *tag_buffer = NULL; int seg_count; outnl(f); @@ -573,12 +575,8 @@ if (!_print_flag_config(f, lv->status, LV_FLAGS)) return_0; - if (!dm_list_empty(&lv->tags)) { - if (!(tag_buffer = alloc_printed_tags(&lv->tags))) - return_0; - outf(f, "tags = %s", tag_buffer); - dm_free(tag_buffer); - } + if (!_out_tags(f, &lv->tags)) + return_0; if (lv->alloc != ALLOC_INHERIT) outf(f, "allocation_policy = \"%s\"", From zkabelac@sourceware.org Mon Nov 29 12:42:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 12:42:00 -0000 Subject: LVM2/libdm libdm-deptree.c Message-ID: <20101129124211.26148.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 12:42:11 Modified files: libdm : libdm-deptree.c Log message: Remove dead assignment in _mirror_emit_segment_line Remove unused 'r' assignment. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-deptree.c.diff?cvsroot=lvm2&r1=1.88&r2=1.89 --- LVM2/libdm/libdm-deptree.c 2010/11/29 11:26:00 1.88 +++ LVM2/libdm/libdm-deptree.c 2010/11/29 12:42:10 1.89 @@ -1536,7 +1536,6 @@ uint64_t *seg_start, char *params, size_t paramsize) { - int r; int block_on_error = 0; int handle_errors = 0; int dm_log_userspace = 0; @@ -1643,7 +1642,7 @@ EMIT_PARAMS(pos, " %u ", seg->mirror_area_count); - if ((r = _emit_areas_line(dmt, seg, params, paramsize, &pos)) <= 0) + if (_emit_areas_line(dmt, seg, params, paramsize, &pos) <= 0) return_0; if (handle_errors) From zkabelac@sourceware.org Mon Nov 29 12:43:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 12:43:00 -0000 Subject: LVM2/libdm/regex matcher.c Message-ID: <20101129124350.26591.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 12:43:49 Modified files: libdm/regex : matcher.c Log message: Remove dead assignment in _step_matcher 'ns' is not used after this assignment and it is reassigned with the following code, so dropping this assignment. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/regex/matcher.c.diff?cvsroot=lvm2&r1=1.13&r2=1.14 --- LVM2/libdm/regex/matcher.c 2010/09/30 21:06:52 1.13 +++ LVM2/libdm/regex/matcher.c 2010/11/29 12:43:49 1.14 @@ -372,7 +372,7 @@ { struct dfa_state *ns; - if (!(ns = cs->lookup[(unsigned char) c])) + if (!cs->lookup[(unsigned char) c]) _calc_state(m, cs, (unsigned char) c); if (!(ns = cs->lookup[(unsigned char) c])) From zkabelac@sourceware.org Mon Nov 29 12:44:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 12:44:00 -0000 Subject: LVM2/daemons/clvmd clvmd.c Message-ID: <20101129124453.26860.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 12:44:52 Modified files: daemons/clvmd : clvmd.c Log message: Remove dead assignment in wait_for_child 'pid' is not used anywhere - remove it. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/clvmd/clvmd.c.diff?cvsroot=lvm2&r1=1.83&r2=1.84 --- LVM2/daemons/clvmd/clvmd.c 2010/11/08 19:37:41 1.83 +++ LVM2/daemons/clvmd/clvmd.c 2010/11/29 12:44:52 1.84 @@ -965,7 +965,6 @@ */ static void be_daemon(int timeout) { - pid_t pid; int devnull = open("/dev/null", O_RDWR); if (devnull == -1) { perror("Can't open /dev/null"); @@ -974,7 +973,7 @@ pipe(child_pipe); - switch (pid = fork()) { + switch (fork()) { case -1: perror("clvmd: can't fork"); exit(2); From zkabelac@sourceware.org Mon Nov 29 14:25:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Mon, 29 Nov 2010 14:25:00 -0000 Subject: LVM2/libdm/regex matcher.c Message-ID: <20101129142514.2245.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-29 14:25:14 Modified files: libdm/regex : matcher.c Log message: Optimize lookup table read Reread lookup table only when needed. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/regex/matcher.c.diff?cvsroot=lvm2&r1=1.14&r2=1.15 --- LVM2/libdm/regex/matcher.c 2010/11/29 12:43:49 1.14 +++ LVM2/libdm/regex/matcher.c 2010/11/29 14:25:13 1.15 @@ -372,11 +372,11 @@ { struct dfa_state *ns; - if (!cs->lookup[(unsigned char) c]) - _calc_state(m, cs, (unsigned char) c); - - if (!(ns = cs->lookup[(unsigned char) c])) - return NULL; + if (!(ns = cs->lookup[(unsigned char) c])) { + _calc_state(m, cs, (unsigned char) c); + if (!(ns = cs->lookup[(unsigned char) c])) + return NULL; + } // yuck, we have to special case the target trans if (ns->final == -1) From agk@sourceware.org Mon Nov 29 18:35:00 2010 From: agk@sourceware.org (agk@sourceware.org) Date: Mon, 29 Nov 2010 18:35:00 -0000 Subject: LVM2 ./WHATS_NEW ./WHATS_NEW_DM lib/metadata/m ... Message-ID: <20101129183538.23978.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: agk@sourceware.org 2010-11-29 18:35:37 Modified files: . : WHATS_NEW WHATS_NEW_DM lib/metadata : metadata.c lib/format_text: import_vsn1.c Log message: Fix memory leak when VG allocation policy in metadata is invalid. Ignore unrecognised allocation policy found in metadata instead of aborting. Fix another missing vg_release() in _vg_read_by_vgid. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1813&r2=1.1814 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW_DM.diff?cvsroot=lvm2&r1=1.426&r2=1.427 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.c.diff?cvsroot=lvm2&r1=1.411&r2=1.412 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/import_vsn1.c.diff?cvsroot=lvm2&r1=1.77&r2=1.78 --- LVM2/WHATS_NEW 2010/11/29 12:19:58 1.1813 +++ LVM2/WHATS_NEW 2010/11/29 18:35:37 1.1814 @@ -1,16 +1,22 @@ Version 2.02.78 - ==================================== - Fix memory leak in outf macro error path of _print_vg/lv/pvs/segment(). - Fix missing reset of vg pointer after vg_release() in _vg_read_by_vgid(). - Fix test for empty system_dir string in _init_backup(). - Certain lvconvert invocations are now required to be done in two steps. - Fix missing context desctruction in err path of lvm1 fallback in lvm2_main(). - Fix memory leak in error path of parse_loop_device_name() from dmsetup. - Fix missing dlclose in _init_formats() error path from init_format call. - Fix missing fclose for _umount() in dmeventd snapshot plugin. - Fix out-of-scope variable usage in process_each_lv(). - Fix dm_task_destroy(NULL) call in _node_clear_table() error path. - Fix resource leak in _rm_blks(). + Fix memory leak when VG allocation policy in metadata is invalid. + Ignore unrecognised allocation policy found in metadata instead of aborting. + Factor out tag printing into _out_tags and avoid leaking string buffer. + Remove some unused variables & assignments. + Add missing vg_release calls in _vg_read_by_vgid. +Still to fix: LCK_CACHE/CLUSTER_VG printing/FIXME + Fix test for no system_dir in _init_backup(). + Disallow lvconvert ops that both allocate & free supplied PEs in a single cmd. + Fix liblvm seg_size to give bytes not sectors. + Add functions to look up LV/PV by name/uuid to liblvm. + Free cmd_context if fallback to LVM1 fails in lvm2_main(). + Free device name buffer in dmsetup parse_loop_device_name() error paths. + Close format lib if init_format_fn fails in _init_formats(). + Don't leave /proc/mounts open after dmeventd snapshot event processing. + Fix out-of-scope arg_vgnames use in process_each_lv(). + Remove incorrect dm_task_destroy(NULL) from _node_clear_table() error path. + Add missing closedir in _rm_blks after removing stray LVM1 VG files. Suppress 'No PV label' message when removing several PVs without mdas. Fix default /etc/lvm permissions to be 0755. (2.02.66) --- LVM2/WHATS_NEW_DM 2010/11/22 18:37:56 1.426 +++ LVM2/WHATS_NEW_DM 2010/11/29 18:35:37 1.427 @@ -1,5 +1,6 @@ Version 1.02.59 - ==================================== + Remove superfluous checks for NULL before calling dm_free. Version 1.02.58 - 22nd November 2010 ==================================== --- LVM2/lib/metadata/metadata.c 2010/11/29 11:08:14 1.411 +++ LVM2/lib/metadata/metadata.c 2010/11/29 18:35:37 1.412 @@ -3086,6 +3086,7 @@ vg->name); dm_pool_destroy(vg->vgmem); + vg->vgmem = NULL; } /* This is only called by lv_from_lvid, which is only called from @@ -3098,7 +3099,7 @@ { const char *vgname; struct dm_list *vgnames; - struct volume_group *vg = NULL; + struct volume_group *vg; struct lvmcache_vginfo *vginfo; struct str_list *strl; int consistent = 0; @@ -3109,20 +3110,17 @@ if ((vg = _vg_read(cmd, NULL, vgid, 1, &consistent, precommitted)) && !strncmp((char *)vg->id.uuid, vgid, ID_LEN)) { - - if (!consistent) { + if (!consistent) log_error("Volume group %s metadata is " "inconsistent", vg->name); - } return vg; } vg_release(vg); - vg = NULL; /* reset so memlock goto out is safe */ } /* Mustn't scan if memory locked: ensure cache gets pre-populated! */ if (memlock()) - goto out; + return_NULL; /* FIXME Need a genuine read by ID here - don't vg_read_internal by name! */ /* FIXME Disabled vgrenames while active for now because we aren't @@ -3132,7 +3130,7 @@ lvmcache_label_scan(cmd, 2); if (!(vgnames = get_vgnames(cmd, 0))) { log_error("vg_read_by_vgid: get_vgnames failed"); - goto out; + return NULL; } dm_list_iterate_items(strl, vgnames) { @@ -3143,18 +3141,17 @@ if ((vg = _vg_read(cmd, vgname, vgid, 1, &consistent, precommitted)) && !strncmp((char *)vg->id.uuid, vgid, ID_LEN)) { - if (!consistent) { log_error("Volume group %s metadata is " "inconsistent", vgname); - goto out; + vg_release(vg); + return NULL; } return vg; } + vg_release(vg); } -out: - vg_release(vg); return NULL; } --- LVM2/lib/format_text/import_vsn1.c 2010/07/09 15:34:44 1.77 +++ LVM2/lib/format_text/import_vsn1.c 2010/11/29 18:35:37 1.78 @@ -529,8 +529,10 @@ } lv->alloc = get_alloc_from_string(cv->v.str); - if (lv->alloc == ALLOC_INVALID) - return_0; + if (lv->alloc == ALLOC_INVALID) { + log_warn("WARNING: Ignoring unrecognised allocation policy %s for LV %s", cv->v.str, lv->name); + lv->alloc = ALLOC_INHERIT; + } } if (!_read_int32(lvn, "read_ahead", &lv->read_ahead)) @@ -660,7 +662,8 @@ return_NULL; /* skip any top-level values */ - for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib) ; + for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib) + ; if (!vgn) { log_error("Couldn't find volume group in file."); @@ -738,12 +741,14 @@ struct config_value *cv = cn->v; if (!cv || !cv->v.str) { log_error("allocation_policy must be a string."); - return 0; + goto bad; } vg->alloc = get_alloc_from_string(cv->v.str); - if (vg->alloc == ALLOC_INVALID) - return_0; + if (vg->alloc == ALLOC_INVALID) { + log_warn("WARNING: Ignoring unrecognised allocation policy %s for VG %s", cv->v.str, vg->name); + vg->alloc = ALLOC_NORMAL; + } } if (!_read_uint32(vgn, "metadata_copies", &vg->mda_copies)) { From mornfall@sourceware.org Tue Nov 30 11:15:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Tue, 30 Nov 2010 11:15:00 -0000 Subject: LVM2/lib/metadata metadata.c Message-ID: <20101130111556.24421.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-30 11:15:55 Modified files: lib/metadata : metadata.c Log message: Avoid the automatic MISSING_PV recovery path in commands with special MISSING_PV handling (cmd->handles_missing_pvs is set). Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.c.diff?cvsroot=lvm2&r1=1.412&r2=1.413 --- LVM2/lib/metadata/metadata.c 2010/11/29 18:35:37 1.412 +++ LVM2/lib/metadata/metadata.c 2010/11/30 11:15:54 1.413 @@ -2614,6 +2614,14 @@ { struct pv_list *pvl; + /* + * Skip these checks in case the tool is going to deal with missing + * PVs, especially since the resulting messages can be pretty + * confusing. + */ + if (correct_vg->cmd->handles_missing_pvs) + return; + dm_list_iterate_items(pvl, &correct_vg->pvs) if (pv->dev == pvl->pv->dev && is_missing_pv(pvl->pv)) { log_warn("Missing device %s reappeared, updating " From mornfall@sourceware.org Tue Nov 30 11:35:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Tue, 30 Nov 2010 11:35:00 -0000 Subject: LVM2/test t-lvconvert-mirror.sh Message-ID: <20101130113532.21653.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-30 11:35:32 Modified files: test : t-lvconvert-mirror.sh Log message: Fix a failing test (it used a combination of lvconvert parameters that is no longer permitted.) Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/t-lvconvert-mirror.sh.diff?cvsroot=lvm2&r1=1.7&r2=1.8 --- LVM2/test/t-lvconvert-mirror.sh 2010/08/17 22:01:41 1.7 +++ LVM2/test/t-lvconvert-mirror.sh 2010/11/30 11:35:32 1.8 @@ -223,8 +223,9 @@ aux prepare_vg 5 lvcreate -l1 -m2 --corelog -n $lv1 $vg $dev1 $dev2 $dev3 while [ `lvs --noheadings -o copy_percent $vg/$lv1` != "100.00" ]; do sleep 1; done -lvconvert -m1 --mirrorlog disk $vg/$lv1 $dev1 -check mirror $vg $lv1 $dev1 +lvconvert -m1 --mirrorlog disk $vg/$lv1 +check mirror $vg $lv1 +not check mirror $vg $lv1 core # --- # add mirror and disk log From mornfall@sourceware.org Tue Nov 30 11:53:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Tue, 30 Nov 2010 11:53:00 -0000 Subject: LVM2 include/.symlinks.in lib/Makefile.in lib/ ... Message-ID: <20101130115336.28589.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-30 11:53:33 Modified files: include : .symlinks.in lib : Makefile.in lib/activate : activate.c activate.h dev_manager.c dev_manager.h lib/display : display.c lib/metadata : lv.c metadata-exported.h mirror.c segtype.h lib/mirror : mirrored.c lib/replicator : replicator.c lib/report : report.c lib/snapshot : snapshot.c tools : lvconvert.c lvcreate.c lvmcmdline.c lvresize.c lvscan.c polldaemon.c tools.h Added files: lib/misc : lvm-percent.c lvm-percent.h Log message: Refactor the percent (mirror sync, snapshot usage) handling code to use fixed-point values instead of a combination of a float value and an enum. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/include/.symlinks.in.diff?cvsroot=lvm2&r1=1.6&r2=1.7 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/Makefile.in.diff?cvsroot=lvm2&r1=1.108&r2=1.109 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/activate.c.diff?cvsroot=lvm2&r1=1.180&r2=1.181 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/activate.h.diff?cvsroot=lvm2&r1=1.71&r2=1.72 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/dev_manager.c.diff?cvsroot=lvm2&r1=1.205&r2=1.206 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/dev_manager.h.diff?cvsroot=lvm2&r1=1.34&r2=1.35 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/display/display.c.diff?cvsroot=lvm2&r1=1.114&r2=1.115 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv.c.diff?cvsroot=lvm2&r1=1.19&r2=1.20 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata-exported.h.diff?cvsroot=lvm2&r1=1.171&r2=1.172 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/mirror.c.diff?cvsroot=lvm2&r1=1.137&r2=1.138 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/segtype.h.diff?cvsroot=lvm2&r1=1.31&r2=1.32 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/mirror/mirrored.c.diff?cvsroot=lvm2&r1=1.78&r2=1.79 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-percent.c.diff?cvsroot=lvm2&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-percent.h.diff?cvsroot=lvm2&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/replicator/replicator.c.diff?cvsroot=lvm2&r1=1.2&r2=1.3 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/report.c.diff?cvsroot=lvm2&r1=1.140&r2=1.141 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/snapshot/snapshot.c.diff?cvsroot=lvm2&r1=1.50&r2=1.51 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvconvert.c.diff?cvsroot=lvm2&r1=1.150&r2=1.151 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvcreate.c.diff?cvsroot=lvm2&r1=1.225&r2=1.226 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvmcmdline.c.diff?cvsroot=lvm2&r1=1.133&r2=1.134 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvresize.c.diff?cvsroot=lvm2&r1=1.125&r2=1.126 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvscan.c.diff?cvsroot=lvm2&r1=1.42&r2=1.43 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/polldaemon.c.diff?cvsroot=lvm2&r1=1.37&r2=1.38 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/tools.h.diff?cvsroot=lvm2&r1=1.73&r2=1.74 --- LVM2/include/.symlinks.in 2010/09/30 13:05:45 1.6 +++ LVM2/include/.symlinks.in 2010/11/30 11:53:31 1.7 @@ -52,6 +52,7 @@ @top_srcdir@/lib/misc/lvm-string.h @top_builddir@/lib/misc/lvm-version.h @top_srcdir@/lib/misc/lvm-wrappers.h +@top_srcdir@/lib/misc/lvm-percent.h @top_srcdir@/lib/misc/sharedlib.h @top_srcdir@/lib/report/properties.h @top_srcdir@/lib/report/report.h --- LVM2/lib/Makefile.in 2010/09/30 13:05:45 1.108 +++ LVM2/lib/Makefile.in 2010/11/30 11:53:31 1.109 @@ -91,6 +91,7 @@ misc/lvm-globals.c \ misc/lvm-string.c \ misc/lvm-wrappers.c \ + misc/lvm-percent.c \ misc/util.c \ mm/memlock.c \ report/properties.c \ --- LVM2/lib/activate/activate.c 2010/11/09 12:34:41 1.180 +++ LVM2/lib/activate/activate.c 2010/11/30 11:53:31 1.181 @@ -158,14 +158,12 @@ { return 0; } -int lv_snapshot_percent(const struct logical_volume *lv, float *percent, - percent_range_t *percent_range) +int lv_snapshot_percent(const struct logical_volume *lv, percent_t *percent) { return 0; } int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv, - int wait, float *percent, percent_range_t *percent_range, - uint32_t *event_nr) + int wait, percent_t *percent, uint32_t *event_nr) { return 0; } @@ -523,8 +521,7 @@ /* * Returns 1 if percent set, else 0 on failure. */ -int lv_snapshot_percent(const struct logical_volume *lv, float *percent, - percent_range_t *percent_range) +int lv_snapshot_percent(const struct logical_volume *lv, percent_t *percent) { int r; struct dev_manager *dm; @@ -535,7 +532,7 @@ if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) return_0; - if (!(r = dev_manager_snapshot_percent(dm, lv, percent, percent_range))) + if (!(r = dev_manager_snapshot_percent(dm, lv, percent))) stack; dev_manager_destroy(dm); @@ -545,8 +542,7 @@ /* FIXME Merge with snapshot_percent */ int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv, - int wait, float *percent, percent_range_t *percent_range, - uint32_t *event_nr) + int wait, percent_t *percent, uint32_t *event_nr) { int r; struct dev_manager *dm; @@ -555,7 +551,7 @@ /* If mirrored LV is temporarily shrinked to 1 area (= linear), * it should be considered in-sync. */ if (dm_list_size(&lv->segments) == 1 && first_seg(lv)->area_count == 1) { - *percent = 100.0; + *percent = PERCENT_100; return 1; } @@ -571,8 +567,7 @@ if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) return_0; - if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, - percent_range, event_nr))) + if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, event_nr))) stack; dev_manager_destroy(dm); --- LVM2/lib/activate/activate.h 2010/08/17 16:25:32 1.71 +++ LVM2/lib/activate/activate.h 2010/11/30 11:53:31 1.72 @@ -83,11 +83,9 @@ /* * Returns 1 if percent has been set, else 0. */ -int lv_snapshot_percent(const struct logical_volume *lv, float *percent, - percent_range_t *percent_range); +int lv_snapshot_percent(const struct logical_volume *lv, percent_t *percent); int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv, - int wait, float *percent, percent_range_t *percent_range, - uint32_t *event_nr); + int wait, percent_t *percent, uint32_t *event_nr); /* * Return number of LVs in the VG that are active. --- LVM2/lib/activate/dev_manager.c 2010/10/25 10:37:35 1.205 +++ LVM2/lib/activate/dev_manager.c 2010/11/30 11:53:31 1.206 @@ -428,8 +428,8 @@ return r; } -static percent_range_t _combine_percent_ranges(percent_range_t a, - percent_range_t b) +static percent_range_t _combine_percent(percent_t a, percent_t b, + uint32_t numerator, uint32_t denominator) { if (a == PERCENT_INVALID || b == PERCENT_INVALID) return PERCENT_INVALID; @@ -440,14 +440,13 @@ if (a == PERCENT_0 && b == PERCENT_0) return PERCENT_0; - return PERCENT_0_TO_100; + return make_percent(numerator, denominator); } static int _percent_run(struct dev_manager *dm, const char *name, const char *dlid, const char *target_type, int wait, - const struct logical_volume *lv, float *percent, - percent_range_t *overall_percent_range, + const struct logical_volume *lv, percent_t *overall_percent, uint32_t *event_nr, int fail_if_percent_unsupported) { int r = 0; @@ -460,13 +459,12 @@ const struct dm_list *segh = &lv->segments; struct lv_segment *seg = NULL; struct segment_type *segtype; - percent_range_t percent_range = 0, combined_percent_range = 0; int first_time = 1; + percent_t percent; uint64_t total_numerator = 0, total_denominator = 0; - *percent = -1; - *overall_percent_range = PERCENT_INVALID; + *overall_percent = PERCENT_INVALID; if (!(dmt = _setup_task(name, dlid, event_nr, wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS, 0, 0))) @@ -511,19 +509,19 @@ if (segtype->ops->target_percent && !segtype->ops->target_percent(&dm->target_state, - &percent_range, dm->mem, + &percent, dm->mem, dm->cmd, seg, params, &total_numerator, &total_denominator)) goto_out; if (first_time) { - combined_percent_range = percent_range; + *overall_percent = percent; first_time = 0; } else - combined_percent_range = - _combine_percent_ranges(combined_percent_range, - percent_range); + *overall_percent = + _combine_percent(*overall_percent, percent, + total_numerator, total_denominator); } while (next); if (lv && (segh = dm_list_next(&lv->segments, segh))) { @@ -532,22 +530,15 @@ goto out; } - if (total_denominator) { - *percent = (float) total_numerator *100 / total_denominator; - *overall_percent_range = combined_percent_range; - } else { - *percent = 100; - if (first_time) { - /* above ->target_percent() was not executed! */ - /* FIXME why return PERCENT_100 et. al. in this case? */ - *overall_percent_range = PERCENT_100; - if (fail_if_percent_unsupported) - goto_out; - } else - *overall_percent_range = combined_percent_range; + if (first_time) { + /* above ->target_percent() was not executed! */ + /* FIXME why return PERCENT_100 et. al. in this case? */ + *overall_percent = PERCENT_100; + if (fail_if_percent_unsupported) + goto_out; } - log_debug("LV percent: %f", *percent); + log_debug("LV percent: %f", percent_to_float(*overall_percent)); r = 1; out: @@ -557,25 +548,21 @@ static int _percent(struct dev_manager *dm, const char *name, const char *dlid, const char *target_type, int wait, - const struct logical_volume *lv, float *percent, - percent_range_t *overall_percent_range, uint32_t *event_nr, - int fail_if_percent_unsupported) + const struct logical_volume *lv, percent_t *percent, + uint32_t *event_nr, int fail_if_percent_unsupported) { if (dlid && *dlid) { if (_percent_run(dm, NULL, dlid, target_type, wait, lv, percent, - overall_percent_range, event_nr, - fail_if_percent_unsupported)) + event_nr, fail_if_percent_unsupported)) return 1; else if (_percent_run(dm, NULL, dlid + sizeof(UUID_PREFIX) - 1, target_type, wait, lv, percent, - overall_percent_range, event_nr, - fail_if_percent_unsupported)) + event_nr, fail_if_percent_unsupported)) return 1; } if (name && _percent_run(dm, name, NULL, target_type, wait, lv, percent, - overall_percent_range, event_nr, - fail_if_percent_unsupported)) + event_nr, fail_if_percent_unsupported)) return 1; return 0; @@ -694,7 +681,7 @@ int dev_manager_snapshot_percent(struct dev_manager *dm, const struct logical_volume *lv, - float *percent, percent_range_t *percent_range) + percent_t *percent) { char *name; const char *dlid; @@ -729,7 +716,7 @@ */ log_debug("Getting device status percentage for %s", name); if (!(_percent(dm, name, dlid, "snapshot", 0, NULL, percent, - percent_range, NULL, fail_if_percent_unsupported))) + NULL, fail_if_percent_unsupported))) return_0; /* FIXME dm_pool_free ? */ @@ -742,8 +729,7 @@ /* FIXME Cope with more than one target */ int dev_manager_mirror_percent(struct dev_manager *dm, const struct logical_volume *lv, int wait, - float *percent, percent_range_t *percent_range, - uint32_t *event_nr) + percent_t *percent, uint32_t *event_nr) { char *name; const char *dlid; @@ -764,7 +750,7 @@ log_debug("Getting device mirror status percentage for %s", name); if (!(_percent(dm, name, dlid, "mirror", wait, lv, percent, - percent_range, event_nr, 0))) + event_nr, 0))) return_0; return 1; --- LVM2/lib/activate/dev_manager.h 2010/08/17 16:25:33 1.34 +++ LVM2/lib/activate/dev_manager.h 2010/11/30 11:53:31 1.35 @@ -46,12 +46,10 @@ struct dm_info *info, uint32_t *read_ahead); int dev_manager_snapshot_percent(struct dev_manager *dm, const struct logical_volume *lv, - float *percent, - percent_range_t *percent_range); + percent_t *percent); int dev_manager_mirror_percent(struct dev_manager *dm, const struct logical_volume *lv, int wait, - float *percent, percent_range_t *percent_range, - uint32_t *event_nr); + percent_t *percent, uint32_t *event_nr); int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv, unsigned origin_only, int lockfs, int flush_required); int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv, unsigned origin_only); --- LVM2/lib/display/display.c 2010/11/09 12:34:42 1.114 +++ LVM2/lib/display/display.c 2010/11/30 11:53:31 1.115 @@ -492,8 +492,7 @@ int inkernel, snap_active = 0; char uuid[64] __attribute__((aligned(8))); struct lv_segment *snap_seg = NULL, *mirror_seg = NULL; - float snap_percent; /* fused, fsize; */ - percent_range_t percent_range; + percent_t snap_percent; if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid))) return_0; @@ -518,9 +517,8 @@ origin_list) { if (inkernel && (snap_active = lv_snapshot_percent(snap_seg->cow, - &snap_percent, - &percent_range))) - if (percent_range == PERCENT_INVALID) + &snap_percent))) + if (snap_percent == PERCENT_INVALID) snap_active = 0; log_print(" %s%s/%s [%s]", lv->vg->cmd->dev_dir, lv->vg->name, @@ -531,9 +529,8 @@ } else if ((snap_seg = find_cow(lv))) { if (inkernel && (snap_active = lv_snapshot_percent(snap_seg->cow, - &snap_percent, - &percent_range))) - if (percent_range == PERCENT_INVALID) + &snap_percent))) + if (snap_percent == PERCENT_INVALID) snap_active = 0; log_print("LV snapshot status %s destination for %s%s/%s", @@ -568,7 +565,8 @@ log_print("COW-table LE %u", lv->le_count); if (snap_active) - log_print("Allocated to snapshot %.2f%% ", snap_percent); + log_print("Allocated to snapshot %.2f%% ", + percent_to_float(snap_percent)); log_print("Snapshot chunk size %s", display_size(cmd, (uint64_t) snap_seg->chunk_size)); --- LVM2/lib/metadata/lv.c 2010/11/17 20:08:14 1.19 +++ LVM2/lib/metadata/lv.c 2010/11/30 11:53:32 1.20 @@ -193,24 +193,22 @@ static int _lv_mimage_in_sync(const struct logical_volume *lv) { - float percent; - percent_range_t percent_range; + percent_t percent; struct lv_segment *mirror_seg = find_mirror_seg(first_seg(lv)); if (!(lv->status & MIRROR_IMAGE) || !mirror_seg) return_0; if (!lv_mirror_percent(lv->vg->cmd, mirror_seg->lv, 0, &percent, - &percent_range, NULL)) + NULL)) return_0; - return (percent_range == PERCENT_100) ? 1 : 0; + return (percent == PERCENT_100) ? 1 : 0; } char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv) { - float snap_percent; - percent_range_t percent_range; + percent_t snap_percent; struct lvinfo info; char *repstr; @@ -272,8 +270,8 @@ /* Snapshot dropped? */ if (info.live_table && lv_is_cow(lv) && - (!lv_snapshot_percent(lv, &snap_percent, &percent_range) || - percent_range == PERCENT_INVALID)) { + (!lv_snapshot_percent(lv, &snap_percent) || + snap_percent == PERCENT_INVALID)) { repstr[0] = toupper(repstr[0]); if (info.suspended) repstr[4] = 'S'; /* Susp Inv snapshot */ --- LVM2/lib/metadata/metadata-exported.h 2010/11/23 01:55:59 1.171 +++ LVM2/lib/metadata/metadata-exported.h 2010/11/30 11:53:32 1.172 @@ -25,6 +25,7 @@ #include "pv.h" #include "vg.h" #include "lv.h" +#include "lvm-percent.h" #define MAX_STRIPES 128U #define SECTOR_SHIFT 9L @@ -139,13 +140,6 @@ DONT_PROMPT_OVERRIDE = 2 /* Skip prompt + override a second condition */ } force_t; -typedef enum { - PERCENT_0 = 0, - PERCENT_0_TO_100 = 1, - PERCENT_100 = 2, - PERCENT_INVALID = 3 -} percent_range_t; - struct cmd_context; struct format_handler; struct labeller; @@ -704,8 +698,7 @@ uint32_t lv_type); const char *get_pvmove_pvname_from_lv(struct logical_volume *lv); const char *get_pvmove_pvname_from_lv_mirr(struct logical_volume *lv_mirr); -float copy_percent(struct logical_volume *lv_mirr, - percent_range_t *percent_range); +percent_t copy_percent(struct logical_volume *lv_mirr); struct dm_list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg, struct logical_volume *lv); --- LVM2/lib/metadata/mirror.c 2010/11/09 12:34:43 1.137 +++ LVM2/lib/metadata/mirror.c 2010/11/30 11:53:32 1.138 @@ -547,17 +547,16 @@ static int _mirrored_lv_in_sync(struct logical_volume *lv) { - float sync_percent; - percent_range_t percent_range; + percent_t sync_percent; if (!lv_mirror_percent(lv->vg->cmd, lv, 0, &sync_percent, - &percent_range, NULL)) { + NULL)) { log_error("Unable to determine mirror sync status of %s/%s.", lv->vg->name, lv->name); return 0; } - return (percent_range == PERCENT_100) ? 1 : 0; + return (sync_percent == PERCENT_100) ? 1 : 0; } /* @@ -1508,8 +1507,7 @@ return lvs; } -float copy_percent(struct logical_volume *lv_mirr, - percent_range_t *percent_range) +percent_t copy_percent(struct logical_volume *lv_mirr) { uint32_t numerator = 0u, denominator = 0u; struct lv_segment *seg; @@ -1523,14 +1521,7 @@ numerator += seg->area_len; } - if (!denominator || (numerator == denominator)) - *percent_range = PERCENT_100; - else if (numerator == 0) - *percent_range = PERCENT_0; - else - *percent_range = PERCENT_0_TO_100; - - return denominator ? (float) numerator *100 / denominator : 100.0; + return denominator ? make_percent( numerator, denominator ) : 100.0; } /* @@ -1604,8 +1595,7 @@ struct dm_list *removable_pvs, int force) { - float sync_percent; - percent_range_t percent_range = PERCENT_0; + percent_t sync_percent; struct lvinfo info; struct volume_group *vg = lv->vg; @@ -1618,7 +1608,7 @@ /* Had disk log, switch to core. */ if (lv_info(cmd, lv, 0, &info, 0, 0) && info.exists) { if (!lv_mirror_percent(cmd, lv, 0, &sync_percent, - &percent_range, NULL)) { + NULL)) { log_error("Unable to determine mirror sync status."); return 0; } @@ -1633,7 +1623,7 @@ else return 0; - if (percent_range == PERCENT_100) + if (sync_percent == PERCENT_100) init_mirror_in_sync(1); else { /* A full resync will take place */ @@ -1798,8 +1788,7 @@ struct alloc_handle *ah; const struct segment_type *segtype; struct dm_list *parallel_areas; - float sync_percent; - percent_range_t percent_range; + percent_t sync_percent; int in_sync; struct logical_volume *log_lv; struct lvinfo info; @@ -1845,9 +1834,8 @@ } /* check sync status */ - if (lv_mirror_percent(cmd, lv, 0, &sync_percent, &percent_range, - NULL) && - (percent_range == PERCENT_100)) + if (lv_mirror_percent(cmd, lv, 0, &sync_percent, NULL) && + (sync_percent == PERCENT_100)) in_sync = 1; else in_sync = 0; --- LVM2/lib/metadata/segtype.h 2010/10/13 21:26:37 1.31 +++ LVM2/lib/metadata/segtype.h 2010/11/30 11:53:32 1.32 @@ -85,7 +85,7 @@ int (*target_status_compatible) (const char *type); int (*check_transient_status) (struct lv_segment *seg, char *params); int (*target_percent) (void **target_state, - percent_range_t *percent_range, + percent_t *percent, struct dm_pool * mem, struct cmd_context *cmd, struct lv_segment *seg, char *params, --- LVM2/lib/mirror/mirrored.c 2010/08/17 16:25:35 1.78 +++ LVM2/lib/mirror/mirrored.c 2010/11/30 11:53:32 1.79 @@ -177,7 +177,7 @@ } static int _mirrored_target_percent(void **target_state, - percent_range_t *percent_range, + percent_t *percent, struct dm_pool *mem, struct cmd_context *cmd, struct lv_segment *seg, char *params, @@ -227,12 +227,7 @@ if (seg) seg->extents_copied = seg->area_len * numerator / denominator; - if (numerator == denominator) - *percent_range = PERCENT_100; - else if (numerator == 0) - *percent_range = PERCENT_0; - else - *percent_range = PERCENT_0_TO_100; + *percent = make_percent(numerator, denominator); return 1; } /cvs/lvm2/LVM2/lib/misc/lvm-percent.c,v --> standard output revision 1.1 --- LVM2/lib/misc/lvm-percent.c +++ - 2010-11-30 11:53:35.265706000 +0000 @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 Red Hat, Inc. All rights reserved. + * + * This file is part of LVM2. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License v.2.1. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "lvm-percent.h" + +float percent_to_float(percent_t v) +{ + return (float)v / PERCENT_1; +} + +percent_t make_percent(uint64_t numerator, uint64_t denominator) +{ + percent_t percent; + if (!denominator) + return PERCENT_100; /* FIXME? */ + if (!numerator) + return PERCENT_0; + if (numerator == denominator) + return PERCENT_100; + switch (percent = PERCENT_100 * ((double) numerator / (double) denominator)) { + case PERCENT_100: + return PERCENT_100 - 1; + case PERCENT_0: + return PERCENT_0 + 1; + default: + return percent; + } +} + /cvs/lvm2/LVM2/lib/misc/lvm-percent.h,v --> standard output revision 1.1 --- LVM2/lib/misc/lvm-percent.h +++ - 2010-11-30 11:53:35.390476000 +0000 @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010 Red Hat, Inc. All rights reserved. + * + * This file is part of LVM2. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License v.2.1. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _LVM_PERCENT_H +#define _LVM_PERCENT_H +#include + +/* + * A fixed-point representation of percent values. One percent equals to + * PERCENT_1 as defined below. Values that are not multiples of PERCENT_1 + * represent fractions, with precision of 1/1000000 of a percent. See + * percent_to_float for a conversion to a floating-point representation. + * + * You should always use make_percent when building percent_t values. The + * implementation of make_percent is biased towards the middle: it ensures that + * the result is PERCENT_0 or PERCENT_100 if and only if this is the actual + * value -- it never rounds any intermediate value (> 0 or < 100) to either 0 + * or 100. + */ +typedef int32_t percent_t; + +typedef enum { + PERCENT_0 = 0, + PERCENT_1 = 1000000, + PERCENT_100 = 100 * PERCENT_1, + PERCENT_INVALID = -1 +} percent_range_t; + +float percent_to_float(percent_t v); +percent_t make_percent(uint64_t numerator, uint64_t denominator); + +#endif --- LVM2/lib/replicator/replicator.c 2010/07/09 15:34:45 1.2 +++ LVM2/lib/replicator/replicator.c 2010/11/30 11:53:32 1.3 @@ -365,7 +365,7 @@ /* FIXME: write something useful for replicator here */ static int _replicator_target_percent(void **target_state, - percent_range_t *percent_range, + percent_t *percent, struct dm_pool *mem, struct cmd_context *cmd, struct lv_segment *seg, @@ -708,7 +708,7 @@ /* FIXME: write something useful for replicator-dev here */ static int _replicator_dev_target_percent(void **target_state, - percent_range_t *percent_range, + percent_t *percent, struct dm_pool *mem, struct cmd_context *cmd, struct lv_segment *seg, --- LVM2/lib/report/report.c 2010/11/17 20:08:14 1.140 +++ LVM2/lib/report/report.c 2010/11/30 11:53:32 1.141 @@ -795,8 +795,7 @@ { const struct logical_volume *lv = (const struct logical_volume *) data; struct lvinfo info; - float snap_percent; - percent_range_t percent_range; + percent_t snap_percent; uint64_t *sortval; char *repstr; @@ -818,8 +817,8 @@ return 1; } - if (!lv_snapshot_percent(lv, &snap_percent, &percent_range) || - (percent_range == PERCENT_INVALID)) { + if (!lv_snapshot_percent(lv, &snap_percent) || + (snap_percent == PERCENT_INVALID)) { if (!lv_is_merging_origin(lv)) { *sortval = UINT64_C(100); dm_report_field_set_value(field, "100.00", sortval); @@ -838,7 +837,7 @@ return 0; } - if (dm_snprintf(repstr, 7, "%.2f", snap_percent) < 0) { + if (dm_snprintf(repstr, 7, "%.2f", percent_to_float(snap_percent)) < 0) { log_error("snapshot percentage too large"); return 0; } @@ -855,8 +854,7 @@ const void *data, void *private __attribute__((unused))) { struct logical_volume *lv = (struct logical_volume *) data; - float percent; - percent_range_t percent_range; + percent_t percent; uint64_t *sortval; char *repstr; @@ -866,21 +864,21 @@ } if ((!(lv->status & PVMOVE) && !(lv->status & MIRRORED)) || - !lv_mirror_percent(lv->vg->cmd, lv, 0, &percent, &percent_range, - NULL) || (percent_range == PERCENT_INVALID)) { + !lv_mirror_percent(lv->vg->cmd, lv, 0, &percent, + NULL) || (percent == PERCENT_INVALID)) { *sortval = UINT64_C(0); dm_report_field_set_value(field, "", sortval); return 1; } - percent = copy_percent(lv, &percent_range); + percent = copy_percent(lv); if (!(repstr = dm_pool_zalloc(mem, 8))) { log_error("dm_pool_alloc failed"); return 0; } - if (dm_snprintf(repstr, 7, "%.2f", percent) < 0) { + if (dm_snprintf(repstr, 7, "%.2f", percent_to_float(percent)) < 0) { log_error("copy percentage too large"); return 0; } --- LVM2/lib/snapshot/snapshot.c 2010/10/13 21:26:37 1.50 +++ LVM2/lib/snapshot/snapshot.c 2010/11/30 11:53:32 1.51 @@ -109,7 +109,7 @@ #ifdef DEVMAPPER_SUPPORT static int _snap_target_percent(void **target_state __attribute__((unused)), - percent_range_t *percent_range, + percent_t *percent, struct dm_pool *mem __attribute__((unused)), struct cmd_context *cmd __attribute__((unused)), struct lv_segment *seg __attribute__((unused)), @@ -130,14 +130,14 @@ *total_numerator += sectors_allocated; *total_denominator += total_sectors; if (r == 3 && sectors_allocated == metadata_sectors) - *percent_range = PERCENT_0; + *percent = PERCENT_0; else if (sectors_allocated == total_sectors) - *percent_range = PERCENT_100; + *percent = PERCENT_100; else - *percent_range = PERCENT_0_TO_100; + *percent = make_percent(*total_numerator, *total_denominator); } else if (!strcmp(params, "Invalid") || !strcmp(params, "Merge failed")) - *percent_range = PERCENT_INVALID; + *percent = PERCENT_INVALID; else return 0; --- LVM2/tools/lvconvert.c 2010/11/28 18:37:33 1.150 +++ LVM2/tools/lvconvert.c 2010/11/30 11:53:33 1.151 @@ -425,23 +425,24 @@ const char *name __attribute__((unused)), struct daemon_parms *parms) { - float percent = 0.0; - percent_range_t percent_range; + percent_t percent = PERCENT_0; - if (!lv_snapshot_percent(lv, &percent, &percent_range)) { + if (!lv_snapshot_percent(lv, &percent)) { log_error("%s: Failed query for merging percentage. Aborting merge.", lv->name); return PROGRESS_CHECK_FAILED; - } else if (percent_range == PERCENT_INVALID) { + } else if (percent == PERCENT_INVALID) { log_error("%s: Merging snapshot invalidated. Aborting merge.", lv->name); return PROGRESS_CHECK_FAILED; } if (parms->progress_display) - log_print("%s: %s: %.1f%%", lv->name, parms->progress_title, percent); + log_print("%s: %s: %.1f%%", lv->name, parms->progress_title, + percent_to_float(percent)); else - log_verbose("%s: %s: %.1f%%", lv->name, parms->progress_title, percent); + log_verbose("%s: %s: %.1f%%", lv->name, parms->progress_title, + percent_to_float(percent)); - if (percent_range == PERCENT_0) + if (percent == PERCENT_0) return PROGRESS_FINISHED_ALL; return PROGRESS_UNFINISHED; --- LVM2/tools/lvcreate.c 2010/11/11 17:29:06 1.225 +++ LVM2/tools/lvcreate.c 2010/11/30 11:53:33 1.226 @@ -19,7 +19,7 @@ #include struct lvcreate_cmdline_params { - percent_t percent; + percent_type_t percent; uint64_t size; char **pvs; int pv_count; --- LVM2/tools/lvmcmdline.c 2010/11/29 11:14:33 1.133 +++ LVM2/tools/lvmcmdline.c 2010/11/30 11:53:33 1.134 @@ -126,7 +126,7 @@ return arg_count(cmd, a) ? cmd->arg_values[a].sign : def; } -percent_t arg_percent_value(struct cmd_context *cmd, int a, const percent_t def) +percent_type_t arg_percent_value(struct cmd_context *cmd, int a, const percent_type_t def) { return arg_count(cmd, a) ? cmd->arg_values[a].percent : def; } --- LVM2/tools/lvresize.c 2010/11/01 14:17:36 1.125 +++ LVM2/tools/lvresize.c 2010/11/30 11:53:33 1.126 @@ -31,7 +31,7 @@ uint32_t extents; uint64_t size; sign_t sign; - percent_t percent; + percent_type_t percent; enum { LV_ANY = 0, @@ -282,24 +282,23 @@ static int _adjust_policy_params(struct cmd_context *cmd, struct logical_volume *lv, struct lvresize_params *lp) { - float percent; - percent_range_t range; + percent_t percent; int policy_threshold, policy_amount; policy_threshold = find_config_tree_int(cmd, "activation/snapshot_autoextend_threshold", - DEFAULT_SNAPSHOT_AUTOEXTEND_THRESHOLD); + DEFAULT_SNAPSHOT_AUTOEXTEND_THRESHOLD) * PERCENT_1; policy_amount = find_config_tree_int(cmd, "activation/snapshot_autoextend_percent", DEFAULT_SNAPSHOT_AUTOEXTEND_PERCENT); - if (policy_threshold >= 100) + if (policy_threshold >= PERCENT_100) return 1; /* nothing to do */ - if (!lv_snapshot_percent(lv, &percent, &range)) + if (!lv_snapshot_percent(lv, &percent)) return_0; - if (range != PERCENT_0_TO_100 || percent <= policy_threshold) + if (!(PERCENT_0 < percent && percent < PERCENT_100) || percent <= policy_threshold) return 1; /* nothing to do */ lp->extents = policy_amount; --- LVM2/tools/lvscan.c 2010/08/17 16:25:35 1.42 +++ LVM2/tools/lvscan.c 2010/11/30 11:53:33 1.43 @@ -23,8 +23,7 @@ uint64_t lv_capacity_total = 0; int inkernel, snap_active = 1; struct lv_segment *snap_seg = NULL; - float snap_percent; /* fused, fsize; */ - percent_range_t percent_range; + percent_t snap_percent; /* fused, fsize; */ const char *active_str, *snapshot_str; @@ -37,17 +36,15 @@ origin_list) { if (inkernel && (snap_active = lv_snapshot_percent(snap_seg->cow, - &snap_percent, - &percent_range))) - if (percent_range == PERCENT_INVALID) + &snap_percent))) + if (snap_percent == PERCENT_INVALID) snap_active = 0; } snap_seg = NULL; } else if (lv_is_cow(lv)) { if (inkernel && - (snap_active = lv_snapshot_percent(lv, &snap_percent, - &percent_range))) - if (percent_range == PERCENT_INVALID) + (snap_active = lv_snapshot_percent(lv, &snap_percent))) + if (snap_percent == PERCENT_INVALID) snap_active = 0; } --- LVM2/tools/polldaemon.c 2010/08/26 16:29:12 1.37 +++ LVM2/tools/polldaemon.c 2010/11/30 11:53:33 1.38 @@ -74,30 +74,29 @@ struct logical_volume *lv, const char *name, struct daemon_parms *parms) { - float segment_percent = 0.0, overall_percent = 0.0; - percent_range_t percent_range, overall_percent_range; + percent_t segment_percent = PERCENT_0, overall_percent = PERCENT_0; uint32_t event_nr = 0; if (!lv_is_mirrored(lv) || !lv_mirror_percent(cmd, lv, !parms->interval, &segment_percent, - &percent_range, &event_nr) || - (percent_range == PERCENT_INVALID)) { + &event_nr) || + (segment_percent == PERCENT_INVALID)) { log_error("ABORTING: Mirror percentage check failed."); return PROGRESS_CHECK_FAILED; } - overall_percent = copy_percent(lv, &overall_percent_range); + overall_percent = copy_percent(lv); if (parms->progress_display) log_print("%s: %s: %.1f%%", name, parms->progress_title, - overall_percent); + percent_to_float(overall_percent)); else log_verbose("%s: %s: %.1f%%", name, parms->progress_title, - overall_percent); + percent_to_float(overall_percent)); - if (percent_range != PERCENT_100) + if (segment_percent != PERCENT_100) return PROGRESS_UNFINISHED; - if (overall_percent_range == PERCENT_100) + if (overall_percent == PERCENT_100) return PROGRESS_FINISHED_ALL; return PROGRESS_FINISHED_SEGMENT; --- LVM2/tools/tools.h 2010/11/11 17:29:06 1.73 +++ LVM2/tools/tools.h 2010/11/30 11:53:33 1.74 @@ -85,7 +85,7 @@ PERCENT_LV, PERCENT_PVS, PERCENT_ORIGIN -} percent_t; +} percent_type_t; enum { CHANGE_AY = 0, @@ -106,7 +106,7 @@ int64_t i64_value; uint64_t ui64_value; sign_t sign; - percent_t percent; + percent_type_t percent; /* void *ptr; // Currently not used. */ }; @@ -174,7 +174,7 @@ uint64_t arg_uint64_value(struct cmd_context *cmd, int a, const uint64_t def); const void *arg_ptr_value(struct cmd_context *cmd, int a, const void *def); sign_t arg_sign_value(struct cmd_context *cmd, int a, const sign_t def); -percent_t arg_percent_value(struct cmd_context *cmd, int a, const percent_t def); +percent_type_t arg_percent_value(struct cmd_context *cmd, int a, const percent_type_t def); int arg_count_increment(struct cmd_context *cmd, int a); unsigned grouped_arg_count(const struct arg_values *av, int a); From zkabelac@sourceware.org Tue Nov 30 22:11:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 30 Nov 2010 22:11:00 -0000 Subject: LVM2 ./WHATS_NEW daemons/clvmd/clvmd-command.c Message-ID: <20101130221127.1763.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-30 22:11:26 Modified files: . : WHATS_NEW daemons/clvmd : clvmd-command.c Log message: Check reallocated buffer for NULL before use As *buf is reallocated in case CLVMD_CMD_TEST: test for NULL is needed before printing status. (realloc() == NULL and status != 0) Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1814&r2=1.1815 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/clvmd/clvmd-command.c.diff?cvsroot=lvm2&r1=1.41&r2=1.42 --- LVM2/WHATS_NEW 2010/11/29 18:35:37 1.1814 +++ LVM2/WHATS_NEW 2010/11/30 22:11:26 1.1815 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Check reallocated buffer for NULL before use in clvmd do_command(). Fix memory leak when VG allocation policy in metadata is invalid. Ignore unrecognised allocation policy found in metadata instead of aborting. Factor out tag printing into _out_tags and avoid leaking string buffer. --- LVM2/daemons/clvmd/clvmd-command.c 2010/10/20 14:51:18 1.41 +++ LVM2/daemons/clvmd/clvmd-command.c 2010/11/30 22:11:26 1.42 @@ -169,7 +169,8 @@ /* Check the status of the command and return the error text */ if (status) { - *retlen = 1 + snprintf(*buf, buflen, "%s", strerror(status)); + *retlen = 1 + (*buf) ? snprintf(*buf, buflen, "%s", + strerror(status)) : -1; } return status; From zkabelac@sourceware.org Tue Nov 30 22:16:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 30 Nov 2010 22:16:00 -0000 Subject: LVM2 ./WHATS_NEW daemons/clvmd/clvmd-command.c Message-ID: <20101130221626.3517.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-30 22:16:25 Modified files: . : WHATS_NEW daemons/clvmd : clvmd-command.c Log message: Replace snprintf with dm_snprintf Use dm_snprintf with known error case return code (-1). Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1815&r2=1.1816 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/clvmd/clvmd-command.c.diff?cvsroot=lvm2&r1=1.42&r2=1.43 --- LVM2/WHATS_NEW 2010/11/30 22:11:26 1.1815 +++ LVM2/WHATS_NEW 2010/11/30 22:16:25 1.1816 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Replace snprintf with dm_snprintf in clvmd-command.c. Check reallocated buffer for NULL before use in clvmd do_command(). Fix memory leak when VG allocation policy in metadata is invalid. Ignore unrecognised allocation policy found in metadata instead of aborting. --- LVM2/daemons/clvmd/clvmd-command.c 2010/11/30 22:11:26 1.42 +++ LVM2/daemons/clvmd/clvmd-command.c 2010/11/30 22:16:25 1.43 @@ -97,10 +97,10 @@ } if (*buf) { uname(&nodeinfo); - *retlen = 1 + snprintf(*buf, buflen, - "TEST from %s: %s v%s", - nodeinfo.nodename, args, - nodeinfo.release); + *retlen = 1 + dm_snprintf(*buf, buflen, + "TEST from %s: %s v%s", + nodeinfo.nodename, args, + nodeinfo.release); } break; @@ -121,9 +121,8 @@ status = do_lock_lv(lock_cmd, lock_flags, lockname); /* Replace EIO with something less scary */ if (status == EIO) { - *retlen = - 1 + snprintf(*buf, buflen, "%s", - get_last_lvm_error()); + *retlen = 1 + dm_snprintf(*buf, buflen, "%s", + get_last_lvm_error()); return EIO; } break; @@ -133,7 +132,7 @@ if (buflen < 3) return EIO; if ((locktype = do_lock_query(lockname))) - *retlen = 1 + snprintf(*buf, buflen, "%s", locktype); + *retlen = 1 + dm_snprintf(*buf, buflen, "%s", locktype); break; case CLVMD_CMD_REFRESH: @@ -169,8 +168,8 @@ /* Check the status of the command and return the error text */ if (status) { - *retlen = 1 + (*buf) ? snprintf(*buf, buflen, "%s", - strerror(status)) : -1; + *retlen = 1 + (*buf) ? dm_snprintf(*buf, buflen, "%s", + strerror(status)) : -1; } return status; @@ -377,7 +376,7 @@ /* Propogate debug options */ if (debug) { if (!(debug_arg = malloc(16)) || - snprintf(debug_arg, 16, "-d%d", (int)debug) < 0) + dm_snprintf(debug_arg, 16, "-d%d", (int)debug) < 0) goto_out; argv[argc++] = debug_arg; } From zkabelac@sourceware.org Tue Nov 30 22:23:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 30 Nov 2010 22:23:00 -0000 Subject: LVM2 ./WHATS_NEW lib/config/config.c Message-ID: <20101130222337.8129.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-30 22:23:35 Modified files: . : WHATS_NEW lib/config : config.c Log message: Add missing test for failed pool allocation Add test for NULL from dm_poll_create. Reorder dm_pool_destroy() before file close and add label out:. Avoid leaking file descriptor if the allocation fails. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1816&r2=1.1817 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/config/config.c.diff?cvsroot=lvm2&r1=1.83&r2=1.84 --- LVM2/WHATS_NEW 2010/11/30 22:16:25 1.1816 +++ LVM2/WHATS_NEW 2010/11/30 22:23:35 1.1817 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Add missing test for failed pool allocation in write_config_node(). Replace snprintf with dm_snprintf in clvmd-command.c. Check reallocated buffer for NULL before use in clvmd do_command(). Fix memory leak when VG allocation policy in metadata is invalid. --- LVM2/lib/config/config.c 2010/11/23 15:08:57 1.83 +++ LVM2/lib/config/config.c 2010/11/30 22:23:35 1.84 @@ -511,7 +511,8 @@ { struct output_line outline; outline.fp = NULL; - outline.mem = dm_pool_create("config_line", 1024); + if (!(outline.mem = dm_pool_create("config_line", 1024))) + return_0; outline.putline = putline; outline.putline_baton = baton; if (!_write_config(cn, 0, &outline, 0)) { @@ -538,7 +539,10 @@ return 0; } - outline.mem = dm_pool_create("config_line", 1024); + if (!(outline.mem = dm_pool_create("config_line", 1024))) { + r = 0; + goto_out; + } log_verbose("Dumping configuration to %s", file); if (!argc) { @@ -559,12 +563,14 @@ argv++; } + dm_pool_destroy(outline.mem); + +out: if (outline.fp && lvm_fclose(outline.fp, file)) { stack; r = 0; } - dm_pool_destroy(outline.mem); return r; } From zkabelac@sourceware.org Tue Nov 30 22:28:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 30 Nov 2010 22:28:00 -0000 Subject: LVM2/lib/activate dev_manager.c dev_manager.h Message-ID: <20101130222807.10187.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-30 22:28:06 Modified files: lib/activate : dev_manager.c dev_manager.h Log message: Remove check for lv is NULL 'lv' is deferenced in the begining of the function so any check later is not helpful. Parameters for dev_manager_transien() are marked as nonnull. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/dev_manager.c.diff?cvsroot=lvm2&r1=1.206&r2=1.207 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/dev_manager.h.diff?cvsroot=lvm2&r1=1.35&r2=1.36 --- LVM2/lib/activate/dev_manager.c 2010/11/30 11:53:31 1.206 +++ LVM2/lib/activate/dev_manager.c 2010/11/30 22:28:06 1.207 @@ -601,14 +601,13 @@ do { next = dm_get_next_target(dmt, next, &start, &length, &type, ¶ms); - if (lv) { - if (!(segh = dm_list_next(&lv->segments, segh))) { - log_error("Number of segments in active LV %s " - "does not match metadata", lv->name); - goto out; - } - seg = dm_list_item(segh, struct lv_segment); + + if (!(segh = dm_list_next(&lv->segments, segh))) { + log_error("Number of segments in active LV %s " + "does not match metadata", lv->name); + goto out; } + seg = dm_list_item(segh, struct lv_segment); if (!type || !params) continue; @@ -619,7 +618,7 @@ } while (next); - if (lv && (segh = dm_list_next(&lv->segments, segh))) { + if ((segh = dm_list_next(&lv->segments, segh))) { log_error("Number of segments in active LV %s does not " "match metadata", lv->name); goto out; --- LVM2/lib/activate/dev_manager.h 2010/11/30 11:53:31 1.35 +++ LVM2/lib/activate/dev_manager.h 2010/11/30 22:28:06 1.36 @@ -56,7 +56,7 @@ int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv, unsigned origin_only, int *flush_required); int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv); -int dev_manager_transient(struct dev_manager *dm, struct logical_volume *lv); +int dev_manager_transient(struct dev_manager *dm, struct logical_volume *lv) __attribute__((nonnull(1, 2))); int dev_manager_mknodes(const struct logical_volume *lv); From zkabelac@sourceware.org Tue Nov 30 22:32:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 30 Nov 2010 22:32:00 -0000 Subject: LVM2/libdm/ioctl libdm-iface.c Message-ID: <20101130223245.11604.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-30 22:32:45 Modified files: libdm/ioctl : libdm-iface.c Log message: Add error path stack traces Check for errors from dm_task_set_name() and dm_task_run(). Add stack traces for error paths. Return 0 if some error is found. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/ioctl/libdm-iface.c.diff?cvsroot=lvm2&r1=1.83&r2=1.84 --- LVM2/libdm/ioctl/libdm-iface.c 2010/10/25 11:44:20 1.83 +++ LVM2/libdm/ioctl/libdm-iface.c 2010/11/30 22:32:44 1.84 @@ -1594,8 +1594,15 @@ !strcmp(dirent->d_name, "..") || !strcmp(dirent->d_name, "control")) continue; - dm_task_set_name(dmt, dirent->d_name); - dm_task_run(dmt); + if (!dm_task_set_name(dmt, dirent->d_name)) { + r = 0; + stack; + continue; /* try next name */ + } + if (!dm_task_run(dmt)) { + r = 0; + stack; /* keep going */ + } } if (closedir(d)) From zkabelac@sourceware.org Tue Nov 30 22:40:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 30 Nov 2010 22:40:00 -0000 Subject: LVM2 ./WHATS_NEW libdm/ioctl/libdm-iface.c Message-ID: <20101130224022.26776.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-30 22:40:20 Modified files: . : WHATS_NEW libdm/ioctl : libdm-iface.c Log message: Add stack trace for error path If dm_task_set_cookie() fails print stack trace, but keep going on. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1817&r2=1.1818 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/ioctl/libdm-iface.c.diff?cvsroot=lvm2&r1=1.84&r2=1.85 --- LVM2/WHATS_NEW 2010/11/30 22:23:35 1.1817 +++ LVM2/WHATS_NEW 2010/11/30 22:40:19 1.1818 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Add error path stack traces for _process_mapper_dir(), _create_and_load_v4(). Add missing test for failed pool allocation in write_config_node(). Replace snprintf with dm_snprintf in clvmd-command.c. Check reallocated buffer for NULL before use in clvmd do_command(). --- LVM2/libdm/ioctl/libdm-iface.c 2010/11/30 22:32:44 1.84 +++ LVM2/libdm/ioctl/libdm-iface.c 2010/11/30 22:40:20 1.85 @@ -1779,9 +1779,10 @@ if (dmt->cookie_set) { cookie = (dmt->event_nr & ~DM_UDEV_FLAGS_MASK) | (DM_COOKIE_MAGIC << DM_UDEV_FLAGS_SHIFT); - dm_task_set_cookie(dmt, &cookie, - (dmt->event_nr & DM_UDEV_FLAGS_MASK) >> - DM_UDEV_FLAGS_SHIFT); + if (!dm_task_set_cookie(dmt, &cookie, + (dmt->event_nr & DM_UDEV_FLAGS_MASK) >> + DM_UDEV_FLAGS_SHIFT)) + stack; /* keep going */ } if (!dm_task_run(dmt)) From zkabelac@sourceware.org Tue Nov 30 22:53:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 30 Nov 2010 22:53:00 -0000 Subject: LVM2/tools dmsetup.c Message-ID: <20101130225338.14835.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-30 22:53:38 Modified files: tools : dmsetup.c Log message: Test uuid for NULL Add test for NULL before passing uuid as src argument to memcpy. As memcpy function is declared as function not accepting NULL. Though we pass NULL only with zero length so this patch presents no functional change to the code. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/dmsetup.c.diff?cvsroot=lvm2&r1=1.148&r2=1.149 --- LVM2/tools/dmsetup.c 2010/11/24 09:43:18 1.148 +++ LVM2/tools/dmsetup.c 2010/11/30 22:53:37 1.149 @@ -343,7 +343,9 @@ return NULL; } - memcpy(uuid_prefix, uuid, len); + if (uuid) + memcpy(uuid_prefix, uuid, len); + uuid_prefix[len] = '\0'; return uuid_prefix; From zkabelac@sourceware.org Tue Nov 30 22:57:00 2010 From: zkabelac@sourceware.org (zkabelac@sourceware.org) Date: Tue, 30 Nov 2010 22:57:00 -0000 Subject: LVM2/lib/format1 import-export.c Message-ID: <20101130225736.17433.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: zkabelac@sourceware.org 2010-11-30 22:57:35 Modified files: lib/format1 : import-export.c Log message: Remove unneeded test for NULL Remove check for system_id (it is defined as int8_t[], so cannot be NULL). Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format1/import-export.c.diff?cvsroot=lvm2&r1=1.115&r2=1.116 --- LVM2/lib/format1/import-export.c 2010/09/30 21:06:51 1.115 +++ LVM2/lib/format1/import-export.c 2010/11/30 22:57:35 1.116 @@ -185,7 +185,7 @@ } /* Generate system_id if PV is in VG */ - if (!pvd->system_id || !*pvd->system_id) + if (!pvd->system_id[0]) if (!_system_id(cmd, (char *)pvd->system_id, "")) return_0; From mornfall@sourceware.org Tue Nov 30 23:03:00 2010 From: mornfall@sourceware.org (mornfall@sourceware.org) Date: Tue, 30 Nov 2010 23:03:00 -0000 Subject: LVM2 WHATS_NEW Message-ID: <20101130230336.19443.qmail@sourceware.org> CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2010-11-30 23:03:35 Modified files: . : WHATS_NEW Log message: What's new. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1818&r2=1.1819 --- LVM2/WHATS_NEW 2010/11/30 22:40:19 1.1818 +++ LVM2/WHATS_NEW 2010/11/30 23:03:35 1.1819 @@ -1,5 +1,6 @@ Version 2.02.78 - ==================================== + Avoid misleading warnings in vgextend --restoremissing in certain cases. Add error path stack traces for _process_mapper_dir(), _create_and_load_v4(). Add missing test for failed pool allocation in write_config_node(). Replace snprintf with dm_snprintf in clvmd-command.c.