7

during a gentoo install from the livedvd, there's one step to create a dev dir to be used later in the chroot of the target for the instalation

it's done like that

mount --rbind /dev /mnt/gentoo/dev

in the middle of the installation i decided to start over... so i just did

rm -fr /mnt/gentoo/*

thinking nothing of it ("will just unpack the stage3 tar ball again") i deleted most of the device files from my actual /dev since the ones in the chroot would be just binded to the real devices.

now, the easy solution is: reboot. i know that if I reboot they will be there again. But this is a livedvd with no persistence. So if I reboot i will lose ~1h of preparation with firmwares and whatnot,

for now i will reboot. But i'd like to learn how to restore a /dev if a case like this does happen again (and because now i need to know even if i will never use it again)


update: just remembered about LFS. reading the linux from scratch docs, i think the simplest fix is to call

 /etc/init.d/udev restart

most of the files seems to be there now.

3 Answers 3

7

2014 update: Latest udev versions do not create device nodes at all, and rely on the kernel's devtmpfs to do so. The old answer will therefore stop working if your distribution has a very recent udev. With devtmpfs, the only automated method might be a reboot.


/dev is managed by udev on most Linux distros, so

udevadm trigger

should help.

Restarting udev completely will also work, but it's not necessary, and the command highly depends on distro used.

NOTE: you have to create a few items manually before that command works. /dev/{zero,null}

2

As seems to be no way to autorestore all files in /dev expect via rebooting, still:

# mknod -m 666 /dev/null c 1 3 
# mknod -m 666 /dev/ptmx c 5 2

The above two commands restored working terminal (new tabs) and ability to start new GUI apps (inc. new terminal windows). Were learned from https://tldp.org/LDP/lfs/LFS-BOOK-6.1.1-HTML/chapter06/devices.html "Linux From Scratch - Version 6.1.1, 6.8. Populating /dev". Outdated as a whole afaik, but useful in parts.

1
  • 1
    Interestingly I've done strace --follow-forks of failed terminal launch and have not found neither ptmx not /dev. Commented Oct 21, 2023 at 3:44
2

Here's an expansion to Alex Martian's answer:

I also found out that udevadm won't restore all files. I fell down the rabbit hole with mknod, and wrote a script to do a more complete restore of /dev. First, create a backup of /dev:

 find /dev | xargs stat > devstat.txt

(of course it's best to create the backup on the same machine before the accident, but what I did was create a backup on a "similar enough" machine)

Then run the following script that will output commands that restores the contents of /dev:

#!/bin/bash

c=0
l=0
d=0

while IFS= read -r line
do
        if [[ $line =~ File:\ (.*) ]]; then
                file=${BASH_REMATCH[1]}
        fi  
        if [[ $line =~ File:\ (.*)\ -\>\ (.*) ]]; then
                file=${BASH_REMATCH[1]}
                link=${BASH_REMATCH[2]}
        fi  
        if [[ $line =~ Device\ type:\ ([0-9a-f]+),([0-9a-f]+) ]]; then
                major=${BASH_REMATCH[1]}
                minor=${BASH_REMATCH[2]}
        fi  
        if [[ $line =~ character\ special\ file ]]; then
                c=1 
        fi  
        if [[ $line =~ symbolic\ link ]]; then
                l=1 
        fi  
        if [[ $line =~ directory ]]; then
                d=1 
        fi  
        if [[ $line =~ Access:\ \(([0-7]+)/c[rwx-]+\) ]]; then
                perm=${BASH_REMATCH[1]}
        fi  
        if [[ $line =~ Uid:\ \(\ *[0-9]+/\ *([a-z]+)\) ]]; then
                uid=${BASH_REMATCH[1]}
        fi  
        if [[ $line =~ Gid:\ \(\ *[0-9]+/\ *([a-z]+)\) ]]; then
                gid=${BASH_REMATCH[1]}
        fi  
        if [[ $line =~ Birth ]]; then
                if [[ $c -eq 1 ]]; then
                        echo mknod -m $perm $file c 0x$major 0x$minor
                        echo chown $uid:$gid $file
                fi  
                if [[ $l -eq 1 ]]; then
                        echo ln -s $link $file
                        echo chown $uid:$gid $file
                fi  
                if [[ $d -eq 1 ]]; then
                        echo mkdir -m $perm $file
                        echo chown $uid:$gid $file
                fi  
                c=0 
                l=0 
                d=0 
        fi  
done < devstat.txt

Review the commands created, then execute them on the machine in question.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .