cluster-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
* [Cluster-devel] [PATCH dlm-tool] libdlm: introduce timeout opt parameter
@ 2021-04-01 14:59 Alexander Aring
  0 siblings, 0 replies; only message in thread
From: Alexander Aring @ 2021-04-01 14:59 UTC (permalink / raw)
  To: cluster-devel.redhat.com

This patch adds a dlm_opts struct which can be extended in future to
apply additional parameters to dlm functionality. This patch will add a
timeout parameter inside dlm opts for several dlm function to set the
amount of polling tries to wait for the dlm control device node. In some
cases of a large amount of creation of lockspaces in a short time it
seems to be necessary to increase this value on some systems. Users of
libdlm can update to this new API in due courses to handle a variable
or user defined timeout value.

Reported-by: Bob Peterson <rpeterso@redhat.com>
---
I saved the timeout value per ls for the release functionality, but I
am not sure if this makes sense because why we wait for a device on release?
It should already be there?

 libdlm/libdlm.c | 75 ++++++++++++++++++++++++++++++++++++++++---------
 libdlm/libdlm.h | 21 +++++++++++++-
 2 files changed, 81 insertions(+), 15 deletions(-)

diff --git a/libdlm/libdlm.c b/libdlm/libdlm.c
index ebfba457..97c7387c 100644
--- a/libdlm/libdlm.c
+++ b/libdlm/libdlm.c
@@ -40,6 +40,7 @@
 #define DLM_CONTROL_NAME	"dlm-control"
 #define DLM_CONTROL_PATH	MISC_PREFIX DLM_CONTROL_NAME
 #define DEFAULT_LOCKSPACE	"default"
+#define DEFAULT_DEVICE_TIMEOUT	10
 
 /*
  * V5 of the dlm_device.h kernel/user interface structs
@@ -96,6 +97,7 @@ struct dlm_ls_info {
 #else
     int tid;
 #endif
+    struct dlm_opts opts;
 };
 
 /*
@@ -110,6 +112,9 @@ static int control_fd = -1;
 static struct dlm_device_version kernel_version;
 static int kernel_version_detected = 0;
 
+static const struct dlm_opts dlm_default_opts = {
+	.ctrl_dev_timeout = DEFAULT_DEVICE_TIMEOUT,
+};
 
 static int release_lockspace(uint32_t minor, uint32_t flags);
 
@@ -367,7 +372,7 @@ static int find_control_minor(int *minor)
 	return -1;
 }
 
-static int open_control_device(void)
+static int open_control_device(unsigned int timeout)
 {
 	struct stat st;
 	int i, rv, minor, found = 0;
@@ -381,7 +386,7 @@ static int open_control_device(void)
 
 	/* wait for udev to create the device */
 
