• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Was gibt es Schöneres als den Mai draußen in der Natur mit allen Sinnen zu genießen? Lasst uns teilhaben an Euren Erlebnissen und macht mit beim Thema des Monats Da blüht uns was! ---> Klick

2 Festplatten im MBP und bind Mounts - Ein Experiment

fyysh

Schweizer Glockenapfel
Registriert
25.01.10
Beiträge
1.386
Ich poste das hier, weil das Ganze ein wenig geekig ist und es noch im Stadium eines Experiments ist. Wer auch immer das befolgt:
AUF EIGENE GEFAHR! :p


Es geht darum:
Ich habe in meinem MBP nun zwei interne Festplatten, eine SSD und eine HDD. Das geht z.B. hiermit.

Gründe für die zwei Festplatten:
• Die 256g SSD reicht nicht
• Eine 500g SSD finde ich zu teuer


Nun also, mit zwei Platten, bin ich auf folgendes Problem gestoßen:

Die zweite Platte ist für große Datein da, die keinen schnellen Zugriff benötigen und Platz wegnehmen, z.B. Bilder, Musik und Videos aber auch mein Download-Archiv usw. Diese möchte ich aber nach wie vor über mein Benutzerprofil erreichen und nicht umständlich auf eine andere Platte klicken, um zum gewünschten Ziel zu kommen.

Eine Möglichkeit wäre es, Symlinks zu benutzen. Blöd nur: Die behandelt der Finder eben auch als solche und wenn sie geöffnet werden, geht der Finder auf die Platte. Mit CMD+UP kommt man also nicht zum Ursprungsort, sagen wir ~/, zurück, sondern eben auf /Volumes/Die2tePlatte/DerMusikOrdner. Das nervt.

Eine andere Möglichkeit: Aliase. Die verursachen jedoch dasselbe Problem wie die Symlinks im Finder. Plus zusätzlich spielen sie nicht gut (überhaupt nicht) mit dem Terminal zusammen. Ich bin ständig im Terminal. Also auch blöd.

Zugegebenermaßen: Ich bin ein Gewohnheitstier.

Mein nächster Gedanke war:
OS X ist ein UNIX. Unixe können solche tollen dinge wie unionfs, bind, nullfs... blah. Aber weit gefehlt. OS X kann von sich aus sowas eben nicht. Damit gab es irgendwelche Probleme und deshalb wurde es entfernt. Agh!

Aber es gibt ja Fuse und bindfs!



Meine bisherige und, wie oben erwähnt, noch experimentelle Lösung, funktioniert also mit bindfs und fuse4x, beides über ports installiert, und sei hiermit schon mal vorgestellt, obwohl der Ausgang des Experiments noch nicht gewiss ist. Vielleicht suchen ja noch andere nach dieser Möglichkeit.

Nebenbei bemerkt: Das ganze läuft bei mir nun schon seit zwei Wochen stabil. Dennoch habe ich Warnungen im Internet vernommen, dass es mit bindfs zu Datenkorruption kommen kan. Bisher habe ich davon noch nichts bemerkt, aber ganz ausschließen lässt es sich noch nicht. Falls es dazu kommen sollte, werde ich es berichten.




Gut, also los. Was will ich?
Ich will mich an meinem Mac einloggen und auf meinen Benutzerordner wie eh und je zugreifen können, obwohl teile der Daten auf einer anderen Platte liegen. Oder anders gesagt: Ich will gar nichts davon merken, dass ich zwei Platten habe.
Und so habe ich's gemacht:


1. Grundvorraussetzungen
• Xcode muss installiert sein
• Macports
• Die zweite Platte ist eingebaut und HFS+ Formattiert (HFS ist kein muss, aber was anderes macht bei einer internen Platte für OSX keinen Sinn - Ich habe jedoch derzeitig ein ZFS Mirror auf der zweiten Platte laufen, um Datenkorruption mitzubekommen und zu vermeiden).





2. bindfs und fuse4x installieren
Code:
sudo port install bindfs
bindfs installiert automatisch fuse4x mit. Ist eine dependency.

