]>
git.ipfire.org Git - thirdparty/systemd.git/blob - udev-add.c
6 * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation version 2 of the License.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 #include "udev_version.h"
35 #include "libsysfs/libsysfs.h"
39 * Right now the major/minor of a device is stored in a file called
41 * The number is stored as:
45 * The value is in hex.
46 * Yes, this will probably change when we go to a bigger major/minor
47 * range, and will have to be changed at that time.
49 static int get_major_minor(struct sysfs_class_device
*class_dev
, int *major
, int *minor
)
55 dev
= sysfs_get_value_from_attributes(class_dev
->directory
->attributes
, "dev");
61 if (sscanf(dev
, "%u:%u", major
, minor
) != 2)
64 dbg("found major = %d, minor = %d", *major
, *minor
);
72 * We also want to add some permissions here, and possibly some symlinks
74 static int create_node(char *name
, char type
, int major
, int minor
, int mode
)
78 strncpy(filename
, UDEV_ROOT
, sizeof(filename
));
79 strncat(filename
, name
, sizeof(filename
));
92 dbg("unknown node type %c\n", type
);
96 retval
= mknod(filename
,mode
,makedev(major
,minor
));
98 dbg("mknod(%s, %#o, %u, %u) failed with error '%s'",
99 filename
, mode
, major
, minor
, strerror(errno
));
103 struct sysfs_class_device
*get_class_dev(char *device_name
)
105 char sysfs_path
[SYSFS_PATH_MAX
];
106 char dev_path
[SYSFS_PATH_MAX
];
108 struct sysfs_class_device
*class_dev
= NULL
;
111 retval
= sysfs_get_mnt_path(sysfs_path
, SYSFS_PATH_MAX
);
112 dbg("sysfs_path = %s", sysfs_path
);
114 dbg("sysfs_get_mnt_path failed");
118 strcpy(dev_path
, sysfs_path
);
119 strcat(dev_path
, device_name
);
121 dbg("looking at %s", dev_path
);
123 /* open up the sysfs class device for this thing... */
124 class_dev
= sysfs_open_class_device(dev_path
);
125 if (class_dev
== NULL
) {
126 dbg ("sysfs_open_class_device failed");
129 dbg("class_dev->name = %s", class_dev
->name
);
135 int udev_add_device(char *device
, char *subsystem
)
137 struct sysfs_class_device
*class_dev
;
138 struct device_attr attr
;
142 int retval
= -EINVAL
;
144 /* for now, the block layer is the only place where block devices are */
145 if (strcmp(subsystem
, "block") == 0)
150 /* sleep for a second or two to give the kernel a chance to
151 * create the dev file
155 class_dev
= get_class_dev(device
);
156 if (class_dev
== NULL
)
159 retval
= namedev_name_device(class_dev
, &attr
);
163 retval
= get_major_minor(class_dev
, &major
, &minor
);
165 dbg ("get_major_minor failed");
168 memset(&dbdev
, 0, sizeof(dbdev
));
169 strncpy(dbdev
.name
, attr
.name
, NAME_SIZE
);
170 strncpy(dbdev
.sysfs_path
, class_dev
->sysdevice
->directory
->path
,
172 strncpy(dbdev
.class_dev_name
, class_dev
->name
, NAME_SIZE
);
173 if ((sysfs_get_name_from_path(subsystem
, dbdev
.class_name
, NAME_SIZE
))
175 strcpy(dbdev
.class_name
, "unkown");
176 strncpy(dbdev
.bus_id
, class_dev
->sysdevice
->bus_id
, ID_SIZE
);
177 strcpy(dbdev
.bus_name
, "unknown");
178 if (class_dev
->driver
!= NULL
)
179 strncpy(dbdev
.driver
, class_dev
->driver
->name
, NAME_SIZE
);
181 strcpy(dbdev
.driver
, "unkown");
185 dbdev
.mode
= attr
.mode
;
187 sysfs_close_class_device(class_dev
);
189 retval
= udevdb_add_udevice(&dbdev
);
193 return create_node(attr
.name
, type
, major
, minor
, attr
.mode
);