-	for (i = 0; i < 10; i++) {
+	for (i = 0; i < timeout; i++) {
 		if (stat(DLM_CONTROL_PATH, &st) == 0 &&
 		    minor(st.st_rdev) == minor) {
 			found = 1;
@@ -409,7 +414,8 @@ static int open_control_device(void)
 /* the max number of characters in a sysfs device name, not including \0 */
 #define MAX_SYSFS_NAME 19
 
-static int find_udev_device(const char *lockspace, int minor, char *udev_path)
+static int find_udev_device(const char *lockspace, int minor, char *udev_path,
+			    unsigned int timeout)
 {
 	char bname[PATH_MAX];
 	char tmp_path[PATH_MAX];
@@ -423,7 +429,7 @@ static int find_udev_device(const char *lockspace, int minor, char *udev_path)
 	snprintf(bname, PATH_MAX, DLM_PREFIX "%s", lockspace);
 	basename_len = strlen(bname);
 
-	for (i = 0; i < 10; i++) {
+	for (i = 0; i < timeout; i++) {
 
 		/* look for a device with the full name */
 
@@ -1285,7 +1291,8 @@ static int create_lockspace_v6(const char *name, uint32_t flags)
 }
 
 static dlm_lshandle_t create_lockspace(const char *name, mode_t mode,
-				       uint32_t flags)
+				       uint32_t flags,
+				       const struct dlm_opts *opts)
 {
 	char dev_path[PATH_MAX];
 	char udev_path[PATH_MAX];
@@ -1293,7 +1300,7 @@ static dlm_lshandle_t create_lockspace(const char *name, mode_t mode,
 	int error, saved_errno, minor;
 
 	/* We use the control device for creating lockspaces. */
-	if (open_control_device())
+	if (open_control_device(opts->ctrl_dev_timeout))
 		return NULL;
 
 	newls = malloc(sizeof(struct dlm_ls_info));
@@ -1301,6 +1308,7 @@ static dlm_lshandle_t create_lockspace(const char *name, mode_t mode,
 		return NULL;
 
 	ls_dev_name(name, dev_path, sizeof(dev_path));
+	newls->opts = *opts;
 
 	if (kernel_version.version[0] == 5)
 		minor = create_lockspace_v5(name, flags);
@@ -1313,7 +1321,8 @@ static dlm_lshandle_t create_lockspace(const char *name, mode_t mode,
 	/* Wait for udev to create the device; the device it creates may
 	   have a truncated name due to the sysfs device name limit. */
 	   
-	error = find_udev_device(name, minor, udev_path);
+	error = find_udev_device(name, minor, udev_path,
+				 opts->ctrl_dev_timeout);
 	if (error)
 		goto fail;
 
@@ -1346,12 +1355,25 @@ static dlm_lshandle_t create_lockspace(const char *name, mode_t mode,
 
 dlm_lshandle_t dlm_new_lockspace(const char *name, mode_t mode, uint32_t flags)
 {
-	return create_lockspace(name, mode, flags);
+	return create_lockspace(name, mode, flags, &dlm_default_opts);
+}
+
+dlm_lshandle_t dlm_new_lockspace_opts(const char *name, mode_t mode,
+				      uint32_t flags,
+				      const struct dlm_opts *opts)
+{
+	return create_lockspace(name, mode, flags, opts);
 }
 
 dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode)
 {
-	return create_lockspace(name, mode, 0);
+	return create_lockspace(name, mode, 0, &dlm_default_opts);
+}
+
+dlm_lshandle_t dlm_create_lockspace_opts(const char *name, mode_t mode,
+					 const struct dlm_opts *opts)
+{
+	return create_lockspace(name, mode, 0, opts);
 }
 
 static int release_lockspace_v5(uint32_t minor, uint32_t flags)
@@ -1405,7 +1427,7 @@ int dlm_release_lockspace(const char *name, dlm_lshandle_t ls, int force)
 	/* Close the lockspace first if it's in use */
 	ls_pthread_cleanup(lsinfo);
 
-	if (open_control_device())
+	if (open_control_device(lsinfo->opts.ctrl_dev_timeout))
 		return -1;
 
 	if (force)
@@ -1439,14 +1461,15 @@ int dlm_release_lockspace(const char *name, dlm_lshandle_t ls, int force)
  * Normal users just open/close lockspaces
  */
 
-dlm_lshandle_t dlm_open_lockspace(const char *name)
+static dlm_lshandle_t _dlm_open_lockspace(const char *name,
+					  const struct dlm_opts *opts)
 {
 	char dev_name[PATH_MAX];
 	struct dlm_ls_info *newls;
 	int saved_errno;
 
 	/* Need to detect kernel version */
-	if (open_control_device())
+	if (open_control_device(opts->ctrl_dev_timeout))
 		return NULL;
 
 	newls = malloc(sizeof(struct dlm_ls_info));
@@ -1455,6 +1478,7 @@ dlm_lshandle_t dlm_open_lockspace(const char *name)
 
 	newls->tid = 0;
 	ls_dev_name(name, dev_name, sizeof(dev_name));
+	newls->opts = *opts;
 
 	newls->fd = open(dev_name, O_RDWR);
 	saved_errno = errno;
@@ -1468,6 +1492,17 @@ dlm_lshandle_t dlm_open_lockspace(const char *name)
 	return (dlm_lshandle_t)newls;
 }
 
+dlm_lshandle_t dlm_open_lockspace(const char *name)
+{
+	return _dlm_open_lockspace(name, &dlm_default_opts);
+}
+
+dlm_lshandle_t dlm_open_lockspace_opts(const char *name,
+				       const struct dlm_opts *opts)
+{
+	return _dlm_open_lockspace(name, opts);
+}
+
 int dlm_close_lockspace(dlm_lshandle_t ls)
 {
 	struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
@@ -1476,9 +1511,10 @@ int dlm_close_lockspace(dlm_lshandle_t ls)
 	return 0;
 }
 
-int dlm_kernel_version(uint32_t *major, uint32_t *minor, uint32_t *patch)
+static int _dlm_kernel_version(uint32_t *major, uint32_t *minor, uint32_t *patch,
+			       const struct dlm_opts *opts)
 {
-	if (open_control_device())
+	if (open_control_device(opts->ctrl_dev_timeout))
 		return -1;
 	*major = kernel_version.version[0];
 	*minor = kernel_version.version[1];
@@ -1486,6 +1522,17 @@ int dlm_kernel_version(uint32_t *major, uint32_t *minor, uint32_t *patch)
 	return 0;
 }
 
+int dlm_kernel_version(uint32_t *major, uint32_t *minor, uint32_t *patch)
+{
+	return _dlm_kernel_version(major, minor, patch, &dlm_default_opts);
+}
+
+int dlm_kernel_version_opts(uint32_t *major, uint32_t *minor, uint32_t *patch,
+			    const struct dlm_opts *opts)
+{
+	return _dlm_kernel_version(major, minor, patch, opts);
+}
+
 void dlm_library_version(uint32_t *major, uint32_t *minor, uint32_t *patch)
 {
 	*major = DLM_DEVICE_VERSION_MAJOR;
diff --git a/libdlm/libdlm.h b/libdlm/libdlm.h
index 9255181c..156aa16e 100644
--- a/libdlm/libdlm.h
+++ b/libdlm/libdlm.h
@@ -56,7 +56,20 @@ struct dlm_lksb {
 struct dlm_queryinfo;
 #endif
 
+/*
+ * dlm opts structure - pass options to dlm functions
+ *
+ * ctrl_dev_timeout - define the amount of polling tries until timeout for a
+ *                    dlm control device. Each polling try results in an one
+ *                    second sleep.
+ */
+struct dlm_opts {
+	unsigned int ctrl_dev_timeout;
+};
+
 extern int dlm_kernel_version(uint32_t *maj, uint32_t *min, uint32_t *patch);
+extern int dlm_kernel_version_opts(uint32_t *major, uint32_t *minor, uint32_t *patch,
+				   const struct dlm_opts *opts);
 extern void dlm_library_version(uint32_t *maj, uint32_t *min, uint32_t *patch);
 
 
@@ -117,7 +130,6 @@ extern int dlm_unlock_wait(uint32_t lkid,
 extern int dlm_get_fd(void);
 extern int dlm_dispatch(int fd);
 
-
 /*
  * Creating your own lockspace
  *
@@ -138,13 +150,20 @@ extern int dlm_dispatch(int fd);
 typedef void *dlm_lshandle_t;
 
 extern dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode);
+extern dlm_lshandle_t dlm_create_lockspace_opts(const char *name, mode_t mode,
+						const struct dlm_opts *opts);
 extern int dlm_release_lockspace(const char *name, dlm_lshandle_t ls,
 		int force);
 extern dlm_lshandle_t dlm_open_lockspace(const char *name);
+extern dlm_lshandle_t dlm_open_lockspace_opts(const char *name,
+					      const struct dlm_opts *opts);
 extern int dlm_close_lockspace(dlm_lshandle_t ls);
 extern int dlm_ls_get_fd(dlm_lshandle_t ls);
 extern dlm_lshandle_t dlm_new_lockspace(const char *name, mode_t mode,
 		uint32_t flags);
+extern dlm_lshandle_t dlm_new_lockspace_opts(const char *name, mode_t mode,
+					     uint32_t flags,
+					     const struct dlm_opts *opts);
 
 
 /*
-- 
2.26.3



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2021-04-01 14:59 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-04-01 14:59 [Cluster-devel] [PATCH dlm-tool] libdlm: introduce timeout opt parameter Alexander Aring

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).