udev_db.c revision 726687ad48bdececed1e7e44387c50e009e28208
c343be283b7152554bac0c02493a4e1759c163f7Kay Sievers * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
b3ae710c251d0ce5cf2cef63208e325497b5e323Zbigniew Jędrzejewski-Szmek * Copyright (C) 2004-2005 Kay Sievers <kay.sievers@vrfy.org>
f957632b960a0a42999b38ded7089fa602b41745Kay Sievers * This program is free software; you can redistribute it and/or modify it
f957632b960a0a42999b38ded7089fa602b41745Kay Sievers * under the terms of the GNU General Public License as published by the
f957632b960a0a42999b38ded7089fa602b41745Kay Sievers * Free Software Foundation version 2 of the License.
8adaf7bd23baa6e2cd99e9e88e55d0f5f5db29a2Richard Maw * This program is distributed in the hope that it will be useful, but
d19e85f0d474ed1882561b458d528cbae49f640eZbigniew Jędrzejewski-Szmek * WITHOUT ANY WARRANTY; without even the implied warranty of
d19e85f0d474ed1882561b458d528cbae49f640eZbigniew Jędrzejewski-Szmek * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d19e85f0d474ed1882561b458d528cbae49f640eZbigniew Jędrzejewski-Szmek * General Public License for more details.
d19e85f0d474ed1882561b458d528cbae49f640eZbigniew Jędrzejewski-Szmek * You should have received a copy of the GNU General Public License along
3e495a6651609d0a45b62aab5c3ed5a3b40e11abZbigniew Jędrzejewski-Szmek * with this program; if not, write to the Free Software Foundation, Inc.,
3e495a6651609d0a45b62aab5c3ed5a3b40e11abZbigniew Jędrzejewski-Szmek * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
fd6c2363af2cb144bb6a7d6b8bdba9f777440078Lennart Poetteringstatic size_t devpath_to_db_path(const char *devpath, char *filename, size_t len)
3efc8c72f02423ece08b5c4d5c812420092cc10aLennart Poettering /* translate to location of db file */
3efc8c72f02423ece08b5c4d5c812420092cc10aLennart Poettering start = strlcat(filename, "/"DB_DIR"/", len);
42718282f5b545684ca1a4e3fd71f8c593d15f97Lennart Poettering return path_encode(&filename[start], len - start);
03364e472bccf64544e3a0d36d09f90c78f9f699Lennart Poettering/* reverse mapping from the device file name to the devpath */
03364e472bccf64544e3a0d36d09f90c78f9f699Lennart Poetteringstatic int name_index(const char *devpath, const char *name, int add)
e6a26d8c972d45a0927ad0b7c654c830daa2243eLennart Poettering /* directory with device name */
e6a26d8c972d45a0927ad0b7c654c830daa2243eLennart Poettering strlcpy(filename, udev_root, sizeof(filename));
e6a26d8c972d45a0927ad0b7c654c830daa2243eLennart Poettering start = strlcat(filename, "/"DB_NAME_INDEX_DIR"/", sizeof(filename));
e6a26d8c972d45a0927ad0b7c654c830daa2243eLennart Poettering strlcat(filename, name, sizeof(filename));
e6a26d8c972d45a0927ad0b7c654c830daa2243eLennart Poettering path_encode(&filename[start], sizeof(filename) - start);
1361205099406d2a19d64547448638a6b665af81Lennart Poettering /* entry with the devpath */
1361205099406d2a19d64547448638a6b665af81Lennart Poettering strlcpy(device, devpath, sizeof(device));
a2088fd025deb90839c909829e27eece40f7fce4Lennart Poettering strlcat(filename, "/", sizeof(filename));
a2088fd025deb90839c909829e27eece40f7fce4Lennart Poettering strlcat(filename, device, sizeof(filename));
a2088fd025deb90839c909829e27eece40f7fce4Lennart Poettering info("creating index: '%s'\n", filename);
c874ef05a705d3c679e5fd5a50b81e1f5512c4fdLennart Poettering fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0644);
affb71da79b0c3cbcd6ff6c0cedb218a14162c7cLennart Poettering info("removing index: '%s'\n", filename);
de587378ea5d22e11373b18b4fcabf8f26f89529Lennart Poetteringint udev_db_get_devices_by_name(const char *name, struct list_head *name_list)
c2570ab99be82eddbee0f397fbf8704a95f6f736Lennart Poettering strlcpy(dirname, udev_root, sizeof(dirname));
c2570ab99be82eddbee0f397fbf8704a95f6f736Lennart Poettering start = strlcat(dirname, "/"DB_NAME_INDEX_DIR"/", sizeof(dirname));
c2570ab99be82eddbee0f397fbf8704a95f6f736Lennart Poettering path_encode(&dirname[start], sizeof(dirname) - start);
c2570ab99be82eddbee0f397fbf8704a95f6f736Lennart Poettering info("no index directory '%s': %s\n", dirname, strerror(errno));
e7e90a8eee056fd12c8ad83470143f7798240dbcLennart Poettering info("found index directory '%s'\n", dirname);
d72bc5973465018e077fcecdcc720840bc1e9cfdLennart Poettering if (ent == NULL || ent->d_name[0] == '\0')
d72bc5973465018e077fcecdcc720840bc1e9cfdLennart Poettering strlcpy(device, ent->d_name, sizeof(device));
c2570ab99be82eddbee0f397fbf8704a95f6f736Lennart Poetteringint udev_db_rename(const char *devpath_old, const char *devpath)
17978b17d9f5d3591f1c644938efc9c27aa60485Lennart Poettering devpath_to_db_path(devpath_old, filename_old, sizeof(filename_old));
17978b17d9f5d3591f1c644938efc9c27aa60485Lennart Poettering devpath_to_db_path(devpath, filename, sizeof(filename));
48e6d6a6e911af0cf4e3ef12b0a3eeb2c8031d8aLennart Poetteringint udev_db_add_device(struct udevice *udev)
449a22a58f0fa55d9d0fd2eb597272446e032acdLennart Poettering devpath_to_db_path(udev->dev->devpath, filename, sizeof(filename));
60d17b74d714fa15d68639062dc2932d7b096229Lennart Poettering * don't waste tmpfs memory pages, if we don't have any data to store
60d17b74d714fa15d68639062dc2932d7b096229Lennart Poettering * create fake db-file; store the node-name in a symlink target
2f653bded321fc2271edcda43d54fcc3e6c20dc9Lennart Poettering if (list_empty(&udev->symlink_list) && list_empty(&udev->env_list) &&
2f653bded321fc2271edcda43d54fcc3e6c20dc9Lennart Poettering !udev->partitions && !udev->ignore_remove) {
ac749874bbb66c0e7eff15ca35d1616d29b6f3c1Lennart Poettering dbg("nothing interesting to store, create symlink\n");
ac749874bbb66c0e7eff15ca35d1616d29b6f3c1Lennart Poettering selinux_setfscreatecon(filename, NULL, S_IFLNK);
e342b74468870f2e4f3e15f7277a0adea42183caZbigniew Jędrzejewski-Szmek ret = symlink(udev->name, filename);
036a4773ffa1152e4cabd27473450b8cc01e019bLennart Poettering err("unable to create db link '%s': %s\n", filename, strerror(errno));
f93b36affa5ac5710cd84bfb8ff0dafabe99fbf1Lennart Poettering err("unable to create db file '%s': %s\n", filename, strerror(errno));
20760dcf5df7e253c21a51886cdb02dee612730bLennart Poettering dbg("storing data for device '%s' in '%s'\n", udev->dev->devpath, filename);
df22b0bbfde403b3fa71f3c2f1e2ca38af946388Lennart Poettering list_for_each_entry(name_loop, &udev->symlink_list, node) {
df22b0bbfde403b3fa71f3c2f1e2ca38af946388Lennart Poettering /* add symlink-name to index */
df22b0bbfde403b3fa71f3c2f1e2ca38af946388Lennart Poettering name_index(udev->dev->devpath, name_loop->name, 1);
73cb77549536deab85d8d1261b5381e87d80ab23Lennart Poettering fprintf(f, "M:%u:%u\n", major(udev->devt), minor(udev->devt));
477e75ef9ea6bb2e7e8cc76278c442942110f227Lennart Poettering fprintf(f, "L:%u\n", udev->link_priority);
477e75ef9ea6bb2e7e8cc76278c442942110f227Lennart Poettering fprintf(f, "T:%u\n", udev->event_timeout);
7dfb0404b3b6882d582a571f61a52b2f56961675Lennart Poettering fprintf(f, "R:%u\n", udev->ignore_remove);
7dfb0404b3b6882d582a571f61a52b2f56961675Lennart Poettering list_for_each_entry(name_loop, &udev->env_list, node)
2bc39683c0cada86c9dc39e5f3d0ea475cf12e57Lennart Poettering /* add name to index */
2bc39683c0cada86c9dc39e5f3d0ea475cf12e57Lennart Poettering name_index(udev->dev->devpath, udev->name, 1);
63b20d5c0fa61e3aa8235de269161d0ee877ebccMichal Sekletarint udev_db_get_device(struct udevice *udev, const char *devpath)
7687f85ea6bab434324bb985e2898bf6373891bfLennart Poettering sysfs_device_set_values(udev->dev, devpath, NULL, NULL);
7687f85ea6bab434324bb985e2898bf6373891bfLennart Poettering devpath_to_db_path(devpath, filename, sizeof(filename));
c14db9b32ab90738973071d31f259d1a457d7b4aLennart Poettering info("no db file to read %s: %s\n", filename, strerror(errno));
fa607802f332e06f4044c3eb38dbea41076c803dLennart Poettering if ((stats.st_mode & S_IFMT) == S_IFLNK) {
c3a0d00d6dd6f5997d673e133ef6f9f856550b0aLennart Poettering target_len = readlink(filename, target, sizeof(target));
c3a0d00d6dd6f5997d673e133ef6f9f856550b0aLennart Poettering info("error reading db link %s: %s\n", filename, strerror(errno));
de146bb2aac13361ade3050d37696499ac4ca9aeLennart Poettering strlcpy(udev->name, target, sizeof(udev->name));
82e6c50c473f4be8df77c7a510577f1975eedddbLennart Poettering if (file_map(filename, &buf, &bufsize) != 0) {
d2f81fb00cc3c49e21b31000ba7d37b81a260257Lennart Poettering info("error reading db file %s: %s\n", filename, strerror(errno));
0a86c1a9d8066267b878dfeddc5e0087dda6a37bLennart Poettering strlcpy(udev->name, line, sizeof(udev->name));
e3286870fdf20c3c93e944b24fd9af53620f7dbaLennart Poettering name_list_add(&udev->symlink_list, line, 0);
8483d73ff158ee0d51ccbba09a470cc6ae9b071aLennart Poetteringint udev_db_delete_device(struct udevice *udev)
384a4be2b00cb95ce215dd343cc9aa77adc9b1ecLennart Poettering devpath_to_db_path(udev->dev->devpath, filename, sizeof(filename));
706d97503df83d141d241b645d2c920d691b3d62Lennart Poettering name_index(udev->dev->devpath, udev->name, 0);
3bcde97e8502c48b53f7420e2433ca68e601662dLennart Poettering list_for_each_entry(name_loop, &udev->symlink_list, node)
3bcde97e8502c48b53f7420e2433ca68e601662dLennart Poettering name_index(udev->dev->devpath, name_loop->name, 0);
b42de08aa4c97636e42c28c7bce08f0d7c2a719aZbigniew Jędrzejewski-Szmekint udev_db_get_all_entries(struct list_head *name_list)
42aeb14a4a0fa7d43da96a8ed0fb0e180a2dd5c8Lennart Poettering strlcpy(dbpath, udev_root, sizeof(dbpath));
42aeb14a4a0fa7d43da96a8ed0fb0e180a2dd5c8Lennart Poettering strlcat(dbpath, "/"DB_DIR, sizeof(dbpath));
6868560773ada8ea31d1f86422be6bf026a1f660Richard Maw info("no udev_db available '%s': %s\n", dbpath, strerror(errno));