public inbox for lvm2-cvs@sourceware.org
help / color / mirror / Atom feed
* LVM2 ./WHATS_NEW_DM libdm/ioctl/libdm-iface.c  ...
@ 2010-06-01 16:08 prajnoha
  0 siblings, 0 replies; 3+ messages in thread
From: prajnoha @ 2010-06-01 16:08 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	prajnoha@sourceware.org	2010-06-01 16:08:14

Modified files:
	.              : WHATS_NEW_DM 
	libdm/ioctl    : libdm-iface.c 
	libdm/misc     : dm-ioctl.h 

Log message:
	Add support for dm-mod module autoload.
	
	A kernel patch is on its way for 2.6.35 adding support for dm-mod module
	autoload. Udev v155 and higher is able to read static node information given
	in modules.devname (extracted by depmod before) and will create such nodes
	at its start. The first access to such node will load the module automatically
	(directly in kernel) before the actual read/write operation is processed.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW_DM.diff?cvsroot=lvm2&r1=1.375&r2=1.376
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/ioctl/libdm-iface.c.diff?cvsroot=lvm2&r1=1.74&r2=1.75
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/misc/dm-ioctl.h.diff?cvsroot=lvm2&r1=1.4&r2=1.5

--- LVM2/WHATS_NEW_DM	2010/05/28 03:50:15	1.375
+++ LVM2/WHATS_NEW_DM	2010/06/01 16:08:13	1.376
@@ -1,5 +1,6 @@
 Version 1.02.49 - 
 ================================
+  Add support for dm-mod module autoload.
   Document 'clear' in dmsetup man page.
   Use expected union semun for arguments in selected semaphore operations.
 
--- LVM2/libdm/ioctl/libdm-iface.c	2010/05/13 13:31:30	1.74
+++ LVM2/libdm/ioctl/libdm-iface.c	2010/06/01 16:08:13	1.75
@@ -64,6 +64,10 @@
 static unsigned _dm_version_patchlevel = 0;
 static int _log_suppress = 0;
 
+static int _kernel_major;
+static int _kernel_minor;
+static int _kernel_release;
+
 /*
  * If the kernel dm driver only supports one major number
  * we store it in _dm_device_major.  Otherwise we indicate
@@ -79,7 +83,6 @@
 static int _version_ok = 1;
 static unsigned _ioctl_buffer_double_factor = 0;
 
-
 /*
  * Support both old and new major numbers to ease the transition.
  * Clumsy, but only temporary.
@@ -136,6 +139,30 @@
 	return (void *) (((unsigned long) ptr + agn) & ~agn);
 }
 
+static int _uname()
+{
+	static int _uts_set = 0;
+	struct utsname _uts;
+
+	if (_uts_set)
+		return 1;
+
+	if (uname(&_uts)) {
+		log_error("uname failed: %s", strerror(errno));
+		return 0;
+	}
+	if (sscanf(_uts.release, "%d.%d.%d",
+			&_kernel_major,
+			&_kernel_minor,
+			&_kernel_release) != 3) {
+		log_error("Could not determine kernel version used.");
+		return 0;
+	}
+
+	_uts_set = 1;
+	return 1;
+}
+
 #ifdef DM_IOCTLS
 /*
  * Set number to NULL to populate _dm_bitset - otherwise first
@@ -266,12 +293,10 @@
 static int _create_dm_bitset(void)
 {
 #ifdef DM_IOCTLS
-	struct utsname uts;
-
 	if (_dm_bitset || _dm_device_major)
 		return 1;
 
-	if (uname(&uts))
+	if (!_uname())
 		return 0;
 
 	/*
@@ -279,7 +304,8 @@
 	 * Assume 2.4 kernels are patched not to.
 	 * FIXME Check _dm_version and _dm_version_minor if 2.6 changes this.
 	 */
-	if (!strncmp(uts.release, "2.6.", 4))
+	if (KERNEL_VERSION(_kernel_major, _kernel_minor, _kernel_release) >=
+	    KERNEL_VERSION(2, 6, 0))
 		_dm_multiple_major_support = 0;
 
 	if (!_dm_multiple_major_support) {
@@ -315,6 +341,16 @@
 		return (major == _dm_device_major) ? 1 : 0;
 }
 
