diff options
-rw-r--r-- | udev-add.c | 57 | ||||
-rw-r--r-- | udev-remove.c | 12 | ||||
-rw-r--r-- | udev.h | 15 | ||||
-rw-r--r-- | udevdb.c | 335 | ||||
-rw-r--r-- | udevdb.h | 25 |
5 files changed, 96 insertions, 348 deletions
diff --git a/udev-add.c b/udev-add.c index 85bcbf6c18..7906638a7f 100644 --- a/udev-add.c +++ b/udev-add.c @@ -70,33 +70,37 @@ exit: /* * We also want to add some permissions here, and possibly some symlinks */ -static int create_node(char *name, char type, int major, int minor, mode_t mode) +static int create_node(struct udevice *dev) { char filename[255]; int retval = 0; + strncpy(filename, UDEV_ROOT, sizeof(filename)); - strncat(filename, name, sizeof(filename)); - switch (type) { + strncat(filename, dev->name, sizeof(filename)); + + switch (dev->type) { case 'b': - mode |= S_IFBLK; + dev->mode |= S_IFBLK; break; case 'c': case 'u': - mode |= S_IFCHR; + dev->mode |= S_IFCHR; break; case 'p': - mode |= S_IFIFO; + dev->mode |= S_IFIFO; break; default: - dbg("unknown node type %c\n", type); + dbg("unknown node type %c\n", dev->type); return -EINVAL; } - dbg("mknod(%s, %#o, %u, %u)", filename, mode, major, minor); - retval = mknod(filename, mode, makedev(major, minor)); + dbg("mknod(%s, %#o, %u, %u)", filename, dev->mode, dev->major, dev->minor); + retval = mknod(filename, dev->mode, makedev(dev->major, dev->minor)); if (retval) dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", - filename, mode, major, minor, strerror(errno)); + filename, dev->mode, dev->major, dev->minor, strerror(errno)); + + // FIXME set the ownership of the node return retval; } @@ -126,7 +130,7 @@ exit: * If it doesn't happen in about 10 seconds, give up. */ #define SECONDS_TO_WAIT_FOR_DEV 10 -int sleep_for_dev(char *device) +int sleep_for_dev(char *path) { char filename[SYSFS_PATH_MAX + 6]; struct stat buf; @@ -134,7 +138,7 @@ int sleep_for_dev(char *device) int retval = -ENODEV; strcpy(filename, sysfs_path); - strcat(filename, device); + strcat(filename, path); strcat(filename, "/dev"); while (loop < SECONDS_TO_WAIT_FOR_DEV) { @@ -154,20 +158,18 @@ exit: return retval; } -int udev_add_device(char *device, char *subsystem) +int udev_add_device(char *path, char *subsystem) { struct sysfs_class_device *class_dev; + struct udevice dev; struct device_attr attr; - int major; - int minor; - char type; int retval = -EINVAL; /* for now, the block layer is the only place where block devices are */ if (strcmp(subsystem, "block") == 0) - type = 'b'; + dev.type = 'b'; else - type = 'c'; + dev.type = 'c'; retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); dbg("sysfs_path = %s", sysfs_path); @@ -176,11 +178,11 @@ int udev_add_device(char *device, char *subsystem) goto exit; } - retval = sleep_for_dev(device); + retval = sleep_for_dev(path); if (retval) goto exit; - class_dev = get_class_dev(device); + class_dev = get_class_dev(path); if (class_dev == NULL) goto exit; @@ -188,21 +190,26 @@ int udev_add_device(char *device, char *subsystem) if (retval) return retval; - retval = get_major_minor(class_dev, &major, &minor); + retval = get_major_minor(class_dev, &dev.major, &dev.minor); if (retval) { dbg("get_major_minor failed"); goto exit; } - retval = udevdb_add_device(device, class_dev, attr.name, type, major, minor, attr.mode); - + strcpy(dev.name, attr.name); + strcpy(dev.owner, attr.owner); + strcpy(dev.group, attr.group); + dev.mode = attr.mode; + + retval = udevdb_add_dev(path, &dev); if (retval != 0) - dbg("udevdb_add_device failed, but we are going to try to create the node anyway. " + dbg("udevdb_add_dev failed, but we are going to try to create the node anyway. " "But remove might not work properly for this device."); sysfs_close_class_device(class_dev); - return create_node(attr.name, type, major, minor, attr.mode); + dbg("name = %s", dev.name); + retval = create_node(&dev); exit: return retval; diff --git a/udev-remove.c b/udev-remove.c index 430f1c901e..c61a948fa0 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -40,15 +40,20 @@ * something different from the kernel name. If we have, us it. If not, use * the default kernel name for lack of anything else to know to do. */ -static char *get_name(char *dev, int major, int minor) +static char *get_name(char *path, int major, int minor) { static char name[100]; + struct udevice *dev; char *temp; - if (udevdb_get_dev(dev, &name[0], sizeof(name)) == 0) + dev = udevdb_get_dev(path); + if (dev != NULL) { + strcpy(name, dev->name); goto exit; + } - temp = strrchr(dev, '/'); + dbg("%s not found in database, falling back on default name", path); + temp = strrchr(path, '/'); if (temp == NULL) return NULL; strncpy(name, &temp[1], sizeof(name)); @@ -84,7 +89,6 @@ int udev_remove_device(char *device, char *subsystem) goto exit; } - udevdb_delete_udevice(name); udevdb_delete_dev(device); return delete_node(name); @@ -23,6 +23,7 @@ #ifndef UDEV_H #define UDEV_H +#include "libsysfs/libsysfs.h" #ifdef DEBUG #include <syslog.h> @@ -62,8 +63,18 @@ struct device_attr { mode_t mode; }; -extern int udev_add_device(char *device, char *subsystem); -extern int udev_remove_device(char *device, char *subsystem); +struct udevice { + char name[NAME_SIZE]; + char owner[OWNER_SIZE]; + char group[GROUP_SIZE]; + char type; + int major; + int minor; + mode_t mode; +}; + +extern int udev_add_device(char *path, char *subsystem); +extern int udev_remove_device(char *path, char *subsystem); extern char **main_argv; extern char **main_envp; @@ -41,212 +41,58 @@ static TDB_CONTEXT *udevdb; -struct sysfsdb_record { - char name[PATH_SIZE]; -}; -/** - * namedb_record - device name is key, remaining udevice info stored here. - */ -struct namedb_record { - char sysfs_dev_path[PATH_SIZE]; - char class_dev_name[NAME_SIZE]; - char class_name[NAME_SIZE]; - char id[ID_SIZE]; - char type; - int major; - int minor; - mode_t mode; -}; - -/** - * udevdb_close: close udev database - */ -static void udevdb_close(void) -{ - if (udevdb != NULL) { - tdb_close(udevdb); - udevdb = NULL; - } -} - -/** - * udevdb_open: opens udev's database - * @method: database can either be in memory - UDEVDB_INTERNAL - or - * written to a file with UDEVDB_DEFAULT. - */ -static int udevdb_open(int method) -{ - udevdb = tdb_open(UDEV_CONFIG_DIR UDEV_DB, 0, method, O_RDWR | O_CREAT, 0644); - if (udevdb == NULL) { - if (method == UDEVDB_INTERNAL) - dbg("Unable to initialize in-memory database"); - else - dbg("Unable to initialize database at %s", UDEV_CONFIG_DIR UDEV_DB); - return -EINVAL; - } - return 0; -} - -static struct sysfsdb_record *sysfsdb_fetch(const char *path) +int udevdb_add_dev(const char *path, const struct udevice *dev) { TDB_DATA key, data; - char keystr[PATH_SIZE+2]; - struct sysfsdb_record *rec = NULL; + char keystr[SYSFS_PATH_MAX]; - if (strlen(path) >= PATH_SIZE) - return NULL; + if ((path == NULL) || (dev == NULL)) + return -ENODEV; - memset(keystr, 0, sizeof(keystr)); + memset(keystr, 0, NAME_SIZE); strcpy(keystr, path); - - dbg("keystr = %s", keystr); - - key.dptr = (void *)keystr; + key.dptr = keystr; key.dsize = strlen(keystr) + 1; - - data = tdb_fetch(udevdb, key); - if (data.dptr == NULL || data.dsize == 0) { - dbg("tdb_fetch did not work :("); - return NULL; - } - rec = (struct sysfsdb_record *)malloc(sizeof(struct sysfsdb_record)); - if (rec == NULL) { - free(data.dptr); - return NULL; - } + data.dptr = (void *)dev; + data.dsize = sizeof(*dev); - memcpy(rec, data.dptr, sizeof(struct sysfsdb_record)); - free(data.dptr); - - return rec; + return tdb_store(udevdb, key, data, TDB_REPLACE); } -/** - * namedb_fetch - */ -static struct namedb_record *namedb_fetch(const char *name) +struct udevice *udevdb_get_dev(const char *path) { TDB_DATA key, data; - char nm_keystr[NAME_SIZE]; - struct namedb_record *nrec = NULL; + struct udevice *dev; - if (name == NULL) - return NULL; - if (strlen(name) >= NAME_SIZE) + if (path == NULL) return NULL; - memset(nm_keystr, 0, NAME_SIZE); - strcpy(nm_keystr, name); - - key.dptr = (void *)nm_keystr; - key.dsize = strlen(nm_keystr) + 1; + key.dptr = (void *)path; + key.dsize = strlen(path) + 1; data = tdb_fetch(udevdb, key); if (data.dptr == NULL || data.dsize == 0) return NULL; - nrec = (struct namedb_record *)malloc(sizeof(struct namedb_record)); - if (nrec == NULL) { - free(data.dptr); - return NULL; - } - - memcpy(nrec, data.dptr, sizeof(struct namedb_record)); - free(data.dptr); - - return nrec; -} - -static int sysfs_store(const char *path, const struct udevice *dev) -{ - TDB_DATA key, data; - char keystr[PATH_SIZE+2]; - struct sysfsdb_record rec; - int retval = 0; - - if (dev == NULL) - return -ENODEV; - - memset(keystr, 0, sizeof(keystr)); - strcpy(keystr, path); - - key.dptr = (void *)keystr; - key.dsize = strlen(keystr) + 1; - - strcpy(rec.name, dev->name); - - data.dptr = (void *) &rec; - data.dsize = sizeof(rec); - - retval = tdb_store(udevdb, key, data, TDB_REPLACE); - return retval; -} - -/** - * namedb_store - */ -static int namedb_store(const struct udevice *dev) -{ - TDB_DATA key, data; - char keystr[NAME_SIZE]; - struct namedb_record rec; - int retval = 0; - + dev = malloc(sizeof(*dev)); if (dev == NULL) - return -1; - - memset(keystr, 0, NAME_SIZE); - strcpy(keystr, dev->name); - - key.dptr = (void *)keystr; - key.dsize = strlen(keystr) + 1; - - strcpy(rec.sysfs_dev_path, dev->sysfs_dev_path); - strcpy(rec.id, dev->bus_id); - strcpy(rec.class_dev_name, dev->class_dev_name); - strcpy(rec.class_name, dev->class_name); - rec.type = dev->type; - rec.major = dev->major; - rec.minor = dev->minor; - rec.mode = dev->mode; - - data.dptr = (void *) &rec; - data.dsize = sizeof(rec); + goto exit; - retval = tdb_store(udevdb, key, data, TDB_REPLACE); - return retval; + memcpy(dev, data.dptr, sizeof(*dev)); +exit: + free(data.dptr); + return dev; } -/** - * namedb_delete - */ -static int namedb_delete(const char *name) +int udevdb_delete_dev(const char *path) { TDB_DATA key; - char keystr[NAME_SIZE]; - int retval = 0; - - if (name == NULL) - return -1; - if (strlen(name) >= NAME_SIZE) - return -1; - - memset(keystr, 0, NAME_SIZE); - strcpy(keystr, name); - - key.dptr = (void *)keystr; - key.dsize = strlen(keystr) + 1; - - retval = tdb_delete(udevdb, key); - return retval; -} + char keystr[SYSFS_PATH_MAX]; -static int sysfs_delete(const char *path) -{ - TDB_DATA key; - char keystr[PATH_SIZE]; + if (path == NULL) + return -EINVAL; memset(keystr, 0, sizeof(keystr)); strcpy(keystr, path); @@ -258,134 +104,33 @@ static int sysfs_delete(const char *path) } /** - * udevdb_delete_udevice - */ -int udevdb_delete_udevice(const char *name) -{ - struct namedb_record *nrec = NULL; - - if (name == NULL) - return -1; - - nrec = namedb_fetch(name); - if (nrec == NULL) - return -1; - - namedb_delete(name); - free(nrec); - - return 0; -} - -/** - * udevdb_add_device: adds class device to database - */ -int udevdb_add_device(const char *device, const struct sysfs_class_device *class_dev, const char *name, char type, int major, int minor, int mode) -{ - struct udevice dbdev; - - if (class_dev == NULL) - return -ENODEV; - - memset(&dbdev, 0, sizeof(dbdev)); - strncpy(dbdev.name, name, NAME_SIZE); - if (class_dev->sysdevice) { - strncpy(dbdev.sysfs_dev_path, class_dev->sysdevice->directory->path, PATH_SIZE); - strncpy(dbdev.bus_id, class_dev->sysdevice->bus_id, ID_SIZE); - } - strncpy(dbdev.class_dev_name, class_dev->name, NAME_SIZE); -// if ((sysfs_get_name_from_path(subsystem, dbdev.class_name, NAME_SIZE)) != 0) -// strcpy(dbdev.class_name, "unknown"); - dbdev.type = type; - dbdev.major = major; - dbdev.minor = minor; - dbdev.mode = mode; - - if ((sysfs_store(device, &dbdev)) != 0) - return -1; -// if ((namedb_store(&dbdev)) != 0) -// return -1; - - return 0; -} - -/** - * udevdb_get_device: grab's device by name - */ -struct udevice *udevdb_get_udevice(const char *name) -{ - struct namedb_record *nrec = NULL; - struct udevice *dev = NULL; - - if (name == NULL) - return NULL; - - nrec = namedb_fetch(name); - if (nrec == NULL) - return NULL; - - dev = (struct udevice *)malloc(sizeof(struct udevice)); - if (dev == NULL) { - free(nrec); - return NULL; - } - - strcpy(dev->name, name); - strcpy(dev->sysfs_dev_path, nrec->sysfs_dev_path); - strcpy(dev->class_dev_name, nrec->class_dev_name); - strcpy(dev->class_name, nrec->class_name); - strcpy(dev->bus_id, nrec->id); - dev->type = nrec->type; - dev->major = nrec->major; - dev->minor = nrec->minor; - dev->mode = nrec->mode; - - free(nrec); - - return dev; -} - -int udevdb_get_dev(const char *path, char *name, size_t name_size) -{ - struct sysfsdb_record *rec = NULL; - - if ((path == NULL) || (name == NULL) || (name_size < 1)) - return -EINVAL; - - rec = sysfsdb_fetch(path); - if (rec == NULL) - return -ENODEV; - - if (strlen(rec->name) >= name_size) - return -EINVAL; - - strncpy(name, rec->name, name_size); - return 0; -} - -int udevdb_delete_dev(const char *path) -{ - if (path == NULL) - return -EINVAL; - - return sysfs_delete(path); -} - -/** * udevdb_exit: closes database */ void udevdb_exit(void) { - udevdb_close(); + if (udevdb != NULL) { + tdb_close(udevdb); + udevdb = NULL; + } } /** * udevdb_init: initializes database + * @init_flag: database can either be in memory - UDEVDB_INTERNAL - or + * written to a file with UDEVDB_DEFAULT. */ int udevdb_init(int init_flag) { if (init_flag != UDEVDB_DEFAULT && init_flag != UDEVDB_INTERNAL) - return -1; + return -EINVAL; - return udevdb_open(init_flag); + udevdb = tdb_open(UDEV_CONFIG_DIR UDEV_DB, 0, init_flag, O_RDWR | O_CREAT, 0644); + if (udevdb == NULL) { + if (init_flag == UDEVDB_INTERNAL) + dbg("Unable to initialize in-memory database"); + else + dbg("Unable to initialize database at %s", UDEV_CONFIG_DIR UDEV_DB); + return -EINVAL; + } + return 0; } @@ -6,35 +6,16 @@ #define UDEV_DB "udevdb.tdb" -#define PATH_SIZE 256 - -#define UDEVDB_DEL "#" - /* Udevdb initialization flags */ #define UDEVDB_DEFAULT 0 /* Defaults database to use file */ #define UDEVDB_INTERNAL 1 /* Don't store db on disk, use in memory */ -struct udevice { - char name[NAME_SIZE]; - char sysfs_dev_path[PATH_SIZE]; - char class_dev_name[NAME_SIZE]; - char class_name[NAME_SIZE]; - char bus_id[NAME_SIZE]; - char bus_name[NAME_SIZE]; - char type; - int major; - int minor; - mode_t mode; -}; - /* Function Prototypes */ extern void udevdb_exit(void); extern int udevdb_init(int init_flag); -extern int udevdb_delete_udevice(const char *name); -extern int udevdb_add_device(const char *device, const struct sysfs_class_device *class_dev, const char *name, char type, int major, int minor, int mode); -extern struct udevice *udevdb_get_udevice(const char *name); -extern char *udevdb_get_udevice_by_sysfs(const char *path); -extern int udevdb_get_dev(const char *path, char *name, size_t name_size); + +extern int udevdb_add_dev(const char *path, const struct udevice *dev); +extern struct udevice *udevdb_get_dev(const char *path); extern int udevdb_delete_dev(const char *path); #endif /* _UDEVDB_H_ */ |