From 3d375aeb2f2cd9c629fd0e99d17f3f24742581ec Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Sat, 04 Oct 2014 22:11:20 -0400 Subject: session_*(): New functions --- (limited to 'lib') diff --git a/lib/local.mk b/lib/local.mk index 3de79f7..66d203f 100644 --- a/lib/local.mk +++ b/lib/local.mk @@ -10,6 +10,7 @@ pkgdata_sources = \ lib/feed.sh \ lib/pkg.sh \ lib/mutex.sh \ + lib/session.sh \ lib/chroot.sh \ lib/opkg.sh \ lib/rand.sh \ diff --git a/lib/session.sh b/lib/session.sh new file mode 100644 index 0000000..1430493 --- /dev/null +++ b/lib/session.sh @@ -0,0 +1,134 @@ +# Functions for managing prokit sessions +# +# Copyright (C) 2014 Patrick "P. J." McDermott +# +# This file is part of the ProteanOS Development Kit. +# +# The ProteanOS Development Kit is free software: you can redistribute +# it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# The ProteanOS Development Kit is distributed in the hope that it +# will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the ProteanOS Development Kit. If not, see +# . + +[ "x${_SESSION_SM+set}" = 'xset' ] && return 0 +_SESSION_SM=1 + +use rand +use mutex +use output +use locale +use profile + +session_id= +session_root= +session_arch= +session_plat= +session_atexit= + +session_begin() +{ + local root="${1}" + local atexit="${2}" + + rand + session_id=${rand_x} + session_root="${root}" + session_arch="$(cat "${root}/etc/proteanos_arch")" + session_plat="$(cat "${root}/etc/proteanos_plat")" + session_atexit="${atexit}" + + if ! mutex_lock_timeout "${session_root}/prokit/sessions.lock" 5; then + error 2 "$(get_msg 'cant_lock_sessions')" + fi + + # Check for a sessions pool. + if [ -d "${session_root}/prokit/sessions" ]; then + if ! profile_file_systems_mounted; then + # If a sessions pool exists but the file systems aren't + # mounted, clean up the old sessions and mount the file + # systems. + rmdir "${session_root}/prokit/sessions/"* + session_mount + fi + else + # If the sessions pool doesn't exist, create it and mount the + # file systems. + mkdir "${session_root}/prokit/sessions" + session_mount + fi + + # Register the session. + mkdir "${session_root}/prokit/sessions/${session_id}" + + mutex_unlock "${session_root}/prokit/sessions.lock" +} + +session_end() +{ + # Unregister the session. + rmdir "${session_root}/prokit/sessions/${session_id}" + + if ! mutex_lock_timeout "${session_root}/prokit/sessions.lock" 5; then + error 2 "$(get_msg 'cant_lock_sessions')" + fi + + # Clear the sessions pool. If there are no more sessions, unmount the + # file systems. + if rmdir "${session_root}/prokit/sessions" 2>/dev/null; then + session_umount + fi + + mutex_unlock "${session_root}/prokit/sessions.lock" +} + +session_id() +{ + printf '%d\n' ${session_id} + return 0 +} + +session_mount() +{ + local fs= + local dir= + local fstype= + local options= + + while read fs dir fstype options; do + [ "x${dir}" = 'x' ] && continue + mount -t "${fstype}" -o "${options}" "${fs}" \ + "${session_root}/${dir}" + done <<-EOF + $(profile_get_fstab "${session_arch}" "${session_plat}") + EOF +} + +session_umount() +{ + local fs= + local dir= + local fstype= + local options= + + while read fs dir fstype options; do + [ "x${dir}" = 'x' ] && continue + # umount sometimes complains that the /dev file system is busy. + # Here's a kludge to try to handle that. We better make sure + # bind mounts get unmounted; otherwise, `rm -Rf ${root}` can be + # painful. + while ! umount "${session_root}/${dir}"; do + sleep 1 + done + done <<-EOF + $(profile_get_fstab "${session_arch}" "${session_plat}" | \ + sed -n '1!G;h;$p') + EOF +} -- cgit v0.9.1