163 lines
3.6 KiB
C
163 lines
3.6 KiB
C
/*
|
|
* 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 <errno.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <dirent.h>
|
|
#include <fcntl.h>
|
|
#include <limits.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/vfs.h>
|
|
#include <sys/wait.h>
|
|
#include <linux/vt.h>
|
|
|
|
#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);
|
|
}
|
|
}
|
|
}
|
|
|