Das ganze testen:
Code:
$> cd ~/tmp
$> mkdir d1 d2
$> touch d1/grunz
$> bindfs d1 d2
$> mount -t fuse4x
bindfs@fuse0 on /Users/fyysh/TMP/d2 (fuse4x, nodev, nosuid, synchronous, mounted by fyysh)
$> ls d2/
grunz
$> umount d2
Funzt.





3. Die UUID der zweiten Platte herausbekommen.
Das geht mit diskutil. Zunächst habe ich die disks gelistet:
Code:
$> diskutil list
/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *320.1 GB   disk0
   1:                        EFI                         209.7 MB   disk0s1
   2:                  Apple_HFS Perseus-HDD             319.7 GB   disk0s2
/dev/disk1
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *256.1 GB   disk1
   1:                        EFI                         209.7 MB   disk1s1
   2:                  Apple_HFS Perseus-SSD             255.2 GB   disk1s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk1s3
Und dann habe ich den Label der zweiten Platte verwendet, in meinem Fall ist das Perseus-HDD, um die UUID der Platte zu bekommen.
Code:
$> diskutil info Perseus-HDD | grep UUID
   Volume UUID:              1B416B9B-4374-4B13-ABED-4F8K2B0G0C1F
Wichtig ist, dass man den Label benutzt, denn ansonsten spuckt diskutil list nicht die UUID aus. Einen anderen Weg die UUID zu bekommen ist über die Disk Utility bzw. das Festplattendienstprogramm, dort die Infos zur Platte aufrufen.

Die UUID habe ich irgendwohin gespeichert.





4. Erforderliche Dateien auf die zweite Festplatte übertragen.
Ich habe einen Ordner auf der zweiten Platte erstellt, wo die ganzen bindfs mounts zu finden sein würden.
Code:
$> mkdir -vp /Volumes/HD-LABEL/bindfs/user
In diesem Ordner habe ich die Pfade ab root ("/") erstellt und entsprechende besitzerrechte vergeben, die ich bindmounten würde. Da alles in mein Benutzerordner gemounted wird, war das also so:
Code:
$> myROOT="/Volumes/Perseus-HDD/bindfs/user/Users/fyysh"
$> mkdir -vp "$myROOT/Music"
$> mkdir -vp "$myROOT/Pictures" 
$> mkdir -vp "$myROOT/Movies" 
$> mkdir -vp "$myROOT/TMP/BIGTMP" 
$> mkdir -vp "$myROOT/Downloads/_DTA"
$> mkdir -vp "$myROOT/VMs/Images"