+static int _open_and_assign_control_fd(const char *control)
+{
+	if ((_control_fd = open(control, O_RDWR)) < 0) {
+		log_sys_error("open", control);
+		return 0;
+	}
+
+	return 1;
+}
+
 static int _open_control(void)
 {
 #ifdef DM_IOCTLS
@@ -324,18 +360,49 @@
 	if (_control_fd != -1)
 		return 1;
 
-	snprintf(control, sizeof(control), "%s/control", dm_dir());
+	if (!_uname())
+		return 0;
 
-	if (!_control_device_number(&major, &minor))
-		log_error("Is device-mapper driver missing from kernel?");
+	snprintf(control, sizeof(control), "%s/%s", dm_dir(), DM_CONTROL_NODE);
 
-	if (!_control_exists(control, major, minor) &&
-	    !_create_control(control, major, minor))
-		goto error;
+	/*
+	 * Try to make use of module autoload kernel feature first.
+	 * This is accomplished with the help of udev that will
+	 * create static nodes based on modules.devname file extracted
+	 * by depmod (that udev reads). The /dev/mapper/control will
+	 * be created this way and the first access to a node will
+	 * load dm module automatically.
+	 *
+	 * To check for the module autoload support, we need:
+	 *
+	 *   - to check if the control node was created before (this
+	 *     should be the static node created by udev at its start)
+	 *
+	 *   - to check if we have recent enough kernel that is supposed
+	 *     to support this feature (a change in dm itself). We can't
+	 *     check dm version - we don't have a node to make an ioctl yet.
+	 *
+	 *   - try to open the control node (this will trigger the autoload).
+	 *     Successfull open means the autoload was successfull.
+	 *
+	 * If any of these three conditions fails, we fallback to old way.
+	 * It means we'll try to get the major:minor of control node,
+	 * we'll check its existence (checking the exact major:minor)
+	 * and we'll create the node if needed.
+	 */
+	if (!_control_exists(control, 0, 0) ||
+	    !(KERNEL_VERSION(_kernel_major, _kernel_minor, _kernel_release) >=
+	      KERNEL_VERSION(2, 6, 35)) ||
+	    !_open_and_assign_control_fd(control)) {
+		if (!_control_device_number(&major, &minor))
+			log_error("Is device-mapper driver missing from kernel?");
+
+		if (!_control_exists(control, major, minor) &&
+		    !_create_control(control, major, minor))
+			goto error;
 
-	if ((_control_fd = open(control, O_RDWR)) < 0) {
-		log_sys_error("open", control);
-		goto error;
+		if (!_open_and_assign_control_fd(control))
+			goto error;
 	}
 
 	if (!_create_dm_bitset()) {
--- LVM2/libdm/misc/dm-ioctl.h	2010/03/23 14:38:38	1.4
+++ LVM2/libdm/misc/dm-ioctl.h	2010/06/01 16:08:14	1.5
@@ -13,6 +13,7 @@
 #endif
 
 #define DM_DIR "mapper"		/* Slashes not supported */
+#define DM_CONTROL_NODE "control"
 #define DM_MAX_TYPE_NAME 16
 #define DM_NAME_LEN 128
 #define DM_UUID_LEN 129


^ permalink raw reply	[flat|nested] 3+ messages in thread

* LVM2 ./WHATS_NEW_DM libdm/ioctl/libdm-iface.c  ...
@ 2010-04-07 15:57 mbroz
  0 siblings, 0 replies; 3+ messages in thread
From: mbroz @ 2010-04-07 15:57 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	mbroz@sourceware.org	2010-04-07 15:57:21

Modified files:
	.              : WHATS_NEW_DM 
	libdm/ioctl    : libdm-iface.c 
	tools          : dmsetup.c 

Log message:
	Wipe dm-ioctl parameters in memory after use.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW_DM.diff?cvsroot=lvm2&r1=1.352&r2=1.353
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/ioctl/libdm-iface.c.diff?cvsroot=lvm2&r1=1.69&r2=1.70
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/dmsetup.c.diff?cvsroot=lvm2&r1=1.136&r2=1.137

--- LVM2/WHATS_NEW_DM	2010/03/23 14:43:18	1.352
+++ LVM2/WHATS_NEW_DM	2010/04/07 15:57:20	1.353
@@ -1,5 +1,6 @@
 Version 1.02.46 - 
 ================================
+  Wipe memory buffers for dm-ioctl parameters before releaseing.
   Strictly require libudev if udev_sync is used.
   Add support for ioctl's DM_UEVENT_GENERATED_FLAG.
 
--- LVM2/libdm/ioctl/libdm-iface.c	2010/03/25 18:22:04	1.69
+++ LVM2/libdm/ioctl/libdm-iface.c	2010/04/07 15:57:20	1.70
@@ -353,13 +353,29 @@
 #endif
 }
 
+static void _dm_zfree_string(char *string)
+{
+	if (string) {
+		memset(string, 0, strlen(string));
+		dm_free(string);
+	}
+}
+
+static void _dm_zfree_dmi(struct dm_ioctl *dmi)
+{
+	if (dmi) {
+		memset(dmi, 0, dmi->data_size);
+		dm_free(dmi);
+	}
+}
+
 void dm_task_destroy(struct dm_task *dmt)
 {
 	struct target *t, *n;
 
 	for (t = dmt->head; t; t = n) {
 		n = t->next;
-		dm_free(t->params);
+		_dm_zfree_string(t->params);
 		dm_free(t->type);
 		dm_free(t);
 	}
@@ -373,8 +389,7 @@
 	if (dmt->message)
 		dm_free(dmt->message);
 
-	if (dmt->dmi.v4)
-		dm_free(dmt->dmi.v4);
+	_dm_zfree_dmi(dmt->dmi.v4);
 
 	if (dmt->uuid)
 		dm_free(dmt->uuid);
@@ -388,6 +403,14 @@
 
 #ifdef DM_COMPAT
 
+static void _dm_zfree_dmi_v1(struct dm_ioctl_v1 *dmi)
+{
+	if (dmi) {
+		memset(dmi, 0, dmi->data_size);
+		dm_free(dmi);
+	}
+}
+
 static int _dm_task_get_driver_version_v1(struct dm_task *dmt, char *version,
 					  size_t size)
 {
@@ -494,13 +517,10 @@
 	struct dm_target_spec_v1 sp;
 	size_t sp_size = sizeof(struct dm_target_spec_v1);
 	int len;
-	const char no_space[] = "Ran out of memory building ioctl parameter";
 
 	out += sp_size;
-	if (out >= end) {
-		log_error(no_space);
-		return NULL;
-	}
+	if (out >= end)
+		return_NULL;
 
 	sp.status = 0;
 	sp.sector_start = t->start;
@@ -509,12 +529,9 @@
 
 	len = strlen(t->params);
 
-	if ((out + len + 1) >= end) {
-		log_error(no_space);
+	if ((out + len + 1) >= end)
+		return_NULL;
 
-		log_error("t->params= '%s'", t->params);
-		return NULL;
-	}
 	strcpy((char *) out, t->params);
 	out += len + 1;
 
@@ -600,8 +617,10 @@
 	e = (void *) ((char *) dmi + len);
 
 	for (t = dmt->head; t; t = t->next)
-		if (!(b = _add_target_v1(t, b, e)))
+		if (!(b = _add_target_v1(t, b, e))) {
+			log_error("Ran out of memory building ioctl parameter");
 			goto bad;
+		}
 
 	if (dmt->newname)
 		strcpy(b, dmt->newname);
@@ -609,7 +628,7 @@
 	return dmi;
 
       bad:
-	dm_free(dmi);
+	_dm_zfree_dmi_v1(dmi);
 	return NULL;
 }
 
@@ -762,7 +781,7 @@
 		dmt->type = DM_DEVICE_INFO;
 		if (!dm_task_run(dmt))
 			goto bad;
-		dm_free(dmi);	/* We'll use what info returned */
+		_dm_zfree_dmi_v1(dmi);	/* We'll use what info returned */
 		return 1;
 	}
 
@@ -770,7 +789,7 @@
 	return 1;
 
       bad:
-	dm_free(dmi);
+	_dm_zfree_dmi_v1(dmi);
 	return 0;
 }
 
@@ -1177,7 +1196,7 @@
 	return t;
 
       bad:
-	dm_free(t->params);
+	_dm_zfree_string(t->params);
 	dm_free(t->type);
 	dm_free(t);
 	return NULL;
@@ -1189,13 +1208,10 @@
 	struct dm_target_spec sp;
 	size_t sp_size = sizeof(struct dm_target_spec);
 	int len;
-	const char no_space[] = "Ran out of memory building ioctl parameter";
 
 	out += sp_size;
-	if (out >= end) {
-		log_error(no_space);
-		return NULL;
-	}
+	if (out >= end)
+		return_NULL;
 
 	sp.status = 0;
 	sp.sector_start = t->start;
@@ -1204,12 +1220,9 @@
 
 	len = strlen(t->params);
 
-	if ((out + len + 1) >= end) {
-		log_error(no_space);
+	if ((out + len + 1) >= end)
+		return_NULL;
 
-		log_error("t->params= '%s'", t->params);
-		return NULL;
-	}
 	strcpy((char *) out, t->params);
 	out += len + 1;
 
@@ -1403,8 +1416,10 @@
 	e = (void *) ((char *) dmi + len);
 
 	for (t = dmt->head; t; t = t->next)
-		if (!(b = _add_target(t, b, e)))
+		if (!(b = _add_target(t, b, e))) {
+			log_error("Ran out of memory building ioctl parameter");
 			goto bad;
+		}
 
 	if (dmt->newname)
 		strcpy(b, dmt->newname);
@@ -1421,7 +1436,7 @@
 	return dmi;
 
       bad:
-	dm_free(dmi);
+	_dm_zfree_dmi(dmi);
 	return NULL;
 }
 
@@ -1782,7 +1797,7 @@
 					  "failed: %s",
 				    	   _cmd_data_v4[dmt->type].name,
 					  strerror(errno));
-			dm_free(dmi);
+			_dm_zfree_dmi(dmi);
 			return NULL;
 		}
 	}
@@ -1853,7 +1868,7 @@
 		case DM_DEVICE_TABLE:
 		case DM_DEVICE_WAITEVENT:
 			_ioctl_buffer_double_factor++;
-			dm_free(dmi);
+			_dm_zfree_dmi(dmi);
 			goto repeat_ioctl;
 		default:
 			log_error("WARNING: libdevmapper buffer too small for data");
@@ -1911,13 +1926,12 @@
 	}
 
 	/* Was structure reused? */
-	if (dmt->dmi.v4)
-		dm_free(dmt->dmi.v4);
+	_dm_zfree_dmi(dmt->dmi.v4);
 	dmt->dmi.v4 = dmi;
 	return 1;
 
       bad:
-	dm_free(dmi);
+	_dm_zfree_dmi(dmi);
 	return 0;
 }
 
--- LVM2/tools/dmsetup.c	2010/03/23 14:43:19	1.136
+++ LVM2/tools/dmsetup.c	2010/04/07 15:57:20	1.137
@@ -266,6 +266,7 @@
 	r = 1;
 
       out:
