commit 7ef0141356454503ab81460290b5dffa32c1f441 Author: David Ward <david.ward@ll.mit.edu> Date: Fri May 4 00:50:15 2012 +0200 refresh lxc-ls Add an '--active' option that lists active containers by searching cgroups. (Otherwise, the directories in /var/lib/lxc are listed.) Modify the cgroup search to only use hierarchies that contain one or more subsystems. When searching, if a hierarchy contains the 'ns' subsystem, do not append '/lxc' to the parent cgroup. Add a '--help' option that prints the command syntax. Print error messages and help information to stderr. Update the documentation. Signed-off-by: David Ward <david.ward@ll.mit.edu> Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com> diff --git a/doc/lxc-ls.sgml.in b/doc/lxc-ls.sgml.in index 3ffd4f8..d33e9b3 100644 --- a/doc/lxc-ls.sgml.in +++ b/doc/lxc-ls.sgml.in @@ -48,7 +48,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA <refsynopsisdiv> <cmdsynopsis> - <command>lxc-ls <optional>ls option</optional> + <command>lxc-ls <optional>--active</optional> <optional>ls option</optional> </command> </cmdsynopsis> </refsynopsisdiv> @@ -67,6 +67,17 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA <varlistentry> <term> + <option><optional>--active</optional></option> + </term> + <listitem> + <para> + List active containers. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term> <option><optional>ls options</optional></option> </term> <listitem> @@ -94,10 +105,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA </varlistentry> <varlistentry> - <term>lxc-ls -1</term> + <term>lxc-ls --active -1</term> <listitem> <para> - list all the containers and display the list in one column. + list active containers and display the list in one column. </para> </listitem> </varlistentry> diff --git a/src/lxc/lxc-ls.in b/src/lxc/lxc-ls.in index a1ad642..11a3b45 100644 --- a/src/lxc/lxc-ls.in +++ b/src/lxc/lxc-ls.in @@ -1,43 +1,100 @@ #!/bin/bash -localstatedir=@LOCALSTATEDIR@ -lxcpath=@LXCPATH@ +# +# lxc: linux Container library -if [ ! -r $lxcpath ]; then - exit 0 -fi +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# This library 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 +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +localstatedir=@LOCALSTATEDIR@ +lxc_path=@LXCPATH@ -function get_cgroup() +usage() { - local mount_string - mount_string=$(mount -t cgroup |grep -E -e '^lxc ') - if test -n "$mount_string"; then - mount_point=$(echo $mount_string |cut -d' ' -f3) - return - fi - mount_string=`grep -m1 -E '^[^ \t]+[ \t]+[^ \t]+[ \t]+cgroup' /proc/self/mounts`; - if test -z "$mount_string"; then - echo "failed to find mounted cgroup" - exit 1 - fi - mount_point=`echo "$mount_string" |cut -d' ' -f2`; + echo "usage: $(basename $0) [--active] [--] [LS_OPTIONS...]" >&2 } -ls "$@" $lxcpath +help() { + usage + echo >&2 + echo "List containers existing on the system." >&2 + echo >&2 + echo " --active list active containers" >&2 + echo " LS_OPTIONS ls command options (see \`ls --help')" >&2 +} + +get_parent_cgroup() +{ + local hierarchies hierarchy fields subsystems init_cgroup mountpoint + + parent_cgroup="" + + # Obtain a list of hierarchies that contain one or more subsystems + hierarchies=$(tail -n +2 /proc/cgroups | cut -f 2) -active=$(netstat -xl 2>/dev/null | grep $lxcpath | \ - sed -e 's#.*'"$lxcpath/"'\(.*\)/command#\1#'); + # Iterate through the list until a suitable hierarchy is found + for hierarchy in $hierarchies; do + # Obtain information about the init process in the hierarchy + fields=$(grep -E "^$hierarchy:" /proc/1/cgroup | head -n 1) + if [ -z "$fields" ]; then continue; fi + fields=${fields#*:} -if test -n "$active"; then - get_cgroup - if test -n "$mount_point"; then - # get cgroup for init - init_cgroup=`cat /proc/1/cgroup | awk -F: '{ print $3 }' | head -1` - if [ ! -d $mount_point/$init_cgroup/lxc ]; then - cd $mount_point/$init_cgroup + # Get a comma-separated list of the hierarchy's subsystems + subsystems=${fields%:*} + + # Get the cgroup of the init process in the hierarchy + init_cgroup=${fields#*:} + + # Get the filesystem mountpoint of the hierarchy + mountpoint=$(grep -E "^cgroup [^ ]+ [^ ]+ ([^ ]+,)?$subsystems(,[^ ]+)? " /proc/self/mounts | cut -d ' ' -f 2) + if [ -z "$mountpoint" ]; then continue; fi + + # Return the absolute path to the containers' parent cgroup + # (do not append '/lxc' if the hierarchy contains the 'ns' subsystem) + if [[ ",$subsystems," == *,ns,* ]]; then + parent_cgroup="${mountpoint}${init_cgroup%/}" else - cd $mount_point/$init_cgroup/lxc + parent_cgroup="${mountpoint}${init_cgroup%/}/lxc" fi - ls "$@" -d $active - fi + break + done +} + +directory="$lxc_path" + +for i in "$@"; do + case $i in + --help) + help; exit 1;; + --active) + get_parent_cgroup; directory="$parent_cgroup"; shift;; + --) + shift; break;; + *) + break;; + esac +done + +containers="" +if [ ! -z "$directory" ]; then + containers=$(find $directory -mindepth 1 -maxdepth 1 -type d -printf "%f\n" 2>/dev/null) fi + +if [ -z "$containers" ]; then + echo "$(basename $0): no containers found" >&2 + exit 1 +fi + +cd "$directory" +ls -d $@ $containers