defmodule ExTmpFs do @moduledoc """ This module provide some functions for the wrapper of TmpFs System. He use System.cmd, so use sudo is preferable. """ # TODO Make documentation @type size_type :: :O | :K | :M | :G @type size :: [size: non_neg_integer, type: size_type] @doc """ Mount and create the directory to mount a tmpfs device. ## Parameters - path: Path.t - size: size ## examples sudo iex -S mix iex> {:ok, ref} = ExTmpFs.mount(".tmp", [size: 1, size_type: :G]) """ @spec mount(path :: Path.t, size :: size) :: {:ok, atom} | {:error, term} def mount(path, size) do name = ((path |> Path.basename) <> (path |> Comeonin.Bcrypt.hashpwsalt |> String.slice(0,5))) |> String.to_atom case ConCache.get(:cache_extmpfs, {:tmpfs, name}) do nil -> case File.mkdir_p(path) do :ok -> case System.cmd("mount", ["-t", "tmpfs", "-o", "size=#{size[:size]}#{size[:size_type]}", "tmpfs", path], [stderr_to_stdout: true]) do {_nil, 0} -> ConCache.put(:cache_extmpfs, {:tmpfs, name}, path) {:ok, name} {_reason, 1} -> {:error, "incorrect invocation or permissions"} {_reason, 2} -> {:error, "system error (out of memory, cannot fork, no more loop devices)"} {_reason, 4} -> {:error, "internal mount bug"} {_reason, 8} -> {:error, "user interrupt"} {_reason, 16} -> {:error, "problems writing or locking /etc/mtab"} {_reason, 32} -> {:error, "mount failure"} {_reason, 64} -> {:error, "some mount succeeded"} {reason, _integer} -> {:error, reason} end _error = file_error -> {:error, file_error} end _ -> {:error, "Name already choosed"} end end @doc """ Umount and destroy the directory of mounting tmpfs device. ## Parameters - name: atom ## examples sudo iex -S mix iex> {:ok, ref} = ExTmpFs.mount(".tmp", [size: 1, size_type: :G]) iex> :ok = ExTmpFs.umount(ref) """ @spec umount(name :: atom) :: :ok | {:error, term} def umount(name) do case ConCache.get(:cache_extmpfs, {:tmpfs, name}) do nil -> {:error, "incorrect name for tmpfs partition"} path -> ConCache.delete(:cache_extmpfs, {:tmpfs, name}) case System.cmd("umount", [path], [stderr_to_stdout: true]) do {_nil, 0} -> File.rmdir(path) :ok {_reason, _value} -> {:error, "some umount errors"} end end end end