+	memset(buffer, 0, buffer_size);
 #ifndef HAVE_GETLINE
 	dm_free(buffer);
 #else


^ permalink raw reply	[flat|nested] 3+ messages in thread

* LVM2 ./WHATS_NEW_DM libdm/ioctl/libdm-iface.c  ...
@ 2010-03-23 14:38 prajnoha
  0 siblings, 0 replies; 3+ messages in thread
From: prajnoha @ 2010-03-23 14:38 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	prajnoha@sourceware.org	2010-03-23 14:38:38

Modified files:
	.              : WHATS_NEW_DM 
	libdm/ioctl    : libdm-iface.c 
	libdm/misc     : dm-ioctl.h 

Log message:
	Add support for ioctl's DM_UEVENT_GENERATED_FLAG.
	
	We need to know whether we should wait for any uevent or not when
	using udev_sync. A kernel patch was posted recently that changed the
	way uevents are sent on dm device resume - it is sent only if the
	device has been suspended before. There's also a new DM_UEVENT_GENERATED_FLAG
	in the ioctl to notify userspace whether the event was generated.
	
	If the uevent was not generated (e.g. the situation where the device is
	*not* suspended and we call a resume), we just call dm_udev_complete
	explicitly from within libdevmapper itself to prevent infinite waiting
	while trying to synchronise with udev processing.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW_DM.diff?cvsroot=lvm2&r1=1.350&r2=1.351
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/ioctl/libdm-iface.c.diff?cvsroot=lvm2&r1=1.67&r2=1.68
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/misc/dm-ioctl.h.diff?cvsroot=lvm2&r1=1.3&r2=1.4

--- LVM2/WHATS_NEW_DM	2010/03/09 14:01:47	1.350
+++ LVM2/WHATS_NEW_DM	2010/03/23 14:38:37	1.351
@@ -1,5 +1,6 @@
 Version 1.02.46 - 
 ================================
+  Add support for ioctl's DM_UEVENT_GENERATED_FLAG.
 
 Version 1.02.45 - 9th March 2010
 ================================
