From 0c83d6068842dd90a88d1c2f8a3d29393fbe0557 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Wed, 12 Jan 2011 20:42:50 +0000 Subject: [PATCH] Replace fs_unlock by sync_local_dev_names to notify local clvmd. (2.02.80) Introduce sync_local_dev_names and CLVMD_CMD_SYNC_NAMES to issue fs_unlock. --- WHATS_NEW | 2 ++ daemons/clvmd/clvm.h | 1 + daemons/clvmd/clvmd-command.c | 6 ++++++ daemons/clvmd/lvm-functions.c | 1 + lib/activate/fs.c | 1 + lib/locking/cluster_locking.c | 20 +++++++++++++------- lib/locking/file_locking.c | 3 +++ lib/locking/locking.c | 2 +- lib/locking/locking.h | 3 +++ lib/locking/no_locking.c | 2 ++ lib/metadata/lv_manip.c | 2 +- lib/metadata/metadata-exported.h | 1 + lib/metadata/metadata.c | 8 ++++++++ lib/misc/lvm-exec.c | 2 +- libdm/libdm-common.c | 2 +- tools/polldaemon.c | 2 +- 16 files changed, 46 insertions(+), 12 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 335365902..d28f9709e 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,7 @@ Version 2.02.81 - =================================== + Replace fs_unlock by sync_local_dev_names to notify local clvmd. (2.02.80) + Introduce sync_local_dev_names and CLVMD_CMD_SYNC_NAMES to issue fs_unlock. Accept fusion fio in device type filter. Add disk to mirrored log type conversion. diff --git a/daemons/clvmd/clvm.h b/daemons/clvmd/clvm.h index c9ea10c49..8922a19c9 100644 --- a/daemons/clvmd/clvm.h +++ b/daemons/clvmd/clvm.h @@ -71,4 +71,5 @@ static const char CLVMD_SOCKNAME[]= DEFAULT_RUN_DIR "/clvmd.sock"; #define CLVMD_CMD_SET_DEBUG 42 #define CLVMD_CMD_VG_BACKUP 43 #define CLVMD_CMD_RESTART 44 +#define CLVMD_CMD_SYNC_NAMES 45 #endif diff --git a/daemons/clvmd/clvmd-command.c b/daemons/clvmd/clvmd-command.c index bd6f348fe..eee5bc3e3 100644 --- a/daemons/clvmd/clvmd-command.c +++ b/daemons/clvmd/clvmd-command.c @@ -139,6 +139,10 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen, do_refresh_cache(); break; + case CLVMD_CMD_SYNC_NAMES: + lvm_do_fs_unlock(); + break; + case CLVMD_CMD_SET_DEBUG: debug = args[0]; break; @@ -275,6 +279,7 @@ int do_pre_command(struct local_client *client) case CLVMD_CMD_GET_CLUSTERNAME: case CLVMD_CMD_SET_DEBUG: case CLVMD_CMD_VG_BACKUP: + case CLVMD_CMD_SYNC_NAMES: case CLVMD_CMD_LOCK_QUERY: case CLVMD_CMD_RESTART: break; @@ -307,6 +312,7 @@ int do_post_command(struct local_client *client) case CLVMD_CMD_LOCK_VG: case CLVMD_CMD_VG_BACKUP: + case CLVMD_CMD_SYNC_NAMES: case CLVMD_CMD_LOCK_QUERY: /* Nothing to do here */ break; diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c index cba6f445d..f06657d9e 100644 --- a/daemons/clvmd/lvm-functions.c +++ b/daemons/clvmd/lvm-functions.c @@ -897,6 +897,7 @@ struct dm_hash_node *get_next_excl_lock(struct dm_hash_node *v, char **name) void lvm_do_fs_unlock(void) { pthread_mutex_lock(&lvm_lock); + DEBUGLOG("Syncing device names\n"); fs_unlock(); pthread_mutex_unlock(&lvm_lock); } diff --git a/lib/activate/fs.c b/lib/activate/fs.c index a3770905f..ae94763ea 100644 --- a/lib/activate/fs.c +++ b/lib/activate/fs.c @@ -403,6 +403,7 @@ int fs_rename_lv(struct logical_volume *lv, const char *dev, void fs_unlock(void) { if (!memlock()) { + log_debug("Syncing device names"); /* Wait for all processed udev devices */ if (!dm_udev_wait(_fs_cookie)) stack; diff --git a/lib/locking/cluster_locking.c b/lib/locking/cluster_locking.c index 8b7fe9998..5ed8a339a 100644 --- a/lib/locking/cluster_locking.c +++ b/lib/locking/cluster_locking.c @@ -345,14 +345,15 @@ static int _lock_for_cluster(struct cmd_context *cmd, unsigned char clvmd_cmd, * locks are cluster-wide. * Also, if the lock is exclusive it makes no sense to try to * acquire it on all nodes, so just do that on the local node too. - * One exception, is that P_ locks /do/ get distributed across - * the cluster because they might have side-effects. + * One exception, is that P_ locks (except VG_SYNC_NAMES) /do/ get + * distributed across the cluster because they might have side-effects. */ - if (strncmp(name, "P_", 2) && - (clvmd_cmd == CLVMD_CMD_LOCK_VG || - (flags & LCK_TYPE_MASK) == LCK_EXCL || - (flags & LCK_LOCAL) || - !(flags & LCK_CLUSTER_VG))) + if ((strncmp(name, "P_", 2) && + (clvmd_cmd == CLVMD_CMD_LOCK_VG || + (flags & LCK_TYPE_MASK) == LCK_EXCL || + (flags & LCK_LOCAL) || + !(flags & LCK_CLUSTER_VG))) || + (clvmd_cmd == CLVMD_CMD_SYNC_NAMES && (flags & LCK_LOCAL))) node = "."; status = _cluster_request(clvmd_cmd, node, args, len, @@ -401,6 +402,11 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags) switch (flags & LCK_SCOPE_MASK) { case LCK_VG: + if (!strcmp(resource, VG_SYNC_NAMES)) { + log_very_verbose("Requesting sync names."); + return _lock_for_cluster(cmd, CLVMD_CMD_SYNC_NAMES, + flags & ~LCK_HOLD, resource); + } if (flags == LCK_VG_BACKUP) { log_very_verbose("Requesting backup of VG metadata for %s", resource); diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c index 434bd92b3..0c8bbed4f 100644 --- a/lib/locking/file_locking.c +++ b/lib/locking/file_locking.c @@ -265,6 +265,9 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource, if (strcmp(resource, VG_GLOBAL)) lvmcache_drop_metadata(resource, 0); + if (!strcmp(resource, VG_SYNC_NAMES)) + fs_unlock(); + /* LCK_CACHE does not require a real lock */ if (flags & LCK_CACHE) break; diff --git a/lib/locking/locking.c b/lib/locking/locking.c index 60eaab3ec..2adf99786 100644 --- a/lib/locking/locking.c +++ b/lib/locking/locking.c @@ -325,7 +325,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname) char path[PATH_MAX]; /* We'll allow operations on orphans */ - if (is_orphan_vg(vgname) || is_global_vg(vgname)) + if (!is_real_vg(vgname)) return 1; /* LVM1 is only present in 2.4 kernels. */ diff --git a/lib/locking/locking.h b/lib/locking/locking.h index 88935004f..1b5e1fc02 100644 --- a/lib/locking/locking.h +++ b/lib/locking/locking.h @@ -109,6 +109,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname); */ #define VG_ORPHANS "#orphans" #define VG_GLOBAL "#global" +#define VG_SYNC_NAMES "#sync_names" /* * Common combinations @@ -169,6 +170,8 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname); lock_vol((vg)->cmd, (vg)->name, LCK_VG_REVERT) #define remote_backup_metadata(vg) \ lock_vol((vg)->cmd, (vg)->name, LCK_VG_BACKUP) +#define sync_local_dev_names(cmd) \ + lock_vol(cmd, VG_SYNC_NAMES, LCK_NONE | LCK_CACHE | LCK_LOCAL) /* Process list of LVs */ int suspend_lvs(struct cmd_context *cmd, struct dm_list *lvs); diff --git a/lib/locking/no_locking.c b/lib/locking/no_locking.c index 8c4110f54..3ad0d38b2 100644 --- a/lib/locking/no_locking.c +++ b/lib/locking/no_locking.c @@ -38,6 +38,8 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource, { switch (flags & LCK_SCOPE_MASK) { case LCK_VG: + if (!strcmp(resource, VG_SYNC_NAMES)) + fs_unlock(); break; case LCK_LV: switch (flags & LCK_TYPE_MASK) { diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index 5f79994b0..a2ae30e31 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -3021,7 +3021,7 @@ int set_lv(struct cmd_context *cmd, struct logical_volume *lv, return 0; } - fs_unlock(); /* Wait until devices are available */ + sync_local_dev_names(cmd); /* Wait until devices are available */ log_verbose("Clearing start of logical volume \"%s\"", lv->name); diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h index 6994e0c1f..a9709d60f 100644 --- a/lib/metadata/metadata-exported.h +++ b/lib/metadata/metadata-exported.h @@ -362,6 +362,7 @@ int move_pvs_used_by_lv(struct volume_group *vg_from, const char *lv_name); int is_global_vg(const char *vg_name); int is_orphan_vg(const char *vg_name); +int is_real_vg(const char *vg_name); int vg_missing_pv_count(const struct volume_group *vg); int vgs_are_compatible(struct cmd_context *cmd, struct volume_group *vg_from, diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index 27abaea38..771cdb08a 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -3560,6 +3560,14 @@ int is_orphan_vg(const char *vg_name) return (vg_name && !strncmp(vg_name, ORPHAN_PREFIX, sizeof(ORPHAN_PREFIX) - 1)) ? 1 : 0; } +/* + * Exclude pseudo VG names used for locking. + */ +int is_real_vg(const char *vg_name) +{ + return (vg_name && *vg_name != '#'); +} + /* * Returns: * 0 - fail diff --git a/lib/misc/lvm-exec.c b/lib/misc/lvm-exec.c index eed3f393e..79291259d 100644 --- a/lib/misc/lvm-exec.c +++ b/lib/misc/lvm-exec.c @@ -55,7 +55,7 @@ int exec_cmd(struct cmd_context *cmd, const char *const argv[], int *rstatus) log_verbose("Executing: %s", _verbose_args(argv, buf, sizeof(buf))); - fs_unlock(); /* Flush oops and ensure cookie is not shared */ + sync_local_dev_names(cmd); /* Flush ops and reset dm cookie */ if ((pid = fork()) == -1) { log_error("fork failed: %s", strerror(errno)); diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c index 6d8bcbd8a..a181c5f07 100644 --- a/libdm/libdm-common.c +++ b/libdm/libdm-common.c @@ -507,7 +507,7 @@ static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor, (void) dm_prepare_selinux_context(path, S_IFBLK); old_mask = umask(0); if (mknod(path, S_IFBLK | mode, dev) < 0) { - log_error("Unable to make device node for '%s'", dev_name); + log_error("%s: mknod for %s failed: %s", path, dev_name, strerror(errno)); umask(old_mask); (void) dm_prepare_selinux_context(NULL, 0); return 0; diff --git a/tools/polldaemon.c b/tools/polldaemon.c index 0ee7a8c59..aac9c17fa 100644 --- a/tools/polldaemon.c +++ b/tools/polldaemon.c @@ -42,7 +42,7 @@ static int _become_daemon(struct cmd_context *cmd) sigaction(SIGCHLD, &act, NULL); - fs_unlock(); /* Flush oops and ensure cookie is not shared */ + sync_local_dev_names(cmd); /* Flush ops and reset dm cookie */ if ((pid = fork()) == -1) { log_error("fork failed: %s", strerror(errno)); -- 2.43.5