diff --git a/cluster_support_mirrord_log.diff b/cluster_support_mirrord_log.diff new file mode 100644 index 0000000..217b78a --- /dev/null +++ b/cluster_support_mirrord_log.diff @@ -0,0 +1,500 @@ +Index: LVM2.2.02.98/daemons/cmirrord/cluster.c +=================================================================== +--- LVM2.2.02.98.orig/daemons/cmirrord/cluster.c ++++ LVM2.2.02.98/daemons/cmirrord/cluster.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #if CMIRROR_HAS_CHECKPOINT + #include + #include +@@ -118,9 +119,11 @@ struct clog_cpg { + struct checkpoint_data *checkpoint_list; + int idx; + char debugging[DEBUGGING_HISTORY][128]; ++ pthread_t thread_pid; + }; + + static struct dm_list clog_cpg_list; ++static pthread_rwlock_t clog_cpg_lock =PTHREAD_RWLOCK_INITIALIZER; + + /* + * cluster_send +@@ -135,12 +138,14 @@ int cluster_send(struct clog_request *rq + struct iovec iov; + struct clog_cpg *entry; + ++ pthread_rwlock_rdlock(&clog_cpg_lock); + dm_list_iterate_items(entry, &clog_cpg_list) + if (!strncmp(entry->name.value, rq->u_rq.uuid, + CPG_MAX_NAME_LENGTH)) { + found = 1; + break; + } ++ pthread_rwlock_unlock(&clog_cpg_lock); + + if (!found) { + rq->u_rq.error = -ENOENT; +@@ -221,11 +226,11 @@ static struct clog_request *get_matching + return NULL; + } + +-static char rq_buffer[DM_ULOG_REQUEST_SIZE]; + static int handle_cluster_request(struct clog_cpg *entry __attribute__((unused)), + struct clog_request *rq, int server) + { + int r = 0; ++ char rq_buffer[DM_ULOG_REQUEST_SIZE]; + struct clog_request *tmp = (struct clog_request *)rq_buffer; + + /* +@@ -332,9 +337,13 @@ static struct clog_cpg *find_clog_cpg(cp + { + struct clog_cpg *match; + ++ pthread_rwlock_rdlock(&clog_cpg_lock); + dm_list_iterate_items(match, &clog_cpg_list) +- if (match->handle == handle) ++ if (match->handle == handle) { ++ pthread_rwlock_unlock(&clog_cpg_lock); + return match; ++ } ++ pthread_rwlock_unlock(&clog_cpg_lock); + + return NULL; + } +@@ -939,28 +948,17 @@ static int resend_requests(struct clog_c + return r; + } + +-static int do_cluster_work(void *data __attribute__((unused))) ++static void cluster_thread_fn(void *data) + { + int r = CS_OK; +- struct clog_cpg *entry, *tmp; +- +- dm_list_iterate_items_safe(entry, tmp, &clog_cpg_list) { +- r = cpg_dispatch(entry->handle, CS_DISPATCH_ALL); +- if (r != CS_OK) +- LOG_ERROR("cpg_dispatch failed: %d", r); +- +- if (entry->free_me) { +- free(entry); +- continue; +- } +- do_checkpoints(entry, 0); +- +- resend_requests(entry); +- } ++ struct clog_cpg * match = data; ++ r = cpg_dispatch (match->handle, CS_DISPATCH_BLOCKING); ++ if (r != CS_OK) ++ LOG_DBG("cpg_dispatch failed"); + +- return (r == CS_OK) ? 0 : -1; /* FIXME: good error number? */ + } + ++ + static int flush_startup_list(struct clog_cpg *entry) + { + int r = 0; +@@ -1011,23 +1009,35 @@ static int flush_startup_list(struct clo + return 0; + } + ++static void do_cpg_message_callback(struct clog_cpg * match , uint32_t nodeid, void *msg, size_t msg_len); ++ + static void cpg_message_callback(cpg_handle_t handle, const struct cpg_name *gname __attribute__((unused)), + uint32_t nodeid, uint32_t pid __attribute__((unused)), + void *msg, size_t msg_len) + { ++ struct clog_cpg * entry; ++ ++ entry = find_clog_cpg(handle); ++ if (!entry) { ++ LOG_ERROR("Unable to find clog_cpg for cluster message"); ++ return; ++ } ++ do_cpg_message_callback(entry, nodeid, msg, msg_len); ++ ++ do_checkpoints(entry, 0); ++ resend_requests(entry); ++ ++} ++ ++static void do_cpg_message_callback(struct clog_cpg * match , uint32_t nodeid, void *msg, size_t msg_len) ++{ + int i; + int r = 0; + int i_am_server; + int response = 0; + struct clog_request *rq = msg; + struct clog_request *tmp_rq; +- struct clog_cpg *match; + +- match = find_clog_cpg(handle); +- if (!match) { +- LOG_ERROR("Unable to find clog_cpg for cluster message"); +- return; +- } + + /* + * Perform necessary endian and version compatibility conversions +@@ -1324,7 +1334,7 @@ static void cpg_leave_callback(struct cl + size_t member_list_entries) + { + unsigned i; +- int j, fd; ++ int j; + uint32_t lowest = match->lowest_id; + struct clog_request *rq, *n; + struct checkpoint_data *p_cp, *c_cp; +@@ -1335,10 +1345,9 @@ static void cpg_leave_callback(struct cl + /* Am I leaving? */ + if (my_cluster_id == left->nodeid) { + LOG_DBG("Finalizing leave..."); ++ pthread_rwlock_wrlock(&clog_cpg_lock); + dm_list_del(&match->list); +- +- cpg_fd_get(match->handle, &fd); +- links_unregister(fd); ++ pthread_rwlock_unlock(&clog_cpg_lock); + + cluster_postsuspend(match->name.value, match->luid); + +@@ -1466,11 +1475,13 @@ static void cpg_config_callback(cpg_hand + struct clog_cpg *match; + int found = 0; + ++ pthread_rwlock_rdlock(&clog_cpg_lock); + dm_list_iterate_items(match, &clog_cpg_list) + if (match->handle == handle) { + found = 1; + break; + } ++ pthread_rwlock_unlock(&clog_cpg_lock); + + if (!found) { + LOG_ERROR("Unable to find match for CPG config callback"); +@@ -1487,6 +1498,16 @@ static void cpg_config_callback(cpg_hand + else + cpg_leave_callback(match, left_list, + member_list, member_list_entries); ++ ++ ++ if (match->free_me) { ++ LOG_DBG("closing thread %x", (unsigned int)match->thread_pid); ++ free(match); ++ return; ++ } ++ ++ do_checkpoints(match, 0); ++ resend_requests(match); + } + + cpg_callbacks_t cpg_callbacks = { +@@ -1554,12 +1575,16 @@ int create_cluster_cpg(char *uuid, uint6 + size_t size; + struct clog_cpg *new = NULL; + struct clog_cpg *tmp; ++ pthread_t new_pid; + ++ pthread_rwlock_rdlock(&clog_cpg_lock); + dm_list_iterate_items(tmp, &clog_cpg_list) + if (!strncmp(tmp->name.value, uuid, CPG_MAX_NAME_LENGTH)) { + LOG_ERROR("Log entry already exists: %s", uuid); ++ pthread_rwlock_unlock(&clog_cpg_lock); + return -EEXIST; + } ++ pthread_rwlock_unlock(&clog_cpg_lock); + + new = malloc(sizeof(*new)); + if (!new) { +@@ -1601,13 +1626,16 @@ int create_cluster_cpg(char *uuid, uint6 + } + + new->cpg_state = VALID; ++ pthread_rwlock_wrlock(&clog_cpg_lock); + dm_list_add(&clog_cpg_list, &new->list); ++ pthread_rwlock_unlock(&clog_cpg_lock); ++ + LOG_DBG("New handle: %llu", (unsigned long long)new->handle); + LOG_DBG("New name: %s", new->name.value); + +- /* FIXME: better variable */ +- cpg_fd_get(new->handle, &r); +- links_register(r, "cluster", do_cluster_work, NULL); ++ pthread_create(&new_pid, NULL, (void *)cluster_thread_fn, (void*)new); ++ new->thread_pid = new_pid; ++ pthread_detach(new_pid); + + return 0; + } +@@ -1676,9 +1704,11 @@ int destroy_cluster_cpg(char *uuid) + { + struct clog_cpg *del, *tmp; + ++ pthread_rwlock_rdlock(&clog_cpg_lock); + dm_list_iterate_items_safe(del, tmp, &clog_cpg_list) + if (!strncmp(del->name.value, uuid, CPG_MAX_NAME_LENGTH)) + _destroy_cluster_cpg(del); ++ pthread_rwlock_unlock(&clog_cpg_lock); + + return 0; + } +Index: LVM2.2.02.98/daemons/cmirrord/functions.c +=================================================================== +--- LVM2.2.02.98.orig/daemons/cmirrord/functions.c ++++ LVM2.2.02.98/daemons/cmirrord/functions.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + #define BYTE_SHIFT 3 + +@@ -105,6 +106,9 @@ struct recovery_request { + static DM_LIST_INIT(log_list); + static DM_LIST_INIT(log_pending_list); + ++static pthread_rwlock_t log_list_lock = PTHREAD_RWLOCK_INITIALIZER; ++static pthread_rwlock_t log_pending_lock = PTHREAD_RWLOCK_INITIALIZER; ++ + static int log_test_bit(dm_bitset_t bs, int bit) + { + return dm_bit(bs, bit) ? 1 : 0; +@@ -151,11 +155,15 @@ static struct log_c *get_log(const char + { + struct log_c *lc; + ++ pthread_rwlock_rdlock(&log_list_lock); + dm_list_iterate_items(lc, &log_list) + if (!strcmp(lc->uuid, uuid) && +- (!luid || (luid == lc->luid))) ++ (!luid || (luid == lc->luid))) { ++ pthread_rwlock_unlock(&log_list_lock); + return lc; ++ } + ++ pthread_rwlock_unlock(&log_list_lock); + return NULL; + } + +@@ -171,10 +179,14 @@ static struct log_c *get_pending_log(con + { + struct log_c *lc; + ++ pthread_rwlock_rdlock(&log_pending_lock); + dm_list_iterate_items(lc, &log_pending_list) + if (!strcmp(lc->uuid, uuid) && +- (!luid || (luid == lc->luid))) ++ (!luid || (luid == lc->luid))) { ++ pthread_rwlock_unlock(&log_pending_lock); + return lc; ++ } ++ pthread_rwlock_unlock(&log_pending_lock); + + return NULL; + } +@@ -517,7 +529,9 @@ static int _clog_ctr(char *uuid, uint64_ + LOG_DBG("Disk log ready"); + } + ++ pthread_rwlock_wrlock(&log_pending_lock); + dm_list_add(&log_pending_list, &lc->list); ++ pthread_rwlock_unlock(&log_pending_lock); + + return 0; + fail: +@@ -641,7 +655,10 @@ static int clog_dtr(struct dm_ulog_reque + + LOG_DBG("[%s] Cluster log removed", SHORT_UUID(lc->uuid)); + ++ pthread_rwlock_wrlock(&log_list_lock); + dm_list_del(&lc->list); ++ pthread_rwlock_unlock(&log_list_lock); ++ + if (lc->disk_fd != -1 && close(lc->disk_fd)) + LOG_ERROR("Failed to close disk log: %s", + strerror(errno)); +@@ -713,8 +730,13 @@ int cluster_postsuspend(char *uuid, uint + lc->resume_override = 0; + + /* move log to pending list */ ++ pthread_rwlock_wrlock(&log_list_lock); + dm_list_del(&lc->list); ++ pthread_rwlock_unlock(&log_list_lock); ++ ++ pthread_rwlock_wrlock(&log_pending_lock); + dm_list_add(&log_pending_list, &lc->list); ++ pthread_rwlock_unlock(&log_pending_lock); + + return 0; + } +@@ -818,9 +840,9 @@ no_disk: + if (commit_log && (lc->disk_fd >= 0)) { + rq->error = write_log(lc); + if (rq->error) +- LOG_ERROR("Failed initial disk log write"); ++ LOG_ERROR("[%s] Failed initial disk log write", SHORT_UUID(lc->uuid)); + else +- LOG_DBG("Disk log initialized"); ++ LOG_DBG("[%s] Disk log initialized", SHORT_UUID(lc->uuid)); + lc->touched = 0; + } + out: +@@ -902,8 +924,13 @@ int local_resume(struct dm_ulog_request + } + + /* move log to official list */ ++ pthread_rwlock_wrlock(&log_pending_lock); + dm_list_del(&lc->list); ++ pthread_rwlock_unlock(&log_pending_lock); ++ ++ pthread_rwlock_wrlock(&log_list_lock); + dm_list_add(&log_list, &lc->list); ++ pthread_rwlock_unlock(&log_list_lock); + } + + return 0; +@@ -1910,7 +1937,6 @@ void log_debug(void) + + LOG_ERROR(""); + LOG_ERROR("LOG COMPONENT DEBUGGING::"); +- LOG_ERROR("Official log list:"); + LOG_ERROR("Pending log list:"); + dm_list_iterate_items(lc, &log_pending_list) { + LOG_ERROR("%s", lc->uuid); +@@ -1920,6 +1946,7 @@ void log_debug(void) + print_bits(lc->clean_bits, 1); + } + ++ LOG_ERROR("Official log list:"); + dm_list_iterate_items(lc, &log_list) { + LOG_ERROR("%s", lc->uuid); + LOG_ERROR(" recoverer : %" PRIu32, lc->recoverer); +Index: LVM2.2.02.98/daemons/cmirrord/local.c +=================================================================== +--- LVM2.2.02.98.orig/daemons/cmirrord/local.c ++++ LVM2.2.02.98/daemons/cmirrord/local.c +@@ -29,13 +29,13 @@ + + static int cn_fd = -1; /* Connector (netlink) socket fd */ + static char recv_buf[2048]; +-static char send_buf[2048]; + + + /* FIXME: merge this function with kernel_send_helper */ + static int kernel_ack(uint32_t seq, int error) + { + int r; ++ char send_buf[2048]; + struct nlmsghdr *nlh = (struct nlmsghdr *)send_buf; + struct cn_msg *msg = NLMSG_DATA(nlh); + +@@ -179,6 +179,7 @@ static int kernel_send_helper(void *data + int r; + struct nlmsghdr *nlh; + struct cn_msg *msg; ++ char send_buf[2048]; + + memset(send_buf, 0, sizeof(send_buf)); + +Index: LVM2.2.02.98/lib/metadata/mirror.c +=================================================================== +--- LVM2.2.02.98.orig/lib/metadata/mirror.c ++++ LVM2.2.02.98/lib/metadata/mirror.c +@@ -1909,10 +1909,6 @@ int add_mirror_log(struct cmd_context *c + unsigned old_log_count; + int r = 0; + +- if (vg_is_clustered(lv->vg) && (log_count > 1)) { +- log_error("Log type, \"mirrored\", is unavailable to cluster mirrors"); +- return 0; +- } + + if (dm_list_size(&lv->segments) != 1) { + log_error("Multiple-segment mirror is not supported"); +@@ -2076,25 +2072,6 @@ int lv_add_mirrors(struct cmd_context *c + return 0; + } + +- if (vg_is_clustered(lv->vg)) { +- /* FIXME: review check of lv_is_active_remotely */ +- /* FIXME: move this test out of this function */ +- /* Skip test for pvmove mirrors, it can use local mirror */ +- if (!(lv->status & (PVMOVE | LOCKED)) && +- !_cluster_mirror_is_available(lv)) { +- log_error("Shared cluster mirrors are not available."); +- return 0; +- } +- +- /* +- * No mirrored logs for cluster mirrors until +- * log daemon is multi-threaded. +- */ +- if (log_count > 1) { +- log_error("Log type, \"mirrored\", is unavailable to cluster mirrors"); +- return 0; +- } +- } + + /* For corelog mirror, activation code depends on + * the global mirror_in_sync status. As we are adding +Index: LVM2.2.02.98/lib/mirror/mirrored.c +=================================================================== +--- LVM2.2.02.98.orig/lib/mirror/mirrored.c ++++ LVM2.2.02.98/lib/mirror/mirrored.c +@@ -366,12 +366,15 @@ static int _add_log(struct dm_pool *mem, + return 0; + } + } else { +- /* If core log, use mirror's UUID and set DM_CORELOG flag */ ++ /* If core log, use mirror's (UUID + CORE) and set DM_CORELOG flag */ + if (!(log_dlid = build_dm_uuid(mem, seg->lv->lvid.s, NULL))) { + log_error("Failed to build uuid for mirror LV %s.", + seg->lv->name); + return 0; + } ++ if (clustered) ++ memcpy(&(log_dlid[strlen(log_dlid)-4]),"CORE",4); ++ + log_flags |= DM_CORELOG; + } + +Index: LVM2.2.02.98/tools/lvconvert.c +=================================================================== +--- LVM2.2.02.98.orig/tools/lvconvert.c ++++ LVM2.2.02.98/tools/lvconvert.c +@@ -1115,15 +1115,6 @@ static int _lvconvert_mirrors_parse_para + return 0; + } + +- /* +- * No mirrored logs for cluster mirrors until +- * log daemon is multi-threaded. +- */ +- if ((*new_log_count == 2) && vg_is_clustered(lv->vg)) { +- log_error("Log type, \"mirrored\", is unavailable to cluster mirrors"); +- return 0; +- } +- + log_verbose("Setting logging type to %s", mirrorlog); + + /* +Index: LVM2.2.02.98/daemons/cmirrord/Makefile.in +=================================================================== +--- LVM2.2.02.98.orig/daemons/cmirrord/Makefile.in ++++ LVM2.2.02.98/daemons/cmirrord/Makefile.in +@@ -26,7 +26,7 @@ TARGETS = cmirrord + + include $(top_builddir)/make.tmpl + +-LIBS += -ldevmapper ++LIBS += -ldevmapper -lpthread + LMLIBS += $(CPG_LIBS) $(SACKPT_LIBS) + CFLAGS += $(CPG_CFLAGS) $(SACKPT_CFLAGS) + diff --git a/csm-converter.tar.gz b/csm-converter.tar.gz new file mode 100644 index 0000000..c9f52db --- /dev/null +++ b/csm-converter.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7e73182cf83099516cdf225748ac297c7368e651e232c4f23dd1fab33d1c3f6 +size 5604 diff --git a/dont_ignore_tmp_device_file.diff b/dont_ignore_tmp_device_file.diff deleted file mode 100644 index cdd3aa1..0000000 --- a/dont_ignore_tmp_device_file.diff +++ /dev/null @@ -1,19 +0,0 @@ ---- - lib/device/dev-cache.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- LVM2.2.02.98.orig/lib/device/dev-cache.c -+++ LVM2.2.02.98/lib/device/dev-cache.c -@@ -434,7 +434,11 @@ static int _insert_dir(const char *dir) - dirent_count = scandir(dir, &dirent, NULL, alphasort); - if (dirent_count > 0) { - for (n = 0; n < dirent_count; n++) { -- if (dirent[n]->d_name[0] == '.') { -+ if (dirent[n]->d_name[0] == '.' && dirent[n]->d_name[1] == '\0') { -+ free(dirent[n]); -+ continue; -+ } -+ if (dirent[n]->d_name[0] == '.' && dirent[n]->d_name[1] == '.' && dirent[n]->d_name[2] == '\0') { - free(dirent[n]); - continue; - } diff --git a/improve-mirror-legs-on-different-tag-pvs.patch b/improve-mirror-legs-on-different-tag-pvs.patch new file mode 100644 index 0000000..c1af385 --- /dev/null +++ b/improve-mirror-legs-on-different-tag-pvs.patch @@ -0,0 +1,71 @@ +From 69092b1179f4fbd0fae7e054665ad049dffd9966 Mon Sep 17 00:00:00 2001 +From: Guangliang Zhao +Date: Wed, 5 Dec 2012 18:25:04 +0800 +Subject: [PATCH 2/2] mirror: improve mirror legs on different tag pvs + +This patch will find the biggest eligible area every time, +and add it to the parallel areas. + +The previous just find the different tag pv area with all +found ones, if the new area's tag has appeared, just throw +it. The new will compare the length, and choose the longer +one. + +Signed-off-by: Guangliang Zhao +--- + lib/metadata/lv_manip.c | 25 ++++++++++++++++++++++--- + 1 file changed, 22 insertions(+), 3 deletions(-) + +diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c +index fb0199f..edafdf1 100644 +--- a/lib/metadata/lv_manip.c ++++ b/lib/metadata/lv_manip.c +@@ -1658,6 +1658,21 @@ static uint32_t _calc_required_extents(struct alloc_handle *ah, struct pv_area * + return required; + } + ++static void _replace_required_area(struct alloc_handle *ah, uint32_t max_to_allocate, ++ unsigned ix_pva, struct pv_area *pva, ++ struct alloc_state *alloc_state, alloc_policy_t alloc) ++{ ++ uint32_t required = _calc_required_extents(ah, pva, ix_pva, max_to_allocate, alloc); ++ ++ /* ++ * We don't worry about the area replaced, because _clear_areas() and ++ * _reset_unreserved() called by _find_some_parallel_space() will clear ++ * the alloc_state and reserved areas every time. ++ */ ++ if (required > alloc_state->areas[ix_pva - 1].used) ++ _reserve_area(&alloc_state->areas[ix_pva - 1], pva, required, ix_pva, pva->unreserved); ++} ++ + static int _reserve_required_area(struct alloc_handle *ah, uint32_t max_to_allocate, + unsigned ix_pva, struct pv_area *pva, + struct alloc_state *alloc_state, alloc_policy_t alloc) +@@ -1767,6 +1782,7 @@ static int _find_some_parallel_space(struct alloc_handle *ah, const struct alloc + { + unsigned ix = 0; + unsigned last_ix; ++ int ret; + struct pv_map *pvm; + struct pv_area *pva; + unsigned preferred_count = 0; +@@ -1875,9 +1891,12 @@ static int _find_some_parallel_space(struct alloc_handle *ah, const struct alloc + continue; + + case USE_AREA: +- if(check_areas_separate_tags(ah, alloc_state, ix_offset, +- ix + ix_offset, pva) >= 0) +- goto next_pv; ++ if((ret = check_areas_separate_tags(ah, alloc_state, ix_offset, ++ ix + ix_offset, pva)) >= 0) { ++ _replace_required_area(ah, max_to_allocate, ret + 1, ++ pva, alloc_state, alloc_parms->alloc); ++ continue; ++ } + + /* + * Except with ALLOC_ANYWHERE, replace first area with this +-- +1.7.10.4 + diff --git a/lvm.conf b/lvm.conf index 04550e0..da3629f 100644 --- a/lvm.conf +++ b/lvm.conf @@ -421,7 +421,7 @@ global { # Type 3 uses built-in clustered locking. # Type 4 uses read-only locking which forbids any operations that might # change metadata. - locking_type = 1 + locking_type = 3 # Set to 0 to fail when a lock request cannot be satisfied immediately. wait_for_locks = 1 @@ -503,7 +503,7 @@ global { # # Specify the '--type ' option to override this default # setting. - mirror_segtype_default = "mirror" + mirror_segtype_default = "raid1" # 'raid10_segtype_default' determines the segment types used by default # when the '--stripes/-i' and '--mirrors/-m' arguments are both specified @@ -541,7 +541,7 @@ global { # # If lvmetad has been running while use_lvmetad was 0, it MUST be stopped # before changing use_lvmetad to 1 and started again afterwards. - use_lvmetad = 0 + use_lvmetad = 1 # Full path of the utility called to check that a thin metadata device # is in a state that allows it to be used. diff --git a/lvm2.changes b/lvm2.changes index 1bd6249..354b9e4 100644 --- a/lvm2.changes +++ b/lvm2.changes @@ -1,3 +1,14 @@ +------------------------------------------------------------------- +Mon Jan 6 07:43:59 UTC 2014 - dmzhang@suse.com + +- add csm_convert to lvm2-clvm package(bnc#854076) +- system fails to boot due to missing /usr/sbin/lvm(bnc#837954) +- lvm2 systemd incorrectly uses dependencies on Fedora services(bnc#851741) +- set use_lvmetad = 1 as default of lvm.conf(bnc#854413) +- drop patch dont_ignore_tmp_device_file.diff +- backport patches from sle11 to support mirrored log in cluster +- set default mirror to md_raid1 insdead of dm_mirror for better performance + ------------------------------------------------------------------- Sun Oct 27 21:44:41 CET 2013 - ohering@suse.de diff --git a/lvm2.spec b/lvm2.spec index 6f2dc8e..bde2e00 100644 --- a/lvm2.spec +++ b/lvm2.spec @@ -1,7 +1,7 @@ # # spec file for package lvm2 # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -48,6 +48,7 @@ Source10: cmirrord.ocf #Source13: mkinitrd-devmapper-boot.sh Source14: baselibs.conf #Source15: lvm2-activation.service +Source16: csm-converter.tar.gz Patch: improve_probing.diff Patch2: no-inc-audit.diff @@ -56,12 +57,25 @@ Patch4: sys_mount_instead_linux_fs.diff Patch6: man_page_sectors.diff Patch13: pipe_buff-definition.diff -Patch19: dont_ignore_tmp_device_file.diff + Patch20: support-drbd-filter.diff Patch22: handle_extended_devt.diff Patch66: device-mapper-type_punning.diff Patch67: lvm-path.patch +#fate312248,patch68,69 +Patch68: make-mirror-legs-on-different-tag-pvs.patch +Patch69: improve-mirror-legs-on-different-tag-pvs.patch + +#fate#314367 +Patch70: cluster_support_mirrord_log.diff + +#upstream +Patch71: make_raid1_default.diff +#suppress warning +Patch72: suppress_locking_failer_message.patch +Patch73: remove-fedora-systemd.patch + BuildRoot: %{_tmppath}/%{name}-%{version}-build # Not a real replacement but we drop evms Provides: evms = 2.5.5 @@ -90,11 +104,16 @@ Volume Manager. %patch4 %patch6 -p1 %patch13 -p1 -%patch19 -p1 %patch20 -p1 %patch22 -p1 %patch66 -p1 %patch67 -p1 +%patch68 -p1 +%patch69 -p1 +%patch70 -p1 +%patch71 -p1 +%patch72 -p1 +%patch73 -p1 %build #set path so that thin_check can be found @@ -116,6 +135,12 @@ export PATH=$PATH:/sbin:/usr/sbin export SUSE_ASNEEDED=0 make -j1 # symlinks are generated in parallel! %{?_smp_mflags} +#csm convert +tar zxvf %{S:16} +pushd bnz +make +popd + %install make install_lvm2 DESTDIR=$RPM_BUILD_ROOT make install_system_dirs DESTDIR=$RPM_BUILD_ROOT @@ -175,13 +200,19 @@ rm -f $RPM_BUILD_ROOT/%{_unitdir}/dm-event.service # install and collect_lvm #install -m755 -D %{S:7} $RPM_BUILD_ROOT%{_udevdir}/collect_lvm +#csm-convert +pushd bnz +install -m755 -D csm-converter $RPM_BUILD_ROOT/usr/sbin/csm-converter +install -m755 -D csm-converter-helper $RPM_BUILD_ROOT/usr/sbin/csm-converter-helper +mv README.csm-converter .. +popd + %post %service_add_post blk-availability.service lvm2-monitor.service lvm2-lvmetad.socket [ -x /sbin/mkinitrd ] && /sbin/mkinitrd /sbin/ldconfig %preun -#%{stop_on_removal boot.lvm} %service_del_preun blk-availability.service lvm2-monitor.service lvm2-lvmetad.service lvm2-lvmetad.socket %postun @@ -195,8 +226,6 @@ rm -f $RPM_BUILD_ROOT/%{_unitdir}/dm-event.service %dir /etc/lvm/backup %dir /etc/lvm/archive %dir /etc/lvm/metadata -%config /etc/lvm/lvm.conf -#%config /etc/init.d/boot.lvm %dir /lib/mkinitrd %dir /lib/mkinitrd/scripts %{_udevdir}/rules.d/11-dm-lvm.rules @@ -206,7 +235,7 @@ rm -f $RPM_BUILD_ROOT/%{_unitdir}/dm-event.service %{_unitdir}/lvm2-lvmetad.socket %{_unitdir}/lvm2-lvmetad.service %{_tmpfilesdir}/lvm2.conf -#%{_udevdir}/collect_lvm +/etc/lvm/lvm.conf /lib/mkinitrd/scripts/setup-lvm2.sh /lib/mkinitrd/scripts/boot-lvm2.sh /usr/lib/systemd/system-generators/lvm2-activation-generator @@ -353,6 +382,9 @@ A daemon for using LVM2 Logival Volumes in a clustered environment. %dir /usr/lib/ocf/resource.d/lvm2 /usr/lib/ocf/resource.d/lvm2/clvmd %{_mandir}/man8/clvmd.8.gz +%doc README.csm-converter +/usr/sbin/csm-converter +/usr/sbin/csm-converter-helper %package cmirrord Url: http://www.sourceware.org/lvm2/ diff --git a/make-mirror-legs-on-different-tag-pvs.patch b/make-mirror-legs-on-different-tag-pvs.patch new file mode 100644 index 0000000..552c07d --- /dev/null +++ b/make-mirror-legs-on-different-tag-pvs.patch @@ -0,0 +1,159 @@ +From 49a5da732c74b8b96bc123a541d590c4fd06d7af Mon Sep 17 00:00:00 2001 +From: Guangliang Zhao +Date: Mon, 12 Nov 2012 15:28:11 +0800 +Subject: [PATCH 1/2] mirror: make mirror legs on different tag pvs + +The mirror legs could be placed on the PVs(with different +tags) from the other mirror legs with this patch. + +The lvcreate allocates the replica "randomly" when creating +a mirrored logical volume now, so it could happen that both +copies end up on the same array (or on the same site), clearly +undesired. + +We can't control the fist allocation, because didn't restrict +the areas into parallel space. This patch add the limit when +finding areas for parallel space, so that mirror legs will +always be placed on pvs with differnt tags. + +Signed-off-by: Guangliang Zhao +--- + doc/example.conf.in | 17 +++++++++++++++++ + lib/config/defaults.h | 1 + + lib/metadata/lv_manip.c | 37 +++++++++++++++++++++++++++++++++++++ + man/lvcreate.8.in | 3 +++ + 4 files changed, 58 insertions(+) + +diff --git a/doc/example.conf.in b/doc/example.conf.in +index f7344bb..57e00d6 100644 +--- a/doc/example.conf.in ++++ b/doc/example.conf.in +@@ -224,6 +224,23 @@ allocation { + # algorithm. + maximise_cling = 1 + ++ # Set to 1 to guarantee that mirror leg will always be placed on ++ # different PVs(with different tags) from the other mirror legs. ++ # ++ # If you want to enable this feature, the following conditions ++ # must be met: ++ # 1) The mirror_legs_require_separate_pvs must be set to 1, the ++ # default value is 0. ++ # 2) The cling_tag_list must be activated. ++ # 3) The length of all pvs with same tag must greater than or equal ++ # to the mirror's. ++ ++ # This feature is only for the first allocation, on the other hand ++ # when creating new mirrored lvs. ++ # Please note that the commond may fail if the number of all tags ++ # on the pvs less than the mirror legs number. ++ mirror_legs_require_separate_pvs = 0 ++ + # Set to 1 to guarantee that mirror logs will always be placed on + # different PVs from the mirror images. This was the default + # until version 2.02.85. +diff --git a/lib/config/defaults.h b/lib/config/defaults.h +index 9730a2d..d08d004 100644 +--- a/lib/config/defaults.h ++++ b/lib/config/defaults.h +@@ -98,6 +98,7 @@ + #define DEFAULT_MAX_LV 0 + #define DEFAULT_ALLOC_POLICY ALLOC_NORMAL + #define DEFAULT_MIRROR_LOGS_REQUIRE_SEPARATE_PVS 0 ++#define DEFAULT_MIRROR_LEGS_REQUIRE_SEPARATE_PVS 0 + #define DEFAULT_MAXIMISE_CLING 1 + #define DEFAULT_CLUSTERED 0 + +diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c +index 9f87854..fb0199f 100644 +--- a/lib/metadata/lv_manip.c ++++ b/lib/metadata/lv_manip.c +@@ -684,6 +684,9 @@ struct alloc_handle { + + unsigned maximise_cling; + unsigned mirror_logs_separate; /* Force mirror logs on separate PVs? */ ++ unsigned mirror_legs_separate; /* Force mirror *legs* on separate PVs*/ ++ ++ const struct segment_type *segtype; + + /* + * RAID devices require a metadata area that accompanies each +@@ -868,6 +871,7 @@ static struct alloc_handle *_alloc_init(struct cmd_context *cmd, + ah->parity_count = parity_count; + ah->region_size = region_size; + ah->alloc = alloc; ++ ah->segtype = segtype; + + /* + * For the purposes of allocation, area_count and parity_count are +@@ -879,6 +883,8 @@ static struct alloc_handle *_alloc_init(struct cmd_context *cmd, + ah->area_multiple = _calc_area_multiple(segtype, area_count + parity_count, stripes); + ah->mirror_logs_separate = find_config_tree_bool(cmd, "allocation/mirror_logs_require_separate_pvs", + DEFAULT_MIRROR_LOGS_REQUIRE_SEPARATE_PVS); ++ ah->mirror_legs_separate = find_config_tree_bool(cmd, "allocation/mirror_legs_require_separate_pvs", ++ DEFAULT_MIRROR_LEGS_REQUIRE_SEPARATE_PVS); + + if (segtype_is_raid(segtype)) { + if (metadata_area_count) { +@@ -1725,6 +1731,33 @@ static void _report_needed_allocation_space(struct alloc_handle *ah, + log_debug(" %" PRIu32 " %ss of %" PRIu32 " extents each", + metadata_count, metadata_type, metadata_size); + } ++ ++/* ++ * Return -1 if we don't need check tags, or there aren't any areas in alloc_status ++ * have the same tag with pva, the index otherwise. ++ */ ++static int check_areas_separate_tags(struct alloc_handle *ah, ++ struct alloc_state *alloc_state, ++ unsigned ix_start, ++ unsigned ix_end, ++ struct pv_area *pva) ++{ ++ int i; ++ ++ if (!segtype_is_mirrored(ah->segtype) || ++ alloc_state->allocated || ++ !ah->mirror_legs_separate || ++ !ah->cling_tag_list_cn) ++ return -1; ++ ++ for (i = ix_start; i < ix_end; i++) ++ if(_pvs_have_matching_tag(ah->cling_tag_list_cn, ++ alloc_state->areas[i].pva->map->pv, ++ pva->map->pv)) ++ return i; ++ return -1; ++} ++ + /* + * Returns 1 regardless of whether any space was found, except on error. + */ +@@ -1842,6 +1875,10 @@ static int _find_some_parallel_space(struct alloc_handle *ah, const struct alloc + continue; + + case USE_AREA: ++ if(check_areas_separate_tags(ah, alloc_state, ix_offset, ++ ix + ix_offset, pva) >= 0) ++ goto next_pv; ++ + /* + * Except with ALLOC_ANYWHERE, replace first area with this + * one which is smaller but still big enough. +diff --git a/man/lvcreate.8.in b/man/lvcreate.8.in +index f374950..d7355b9 100644 +--- a/man/lvcreate.8.in ++++ b/man/lvcreate.8.in +@@ -205,6 +205,9 @@ will create a persistent log that is itself mirrored. + + The optional argument --corelog is equivalent to --mirrorlog core. + ++Every leg of the mirrored logical volume could be placed on the pvs with ++same tag, see details(mirror_legs_require_separate_pvs) in lvm.conf. ++ + .TP + .IR \fB\-n ", " \fB\-\-name " " LogicalVolume { Name | Path } + The name for the new logical volume. +-- +1.7.10.4 + diff --git a/make_raid1_default.diff b/make_raid1_default.diff new file mode 100644 index 0000000..d3662b4 --- /dev/null +++ b/make_raid1_default.diff @@ -0,0 +1,19 @@ +commit 7e1083c985fd130b240c2471643350cc5c0f05cf +Author: Jonathan Brassow +Date: Tue Aug 6 14:13:55 2013 -0500 + + RAID: Make "raid1" the default mirror segment type + +diff --git a/lib/config/defaults.h b/lib/config/defaults.h +index 5af0f00..59282c5 100644 +--- a/lib/config/defaults.h ++++ b/lib/config/defaults.h +@@ -51,7 +51,7 @@ + #define DEFAULT_METADATA_READ_ONLY 0 + #define DEFAULT_LVDISPLAY_SHOWS_FULL_DEVICE_PATH 0 + +-#define DEFAULT_MIRROR_SEGTYPE "mirror" ++#define DEFAULT_MIRROR_SEGTYPE "raid1" + #define DEFAULT_MIRRORLOG "disk" + #define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate" + #define DEFAULT_MIRROR_IMAGE_FAULT_POLICY "remove" diff --git a/remove-fedora-systemd.patch b/remove-fedora-systemd.patch new file mode 100644 index 0000000..9e9b983 --- /dev/null +++ b/remove-fedora-systemd.patch @@ -0,0 +1,54 @@ +commit 360c569ce8f0bfe936d59ca91de2716958550524 +Author: Peter Rajnoha +Date: Tue Oct 30 20:36:49 2012 +0100 + + systemd: various updates and fixes + + Don't use lvmetad in lvm2-monitor.service ExecStop to avoid a systemd issue. + - a systemd design issue while processing dependencies + with socket-based activation that ends up with a hang + - https://bugzilla.redhat.com/show_bug.cgi?id=843587 + (also tracker bug https://bugzilla.redhat.com/show_bug.cgi?id=871527) + - not using lvmetad in this case is just a workaround, once the bug + above is resolved, we should enable the lvmetad in that specific case + + Remove dependency on fedora-storage-init.service in lvm2 systemd units. + - fedora-storage-init.service and fedora-storage-init-late.service is + going to be separated into respective units that belong to each block + device subsystem: + - mpath + mdraid activated via udev solely + - dmraid with its own dmraid-activation.service unit + - lvm2 with the lvm2-activation-generator to generate the + activation units runtime if lvmetad disabled + (global/use_lvmetad=0 set in lvm.conf) and activation done + via udev+lvmetad if lvmetad enabled (global/use_lvmetad=1 set + in lvm.conf) + + Depend on lvm2-lvmetad.socket in lvm2-monitor.service systemd unit. + - as lvm2-monitor uses lvmetad if lvmetad is enabled + +diff --git a/scripts/lvm2_monitoring_systemd_red_hat.service.in b/scripts/lvm2_monitoring_systemd_red_hat.service.in +index 6c4c55f..e6b4814 100644 +--- a/scripts/lvm2_monitoring_systemd_red_hat.service.in ++++ b/scripts/lvm2_monitoring_systemd_red_hat.service.in +@@ -1,8 +1,8 @@ + [Unit] + Description=Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling + Documentation=man:dmeventd(8) man:lvcreate(8) man:lvchange(8) man:vgchange(8) +-Requires=dm-event.socket +-After=dm-event.socket fedora-storage-init.service fedora-storage-init-late.service lvm2-activation.service lvm2-lvmetad.service ++Requires=dm-event.socket lvm2-lvmetad.socket ++After=dm-event.socket lvm2-lvmetad.socket lvm2-lvmetad.service + Before=local-fs.target + DefaultDependencies=no + Conflicts=shutdown.target +@@ -11,7 +11,8 @@ Conflicts=shutdown.target + Type=oneshot + Environment=LVM_SUPPRESS_LOCKING_FAILURE_MESSAGES=1 + ExecStart=@sbindir@/lvm vgchange --monitor y +-ExecStop=@sbindir@/lvm vgchange --monitor n ++# The lvmetad must be disabled here, it needs https://bugzilla.redhat.com/show_bug.cgi?id=843587 to be resolved first. ++ExecStop="@sbindir@/lvm vgchange --monitor n --config 'global{use_lvmetad=0}'" + RemainAfterExit=yes + + [Install] diff --git a/suppress_locking_failer_message.patch b/suppress_locking_failer_message.patch new file mode 100644 index 0000000..ac9c9af --- /dev/null +++ b/suppress_locking_failer_message.patch @@ -0,0 +1,15 @@ +Index: LVM2.2.02.98/lib/locking/locking.c +=================================================================== +--- LVM2.2.02.98.orig/lib/locking/locking.c ++++ LVM2.2.02.98/lib/locking/locking.c +@@ -221,8 +221,8 @@ static void _update_vg_lock_count(const + */ + int init_locking(int type, struct cmd_context *cmd, int suppress_messages) + { +- if (getenv("LVM_SUPPRESS_LOCKING_FAILURE_MESSAGES")) +- suppress_messages = 1; ++ ++ suppress_messages = 1; + + if (type < 0) + type = find_config_tree_int(cmd, "global/locking_type", 1);