Nachdem ich die Ordner erstellt hatte, habe ich angefangen die Daten auf die zweite Platte zu übertragen. Ich habe es mit rsync gemacht. Das dauert je nach dem eine Weile. Zum Beispiel:
Code:
[$> rsync -PahvWlH --remove-source-files "~/Music" "/Volumes/HD-LABEL/bindfs/user/Users/fyysh"
Und dann, als alles auf der zweiten Platte war, habe ich die ursprünglichen Ordner gelöscht.

Vorsicht: Obiger Befehl löscht die Originaldateien ==> --remove-source-files!!!
Auch Vorsicht: Falls die Daten mit dem Finder übertragen werden und die invisibles nicht angezeigt werden, werden die auch nicht mit übertragen!!!





5. Die bindfs src dirs Liste und das VolumeIcon
In dieser Liste wird das nachfolgende Script rauslesen, was es Mounten muss. Es ist einfach eine Textdatei namens bindfs-srcdirs.txt unter /Volumes/Perseus-HDD/bindfs/user/Users/fyysh. Sie sieht so aus:
Code:
# one mountpoint per line
# use relative path from location of this file
# dont quote! dont escape blanks!


Downloads/_DTA #dta folder
TMP/BIGTMP
Movies
Music
Pictures
VMs/Images
Wenn diese Datei fehlt oder leer ist, dann wird das nachfolgende Script einfach alle Ordner, die es in Benutzerordner auf der zweiten Platte findet, einhängen (also ohne in manche Ordner abzusteigen).

Ebenfalls unter /Volumes/Perseus-HDD/bindfs/user/Users/fyysh habe ich eine icns-Datei mit dem Namen VolumeIcon.icns hinterlegt, welche das Icon für die gemounteten Laufwerke enthalten soll. Das ist nicht unbedingt nötig, sieht aber nachher schick aus.





6. Das Script bindfs-mounter.sh
Folgendes Bash Script führt die bindfs mounts aus:
Code:
#!/bin/bash


## variables
BINDFS_BIN="/opt/local/bin/bindfs"                        # bindfs executable


CURRENT_USER="${USER}"
CURRENT_USER_HOME="${HOME}"


SRC_DISK_UUID="1B416B9B-4374-4B13-ABED-4F8K2B0G0C1F"    # find out with diskutil or disk utility
SRC_DISK_USER_DIR="bindfs/user"                            # where to find the usr dir
SRC_DISK_MOUNTPOINT=                                    # leave empty here


SRC_DIRS_FILENAME="bindfs-srcdirs.txt"                    # file name of the file containing the dirs to mount
VOLICON_NAME="VolumeIcon.icns"                            # icns used for the mounted dir




## functions
function show_help () {
    cat <<-HEREDOC
    
        usage:
        $(basename "$0") [ help | umount | uuid=diskuuid]
    
        args:
        help                show this
        umount                unmounts all mounts with type=fuse4x
        uuid=diskuuid        uses given uuid instead of hardcoded one
        
    HEREDOC
    return 0
}


function get_fuse4x_mounts () {
    local line
    mount -t fuse4x \
        | grep -oE '/.* \(fuse4x' \
        | sed 's/ (fuse4x//' \
        | while read line; do
            echo ${line}
        done


    return 0
}




function umount_bindfs () {
    get_fuse4x_mounts | while read line;do umount -fv "$line";done
    return 0
}




function get_uuid_from_arg () {
    local argUuid="$1"
    local newUuid
    
    newUuid="$(printf '%s' "${argUuid}" | awk -F '=' '{print $2}')"
    
    [[ -n "${newUuid}" ]] \
        && { echo "${newUuid}"; return 0; } \
        || return 1
}




function get_mountpoint () {
    local diskUuid="$1"
    local diskMountpoint


    # getting the mountpoint for the disk with uuid=$diskUuid from diskutil and xpath
    diskMountpoint="$(diskutil info -plist "${diskUuid}" \
        | /usr/bin/xpath  "/plist/dict/key[.='MountPoint']/following-sibling::*[1]/text()" 2>/dev/null)"
    
    [[ -n "${diskMountpoint}" ]] \
        && { echo "${diskMountpoint}"; return 0; } \
        || return 1
}




function create_dest_dir () {
    local destDir="$1"
    mkdir -p "${destDir}" &>/dev/null \
        && return 0 \
        || return 1
}




function test_if_mounted () {
    local destDir="$1"
    get_fuse4x_mounts | grep -qE "^${destDir}$" \
        && return 1 \
        || return 0
}






function mount_bindfs () {
    local IFS=$'\n'
    local srcDir="$1"
    local volName
    volName="$(basename "${srcDir}")"


    local destDir="$2"
    
    test_if_mounted "${destDir}" \
        || { echo -e "destDir ${destDir} is already mounted."; return 1; }
    
    [[ -n "${destDir}" ]] || destDir="${CURRENT_USER_HOME}/${volName}"
        
    if [[ ! -d "$destDir" ]];then
        echo -n "destDir ${destDir} does not exist. creating ... "
        create_dest_dir "${destDir}" \
            && echo "SUCCESS" \
            || { echo -e "FAILED\ncannot mount srcDir ${srcDir} to destDir ${destDir}"; return 1; }
    fi


    local fuseOpts="volname=${volName/ /\\ }"
    
    # get the volicon
    if [[ -f "${srcDir}/${VOLICON_NAME}" ]]; then
        fuseOpts="${fuseOpts},volicon=${srcDir/ /\\ }/${VOLICON_NAME/ /\\ }"
    elif [[ -f "${SRC_DISK_MOUNTPOINT}/${SRC_DISK_USER_DIR}/${CURRENT_USER_HOME}/${VOLICON_NAME}" ]]; then
        fuseOpts="${fuseOpts},volicon=${SRC_DISK_MOUNTPOINT/ /\\ }/${SRC_DISK_USER_DIR/ /\\ }/${CURRENT_USER_HOME/ /\\ }/${VOLICON_NAME/ /\\ }"
    fi


    echo -n "executing ${BINDFS_BIN} -n --xattr-none -o ${fuseOpts} \"${srcDir}\" \"${destDir}\" ..."    
    "${BINDFS_BIN}" -n --xattr-none -o ${fuseOpts} "${srcDir}" "${destDir}"  \
        && { echo "SUCCESS"; return 0; } \
        || { echo "FAILED"; return 1; }
}




function read_bindfs-srcdirs_from_file () {
    echo "using $FUNCNAME"
    local bindfsMountsFile="$1"
    local bindfsSrcRoot
    bindfsSrcRoot="$(dirname "${bindfsMountsFile}")"
    
    awk '/^[^#]/ {gsub(/#.*/,"");print}' "${bindfsMountsFile}" | \
        while read line; do
            [[ -d "${bindfsSrcRoot}/${line}" ]] \
                || { echo "${bindfsSrcRoot}/${line} is not a directory or does not exist."; continue; }
            
            mount_bindfs "${bindfsSrcRoot}/${line}" "${CURRENT_USER_HOME}/${line}"
        done
        
    return 0    
}




function bindfs_mount_every_1st_level_dir () {
    echo "using $FUNCNAME"
    local level0Dir="$1"
    find "${level0Dir}" -type d -depth 1 \
        | while read dir; do
            mount_bindfs "${dir}"
        done
        
    return 0
}




## main
echo "$(basename "$0") started"


# check if there's a conf file by the script and if yes, source it'
# the conf file' name is $0.conf
# it may contain BINDFS_BIN, SRC_DISK_UUID, SRC_DISK_USER_DIR, SRC_DIRS_FILENAME , VOLICON_NAME
# value of those variables will be set to the calues in conf
[[ -f "$0.conf" ]] && \
    {
        echo "found conf. sourcing."
        . "$0.conf"
    }


for arg in "$@"; do
    case "${arg}" in
        umount )
            umount_bindfs
            echo "$(basename "$0") finished"
            exit 0
            ;;
        unmount )
            umount_bindfs
            echo "$(basename "$0") finished"
            exit 0
            ;;
        uuid=* )
            SRC_DISK_UUID="$(get_uuid_from_arg "${arg}")"
            [[ -n "${SRC_DISK_UUID}" ]] \
                && echo "using SRC_DISK_UUID=${SRC_DISK_UUID}" \
                || { echo "uuid must not be empty. script ends here"; exit 1; }
            ;;
        -h )
            show_help
            exit 0
            ;;
        --help )
            show_help
            exit 0
            ;;
        help )
            show_help
            exit 0
            ;;
    esac
