diff options
| -rw-r--r-- | TODO | 11 | ||||
| -rw-r--r-- | udev/lib/exported_symbols | 3 | ||||
| -rw-r--r-- | udev/lib/libudev-device.c | 16 | ||||
| -rw-r--r-- | udev/lib/libudev-enumerate.c | 101 | ||||
| -rw-r--r-- | udev/lib/libudev-list.c | 10 | ||||
| -rw-r--r-- | udev/lib/libudev.h | 5 | ||||
| -rw-r--r-- | udev/lib/test-libudev.c | 45 | ||||
| -rw-r--r-- | udev/udevadm-info.c | 4 | 
8 files changed, 146 insertions, 49 deletions
| @@ -1,13 +1,12 @@ -  o enumerate() - add buses and drivers +  o libudev enumerate +      add buses and drivers +      add /sys/block/ scanning crap        use enumerate for "trigger" - -  o add libudev interface for /dev/.udev/queue/ state +  o libudev queue - interface for /dev/.udev/queue/ state        use queue interface for "settle" - -  o use libudev in udev_rules.c +  o use libudev device in udev_rules.c        get rid of udevice, store rule matching state in rule iterator    o rework rules to a match-action list, instead of a rules array -    o add DVB variables to kernel, and drop shell script rule    o add watershed extra    o log warning if the kernel uses CONFIG_SYSFS_DEPRECATED*=y, diff --git a/udev/lib/exported_symbols b/udev/lib/exported_symbols index 8c5f700d46..1877f32e89 100644 --- a/udev/lib/exported_symbols +++ b/udev/lib/exported_symbols @@ -10,6 +10,7 @@ udev_set_userdata  udev_get_sys_path  udev_get_dev_path  udev_list_entry_get_next +udev_list_entry_get_by_name  udev_list_entry_get_name  udev_list_entry_get_value  udev_device_new_from_syspath @@ -30,9 +31,11 @@ udev_device_get_driver  udev_device_get_devnum  udev_device_get_seqnum  udev_device_get_attr_value +udev_enumerate_new_from_devices  udev_enumerate_new_from_subsystems  udev_enumerate_ref  udev_enumerate_unref +udev_enumerate_get_udev  udev_enumerate_get_list_entry  udev_monitor_new_from_socket  udev_monitor_new_from_netlink diff --git a/udev/lib/libudev-device.c b/udev/lib/libudev-device.c index a201fb25df..3437d69798 100644 --- a/udev/lib/libudev-device.c +++ b/udev/lib/libudev-device.c @@ -252,7 +252,7 @@ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *  	subdir = &syspath[len+1];  	pos = strrchr(subdir, '/');  	if (pos == NULL || pos < &subdir[2]) { -		info(udev, "not in subdir :%s\n", syspath); +		info(udev, "not a subdir :%s\n", syspath);  		return NULL;  	} @@ -312,8 +312,11 @@ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, de  	if (util_resolve_sys_link(udev, path, sizeof(path)) == 0)  		return udev_device_new_from_syspath(udev, path); -	/* fallback to search all sys devices for the major/minor */ -	enumerate = udev_enumerate_new_from_subsystems(udev, NULL); +	/* fallback to search sys devices for the major/minor */ +	if (type == 'b') +		enumerate = udev_enumerate_new_from_devices(udev, "block", NULL); +	else if (type == 'c') +		enumerate = udev_enumerate_new_from_devices(udev, "!block", NULL);  	if (enumerate == NULL)  		return NULL;  	udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) { @@ -322,6 +325,13 @@ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, de  		device_loop = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry));  		if (device_loop != NULL) {  			if (udev_device_get_devnum(device_loop) == devnum) { +				const char *subsystem; + +				subsystem = udev_device_get_subsystem(device_loop); +				if (type == 'b' && strcmp(subsystem, "block") != 0) +					continue; +				if (type == 'c' && strcmp(subsystem, "block") == 0) +					continue;  				device = device_loop;  				break;  			} diff --git a/udev/lib/libudev-enumerate.c b/udev/lib/libudev-enumerate.c index 8f5c5640b2..c7fb683c10 100644 --- a/udev/lib/libudev-enumerate.c +++ b/udev/lib/libudev-enumerate.c @@ -54,6 +54,13 @@ void udev_enumerate_unref(struct udev_enumerate *udev_enumerate)  	free(udev_enumerate);  } +struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumerate) +{ +	if (udev_enumerate == NULL) +		return NULL; +	return udev_enumerate->udev; +} +  struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate)  {  	if (udev_enumerate == NULL) @@ -63,7 +70,7 @@ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *ude  static int devices_scan_subsystem(struct udev *udev,  				  const char *basedir, const char *subsystem, const char *subdir, -				  struct list_node *device_list) +				  struct list_node *devices_list)  {  	char path[UTIL_PATH_SIZE];  	DIR *dir; @@ -87,34 +94,44 @@ static int devices_scan_subsystem(struct udev *udev,  		util_strlcat(syspath, "/", sizeof(syspath));  		util_strlcat(syspath, dent->d_name, sizeof(syspath));  		util_resolve_sys_link(udev, syspath, sizeof(syspath)); -		list_entry_add(udev, device_list, syspath, NULL, 1, 1); +		list_entry_add(udev, devices_list, syspath, NULL, 1, 1);  	}  	closedir(dir);  	return 0;  }  static int devices_scan_subsystems(struct udev *udev, -				   const char *basedir, const char *subsystem, const char *subdir, -				   struct list_node *device_list) +				   const char *basedir, const char *subdir, +				   struct udev_list_entry *subsystem_include_list, +				   struct udev_list_entry *subsystem_exclude_list, +				   struct list_node *devices_list)  { -	char path[UTIL_PATH_SIZE]; -	DIR *dir; -	struct dirent *dent; - -	if (subsystem != NULL) -		return devices_scan_subsystem(udev, basedir, subsystem, subdir, device_list); +	if (subsystem_include_list != NULL) { +		struct udev_list_entry *list_entry; -	util_strlcpy(path, udev_get_sys_path(udev), sizeof(path)); -	util_strlcat(path, basedir, sizeof(path)); -	dir = opendir(path); -	if (dir == NULL) -		return -1; -	for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { -		if (dent->d_name[0] == '.') -			continue; -		devices_scan_subsystem(udev, basedir, dent->d_name, subdir, device_list); +		/* if list of subsystems to scan is given, just use this list */ +		udev_list_entry_foreach(list_entry, subsystem_include_list) +			devices_scan_subsystem(udev, basedir, udev_list_entry_get_name(list_entry), subdir, devices_list); +	} else { +		char path[UTIL_PATH_SIZE]; +		DIR *dir; +		struct dirent *dent; + +		/* if no list of subsystems to scan is given, scan all, and possible exclude some subsystems */ +		util_strlcpy(path, udev_get_sys_path(udev), sizeof(path)); +		util_strlcat(path, basedir, sizeof(path)); +		dir = opendir(path); +		if (dir == NULL) +			return -1; +		for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { +			if (dent->d_name[0] == '.') +				continue; +			if (udev_list_entry_get_by_name(subsystem_exclude_list, dent->d_name) != NULL) +					continue; +			devices_scan_subsystem(udev, basedir, dent->d_name, subdir, devices_list); +		} +		closedir(dir);  	} -	closedir(dir);  	return 0;  } @@ -140,17 +157,21 @@ static int devices_delay(struct udev *udev, const char *syspath)  }  /** - * udev_enumerate_new_from_subsystems: + * udev_enumerate_new_from_devices:   * @udev: udev library context - * @subsystem: the subsystem to enumerate + * @subsystem: the list of names of subsystems to look for devices   *   * Returns: an enumeration context   **/ -struct udev_enumerate *udev_enumerate_new_from_subsystems(struct udev *udev, const char *subsystem) +struct udev_enumerate *udev_enumerate_new_from_devices(struct udev *udev, const char *subsystem, ...)  {  	struct udev_enumerate *udev_enumerate; +	va_list vargs; +	const char *arg;  	char base[UTIL_PATH_SIZE];  	struct stat statbuf; +	struct list_node subsystem_include_list; +	struct list_node subsystem_exclude_list;  	struct udev_list_entry *list_entry;  	if (udev == NULL) @@ -164,19 +185,42 @@ struct udev_enumerate *udev_enumerate_new_from_subsystems(struct udev *udev, con  	udev_enumerate->udev = udev;  	list_init(&udev_enumerate->devices_list); +	va_start(vargs, subsystem); +	list_init(&subsystem_include_list); +	list_init(&subsystem_exclude_list); +	for (arg = subsystem; arg != NULL; arg = va_arg(vargs, const char *)) { +		if (arg[0] != '!') +			list_entry_add(udev, &subsystem_include_list, arg, NULL, 1, 0); +		else +			list_entry_add(udev, &subsystem_exclude_list, &arg[1], NULL, 1, 0); +	} +	va_end(vargs); +  	/* if we have /sys/subsystem/, forget all the old stuff */  	util_strlcpy(base, udev_get_sys_path(udev), sizeof(base));  	util_strlcat(base, "/subsystem", sizeof(base));  	if (stat(base, &statbuf) == 0) {  		info(udev, "searching 'subsystem/*/devices/*' dir\n"); -		devices_scan_subsystems(udev, "/subsystem", subsystem, "/devices", &udev_enumerate->devices_list); +		devices_scan_subsystems(udev, "/subsystem", "/devices", +					list_get_entry(&subsystem_include_list), +					list_get_entry(&subsystem_exclude_list), +					&udev_enumerate->devices_list);  	} else {  		info(udev, "searching 'bus/*/devices/*' dir\n"); -		devices_scan_subsystems(udev, "/bus", subsystem, "/devices", &udev_enumerate->devices_list); +		devices_scan_subsystems(udev, "/bus", "/devices", +					list_get_entry(&subsystem_include_list), +					list_get_entry(&subsystem_exclude_list), +					&udev_enumerate->devices_list);  		info(udev, "searching 'class/*' dir\n"); -		devices_scan_subsystems(udev, "/class", subsystem, NULL, &udev_enumerate->devices_list); +		devices_scan_subsystems(udev, "/class", NULL, +					list_get_entry(&subsystem_include_list), +					list_get_entry(&subsystem_exclude_list), +					&udev_enumerate->devices_list);  	} +	list_cleanup(udev, &subsystem_include_list); +	list_cleanup(udev, &subsystem_exclude_list); +  	/* sort delayed devices to the end of the list */  	udev_list_entry_foreach(list_entry, list_get_entry(&udev_enumerate->devices_list)) {  		if (devices_delay(udev, udev_list_entry_get_name(list_entry))) @@ -184,3 +228,8 @@ struct udev_enumerate *udev_enumerate_new_from_subsystems(struct udev *udev, con  	}  	return udev_enumerate;  } + +struct udev_enumerate *udev_enumerate_new_from_subsystems(struct udev *udev) +{ +	return NULL; +} diff --git a/udev/lib/libudev-list.c b/udev/lib/libudev-list.c index 895c665e40..00e3b7c37d 100644 --- a/udev/lib/libudev-list.c +++ b/udev/lib/libudev-list.c @@ -192,6 +192,16 @@ struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_en  	return list_node_to_entry(next);  } +struct udev_list_entry *udev_list_entry_get_by_name(struct udev_list_entry *list_entry, const char *name) +{ +	struct udev_list_entry *entry; + +	udev_list_entry_foreach(entry, list_entry) +		if (strcmp(udev_list_entry_get_name(entry), name) == 0) +			return entry; +	return NULL; +} +  const char *udev_list_entry_get_name(struct udev_list_entry *list_entry)  {  	if (list_entry == NULL) diff --git a/udev/lib/libudev.h b/udev/lib/libudev.h index 25b5f9c02a..29c4a47e51 100644 --- a/udev/lib/libudev.h +++ b/udev/lib/libudev.h @@ -52,6 +52,7 @@ extern void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsign  /* list iteration */  struct udev_list_entry;  extern struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry); +extern struct udev_list_entry *udev_list_entry_get_by_name(struct udev_list_entry *list_entry, const char *name);  extern const char *udev_list_entry_get_name(struct udev_list_entry *list_entry);  extern const char *udev_list_entry_get_value(struct udev_list_entry *list_entry);  #define udev_list_entry_foreach(entry, first) \ @@ -93,8 +94,10 @@ extern struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev  /* sys enumeration */  struct udev_enumerate; -extern struct udev_enumerate *udev_enumerate_new_from_subsystems(struct udev *udev, const char *subsystem); +extern struct udev_enumerate *udev_enumerate_new_from_devices(struct udev *udev, const char *subsystem, ...); +extern struct udev_enumerate *udev_enumerate_new_from_subsystems(struct udev *udev);  extern struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate); +extern struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumerate);  extern void udev_enumerate_unref(struct udev_enumerate *udev_enumerate);  extern struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate); diff --git a/udev/lib/test-libudev.c b/udev/lib/test-libudev.c index bff55cfcd6..0f485248e8 100644 --- a/udev/lib/test-libudev.c +++ b/udev/lib/test-libudev.c @@ -157,20 +157,16 @@ static int test_device_devnum(struct udev *udev)  	return 0;  } -static int test_enumerate(struct udev *udev, const char *subsystem) +static int test_enumerate_print_list(struct udev_enumerate *enumerate)  { -	struct udev_enumerate *enumerate;  	struct udev_list_entry *list_entry;  	int count = 0; -	enumerate = udev_enumerate_new_from_subsystems(udev, NULL); -	if (enumerate == NULL) -		return -1; -	list_entry = udev_enumerate_get_list_entry(enumerate); -	while (list_entry != NULL) { +	udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {  		struct udev_device *device; -		device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry)); +		device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate), +						      udev_list_entry_get_name(list_entry));  		if (device != NULL) {  			printf("device:    '%s' (%s) '%s'\n",  			       udev_device_get_syspath(device), @@ -179,9 +175,7 @@ static int test_enumerate(struct udev *udev, const char *subsystem)  			udev_device_unref(device);  			count++;  		} -		list_entry = udev_list_entry_get_next(list_entry);  	} -	udev_enumerate_unref(enumerate);  	printf("found %i devices\n\n", count);  	return count;  } @@ -248,6 +242,7 @@ int main(int argc, char *argv[], char *envp[])  		{ "version", 0, NULL, 'V' },  		{}  	}; +	struct udev_enumerate *enumerate;  	const char *syspath = "/devices/virtual/mem/null";  	const char *subsystem = NULL;  	const char *socket = "@/org/kernel/udev/monitor"; @@ -309,7 +304,35 @@ int main(int argc, char *argv[], char *envp[])  	test_device(udev, syspath);  	test_device_devnum(udev);  	test_device_parents(udev, syspath); -	test_enumerate(udev, subsystem); + +	printf("enumerate '%s'\n", subsystem == NULL ? "<all>" : subsystem); +	enumerate = udev_enumerate_new_from_devices(udev, subsystem, NULL); +	if (enumerate == NULL) +		return -1; +	test_enumerate_print_list(enumerate); +	udev_enumerate_unref(enumerate); + +	printf("enumerate 'block'\n"); +	enumerate = udev_enumerate_new_from_devices(udev, "block", NULL); +	if (enumerate == NULL) +		return -1; +	test_enumerate_print_list(enumerate); +	udev_enumerate_unref(enumerate); + +	printf("enumerate '!block'\n"); +	enumerate = udev_enumerate_new_from_devices(udev, "!block", NULL); +	if (enumerate == NULL) +		return -1; +	test_enumerate_print_list(enumerate); +	udev_enumerate_unref(enumerate); + +	printf("enumerate 'pci, mem, vc'\n"); +	enumerate = udev_enumerate_new_from_devices(udev, "pci", "mem", "vc", NULL); +	if (enumerate == NULL) +		return -1; +	test_enumerate_print_list(enumerate); +	udev_enumerate_unref(enumerate); +  	test_monitor(udev, socket);  out:  	udev_unref(udev); diff --git a/udev/udevadm-info.c b/udev/udevadm-info.c index f59c196e02..e470ff624d 100644 --- a/udev/udevadm-info.c +++ b/udev/udevadm-info.c @@ -186,7 +186,7 @@ static int export_devices(struct udev *udev)  	struct udev_enumerate *enumerate;  	struct udev_list_entry *list_entry; -	enumerate = udev_enumerate_new_from_subsystems(udev, NULL); +	enumerate = udev_enumerate_new_from_devices(udev, NULL);  	if (enumerate == NULL)  		return -1;  	udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) { @@ -301,7 +301,7 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])  				rc = 2;  				goto exit;  			} -			/* add /sys if needed */ +			/* add sys dir if needed */  			if (strncmp(optarg, udev_get_sys_path(udev), strlen(udev_get_sys_path(udev))) != 0) {  				util_strlcpy(path, udev_get_sys_path(udev), sizeof(path));  				util_strlcat(path, optarg, sizeof(path)); | 
