Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
changeset 644:0c7917469e04
Put the check for opened files with "procstat" into a subroutine and use it
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Fri, 27 Sep 2024 17:23:01 +0200 |
| parents | 4f2257ea7d0a |
| children | aa21ec8b86c5 |
| files | sbin/ftjail share/local-bsdtools/common.subr |
| diffstat | 2 files changed, 128 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/sbin/ftjail Fri Sep 27 17:07:57 2024 +0200 +++ b/sbin/ftjail Fri Sep 27 17:23:01 2024 +0200 @@ -931,22 +931,9 @@ return 1 fi done - # - # Check whether there are any open files within the jail. - # - # "procstat file" also lists fifo, socket, message queue, kgueue et al. - # file types. - # - # Note that procstat places extra whitespace at the end of lines sometimes. - # - # - if procstat -a file | /usr/bin/grep -E '['$'\t '']+'"${_directory}"'(/|(['$'\t '']*)$)' ; then - echo "ERROR: There are open files within the jail" >&2 - return 1 - fi - # The same for memory mappings - if procstat -a vm | /usr/bin/grep -E '['$'\t '']+'"${_directory}"'(/|(['$'\t '']*)$)' ; then - echo "ERROR: There are open memory mappings within the jail" >&2 + # Check whether there are any open files or VM mappings within the jail. + if ! _check_no_open_files_from_all_proc "${_directory}" ; then + err "There are open files or memory mappings within the jail" return 1 fi
--- a/share/local-bsdtools/common.subr Fri Sep 27 17:07:57 2024 +0200 +++ b/share/local-bsdtools/common.subr Fri Sep 27 17:23:01 2024 +0200 @@ -11,6 +11,16 @@ #: :ID: @(#)@@SIMPLEVERSIONTAG@@ #: +# +# "procstat --libxo=json,no-locale -a file | jq -r $'.procstat.files | map(.) | .[] | [ .command, .files.[] | .fd, .fd_type, .path] | @tsv ' +# +# WORKING (without the command name) +# procstat --libxo=json,no-locale -a file | jq -r $'.procstat.files | map(.)| .[] | .files.[] | [.fd, .fd_type, .path] | @tsv ' +# +# FULL WITH command name +# procstat --libxo=json,no-locale -a file | jq -r $'.procstat.files | map(.) | .[] | .command as $cmd | .files[] | [ $cmd, .fd, .fd_type, .vode_type, .path ] | @tsv ' + + #: #: Dummy function to make the first "shellcheck" directive below non-global @@ -506,6 +516,121 @@ #: +#: Use :command:`/usr/bin/procstat` to check if there are opened files or +#: VM mappings with a given path prefix. +#: +#: Args: +#: $1 (str, optional): The path prefix to check open files for. +#: This must be an absolute path. +#: The root directory :file:`/` is allowed. +#: A `null` value is treated as if the root directory :file:`/` is given +#: as argument. +#: +#: Returns: +#: int: 0 if there are no opened files found, +#: 10 if there are opened files found. +#: Other error codes may also returned on errors. +#: +_check_no_open_files_from_all_proc() { + local _path_prefix + + local _command _fd _fd_type _vnode_type _path _pid _kve_type _kve_path _rc + + _path_prefix="${1-}" + case "${_path_prefix}" in + '') + # OK this matches at the root directory + _p1='/' + _p2='/' + ;; + /) + # OK this matches at the root directory + _p1='/' + _p2='/' + ;; + *//*) + fatal 1 "given path prefix must not contain consequtive slashes" + ;; + /*/) + # Remove trailing slash for equality check + _p1="${_path_prefix%/}" + # Hold the trailing slash as-is for prefix check + _p2="${_path_prefix}" + ;; + /*) + _p1="${_path_prefix}" + _p2="${_path_prefix}/" + ;; + *) + fatal 1 "given path prefix must be an absolute path" + ;; + esac + if [ -x "${JQ}" ]; then + # shellcheck disable=SC2016 # $cmd is really not to expand here + LC_ALL=C.UTF-8 /usr/bin/procstat --libxo=json -a file | LC_ALL=C.UTF-8 "${JQ}" -r '.procstat.files | map(.)| .[] | .command as $cmd | .files[] | [ $cmd, .fd, .fd_type, .vode_type, .path ] | @tsv' \ + | { + _rc=0 + while IFS=$'\t' read -r _command _fd _fd_type _vnode_type _path; do + case "${_path}" in + "${_p1}"|"${_p2}"*) + _rc=10 + ;; + *) + ;; + esac + done + [ "${_rc}" -ne 0 ] && return ${_rc} + } + LC_ALL=C.UTF-8 /usr/bin/procstat --libxo=json -a vm | LC_ALL=C.UTF-8 "${JQ}" -r $'.procstat.vm | map(.) | .[] | .process_id as $pid | .vm[] | [ $pid, .kve_type, .kve_path ] | @tsv' \ + | { + _rc=0 + while IFD=$'\t' read -r _pid _kve_type _kve_path; do + case "${_kve_path}" in + "${_p1}"|"${_p2}"*) + _rc=10 + ;; + *) + ;; + esac + done + return ${_rc} + } + else + /usr/bin/procstat --libxo=text,no-locale -a file \ + | LC_ALL=C /usr/bin/awk -v OFS=$'\t' '{ print $2, $3, $4, $10; }' \ + | { + _rc=0 + while IFS=$'\t' read -r _command _fd _fd_type _path; do + case "${_path}" in + "${_p1}"|"${_p2}"*) + _rc=10 + ;; + *) + ;; + esac + done + [ "${_rc}" -ne 0 ] && return ${_rc} + } + /usr/bin/procstat --libxo=text,no-locale -a vm \ + | LC_ALL=C /usr/bin/awk -v OFS=$'\t' '{ print $1, $10, $11; }' \ + | { + _rc=0 + while IFD=$'\t' read -r _pid _kve_type _kve_path; do + case "${_kve_path}" in + "${_p1}"|"${_p2}"*) + _rc=10 + ;; + *) + ;; + esac + done + return ${_rc} + } + fi +} + + +#: #: Check the validity of ZFS dataset names. #: #: See: ZFS Component Naming Requirements