done




# get the disk mountpoint
SRC_DISK_MOUNTPOINT="$(get_mountpoint "${SRC_DISK_UUID}")"


# test if SRC_DISK_MOUNTPOINT exists or exit
[[ -n "${SRC_DISK_MOUNTPOINT}" ]] \
    && echo "found SRC_DISK_MOUNTPOINT=${SRC_DISK_MOUNTPOINT}" \
    || { echo "failed getting SRC_DISK_MOUNTPOINT. script ends here."; exit 1; }


# test if userhome exists on src_disk
[[ -d "${SRC_DISK_MOUNTPOINT}/${SRC_DISK_USER_DIR}/${CURRENT_USER_HOME}" ]] \
    && echo "found user home in ${SRC_DISK_MOUNTPOINT}/${SRC_DISK_USER_DIR}/${CURRENT_USER_HOME}." \
    || { echo "${SRC_DISK_MOUNTPOINT}/${SRC_DISK_USER_DIR}/${CURRENT_USER_HOME} does not exist. script ends here"; exit 0; }


# if file bindfs-mounts.txt exists, read the mountpoints from there
# else use bindfs to mount each directory from user_home on src_disk to $home
[[ -f "${SRC_DISK_MOUNTPOINT}/${SRC_DISK_USER_DIR}/${CURRENT_USER_HOME}/${SRC_DIRS_FILENAME}" \
    && $(awk '$1 ~ /^[^#]/ {++c} END {print c}' "${SRC_DISK_MOUNTPOINT}/${SRC_DISK_USER_DIR}/${CURRENT_USER_HOME}/${SRC_DIRS_FILENAME}") -gt 0 ]] \
        && read_bindfs-srcdirs_from_file "${SRC_DISK_MOUNTPOINT}/${SRC_DISK_USER_DIR}/${CURRENT_USER_HOME}/${SRC_DIRS_FILENAME}" \
        || bindfs_mount_every_1st_level_dir "${SRC_DISK_MOUNTPOINT}/${SRC_DISK_USER_DIR}/${CURRENT_USER_HOME}"


