Apple Event: May 7th at 7 am PT

Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

RAM Disk Ejects Too Fast on Shutdown

This is a more specific, more drilled-down version of a post I made a few weeks ago. The situation is this:


I have a shell script that runs on boot as a launchd that creates a RAM disk on my server, and copies a bunch of files to it. The shell script keeps running, and when the computer is shutdown, it runs it's own "shutdown" function that copies all of the files off of the RAM disk before the system shuts down.


Please note that this is not the only way I backup the data on this RAM disk. I am fully aware how tenuous RAM disks and the data kept on them are. The data is backed up in several other ways. But the final writing out on shutdown is an important one to keep recent changes from being lost.


Back to the script. It all works properly, the right parts of my script run when they should. The problem seems to be however, that the system sends my script the shutdown command, and at the same time, it shuts down the RAM disk system. Thus I am only able to copy a small amount of the files off before the RAM disk ceases to exist. It only takes a few seconds to run this copy command, but apparently you only get one second.


The script uses a `tail -f /dev/null` command to keep it running. I changed that to `tail -f /path/to/ramdisk/.handle`, the idea being it would keep a file open on the RAM disk and that would prevent the RAM disk from ejecting until after my script had finished coping the files. It *helped*, I get more of the files, but I don't get all of them.


So unless there's a better way entirely to do this, what it seems I need is a way to "jam" the RAM disk open, so it can't unmount, until my script is done. I do not have a lot of experience with anything beyond the most simple of shell scripts, so I'm in uncharted waters a bit.


This is the simple script I use. It works very well, and if I were doing anything other than access a RAM disk, it seems like it would work perfectly. In my destroy ramdisk function, I just need a way to prop the RAM disk open before I call the backup script, then remove the prop immediately after.


#!/bin/bash


function create_ramdisk()

{

# /create.ramdisk.sh

tail -f /Volumes/ramdisk/.handle &

wait $!

}


function destroy_ramdisk()

{

## /backup.ramdisk.sh

exit 0

}


trap destroy_ramdisk SIGTERM

create_ramdisk;

Xserve, OS X El Capitan (10.11.6), 2009

Posted on Mar 11, 2018 9:11 AM

Reply

Similar questions

5 replies

Mar 31, 2018 6:45 PM in response to l008com

Shutdown will first kill (kill, Kill, KILL) all the running processes, and then it will unmount mounted volumes, so you tail command is not going to work because your tail command is killed. Shutdown will first send a kill -HUP to give processes a change to terminate cleanly, but if they do not do that in a timely manor, shutdown will send kill -9 which is next to impossible for any process to ignore (except a process hung in kernel space, they just never see the kill signal, which is also generally considered a bug).


Why not write a script that does a shutdown AFTER saving your RAMDISK contents?

Terminal session "man shutdown", and if using Applescript, something like

do shell script "yourScriptHere" with administrator privileges

Mar 31, 2018 7:35 PM in response to BobHarris

The problem is I want my script to run when a normal shutdown (or reboot) is initiated. The solution you suggest would only work in cases where i manually initiate the shutdown using my script. So for example if the system reboots after a software update, my script wouldn't run.


A similar solution along those lines I've seen is to actually replace the system's own shutdown command with my own script that first backs up the RAM disk and THEN calls the system's real shutdown command. Kind of hackey but it could work. Problem is system updates will get rid of my script. AND the big problem is that with SIP, it's a pain in the *** to replace the shutdown command. And since this computer is going to live in a data center, I don't want to have to fight with SIP remotely, that could lead to even more headaches.

Apr 2, 2018 5:54 AM in response to l008com

Then I think it is time you started looking at "man launchd.plist", and most likely a lot of Google searching for launchd examples.


While I am not proficient with launchd, I did look at the man page and saw

ExitTimeOut <integer>

The amount of time launchd waits between sending the SIGTERM signal and before sending a SIGKILL signal when the job is to be stopped. The default value is system-defined. The value zero is interpreted as infinity and should not be used, as it can stall system shutdown forever.

and of course, whatever you are implementing must ignore SIGTERM. A shell script would use 'trap' to do that.

Apr 2, 2018 4:39 PM in response to l008com

While I do not develop software for macOS, my day job is as a Unix file system developer and the general rule is that you cannot unmount a file system until all the processes that have open files on the file system have closed their files.


A "umount -f" effectively causes the kernel to kill all the processes that have files open on the file system. Reading the macOS "man umount" page indicates that "umount -f" does not kill the process, but rather just dead ends the open file, such that the process gets an error. I do NOT know if macOS uses umount -f or if it uses SIGKILL at the ultimate solution.


And as I mentioned before, the typical shutdown sequence on a Unix system is to first send a SIGHUP (which based on the launchd.plist man page, might actually be a SIGTERM, and then if the process does not go away after a wait interval, the shutdown sequence sends a SIGKILL which cannot be caught, nor ignored by any process, and generally, the process dies. In the act of dying, the operating system closes all its open file references.


So while you seem to have a "trap SIGKILL", there is nothing you can do to stop the SIGKILL, which is why maybe you need to play with the ExitTimeOut launchd.plist value.


NOTE: Best practice for a RAM disk is that it be files you do not care about. Either it is loaded with files that are there for faster read access, or it is used to hold scratch files that can be lost without consequences if there is a crash or power failure. You are not doing that, and as a result, your files are at risk.


You could also look at maybe having a periodic rsync command save updated files. Rsync has options for deleting files that were deleted from the source, and when you are in shutdown save mode, rsync would only need to copy modified files. It is a thought, assume the RAM disk contents do not change so often that rsync would effectively be copying all the files anyway.

RAM Disk Ejects Too Fast on Shutdown

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.