diff --git a/udev.c b/udev.c new file mode 100644 index 0000000..0c211a9 --- /dev/null +++ b/udev.c @@ -0,0 +1,162 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 MandrakeSoft + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com), + * + * Copyright 1996 Red Hat Software + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "init.h" +#include "udev.h" +#include "common.h" + +/* + * This need to safe symbols import + */ +#define fatal(m) init_fatal(m) +#define warn(m) init_warn(m) + +/* defined in init.c */ +extern int cooperate_mode; +extern char * const env[]; + +static pid_t udevd_pid; + + +static void spawn_wait(char * const command[], const char *message) +{ + int status = 0; + + if (waitpid(spawn(command), &status, 0) < 0 || !(WIFEXITED(status))) { + warn(message); + } +} + + +static void spawn_silent(char * const command[]) +{ + int fd = 0; + pid_t pid = fork(); + + if (pid < 0) + fatal(command[0]); + else if (pid == 0) { + fd = open("/dev/null", O_WRONLY, 0666); + if (fd >= 0) { + dup2(fd, 1); + dup2(fd, 2); + close(fd); + } + execve(command[0], &command[1], env); + perror(command[0]); + exit(1); + } + + if (waitpid(pid, &fd, 0) >= 0) { + fd = WIFEXITED(fd); + } +} + + +void udev_start(void) +{ + /* See make-initrd v0.8.x @ /data/lib/initrd/modules/050-udev for more details */ + static char* const udevd[] = {"/sbin/udevd", "udevd", "--resolve-names=never", NULL}; + static char* const priority[] = {"/sbin/udevadm", "udevadm", "control", "--log-priority=info", NULL}; + static char* const startup[] = {"/sbin/udevadm", "udevadm", "control", "--property=STARTUP=1", NULL}; + static char* const reload[] = {"/sbin/udevadm", "udevadm", "control", "--reload-rules", NULL}; + static char* const subsys[] = {"/sbin/udevadm", "udevadm", "trigger", "--type=subsystems", "--action=add", NULL}; + static char* const devices[] = {"/sbin/udevadm", "udevadm", "trigger", "--type=devices", "--action=add", NULL}; + + if (mkdirs_dev(".udev", ".udev/db", NULL) < 0) + fatal("/dev/.udev/db"); + if (cooperate_mode) { + if (mkdir_dev(".udev/queue") < 0) + fatal("cannot create /dev/.udev/queue"); + /* No more to do in lazy initialization mode */ + return; + } + + printf("Spawning udevd... "); + + udevd_pid = spawn(udevd); + spawn_wait(priority, "udev_priority"); + spawn_wait(startup, "udev_startup"); + spawn_silent(reload); + + if (mkdir_dev(".udev/queue") < 0) + fatal("cannot create /dev/.udev/queue"); + + spawn_silent(subsys); + spawn_silent(devices); + udev_settle(); + + printf("done\n"); +} + + +void udev_settle(void) +{ + /* See make-initrd v0.8.x @ /data/lib/initrd/modules/080-loop for more details */ + static char* const settle[] = {"/sbin/udevadm", "udevadm", "settle", "--timeout=5", NULL}; + + spawn_wait(settle, "udev_settle"); +} + + +void udev_stop(void) +{ + int fd, n = 0; + + /* This code moved from init.c/main() for compatibility */ + + udev_settle(); + if (!cooperate_mode) { + kill(udevd_pid, 9); + if (waitpid(udevd_pid, &n, 0) >= 0) + n = WIFEXITED(n); + } + nuke_dir("/dev/.udev/queue"); + fd = open("/.udev_version", O_RDONLY, 0); + if (fd >= 0) { + char buf[32]; + + n = read(fd, buf, sizeof(buf)); + close(fd); + + fd = creat("/dev/.initramfs/udev_version", 0); + if (fd < 0) + fatal("/dev/.initramfs/udev_version"); + else { + n = write(fd, buf, n); + close(fd); + } + } +} + diff --git a/udev.h b/udev.h new file mode 100644 index 0000000..44226eb --- /dev/null +++ b/udev.h @@ -0,0 +1,25 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 MandrakeSoft + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com), + * + * Copyright 1996 Red Hat Software + * + */ + +void udev_start(void); +void udev_settle(void); +void udev_stop(void); +