예제 #1
0
파일: libudev.c 프로젝트: StarchLinux/udev
/**
 * udev_unref:
 * @udev: udev library context
 *
 * Drop a reference of the udev library context. If the refcount
 * reaches zero, the resources of the context will be released.
 *
 **/
void udev_unref(struct udev *udev)
{
	if (udev == NULL)
		return;
	udev->refcount--;
	if (udev->refcount > 0)
		return;
	udev_list_cleanup_entries(udev, &udev->properties_list);
	free(udev->dev_path);
	free(udev->sys_path);
	free(udev->rules_path);
	dbg(udev, "context %p released\n", udev);
	free(udev);
}
예제 #2
0
파일: udev-node.c 프로젝트: OPSF/uClinux
static int update_link(struct udev_device *dev, const char *slink, int test)
{
	struct udev *udev = udev_device_get_udev(dev);
	struct udev_list_node dev_list;
	struct udev_list_entry *dev_entry;
	char target[UTIL_PATH_SIZE];
	int count;
	int priority = 0;
	int rc = 0;

	dbg(udev, "update symlink '%s' of '%s'\n", slink, udev_device_get_syspath(dev));

	udev_list_init(&dev_list);
	count = name_index_get_devices(udev, slink, &dev_list);
	if (count > 1)
		info(udev, "found %i devices with name '%s'\n", count, slink);

	/* if we don't have a reference, delete it */
	if (count <= 0) {
		info(udev, "no reference left, remove '%s'\n", slink);
		if (!test) {
			unlink(slink);
			util_delete_path(udev, slink);
		}
		goto out;
	}

	/* find the device with the highest priority */
	target[0] = '\0';
	udev_list_entry_foreach(dev_entry, udev_list_get_entry(&dev_list)) {
		const char *syspath;
		struct udev_device *dev_db;
		const char *devnode;

		syspath = udev_list_entry_get_name(dev_entry);
		dbg(udev, "found '%s' for '%s'\n", syspath, slink);

		/* did we find ourself? we win, if we have the same priority */
		if (strcmp(udev_device_get_syspath(dev), syspath) == 0) {
			dbg(udev, "compare (our own) priority of '%s' %i >= %i\n",
			    udev_device_get_devpath(dev), udev_device_get_devlink_priority(dev), priority);
			if (strcmp(udev_device_get_devnode(dev), slink) == 0) {
				info(udev, "'%s' is our device node, database inconsistent, skip link update\n",
				     udev_device_get_devnode(dev));
			} else if (target[0] == '\0' || udev_device_get_devlink_priority(dev) >= priority) {
				priority = udev_device_get_devlink_priority(dev);
				util_strlcpy(target, udev_device_get_devnode(dev), sizeof(target));
			}
			continue;
		}

		/* another device, read priority from database */
		dev_db = udev_device_new_from_syspath(udev, syspath);
		if (dev_db == NULL)
			continue;
		devnode = udev_device_get_devnode(dev_db);
		if (devnode != NULL) {
			if (strcmp(devnode, slink) == 0) {
				info(udev, "'%s' is a device node of '%s', skip link update\n",
				     devnode, syspath);
			} else {
				dbg(udev, "compare priority of '%s' %i > %i\n",
				    udev_device_get_devpath(dev_db),
				    udev_device_get_devlink_priority(dev_db),
				    priority);
				if (target[0] == '\0' || udev_device_get_devlink_priority(dev_db) > priority) {
					priority = udev_device_get_devlink_priority(dev_db);
					util_strlcpy(target, devnode, sizeof(target));
				}
			}
		}
		udev_device_unref(dev_db);
	}
	udev_list_cleanup_entries(udev, &dev_list);

	if (target[0] == '\0') {
		info(udev, "no current target for '%s' found\n", slink);
		rc = 1;
		goto out;
	}

	/* create symlink to the target with the highest priority */
	info(udev, "'%s' with target '%s' has the highest priority %i, create it\n", slink, target, priority);
	if (!test) {
		util_create_path(udev, slink);
		node_symlink(udev, target, slink);
	}
out:
	return rc;
}