Exemplo n.º 1
0
/* reverse mapping from the device file name to the devpath */
static int name_index(struct udev *udev, const char *devpath, const char *name, int add, int test)
{
	char device[UTIL_PATH_SIZE];
	char filename[UTIL_PATH_SIZE * 2];
	size_t devlen = strlen(udev_get_dev_path(udev))+1;
	size_t start;
	int fd;

	/* directory with device name */
	util_strlcpy(filename, udev_get_dev_path(udev), sizeof(filename));
	start = util_strlcat(filename, "/.udev/names/", sizeof(filename));
	util_strlcat(filename, &name[devlen], sizeof(filename));
	util_path_encode(&filename[start], sizeof(filename) - start);
	/* entry with the devpath */
	util_strlcpy(device, devpath, sizeof(device));
	util_path_encode(device, sizeof(device));
	util_strlcat(filename, "/", sizeof(filename));
	util_strlcat(filename, device, sizeof(filename));

	if (add) {
		dbg(udev, "creating index: '%s'\n", filename);
		util_create_path(udev, filename);
		fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0644);
		if (fd > 0)
			close(fd);
	} else {
		dbg(udev, "removing index: '%s'\n", filename);
		unlink(filename);
		util_delete_path(udev, filename);
	}
	return 0;
}
Exemplo n.º 2
0
/* manage "stack of names" with possibly specified device priorities */
static void link_update(struct udev_device *dev, const char *slink, bool add)
{
        struct udev *udev = udev_device_get_udev(dev);
        char name_enc[UTIL_PATH_SIZE];
        char filename[UTIL_PATH_SIZE * 2];
        char dirname[UTIL_PATH_SIZE];
        const char *target;
        char buf[UTIL_PATH_SIZE];

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

        util_path_encode(&slink[strlen(udev_get_dev_path(udev))+1], name_enc, sizeof(name_enc));
        util_strscpyl(dirname, sizeof(dirname), udev_get_run_path(udev), "/links/", name_enc, NULL);
        util_strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL);

        if (!add) {
                dbg(udev, "removing index: '%s'\n", filename);
                if (unlink(filename) == 0)
                        rmdir(dirname);
        }

        target = link_find_prioritized(dev, add, dirname, buf, sizeof(buf));
        if (target == NULL) {
                info(udev, "no reference left, remove '%s'\n", slink);
                if (unlink(slink) == 0)
                        util_delete_path(udev, slink);
        } else {
                info(udev, "creating link '%s' to '%s'\n", slink, target);
                node_symlink(udev, target, slink);
        }

        if (add) {
                int err;

                dbg(udev, "creating index: '%s'\n", filename);
                do {
                        int fd;

                        err = util_create_path(udev, filename);
                        if (err != 0 && err != -ENOENT)
                                break;
                        fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444);
                        if (fd >= 0)
                                close(fd);
                        else
                                err = -errno;
                } while (err == -ENOENT);
        }
}
Exemplo n.º 3
0
/* manage "stack of names" with possibly specified device priorities */
static void link_update(struct udev_device *dev, const char *slink, bool add)
{
	struct udev *udev = udev_device_get_udev(dev);
	char name_enc[UTIL_PATH_SIZE];
	char filename[UTIL_PATH_SIZE * 2];
	char dirname[UTIL_PATH_SIZE];
	const char *target;
	char buf[UTIL_PATH_SIZE];

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

	util_path_encode(&slink[strlen(udev_get_dev_path(udev))+1], name_enc, sizeof(name_enc));
	snprintf(dirname, sizeof(dirname), "%s/.udev/links/%s", udev_get_dev_path(udev), name_enc);
	snprintf(filename, sizeof(filename), "%s/%c%u:%u", dirname,
		 strcmp(udev_device_get_subsystem(dev), "block") == 0 ? 'b' : 'c',
		 major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));

	if (!add) {
		dbg(udev, "removing index: '%s'\n", filename);
		unlink(filename);
		util_delete_path(udev, filename);
	}

	target = link_find_prioritized(dev, add, dirname, buf, sizeof(buf));
	if (target == NULL) {
		info(udev, "no reference left, remove '%s'\n", slink);
		unlink(slink);
		util_delete_path(udev, slink);
	} else {
		info(udev, "creating link '%s' to '%s'\n", slink, target);
		node_symlink(udev, target, slink);
	}

	if (add) {
		int err;

		dbg(udev, "creating index: '%s'\n", filename);
		do {
			err = util_create_path(udev, filename);
			if (err != 0 && err != -ENOENT)
				break;
			err = symlink(udev_device_get_devpath(dev), filename);
			if (err != 0)
				err = -errno;
		} while (err == -ENOENT);
	}
}
Exemplo n.º 4
0
/* manage "stack of names" with possibly specified device priorities */
static int link_update(sd_device *dev, const char *slink, bool add) {
        _cleanup_free_ char *target = NULL, *filename = NULL, *dirname = NULL;
        char name_enc[PATH_MAX];
        const char *id_filename;
        int r;

        assert(dev);
        assert(slink);

        r = device_get_id_filename(dev, &id_filename);
        if (r < 0)
                return log_device_debug_errno(dev, r, "Failed to get id_filename: %m");

        util_path_encode(slink + STRLEN("/dev"), name_enc, sizeof(name_enc));
        dirname = path_join("/run/udev/links/", name_enc);
        if (!dirname)
                return log_oom();
        filename = path_join(dirname, id_filename);
        if (!filename)
                return log_oom();

        if (!add && unlink(filename) == 0)
                (void) rmdir(dirname);

        r = link_find_prioritized(dev, add, dirname, &target);
        if (r < 0) {
                log_device_debug(dev, "No reference left, removing '%s'", slink);
                if (unlink(slink) == 0)
                        (void) rmdir_parents(slink, "/");
        } else
                (void) node_symlink(dev, target, slink);

        if (add)
                do {
                        _cleanup_close_ int fd = -1;

                        r = mkdir_parents(filename, 0755);
                        if (!IN_SET(r, 0, -ENOENT))
                                break;
                        fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444);
                        if (fd < 0)
                                r = -errno;
                } while (r == -ENOENT);

        return r;
}
Exemplo n.º 5
0
/* manage "stack of names" with possibly specified device priorities */
static void link_update(struct udev_device *dev, const char *slink, bool add)
{
        struct udev *udev = udev_device_get_udev(dev);
        char name_enc[UTIL_PATH_SIZE];
        char filename[UTIL_PATH_SIZE * 2];
        char dirname[UTIL_PATH_SIZE];
        const char *target;
        char buf[UTIL_PATH_SIZE];

        util_path_encode(slink + strlen("/dev"), name_enc, sizeof(name_enc));
        strscpyl(dirname, sizeof(dirname), "/run/udev/links/", name_enc, NULL);
        strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL);

        if (!add && unlink(filename) == 0)
                rmdir(dirname);

        target = link_find_prioritized(dev, add, dirname, buf, sizeof(buf));
        if (target == NULL) {
                log_debug("no reference left, remove '%s'", slink);
                if (unlink(slink) == 0)
                        util_delete_path(udev, slink);
        } else {
                log_debug("creating link '%s' to '%s'", slink, target);
                node_symlink(dev, target, slink);
        }

        if (add) {
                int err;

                do {
                        int fd;

                        err = mkdir_parents(filename, 0755);
                        if (err != 0 && err != -ENOENT)
                                break;
                        fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444);
                        if (fd >= 0)
                                close(fd);
                        else
                                err = -errno;
                } while (err == -ENOENT);
        }
}
Exemplo n.º 6
0
static int name_index_get_devices(struct udev *udev, const char *name, struct udev_list_node *dev_list)
{
	char dirname[PATH_MAX];
	size_t devlen = strlen(udev_get_dev_path(udev))+1;
	size_t start;
	DIR *dir;
	int count = 0;

	util_strlcpy(dirname, udev_get_dev_path(udev), sizeof(dirname));
	start = util_strlcat(dirname, "/.udev/names/", sizeof(dirname));
	util_strlcat(dirname, &name[devlen], sizeof(dirname));
	util_path_encode(&dirname[start], sizeof(dirname) - start);
	dir = opendir(dirname);
	if (dir == NULL) {
		dbg(udev, "no index directory '%s': %m\n", dirname);
		count = -1;
		goto out;
	}
	dbg(udev, "found index directory '%s'\n", dirname);

	while (1) {
		struct dirent *ent;
		char device[UTIL_PATH_SIZE];

		ent = readdir(dir);
		if (ent == NULL || ent->d_name[0] == '\0')
			break;
		if (ent->d_name[0] == '.')
			continue;

		util_strlcpy(device, udev_get_sys_path(udev), sizeof(device));
		util_strlcat(device, ent->d_name, sizeof(device));
		util_path_decode(device);
		udev_list_entry_add(udev, dev_list, device, NULL, 1, 0);
		count++;
	}
	closedir(dir);
out:
	return count;
}
Exemplo n.º 7
0
static int builtin_firmware(struct udev_device *dev, int argc, char *argv[], bool test)
{
        struct udev *udev = udev_device_get_udev(dev);
        static const char *searchpath[] = { FIRMWARE_PATH };
        char fwencpath[UTIL_PATH_SIZE];
        char misspath[UTIL_PATH_SIZE];
        char loadpath[UTIL_PATH_SIZE];
        char datapath[UTIL_PATH_SIZE];
        char fwpath[UTIL_PATH_SIZE];
        const char *firmware;
        FILE *fwfile = NULL;
        struct utsname kernel;
        struct stat statbuf;
        unsigned int i;
        int rc = EXIT_SUCCESS;

        firmware = udev_device_get_property_value(dev, "FIRMWARE");
        if (firmware == NULL) {
                log_error("firmware parameter missing\n\n");
                rc = EXIT_FAILURE;
                goto exit;
        }

        /* lookup firmware file */
        uname(&kernel);
        for (i = 0; i < ELEMENTSOF(searchpath); i++) {
                util_strscpyl(fwpath, sizeof(fwpath), searchpath[i], kernel.release, "/", firmware, NULL);
                fwfile = fopen(fwpath, "re");
                if (fwfile != NULL)
                        break;

                util_strscpyl(fwpath, sizeof(fwpath), searchpath[i], firmware, NULL);
                fwfile = fopen(fwpath, "re");
                if (fwfile != NULL)
                        break;
        }

        util_path_encode(firmware, fwencpath, sizeof(fwencpath));
        util_strscpyl(misspath, sizeof(misspath), "/run/udev/firmware-missing/", fwencpath, NULL);
        util_strscpyl(loadpath, sizeof(loadpath), udev_device_get_syspath(dev), "/loading", NULL);

        if (fwfile == NULL) {
                int err;

                /* This link indicates the missing firmware file and the associated device */
                log_debug("did not find firmware file '%s'\n", firmware);
                do {
                        err = mkdir_parents(misspath, 0755);
                        if (err != 0 && err != -ENOENT)
                                break;
                        err = symlink(udev_device_get_devpath(dev), misspath);
                        if (err != 0)
                                err = -errno;
                } while (err == -ENOENT);
                rc = EXIT_FAILURE;
                /*
                 * Do not cancel the request in the initrd, the real root might have
                 * the firmware file and the 'coldplug' run in the real root will find
                 * this pending request and fulfill or cancel it.
                 * */
                if (!in_initrd())
                        set_loading(udev, loadpath, "-1");
                goto exit;
        }

        if (stat(fwpath, &statbuf) < 0 || statbuf.st_size == 0) {
                if (!in_initrd())
                        set_loading(udev, loadpath, "-1");
                rc = EXIT_FAILURE;
                goto exit;
        }

        if (unlink(misspath) == 0)
                util_delete_path(udev, misspath);

        if (!set_loading(udev, loadpath, "1"))
                goto exit;

        util_strscpyl(datapath, sizeof(datapath), udev_device_get_syspath(dev), "/data", NULL);
        if (!copy_firmware(udev, fwpath, datapath, statbuf.st_size)) {
                log_error("error sending firmware '%s' to device\n", firmware);
                set_loading(udev, loadpath, "-1");
                rc = EXIT_FAILURE;
                goto exit;
        };

        set_loading(udev, loadpath, "0");
exit:
        if (fwfile)
                fclose(fwfile);
        return rc;
}