Current section
Files
Jump to
Current section
Files
lib/extmpfs.ex
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