Ankündigung

Einklappen

Serverwartung 21.2.



Am 21.2. im Laufe des späten Abends wird eine Serverwartung durchgeführt. Das Forum ist dadurch für gut zwei Stunden nicht erreichbar.
Es wird eine Wartungsseite geschaltet.

Mehr anzeigen
Weniger anzeigen

Script: RaspberryPi mit Rasbion Read-Only machen

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Script: RaspberryPi mit Rasbion Read-Only machen

    Hallo zusammen,

    wer einen Raspi dauerhaft und auf langen zeitraum einsetzen will, den wird irgendwas das wear-leveling der SD-Karte einholen.
    Um das problem mit dem schleichenden Tod der SD-Karte zu umgehen, kann man den Raspi weitgehend read-only machen.

    Hab hierzu folgende Anleitung gefunden:

    http://blog.pi3g.com/2014/04/make-ra...tem-read-only/

    Und weil ich das nicht immer (über die Zeit werden es irgendwie immer mehr Raspis...) von Hand machen will, hab ich das aus der Anleitung in ein Script gezogen:

    Code:
    #!/bin/bash
    # Created 2015-10-24 by tuxedo
    # inspired by http://blog.pi3g.com/2014/04/make-raspbian-system-read-only/
    
    if [ $EUID -ne 0 ]; then
        echo "Please run as root"
           exit 1
    fi
        
    
    #echo -n "Disable swap ..."
    #dphys-swapfile swapoff
    #dphys-swapfile uninstall
    #update-rc.d dphys-swapfile disable
    #echo "*done*"
    echo "Checking for FuseFS..."
    
    dpkg-query -l unionfs-fuse
    FUSEFS_INSTALLED=$?
    
    if [ $FUSEFS_INSTALLED -eq 1 ]; then
        echo "FuseFS not installed. Installing ..."
        apt-get install unionfs-fuse
        echo "FuseFS has been installed."
    else
        echo "FuseFS already installed. Skipping."
    fi
    
    
    
    
    echo -n "Creating UnioNFS mount script ..."
    cat <<\EOF > /usr/local/bin/mount_unionfs
    #!/bin/sh
    DIR=$1
    ROOT_MOUNT=$(awk '$2=="/" {print substr($4,1,2)}' < /etc/fstab)
    if [ $ROOT_MOUNT = "rw" ]; then
      /bin/mount --bind ${DIR}_org ${DIR}
    else
      /bin/mount -t tmpfs ramdisk ${DIR}_rw
      /usr/bin/unionfs-fuse -o cow,allow_other,suid,dev,nonempty ${DIR}_rw=RW:${DIR}_org=RO ${DIR}
    fi
    EOF
    chmod +x /usr/local/bin/mount_unionfs
    echo "*done*"
    
    
    
    
    if grep -q "mount stuff read-only" "/etc/fstab"; then
        echo "fstab already contains read-only mounts. Skipping."
    else
        NOW=$(date +"%Y-%m-%d")
        # make backup file
        cp /etc/fstab /etc/fstab_backup_readonlymount_$NOW
        echo -n "Updating fstab with read-only mounts..."
        cat <<EOF > /etc/fstab
    # mount stuff read-only    
    prov            /proc           proc    defaults          0       0
    # mount as read only
    /dev/mmcblk0p1  /boot           vfat    ro                0       2
    /dev/mmcblk0p2  /               ext4    ro,noatime        0       1
    # mount special folders to raw, using special mount_unionfs script
    mount_unionfs   /etc            fuse    defaults          0       0
    mount_unionfs   /var            fuse    defaults          0       0
    none            /tmp            tmpfs   defaults          0       0
    
    EOF
        echo "*done*"
    fi
    
    
    
    
    if [ ! -d "/etc_org" ]; then
        echo -n "Prepare directories ..."
        # backups where all the initial stuff is located (like configs in /etc)
        cp -al /etc /etc_org
        mv /var /var_org
        # read/write folders for ram disk
        mkdir /etc_rw
        mkdir /var /var_rw
        echo "*done*"
    else
        echo "Directories already prepared. Skipping."
    fi
    
    
    echo -n "Clean up log folder"
    cd /var_org/log
    # empty files ending with "log"
    for f in $(find . -name \*log); do > $f; done
    # delete all log-archives
    rm -f *.gz
    echo "*done*"
    
    echo ""
    echo ""
    echo "All done."
    echo "Please reboot now. Type 'reboot' followed by [enter]-key."
    echo ""
    Einzige Abwandlung: Das leeren von Log-Files habe ich auf /var/log begrenzt. Erschien mir wenig sinnvoll alles auf dem SD-Speicher was im Dateinamen auf "log" endet zu leeren.

    Gibt's mutige die das auch mal bei sich testen wollen?

    Muss für meine Basteleien in /opt/ noch eine Lösung finden (weil da werden auch Log und Cache-Files erzeugt), aber davon mal abgesehen scheint es prima zu laufen.




    [update]

    Um beispielsweise /opt noch für den read-write Modus im RAM zu nutzen:

    Code:
    cp -al /opt /opt_org
    mkdir /opt_rw
    und in /etc/fstab folgendes hinzufügen:

    Code:
    mount_unionfs   /opt            fuse    defaults          0       0
    Zuletzt geändert von tuxedo; 24.10.2015, 12:35.

    #2
    Um nachträglich nochmal in den Schreib-Modus zu gelangen, bedarf es dieses Scripts:

    Code:
    #!/bin/bash
    
    # remount root rw
    mount -o remount,rw /
    
    # prapare target paths
    mkdir -p /chroot
    mkdir -p /chroot/{bin,boot,dev,etc,home,lib,opt,proc,root,run,sbin,sys,tmp,usr,var}
    
    # mount special filesystems
    mount -t proc proc /chroot/proc
    mount --rbind /sys /chroot/sys
    mount --rbind /dev /chroot/dev
    
    # bind rw directories
    for f in {etc,var}; do
        mount --rbind /${f}_org /chroot/$f
    done
    
    # bind remaining directories
    for f in {bin,boot,home,lib,opt,root,run,sbin,tmp,usr}; do
        mount --rbind /$f /chroot/$f
    done
    
    # chroot
    echo "Note: /boot is still mounted read-only, remount to read-write if needed."
    echo -e "\e[33mYou are now in read-write chroot. Use CTRL+D when done to exit chroot and mount read-only again.\e[39m"
    chroot /chroot /usr/bin/env PS1="(rw) \u@\h:\w\$ " /bin/bash --noprofile -l
    
    # unmount mounts
    for f in /chroot/{bin,boot,dev,etc,home,lib,opt,proc,root,run,sbin,sys,tmp,usr,var};
    do
        umount -l $f
    done
    
    sleep 1
    
    # remount read-only again
    echo -e "\e[32mChroot left, re-mounting read-only again.\e[39m"
    mount -o remount,ro /
    Ein einfaches "mount -o remount,rw /" reicht leider nicht.

    Und einen Haken hat das ganze noch: "cron" arbeitet nicht mehr wie es soll. Der Trick an diesem read-only-Weg ist, dass z.B. das Verzeichnis "etc" als hard-link-kopie angelegt wird. D.h. es wir keine echte Kopie angelegt, sondern nur hard-links. Und der cron-daemon mag das gar nicht wenn seine config ein "hard link" ist:

    root@raspberrypi2:/usr/local/bin# tail -f /var/log/syslog
    Oct 24 12:48:01 raspberrypi2 cron[491]: (*system*php5) NUMBER OF HARD LINKS > 1 (/etc/cron.d/php5)
    Oct 24 12:49:01 raspberrypi2 cron[491]: (*system*) NUMBER OF HARD LINKS > 1 (/etc/crontab)
    Oct 24 12:49:01 raspberrypi2 cron[491]: (*system*php5) NUMBER OF HARD LINKS > 1 (/etc/cron.d/php5)
    Oct 24 12:49:01 raspberrypi2 rsyslogd-2007: action 'action 17' suspended, next retry is Sat Oct 24 12:50:01 2015 [try http://www.rsyslog.com/e/2007 ]
    Oct 24 12:50:01 raspberrypi2 cron[491]: (*system*) NUMBER OF HARD LINKS > 1 (/etc/crontab)
    Oct 24 12:50:01 raspberrypi2 cron[491]: (*system*php5) NUMBER OF HARD LINKS > 1 (/etc/cron.d/php5)
    Oct 24 12:50:01 raspberrypi2 rsyslogd-2007: action 'action 17' suspended, next retry is Sat Oct 24 12:51:01 2015 [try http://www.rsyslog.com/e/2007 ]
    Oct 24 12:51:01 raspberrypi2 cron[491]: (*system*) NUMBER OF HARD LINKS > 1 (/etc/crontab)
    Oct 24 12:51:01 raspberrypi2 rsyslogd-2007: action 'action 17' suspended, next retry is Sat Oct 24 12:52:31 2015 [try http://www.rsyslog.com/e/2007 ]
    Oct 24 12:51:01 raspberrypi2 cron[491]: (*system*php5) NUMBER OF HARD LINKS > 1 (/etc/cron.d/php
    Bin da noch dran dieses Problem zu beheben.
    Aber mal von Cron abgesehen läuft die Sache bisher ganz gut.

    Kommentar

    Lädt...
    X