summaryrefslogtreecommitdiff
path: root/daemons/lvmlockd/lvmlockd-internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'daemons/lvmlockd/lvmlockd-internal.h')
-rw-r--r--daemons/lvmlockd/lvmlockd-internal.h317
1 files changed, 317 insertions, 0 deletions
diff --git a/daemons/lvmlockd/lvmlockd-internal.h b/daemons/lvmlockd/lvmlockd-internal.h
new file mode 100644
index 000000000..0c84a798a
--- /dev/null
+++ b/daemons/lvmlockd/lvmlockd-internal.h
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * 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.
+ */
+
+
+#ifndef _LVM_LVMLOCKD_INTERNAL_H
+#define _LVM_LVMLOCKD_INTERNAL_H
+
+/* TODO: figure out real restraints/requirements for these */
+#define MAX_NAME 64
+#define MAX_ARGS 64
+
+#define R_NAME_GL_DISABLED "_GLLK_disabled"
+#define R_NAME_GL "GLLK"
+#define R_NAME_VG "VGLK"
+#define S_NAME_GL_DLM "lvmglobal"
+/* global lockspace name for sanlock is a vg name */
+
+/* lock manager types */
+enum {
+ LD_LM_NONE = 0,
+ LD_LM_UNUSED = 1, /* place holder so values match lib/locking/lvmlockd.h */
+ LD_LM_DLM = 2,
+ LD_LM_SANLOCK = 3,
+};
+
+/* operation types */
+enum {
+ LD_OP_HELLO = 1,
+ LD_OP_QUIT,
+ LD_OP_INIT,
+ LD_OP_FREE,
+ LD_OP_START,
+ LD_OP_STOP,
+ LD_OP_LOCK,
+ LD_OP_UPDATE,
+ LD_OP_CLOSE,
+ LD_OP_ENABLE,
+ LD_OP_DISABLE,
+ LD_OP_ADD_LOCAL,
+ LD_OP_REM_LOCAL,
+ LD_OP_UPDATE_LOCAL,
+ LD_OP_START_WAIT,
+ LD_OP_STOP_ALL,
+ LD_OP_DUMP_INFO,
+ LD_OP_DUMP_LOG,
+};
+
+/* resource types */
+enum {
+ LD_RT_GL = 1,
+ LD_RT_VG,
+ LD_RT_LV,
+};
+
+/* lock modes, more restrictive must be larger value */
+enum {
+ LD_LK_IV = -1,
+ LD_LK_UN = 0,
+ LD_LK_NL = 1,
+ LD_LK_SH = 2,
+ LD_LK_EX = 3,
+};
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+struct client {
+ struct list_head list;
+ pthread_mutex_t mutex;
+ int pid;
+ int fd;
+ int pi;
+ uint32_t id;
+ unsigned int recv : 1;
+ unsigned int dead : 1;
+ unsigned int poll_ignore : 1;
+ char name[MAX_NAME];
+};
+
+#define LD_AF_PERSISTENT 0x00000001
+#define LD_AF_CLIENT_DEAD 0x00000002
+#define LD_AF_UNLOCK_CANCEL 0x00000004
+#define LD_AF_NEXT_VERSION 0x00000008
+#define LD_AF_WAIT 0x00000010
+#define LD_AF_FORCE 0x00000020
+#define LD_AF_EX_DISABLE 0x00000040
+#define LD_AF_ENABLE 0x00000080
+#define LD_AF_DISABLE 0x00000100
+#define LD_AF_SEARCH_LS 0x00000200
+#define LD_AF_LOCAL_LS 0x00000400
+#define LD_AF_UPDATE_NAMES_VERSION 0x00000800
+#define LD_AF_WAIT_STARTING 0x00001000
+#define LD_AF_DUP_GL_LS 0x00002000
+#define LD_AF_INACTIVE_LS 0x00004000
+#define LD_AF_ADD_LS_ERROR 0x00008000
+
+/*
+ * Number of times to repeat a lock request after
+ * a lock conflict (-EAGAIN) if unspecified in the
+ * request.
+ */
+#define DEFAULT_MAX_RETRIES 4
+
+struct action {
+ struct list_head list;
+ uint32_t client_id;
+ uint32_t flags; /* LD_AF_ */
+ uint32_t version;
+ uint64_t host_id;
+ int8_t op; /* operation type LD_OP_ */
+ int8_t rt; /* resource type LD_RT_ */
+ int8_t mode; /* lock mode LD_LK_ */
+ int8_t lm_type; /* lock manager: LM_DLM, LM_SANLOCK */
+ int retries;
+ int max_retries;
+ int result;
+ int lm_rv; /* return value from lm_ function */
+ char vg_uuid[64];
+ char vg_name[MAX_NAME+1];
+ char lv_name[MAX_NAME+1];
+ char vg_args[MAX_ARGS];
+ char lv_args[MAX_ARGS];
+ char vg_sysid[MAX_NAME+1];
+};
+
+struct resource {
+ struct list_head list; /* lockspace.resources */
+ char name[MAX_NAME+1]; /* vg name or lv name */
+ int8_t type; /* resource type LD_RT_ */
+ int8_t mode;
+ unsigned int sh_count; /* number of sh locks on locks list */
+ uint32_t version;
+ struct list_head locks;
+ struct list_head actions;
+ void *lm_data;
+};
+
+#define LD_LF_PERSISTENT 0x00000001
+
+struct lock {
+ struct list_head list; /* resource.locks */
+ int8_t mode; /* lock mode LD_LK_ */
+ uint32_t version;
+ uint32_t flags; /* LD_LF_ */
+ uint32_t client_id; /* may be 0 for persistent or internal locks */
+};
+
+struct lockspace {
+ struct list_head list; /* lockspaces */
+ char name[MAX_NAME+1];
+ char vg_name[MAX_NAME+1];
+ char vg_uuid[64];
+ char vg_args[MAX_ARGS]; /* lock manager specific args */
+ char vg_sysid[MAX_NAME+1];
+ int8_t lm_type; /* lock manager: LM_DLM, LM_SANLOCK */
+ void *lm_data;
+ uint64_t host_id;
+ uint32_t names_version; /* read/write from/to gl val_blk n_version */
+
+ uint32_t start_client_id; /* client_id that started the lockspace */
+ pthread_t thread; /* makes synchronous lock requests */
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+ unsigned int create_fail : 1;
+ unsigned int create_done : 1;
+ unsigned int thread_work : 1;
+ unsigned int thread_stop : 1;
+ unsigned int thread_done : 1;
+ unsigned int update_local_vgs : 1;
+ unsigned int update_names_version: 1;
+ unsigned int sanlock_gl_enabled: 1;
+ unsigned int sanlock_gl_dup: 1;
+
+ struct list_head actions; /* new client actions */
+ struct list_head resources; /* resource/lock state for gl/vg/lv */
+ /* TODO: should probably be tree */
+};
+
+#define VAL_BLK_VERSION 0x0101
+
+struct val_blk {
+ uint16_t version;
+ uint16_t flags;
+ uint32_t r_version;
+ uint32_t n_version;
+};
+
+/* lm_unlock flags */
+#define LMUF_FREE_VG 0x00000001
+
+int lockspaces_empty(void);
+int last_string_from_args(char *args_in, char *last);
+int version_from_args(char *args, unsigned int *major, unsigned int *minor, unsigned int *patch);
+
+int lm_init_vg_dlm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
+int lm_add_lockspace_dlm(struct lockspace *ls);
+int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg);
+int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
+ uint32_t *r_version, uint32_t *n_version);
+int lm_convert_dlm(struct lockspace *ls, struct resource *r,
+ int ld_mode, uint32_t r_version);
+int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
+ uint32_t r_version, uint32_t n_version, uint32_t lmu_flags);
+int lm_rem_resource_dlm(struct lockspace *ls, struct resource *r);
+
+int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
+int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args);
+int lm_free_lv_sanlock(struct lockspace *ls, struct resource *r);
+int lm_add_lockspace_sanlock(struct lockspace *ls);
+int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg);
+int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
+ char *lv_args, uint32_t *r_version, uint32_t *n_version, int *retry);
+int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
+ int ld_mode, uint32_t r_version);
+int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
+ uint32_t r_version, uint32_t n_version, uint32_t lmu_flags);
+int lm_able_gl_sanlock(struct lockspace *ls, int enable);
+int lm_ex_disable_gl_sanlock(struct lockspace *ls);
+int lm_hosts_sanlock(struct lockspace *ls, int notify);
+int lm_rem_resource_sanlock(struct lockspace *ls, struct resource *r);
+int lm_gl_is_enabled(struct lockspace *ls);
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define le16_to_cpu(x) (bswap_16((x)))
+#define le32_to_cpu(x) (bswap_32((x)))
+#define le64_to_cpu(x) (bswap_64((x)))
+#define cpu_to_le16(x) (bswap_16((x)))
+#define cpu_to_le32(x) (bswap_32((x)))
+#define cpu_to_le64(x) (bswap_64((x)))
+#endif
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define le16_to_cpu(x) (x)
+#define le32_to_cpu(x) (x)
+#define le64_to_cpu(x) (x)
+#define cpu_to_le16(x) (x)
+#define cpu_to_le32(x) (x)
+#define cpu_to_le64(x) (x)
+#endif
+
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+/* to improve readability */
+#define WAIT 1
+#define NO_WAIT 0
+#define FORCE 1
+#define NO_FORCE 0
+
+/*
+ * global variables
+ */
+
+#ifndef EXTERN
+#define EXTERN extern
+#define INIT(X)
+#else
+#undef EXTERN
+#define EXTERN
+#define INIT(X) =X
+#endif
+
+/*
+ * gl_type_static and gl_use_ are set by command line or config file
+ * to specify whether the global lock comes from dlm or sanlock.
+ * Without a static setting, lvmlockd will figure out where the
+ * global lock should be (but it could get mixed up in cases where
+ * both sanlock and dlm vgs exist.)
+ *
+ * gl_use_dlm means that the gl should come from lockspace gl_lsname_dlm
+ * gl_use_sanlock means that the gl should come from lockspace gl_lsname_sanlock
+ *
+ * gl_use_dlm has precedence over gl_use_sanlock, so if a node sees both
+ * dlm and sanlock vgs, it will use the dlm gl.
+ *
+ * gl_use_ is set when the first evidence of that lm_type is seen
+ * in any command.
+ *
+ * gl_lsname_sanlock is set when the first vg is seen in which an
+ * enabled gl is exists, or when init_vg creates a vg with gl enabled,
+ * or when enable_gl is used.
+ *
+ * gl_lsname_sanlock is cleared when free_vg deletes a vg with gl enabled
+ * or when disable_gl matches.
+ */
+
+EXTERN int gl_type_static;
+EXTERN int gl_use_dlm;
+EXTERN int gl_use_sanlock;
+EXTERN pthread_mutex_t gl_type_mutex;
+
+EXTERN char gl_lsname_dlm[MAX_NAME+1];
+EXTERN char gl_lsname_sanlock[MAX_NAME+1];
+
+EXTERN int gl_running_dlm;
+EXTERN int gl_auto_dlm;
+
+EXTERN int daemon_test; /* run as much as possible without a live lock manager */
+EXTERN int daemon_debug;
+EXTERN int daemon_host_id;
+EXTERN const char *daemon_host_id_file;
+
+void log_level(int level, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
+#define log_debug(fmt, args...) log_level(LOG_DEBUG, fmt, ##args)
+#define log_error(fmt, args...) log_level(LOG_ERR, fmt, ##args)
+#define log_warn(fmt, args...) log_level(LOG_WARNING, fmt, ##args)
+
+#endif