--- LVM2/libdm/ioctl/libdm-iface.c	2010/02/15 16:21:34	1.67
+++ LVM2/libdm/ioctl/libdm-iface.c	2010/03/23 14:38:37	1.68
@@ -1505,18 +1505,28 @@
  */
 static int _udev_complete(struct dm_task *dmt)
 {
-	uint32_t cookie;
+	uint16_t base;
 
-	if (dmt->cookie_set) {
+	if (dmt->cookie_set &&
+	    (base = dmt->event_nr & ~DM_UDEV_FLAGS_MASK))
 		/* strip flags from the cookie and use cookie magic instead */
-		cookie = (dmt->event_nr & ~DM_UDEV_FLAGS_MASK) |
-			  (DM_COOKIE_MAGIC << DM_UDEV_FLAGS_SHIFT);
-		return dm_udev_complete(cookie);
-	}
+		return dm_udev_complete(base | (DM_COOKIE_MAGIC <<
+						DM_UDEV_FLAGS_SHIFT));
 
 	return 1;
 }
 
+static int _check_uevent_generated(struct dm_ioctl *dmi)
+{
+	if (!dm_check_version() ||
+	    _dm_version < 4 ||
+	    _dm_version_minor < 17)
+		/* can't check, assume uevent is generated */
+		return 1;
+
+	return dmi->flags & DM_UEVENT_GENERATED_FLAG;
+}
+
 static int _create_and_load_v4(struct dm_task *dmt)
 {
 	struct dm_task *task;
@@ -1691,6 +1701,7 @@
 				     unsigned repeat_count)
 {
 	struct dm_ioctl *dmi;
+	int ioctl_with_uevent;
 
 	dmi = _flatten(dmt, repeat_count);
 	if (!dmi) {
@@ -1706,6 +1717,10 @@
 	if (dmt->no_open_count)
 		dmi->flags |= DM_SKIP_BDGET_FLAG;
 
+	ioctl_with_uevent = dmt->type == DM_DEVICE_RESUME ||
+			    dmt->type == DM_DEVICE_REMOVE ||
+			    dmt->type == DM_DEVICE_RENAME;
+
 	/*
 	 * Prevent udev vs. libdevmapper race when processing nodes and
 	 * symlinks. This can happen when the udev rules are installed and
@@ -1715,10 +1730,7 @@
 	 * to be applied at all in this situation so we can gracefully fallback
 	 * to libdevmapper's node and symlink creation code.
 	 */
-	if (dm_udev_get_sync_support() && !dmt->cookie_set &&
-	    (dmt->type == DM_DEVICE_RESUME ||
-	     dmt->type == DM_DEVICE_REMOVE ||
-	     dmt->type == DM_DEVICE_RENAME)) {
+	if (dm_udev_get_sync_support() && !dmt->cookie_set && ioctl_with_uevent) {
 		log_debug("Cookie value is not set while trying to call "
 			  "DM_DEVICE_RESUME, DM_DEVICE_REMOVE or DM_DEVICE_RENAME "
 			  "ioctl. Please, consider using libdevmapper's udev "
@@ -1774,6 +1786,10 @@
 			return NULL;
 		}
 	}
+
+	if (ioctl_with_uevent && !_check_uevent_generated(dmi))
+		_udev_complete(dmt);
+
 #else /* Userspace alternative for testing */
 #endif
 	return dmi;
--- LVM2/libdm/misc/dm-ioctl.h	2009/11/06 00:43:09	1.3
+++ LVM2/libdm/misc/dm-ioctl.h	2010/03/23 14:38:38	1.4
@@ -268,9 +268,9 @@
 #define DM_DEV_SET_GEOMETRY	_IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 
 #define DM_VERSION_MAJOR	4
-#define DM_VERSION_MINOR	16
+#define DM_VERSION_MINOR	17
 #define DM_VERSION_PATCHLEVEL	0
-#define DM_VERSION_EXTRA	"-ioctl (2009-11-05)"
+#define DM_VERSION_EXTRA	"-ioctl (2010-03-05)"
 
 /* Status bits */
 #define DM_READONLY_FLAG	(1 << 0) /* In/Out */
@@ -318,4 +318,9 @@
  */
 #define DM_QUERY_INACTIVE_TABLE_FLAG	(1 << 12) /* In */
 
+/*
+ * If set, a uevent was generated for which the caller may need to wait.
+ */
+#define DM_UEVENT_GENERATED_FLAG	(1 << 13) /* Out */
+
 #endif				/* _LINUX_DM_IOCTL_H */


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-06-01 16:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-01 16:08 LVM2 ./WHATS_NEW_DM libdm/ioctl/libdm-iface.c prajnoha
  -- strict thread matches above, loose matches on Subject: below --
2010-04-07 15:57 mbroz
2010-03-23 14:38 prajnoha

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 read-only IMAP folder(s) and NNTP newsgroup(s).