Shell scripts & ασφαλής ενημέρωση fstab (was: Re: Αποσπωμενος Δισκος /flash δισκος)

Giorgos Keramidas keramida at ceid.upatras.gr
Sat Jan 28 21:12:16 EET 2006


On 2006-01-28 16:06, djemos <dijemos at yahoo.gr> wrote:
>O/H basil έγραψε:
>> Ενα θεμα που τιθεται αν εχεις 2 αποσπωμενα mass storage devices (π.χ.
>> "φλασακι" και σκληρο δισκο , σε usb και τα 2) ειναι οτι καθε φορα που τα
>> συνδεεις παιρνουν το πρωτο διαθεσιμο ονομα (/dev/sda , sdb κλπ). Αυτο τα
>> κανει δυσχρηστα για καταχωρησεις στο fstab.

Γιατί να τα καταχωρήσεις στο `fstab', βασικά;

Δεν είναι πιο απλό το event model που χρησιμοποιείται και στέλνει
μηνύματα "το τάδε USB device συνδέθηκε", "το τάδε έφυγε", μπορεί να
τρέξει με λίγο προσπάθεια τις σωστές mount/umount εντολές.

> Στο slackel-1.0 livecd που δημιούργησα η αναγνώριση των usb devices
> γίνεται αυτόματα με ένα script to /usr/bin/mntall που δουλεύει σαν
> δαίμονας και από το οποίο καλείται ενα άλλο το /usr/bin/fstab-create που
> ενημερώνει δυναμικά το fstab.

Χεχε!  Ενδιαφέρον... με λίγο file locking για να μην υπάρχει περίπτωση
να μείνει το `fstab' κι ο root με το πουλί στο χέρι, θα είναι jet :)))

Δημήτρη,

Μια ιδέα είναι το `mntall' να μην τρέχει απλά ώς ένα άλλο process στο
background, αλλά να ξεκινάει με μια εγγραφή στο `inittab'.  Ετσι όταν
ψοφήσει θα το ξεκινάει πάλι η init :)

> #!/bin/bash
>
> if [ "`cat /proc/cmdline | grep nohd`" != "" -o "`cat /proc/cmdline |
> grep nohotplug`" !
>    exit 0
> fi
>
> echo "Starting $0 daemon, which will update fstab automatically ..."
> while [ 1 ]; do
>    PARTS="$(< /proc/partitions)"

Οπωσδήποτε, εδώ χρειάζεται κάποιου είδους sorting.  Για να μην κάνεις
τσάμπα κόπο όταν, ας πούμε, τα παλιά partitions είναι τα "hda1 hda3
hda2" και τα νέα είναι τα "hda1 hda2 hda3"...

>    if [ "$OLDPARTS" != "$PARTS" ]; then
>       /usr/bin/fstab-create -m
>       OLDPARTS="$PARTS"
>    fi
>    sleep 1
> done

Από δω και κάτω είναι που χρειάζεται λίγο locking :)

> #!/bin/bash
> # recreate fstab entries in /etc/fstab
> # (and make /mnt directories if $1 = -m)
> #
> # Author: Tomas M <http://slax.linux-live.org/>
> # Modified: by Dimitris Tzemos <djemos at tetradio.gr>
> if [ "`cat /proc/cmdline | grep nohd`" != "" -o "`cat /proc/cmdline |
> grep nohotplug`" != "" ]; then
>    exit 0;
> fi
>
> if grep el_GR /proc/cmdline 1> /dev/null 2> /dev/null ; then
>      GRFS=""
> else
>      GRFS=",utf8"
> fi
>
> FSTAB=/etc/fstab
>
> echo "tmpfs            /                tmpfs       defaults         0   0
> devpts           /dev/pts         devpts      gid=5,mode=620   0   0
> proc             /proc            proc        defaults         0   0
> /dev/fd0         /mnt/floppy      vfat,msdos
> noauto,users,suid,dev,exec,codepage=737,iocharset=iso8859-7$GRFS,rw 0 0"
> >$FSTAB~

Ένας ωραίος τρόπος, όταν θες να γράψεις πολλά πράγματα σε ένα αρχείο,
είναι να `ανοίξεις' ένα συγκεκριμένο file descriptor με ανακατεύθυνση σε
αυτό το αρχείο.  Σε POSIX sh(1) (άρα και σε bash) αυτό γίνεται ως εξής:

    FSTAB="/etc/fstab"
    NEWFSTAB="/etc/fstab.tmp"

    exec 3> "${NEWFSTAB}"

κι ύστερα μπορείς να γράφεις με echo πολλά πράγματα, αντί να έχεις
hardcoded strings μέσα στο script, ακόμα κι από πολύ διαφορετικά μέρη
του script:

    echo >&3 "kot"
    ...
    echo >&3 "kotkot"

Έτσι μπορείς να `χτίσεις' το νέο `fstab' μία-μία γραμμή, κι όταν είσαι
έτοιμος να το κλείσεις και να κάνεις swap τα δύο αρχεία:

    exec 3> /dev/null
    mv "${NEWFSTAB}" "${FSTAB}"
    [ $? -eq 0 ] || err 1 "Coult not install new fstab entries"

Κάτι άλλο, που μπορεί να είναι χρήσιμο, ειδικά αν υπάρχει περίπτωση να
τρέξουν πολλά instances από το shell script που ενημερώνει το `fstab',
είναι να κρατάς ένα MD5 hash από το αρχικό `fstab' πριν αρχίσεις να
δημιουργείς το νέο `fstab' και λίγο πριν το αντικαταστήσεις, μέσα σε μια
``κρίσιμη περιοχή'' (η οποία προστατεύεται από lockf(1) ή lockfile(1)),
να ελέγχεις ότι δεν άλλαξε στο μεταξύ το original `fstab':

    FSTAB="/etc/fstab"
    FSTABLOCK="${FSTAB}.lock"

    # Get a checksum of the original fstab file, before we make any
    # changes to it.
    lockfile "${FSTABLOCK}"
    if test $? -ne 0 ; then
        err 1 "${FSTAB}: can not lock file"
    fi
    MDSUM=`md5 /etc/fstab`
    rm -f "${FSTABLOCK}"

    # Δημιουργία του νέου fstab:
    NEWFSTAB=`mktemp "${FSTAB}.XXX"
    if test $? -ne 0 ; then
        err 1 "${NEWFSTAB}: can not create temporary, new fstab"
    fi

    ... κώδικας που ενημερώνει το NEWFSTAB ...

    # Check the checksum of the fstab file and update it atomically.
    lockfile "${FSTABLOCK}"
    if test $? -ne 0 ; then
        err 1 "${FSTAB}: can not lock file"
    fi
    MDNEW=`md5 /etc/fstab`
    if test "$MDSUM" = "$MDNEW" ; then
        mv "$NEWFSTAB" "$FSTAB"
    else
        rm -f "${FSTABLOCK}"
        err 1 "${FSTAB}: file has been modified, aborting"
    fi
    rm -f "${FSTABLOCK}"




More information about the Linux-greek-users mailing list