echo "$(basename "$0") finished"
exit 0


Folgende Variabeln müssen gesetzt werden:
BINDFS_BIN: executable von bindfs, bei einer port installation normalerweise in /opt/local/bin/bindfs
SRC_DISK_UUID: Die UUID von 3.
SRC_DISK_USER_DIR: Hier ist der relative Pfad ab Einhängepunkt der zweiten Platte zu hinterlegen, wo root abgebildet wurde. Bei mir ist das bindfs/user (siehe 4.)
SRC_DIRS_FILENAME: Das ist der Name der Datei von dem in 5. die Rede ist
VOLICON_NAME: Name der icns-Datei, die als Icon für die Mounts dient (siehe ebenfalls 5.)

Dies ist die erste Version des Scripts. Wenn ich ein bisschen mehr Zeit habe, werde ich es wohl noch polieren. Gerade um, um es als echtes launchd Script zu verwenden (kommt weiter unten), benötigt es noch ein paar kleine Anpassungen und auch noch ein paar andere Dinge werde ich noch ändern, wie z.b. dass die Mounts sauber geunmounted werden, wenn der Rechner runterfährt, man sich abmeldet, oder der Rechner schlafen geht. ^^
Aber es funktioniert schonmal.




7. Script testen
Das Script benutzt den Benutzernamen des ausführenden Benutzers, um die Quellordner und die Einhängepunkte zu finden. Ich muss es also als mein Benutzer ausführen.
Code:
$> ./bindfs-mounter.sh 
bindfs-mounter.sh started
found SRC_DISK_MOUNTPOINT=/Volumes/Perseus-HDD
found user home in /Volumes/Perseus-HDD/bindfs/user//Users/fyysh.
using read_bindfs-srcdirs_from_file
executing /opt/local/bin/bindfs -n --xattr-none -o volname=_DTA,volicon=/Volumes/Perseus-HDD/bindfs/user//Users/fyysh/VolumeIcon.icns "/Volumes/Perseus-HDD/bindfs/user//Users/fyysh/Downloads/_DTA" "/Users/fyysh/Downloads/_DTA" ...SUCCESS
executing /opt/local/bin/bindfs -n --xattr-none -o volname=BIGTMP,volicon=/Volumes/Perseus-HDD/bindfs/user//Users/fyysh/VolumeIcon.icns "/Volumes/Perseus-HDD/bindfs/user//Users/fyysh/TMP/BIGTMP" "/Users/fyysh/TMP/BIGTMP" ...SUCCESS
executing /opt/local/bin/bindfs -n --xattr-none -o volname=Movies,volicon=/Volumes/Perseus-HDD/bindfs/user//Users/fyysh/VolumeIcon.icns "/Volumes/Perseus-HDD/bindfs/user//Users/fyysh/Movies" "/Users/fyysh/Movies" ...SUCCESS
executing /opt/local/bin/bindfs -n --xattr-none -o volname=Music,volicon=/Volumes/Perseus-HDD/bindfs/user//Users/fyysh/VolumeIcon.icns "/Volumes/Perseus-HDD/bindfs/user//Users/fyysh/Music" "/Users/fyysh/Music" ...SUCCESS
executing /opt/local/bin/bindfs -n --xattr-none -o volname=Pictures,volicon=/Volumes/Perseus-HDD/bindfs/user//Users/fyysh/VolumeIcon.icns "/Volumes/Perseus-HDD/bindfs/user//Users/fyysh/Pictures" "/Users/fyysh/Pictures" ...SUCCESS
executing /opt/local/bin/bindfs -n --xattr-none -o volname=Images,volicon=/Volumes/Perseus-HDD/bindfs/user//Users/fyysh/VolumeIcon.icns "/Volumes/Perseus-HDD/bindfs/user//Users/fyysh/VMs/Images" "/Users/fyysh/VMs/Images" ...SUCCESS
bindfs-mounter.sh finished
Das sieht gut aus. Kurz überprüfen...
Code:
$> mount -t fuse4x
bindfs@fuse0 on /Users/fyysh/Downloads/_DTA (fuse4x, nodev, nosuid, synchronous, mounted by fyysh)
bindfs@fuse2 on /Users/fyysh/TMP/BIGTMP (fuse4x, nodev, nosuid, synchronous, mounted by fyysh)
bindfs@fuse3 on /Users/fyysh/Movies (fuse4x, nodev, nosuid, synchronous, mounted by fyysh)
bindfs@fuse4 on /Users/fyysh/Music (fuse4x, nodev, nosuid, synchronous, mounted by fyysh)
bindfs@fuse5 on /Users/fyysh/Pictures (fuse4x, nodev, nosuid, synchronous, mounted by fyysh)
bindfs@fuse8 on /Users/fyysh/VMs/Images (fuse4x, nodev, nosuid, synchronous, mounted by fyysh)
Großartig. Kurz überprüfen, ob das Ganze auch im Finder funktioniert...
2012-06-15_2040.png

Nice. Und wieder unmounten.
Code:
$> ./bindfs-mounter.sh umount
bindfs-mounter.sh started
bindfs@fuse0 unmount from /Users/fyysh/Downloads/_DTA
bindfs@fuse2 unmount from /Users/fyysh/TMP/BIGTMP
bindfs@fuse3 unmount from /Users/fyysh/Movies
bindfs@fuse4 unmount from /Users/fyysh/Music
bindfs@fuse5 unmount from /Users/fyysh/Pictures
bindfs@fuse8 unmount from /Users/fyysh/VMs/Images
bindfs-mounter.sh finished





8. launchd
Damit die Mounts nun immer da sind, wenn man sie braucht, also nach dem Starten, Aufwecken, Benutzerwechsel etc., sollte man einen launchd Job einrichten. Wenn es nur für den eigenen Benutzer ist, kann man das in ~/Library/LaunchAgents machen, soll es für alle Benutzer gelten, so sollte es in /Library/LaunchAgents sein. Soll das Script durch den root ausgeführt werden, müsste es in /Library/LaunchDaemons (vorsicht damit! Das Script ist dafür noch nicht ausgelegt!).

Ich lege mir solche Scripts samt ihren launchd plists gern in ~/Library/Scripts/LaunchAgents respektive /Library/Scripts/LaunchAgents und linke dann die plist in den entsprechenden Ordner.

So sieht meine launchd plist aus:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>de.fyysh.bindfs-mounter</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Library/Scripts/LaunchAgents/bindfs-mounter/bindfs-mounter.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

Diese ist, wie gesagt in /Library/Scripts/LaunchAgents/bindfs-mounter. Dort liegt auch das Script bindfs-mounter.sh. Da ich die LaunchAgents in /Library verwende, ist es wichtig, dass die Dateien und Ordner dem root gehören.
Code:
$> sudo mkdir -vp "/Library/Scripts/LaunchAgents/bindfs-mounter"
$> sudo mv "~/tmp/bindfsla/*" "/Library/Scripts/LaunchAgents/bindfs-mounter"
$> chown -R root:wheel "/Library/Scripts/LaunchAgents/bindfs-mounter"

Ich linke also die plist in die LaunchAgents:
Code:
$> sudo ln -sfv [I]/Library/Scripts/LaunchAgents/bindfs-mounter/[/I]de.fyysh.bindfs-mounter.plist [I]/Library/Scripts/LaunchAgents
[/I]

Und lade es in launchd und zwar ohne sudo, also wie es launchd machen würde, wenn ich mich anmelde o.ä.
Code:
$> launchctl load /Library/LaunchAgents/de.fyysh.bindfs-mounter.plist
$> mount -t fuse4x
bindfs@fuse0 on /Users/fyysh/Downloads/_DTA (fuse4x, nodev, nosuid, synchronous, mounted by fyysh)
bindfs@fuse2 on /Users/fyysh/TMP/BIGTMP (fuse4x, nodev, nosuid, synchronous, mounted by fyysh)
bindfs@fuse3 on /Users/fyysh/Movies (fuse4x, nodev, nosuid, synchronous, mounted by fyysh)
bindfs@fuse4 on /Users/fyysh/Music (fuse4x, nodev, nosuid, synchronous, mounted by fyysh)
bindfs@fuse5 on /Users/fyysh/Pictures (fuse4x, nodev, nosuid, synchronous, mounted by fyysh)
bindfs@fuse8 on /Users/fyysh/VMs/Images (fuse4x, nodev, nosuid, synchronous, mounted by fyysh)

Tadaaa.

Letzter Test: Neu starten und gucken, ob das Script ausgeführt wird.






9. Bisherige Beobachtungen
• Es kann ein wenig dauern, bis die Mounts nach dem Login verfügbar sind.

launchd sorgt zuverlässig dafür, dass die Mounts immer gemounted sind (auch wenn das noch kein optimales launchd Script ist).

• Bisher funktioniert es sehr zuverlässig.

• Time Machine sichert beide Platten, aber trotz den bindfs Mounts nichts doppelt. Das liegt daran, dass die Mounts für OS X Netzlaufwerke sind (solange man nicht die Option local für die Mounts verwendet, wovon ich dringend abraten möchte). Kurz: Time Machine funktioniert wunderbar.

• Trotz Warnungen vor Dateikorruption noch keine erlebt. Zur Sicherheit habe ich die zweite Platte derzeitig in zwei Partitionen aufgeteilt und als ZFS-mirror laufen. Falls eine Datei korrumpiert wird, sollte es ZFS bemerken. Ich habe große Dateien (>10g) auf der zweiten Platte erstellt und anschließend durch die Einhängepunkte hin und her geschoben - keine Probleme. Ob es nicht doch irgendwann zur Datenkorruption kommt, kann ich aber derzeitig nicht sagen. Ich hoffe nicht.



10. Was noch kommt
• Script 100%ig launchd-tauglich machen und an ein paar Stellen polieren.

• Script als daemon ausführen und so die /.MobileBackups von der SSD auf die zweite Platte umlenken.
Die .MobileBackups nehmen mir zu viel Platz auf der SSD ein, weshalb ich sie derzeitig deaktiviert habe. Ein manueller Kurztest hat gezeigt, dass es funktionieren könnte.

Allerdings ist meine Zeit knapp und das wird sicher dauern... ;)
 
Zuletzt bearbeitet:

ImperatoR

Roter Astrachan
Registriert
02.12.06
Beiträge
6.261
Ein sehr schöner Bericht, danke dafür!

Ich habe auch eine solche Festplatten-Konstellation, jedoch bisher haben mir die Links gereicht, die mit `ln -s quelle link` bzw. Alias erstellt wurden. Die Shell folgt ihnen ohne Problem und der Finder verhält sich doch so, als wäre der Ordner auch dort. Oder wie meinst du das?

Und die Lösung mit bindfs ist wohl sonderlich performant, da fuse rein im Userspace läuft. Schade, dass es nicht einfach mit `mount --bind` funktioniert.
 

fyysh

Schweizer Glockenapfel
Registriert
25.01.10
Beiträge
1.386
... bisher haben mir die Links gereicht, die mit `ln -s quelle link` bzw. Alias erstellt wurden. Die Shell folgt ihnen ohne Problem und der Finder verhält sich doch so, als wäre der Ordner auch dort. Oder wie meinst du das?
In der Listenansicht funktioniert es nicht.

Und die Lösung mit bindfs ist wohl sonderlich performant, da fuse rein im Userspace läuft. Schade, dass es nicht einfach mit `mount --bind` funktioniert.

Auf Von SSD auf die die HDD schreiben mit nicht knapp 70MB/s
Von HDD auf die SSD schreiben mit knapp 86 MB/s.

Das reicht mir. ;)
 

ImperatoR

Roter Astrachan
Registriert
02.12.06
Beiträge
6.261
In der Listenansicht funktioniert es nicht.

