syscl / Fix-usb-sleep

Fix issue of "Diks not ejected properly upon sleep" on macOS
71 stars 20 forks source link

Mojave / 2018 Mac mini issue #16

Open jj5836 opened 6 years ago

jj5836 commented 6 years ago

I've started using this package with my new Mac mini. It ejects the disk just fine on sleep, but does not remount it on wake. The issue is that somehow (maybe due to APFS) my one external SSD shows up as two disks:

/dev/disk2 (external, physical):

: TYPE NAME SIZE IDENTIFIER

0: GUID_partition_scheme *1.0 TB disk2 1: EFI EFI 209.7 MB disk2s1 2: Apple_APFS Container disk3 1000.0 GB disk2s2

/dev/disk3 (synthesized):

: TYPE NAME SIZE IDENTIFIER

0: APFS Container Scheme - +1000.0 GB disk3 Physical Store disk2s2 1: APFS Volume ExtSSD 597.2 GB disk3s1

So disk3 is somehow "synthesized" and related to disk2. This interferes with the sleep script because it unmounts disk2 first, which also unmounts disk3. But then it never sees disk3 (which has the actual mounted filesystem) to write it down as something to be mounted on wake. So the disk is never re-mounted. A simple fix is to separate this into two loops. One loop to write down things to be remounted, and a second to eject or unmount disks.

Here is the modified code with two loops:

# first write down things we need to remount
for ((i=0; i<${#gDisk[@]}; ++i))
do
    gProtocol=$(diskutil info ${gDisk[i]} |grep -i "Protocol" |sed -e "s|Protocol:||" -e "s| ||g")
    if [[ ${gProtocol} == *"USB"* ]];
    then
    gCurrent_Partitions=($(diskutil list ${gDisk[i]} |grep -o "disk[0-9]s[0-9]"))
    for ((k=0; k<${#gCurrent_Partitions[@]}; ++k))
    do
            gConfirm_Mounted=$(diskutil info ${gCurrent_Partitions[k]} |grep -i Mounted |sed -e "s| Mounted:||" -e "s| ||g")
            if [[ ${gConfirm_Mounted} == *"Yes"* ]];
            then
        echo ${gCurrent_Partitions[k]} >> ${gMountPartition}
            fi
    done
    fi
done

# now actually eject or unmount things
for ((i=0; i<${#gDisk[@]}; ++i))
do
  gProtocol=$(diskutil info ${gDisk[i]} |grep -i "Protocol" |sed -e "s|Protocol:||" -e "s| ||g")
  is_SDCard=$(diskutil info ${gDisk[i]} |grep -i "Device / Media Name" |grep -i "SD Card")
  if [[ ${gProtocol} == *"USB"* ]];
    then
      if [ -z ${is_SDCard} ]; then
          diskutil eject ${gDisk[i]}
      else
          diskutil unmountDisk ${gDisk[i]}
      fi
  fi
done
maz-1 commented 6 years ago

It could be stripped down. I have made a pull request: https://github.com/syscl/Fix-usb-sleep/pull/17

syscl commented 6 years ago

Thank you @jj5836, please try @maz-1 's fix.