In der Tat, dort funktioniert es nicht. Ich verwende halt die Spalten-Darstellung, daher ist es mir bisher noch nicht aufgefallen. :)


Auf Von SSD auf die die HDD schreiben mit nicht knapp 70MB/s
Von HDD auf die SSD schreiben mit knapp 86 MB/s.

Da kann man nicht meckern. Wenn die CPU-Last sich noch in Grenzen hält...
 

fyysh

Schweizer Glockenapfel
Registriert
25.01.10
Beiträge
1.386
Update hierzu:

Während anfänglich Beschriebenes mit dem Port fuse4x @0.9.0 problemlos lief, scheint es mit Port fuse4x @0.9.1 Probleme zu geben. Nach dem Update habe ich bei der Benutzung der bindfs Mounts einige Probleme erfahren.
Vom Terminal aus geht alles immer noch super, aber, sobald der Zugriff aus höheren Schichten als dem BSD Subsystem erfolgt, so scheint es zumindest, wird es unzuverlässig und kann sogar zu 'nem Sysfreeze führen.
Deshalb: Nicht empfehlenswert.

Ich bin wieder auf die Softlinks umgestiegen.
Schade eigentlich.
 

chrisrig

Süssreinette (Aargauer Herrenapfel)
Registriert
07.11.06
Beiträge
408
2. Festplatte nach /User/Benutzername mounten

Nun also, mit zwei Platten, bin ich auf folgendes Problem gestoßen:

Die zweite Platte ist für große Datein da, die keinen schnellen Zugriff benötigen und Platz wegnehmen, z.B. Bilder, Musik und Videos aber auch mein Download-Archiv usw. Diese möchte ich aber nach wie vor über mein Benutzerprofil erreichen und nicht umständlich auf eine andere Platte klicken, um zum gewünschten Ziel zu kommen.

Eine Möglichkeit wäre es, Symlinks zu benutzen. Blöd nur: Die behandelt der Finder eben auch als solche und wenn sie geöffnet werden, geht der Finder auf die Platte. Mit CMD+UP kommt man also nicht zum Ursprungsort, sagen wir ~/, zurück, sondern eben auf /Volumes/Die2tePlatte/DerMusikOrdner. Das nervt.

Was spricht dagegen, die 2. Festplatte nach /User/Benutzername zu mounten, anstatt nach /Volumes ?

Bis SL 10.6 funktioniert das einwandfrei über einen Eintrag in die Datei /etc/fstab

sieht bei mir so aus:
UUID=7185CC04-9B85-3CD5-A128-F4DED50BAF43 /Users/chris hfs rw

Ob es mit Lion und später noch funktioniert kann ich nicht sagen.

Grüße.
 

nightmare28

Jonagold
Registriert
11.11.06
Beiträge
20
Hallo kurze Frage. Ist dieses nicht durch die MacOsX 10.8 beinhaltende Lösung a la FUSION DRIVE?
 

chrisrig

Süssreinette (Aargauer Herrenapfel)
Registriert
07.11.06
Beiträge
408
nein, bei Fusion Drive entscheidet das OS welche Daten auf der SSD und welche auf der HDD landen.
Wenn du die 2. Festplatte an eine bestimmt stelle mountest, musst du dich selbst darum kümmern,
welche Daten auf der schnellen und welche auf der langsamen Disk liegen.
 

fyysh

Schweizer Glockenapfel
Registriert
25.01.10
Beiträge
1.386
Was spricht dagegen, die 2. Festplatte nach /User/Benutzername zu mounten, anstatt nach /Volumes ?

Hi,

das geht auch bei Lion - gar kein Problem.
Die Frage ist, ob es das ist, was man will.

Ich wollte das nicht. Was ich wollte waren tatsächlich nullfs mounts (oder etwas, was zumindest so ähnlich funktioniert) innerhalb meines Benutzerordners, so dass *manche* Verzeichnisse in meinem Benutzerordner zur HDD führen (nicht alle), mein Home aber dennoch so funktioniert, als wäre nach wie vor alles darin gespeichert und nicht auf verschiedenen Datenträgern... blablaetc.

Bei deiner Lösung ist ja dein gesamtes $HOME auf dem anderen Datenträger.