From 58c696e88cfeb6d97d836b9f328d683b0e187d65 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Tue, 2 Dec 2003 17:20:39 +0000 Subject: Initial Import --- AUTHORS | 4 + BUGS | 3 + COPYING | 14 ++ INSTALL | 17 +++ Makefile.am | 3 + NEWS | 1 + README | 13 ++ config.h.in | 100 ++++++++++++++ configure.ac | 33 +++++ jails_man.html | 46 +++++++ killjail_man.html | 76 +++++++++++ src/Makefile | 357 +++++++++++++++++++++++++++++++++++++++++++++++++ src/Makefile.am | 8 ++ src/getjail.c | 69 ++++++++++ src/getjail.h | 35 +++++ src/jails.8 | 26 ++++ src/jails.c | 157 ++++++++++++++++++++++ src/killjail.8 | 68 ++++++++++ src/killjail.c | 387 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 19 files changed, 1417 insertions(+) create mode 100644 AUTHORS create mode 100644 BUGS create mode 100644 COPYING create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100644 config.h.in create mode 100644 configure.ac create mode 100644 jails_man.html create mode 100644 killjail_man.html create mode 100644 src/Makefile create mode 100644 src/Makefile.am create mode 100644 src/getjail.c create mode 100644 src/getjail.h create mode 100644 src/jails.8 create mode 100644 src/jails.c create mode 100644 src/killjail.8 create mode 100644 src/killjail.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..b3bce76 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,4 @@ +nielsen@memberwebs.com + +Patches and Contributions: +steve@rhythm.cx \ No newline at end of file diff --git a/BUGS b/BUGS new file mode 100644 index 0000000..cc12c86 --- /dev/null +++ b/BUGS @@ -0,0 +1,3 @@ +JAILUTILS TODOS and BUGS + +- Email diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..cf2037b --- /dev/null +++ b/COPYING @@ -0,0 +1,14 @@ +LICENSE +This software is in the public domain. + +The software is provided "as is", without warranty of any kind, +express or implied, including but not limited to the warranties +of merchantability, fitness for a particular purpose, and +noninfringement. In no event shall the author(s) be liable for any +claim, damages, or other liability, whether in an action of +contract, tort, or otherwise, arising from, out of, or in connection +with the software or the use or other dealings in the software. + +SUPPORT +Send bug reports to: + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..bb81194 --- /dev/null +++ b/INSTALL @@ -0,0 +1,17 @@ +====================================================================== + JAILUTILS INSTALL + + +This software only works with FreeBSD jails. It should be installed +on the host system. + + +QUICK INSTALLATION: + # tar -zxvf jailutils-0.5.4.tar.gz + # ./configure + # make && make install + + +This installs the commands killjails and jails on your system, probably +in /usr/local/sbin. See the man pages for more detailed info. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..0739508 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,3 @@ +EXTRA_DIST = BUGS +SUBDIRS = src + diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..c7ab92a --- /dev/null +++ b/NEWS @@ -0,0 +1 @@ +See ChangeLog \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..330112e --- /dev/null +++ b/README @@ -0,0 +1,13 @@ +================================================================= + JAILUTILS README + +Several utilies for managing jails. + +killjail: shutdown or restart a jail (when used with jailer). +jails: list the jails running on a system. + + +For further jail aids see: + +http://memberwebs.com/nielsen/freebsd/jails/ + diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..f528c73 --- /dev/null +++ b/config.h.in @@ -0,0 +1,100 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `kvm' library (-lkvm). */ +#undef HAVE_LIBKVM + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if your system has a working `malloc' function. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_PATH_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSLOG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `long' if does not define. */ +#undef off_t + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `unsigned' if does not define. */ +#undef size_t diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..3b34e62 --- /dev/null +++ b/configure.ac @@ -0,0 +1,33 @@ +# Process this file with autoconf to produce a configure script. +AC_INIT(jailutils, 0.5.4, nielsen@memberwebs.com) +AM_INIT_AUTOMAKE(jailutils, 0.5.4) + +AC_CONFIG_SRCDIR([src/killjail.c]) +AM_CONFIG_HEADER([config.h]) + +# Checks for programs. +AC_PROG_CC + +# Checks for libraries. +AC_CHECK_LIB([kvm], [kvm_open]) + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([syslog.h path.h fcntl.h limits.h sys/param.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_SIZE_T +AC_TYPE_PID_T +AC_TYPE_OFF_T + +# Checks for library functions. +AC_TYPE_SIGNAL +AC_CHECK_FUNCS([strerror strstr memmove]) +AC_FUNC_MALLOC + +AC_STRUCT_TM + +AC_CONFIG_FILES([Makefile src/Makefile]) +AC_OUTPUT + diff --git a/jails_man.html b/jails_man.html new file mode 100644 index 0000000..2d63ae7 --- /dev/null +++ b/jails_man.html @@ -0,0 +1,46 @@ + + +
+
+
+
+

SYNOPSIS

+       jails
+
+
+
+
+

DESCRIPTION

+       The  jails  command  will  print a list of all the various
+       jails running on your system. The hostnames of those jails
+       are printed.  The list is not ordered.
+
+
+
+
+

BUGS

+       I'm sure they're out there.
+
+
+
+
+

AUTHOR

+       Nate Nielsen <nielsen@memberwebs.com>
+
+
+
+
+

SEE ALSO

+       jail(8), jailer(8)
+
+
+
+FreeBSD                      May 2002                    JAILS(8)
+
+
+
+Man(1) output converted with +man2html +
+ + diff --git a/killjail_man.html b/killjail_man.html new file mode 100644 index 0000000..3a75ebd --- /dev/null +++ b/killjail_man.html @@ -0,0 +1,76 @@ + + +
+
+
+
+

SYNOPSIS

+       killjail [ -h | -r ] [ -t timeout ] [ -fq ] jailname ...
+
+
+
+

DESCRIPTION

+       killjail can either send signals to a jailer(8) process to
+       manage the shutdown or restart of a jail or  it  can  kill
+       all the processes in a jail on it's own.
+
+       When no options are given the jail is shutdown as follows:
+
+       1. A stop request (SIGTERM) is sent to the jailer(8)  pro-
+          cess  for  the  jail if there is one. This initiates an
+          orderly shutdown.
+
+       2. Any remaining processes are killed with a SIGTERM.
+
+       3. If the -f option is specified, send a  SIGKILL  to  any
+          remaining processes.
+
+
+
+
+

OPTIONS

+       -f     Force  jail to shutdown sending a SIGKILL as a last
+              resort.
+
+       -h     Sends a halt request to a jail (SIGQUIT). The  jail
+              must  have  a  jailer(8) process running inside it.
+              The jailer(8) process remains  running  within  the
+              jail,  but  all other jailed processes are shutdown
+              in and orderly fashion.
+
+       -q     Supress warnings.
+
+       -r     Sends a restart request to  a  jail  (SIGHUP).  The
+              jail  must  have a jailer(8) process running inside
+              it.
+
+       -t timeout
+              The timeout in seconds to wait between steps  1,  2
+              and 3 above. Defaults to 3.
+
+
+
+
+

BUGS

+       I'm sure they're out there. Let me know.
+
+
+
+
+

AUTHOR

+       Nate Nielsen <nielsen@memberwebs.com>
+
+
+
+
+

SEE ALSO

+       jail(8), jailer(8), kill(1)
+
+
+
+
+Man(1) output converted with +man2html +
+ + diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..7b914d5 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,357 @@ +# Makefile.in generated automatically by automake 1.5 from Makefile.am. + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + +SHELL = /bin/sh + +srcdir = . +top_srcdir = .. + +prefix = /usr/local +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/info +mandir = ${prefix}/man +includedir = ${prefix}/include +oldincludedir = /usr/include +pkgdatadir = $(datadir)/jailutils +pkglibdir = $(libdir)/jailutils +pkgincludedir = $(includedir)/jailutils +top_builddir = .. + +ACLOCAL = ${SHELL} /usr/work/src/jailutils/missing --run aclocal +AUTOCONF = ${SHELL} /usr/work/src/jailutils/missing --run autoconf +AUTOMAKE = ${SHELL} /usr/work/src/jailutils/missing --run automake +AUTOHEADER = ${SHELL} /usr/work/src/jailutils/missing --run autoheader + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL} +INSTALL_HEADER = $(INSTALL_DATA) +transform = s,x,x, +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +AMTAR = ${SHELL} /usr/work/src/jailutils/missing --run tar +AWK = nawk +CC = gcc +DEPDIR = .deps +EXEEXT = +INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s +OBJEXT = o +PACKAGE = jailutils +VERSION = 0.5.4 +am__include = include +am__quote = +install_sh = /usr/work/src/jailutils/install-sh + +sbin_PROGRAMS = killjail jails +killjail_SOURCES = killjail.c getjail.c getjail.h +killjail_LDADD = -lkvm +jails_SOURCES = jails.c getjail.c getjail.h +jails_LDADD = -lkvm +man_MANS = killjail.8 jails.8 +EXTRA_DIST = $(man_MANS) +subdir = src +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +sbin_PROGRAMS = killjail$(EXEEXT) jails$(EXEEXT) +PROGRAMS = $(sbin_PROGRAMS) + +am_jails_OBJECTS = jails.$(OBJEXT) getjail.$(OBJEXT) +jails_OBJECTS = $(am_jails_OBJECTS) +jails_DEPENDENCIES = +jails_LDFLAGS = +am_killjail_OBJECTS = killjail.$(OBJEXT) getjail.$(OBJEXT) +killjail_OBJECTS = $(am_killjail_OBJECTS) +killjail_DEPENDENCIES = +killjail_LDFLAGS = + +DEFS = -DHAVE_CONFIG_H +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +CPPFLAGS = +LDFLAGS = +LIBS = -lkvm +depcomp = $(SHELL) $(top_srcdir)/depcomp +DEP_FILES = $(DEPDIR)/getjail.Po $(DEPDIR)/jails.Po \ + $(DEPDIR)/killjail.Po +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +CFLAGS = -g -O2 +DIST_SOURCES = $(jails_SOURCES) $(killjail_SOURCES) + +NROFF = nroff +MANS = $(man_MANS) +DIST_COMMON = Makefile.am Makefile.in +SOURCES = $(jails_SOURCES) $(killjail_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && \ + CONFIG_HEADERS= CONFIG_LINKS= \ + CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(sbindir) + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + ; then \ + f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/$$f"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/$$f; \ + else :; fi; \ + done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \ + rm -f $(DESTDIR)$(sbindir)/$$f; \ + done + +clean-sbinPROGRAMS: + -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) +jails$(EXEEXT): $(jails_OBJECTS) $(jails_DEPENDENCIES) + @rm -f jails$(EXEEXT) + $(LINK) $(jails_LDFLAGS) $(jails_OBJECTS) $(jails_LDADD) $(LIBS) +killjail$(EXEEXT): $(killjail_OBJECTS) $(killjail_DEPENDENCIES) + @rm -f killjail$(EXEEXT) + $(LINK) $(killjail_LDFLAGS) $(killjail_OBJECTS) $(killjail_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +include $(DEPDIR)/getjail.Po +include $(DEPDIR)/jails.Po +include $(DEPDIR)/killjail.Po + +distclean-depend: + -rm -rf $(DEPDIR) + +.c.o: + source='$<' object='$@' libtool=no \ + depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \ + $(CCDEPMODE) $(depcomp) \ + $(COMPILE) -c `test -f $< || echo '$(srcdir)/'`$< + +.c.obj: + source='$<' object='$@' libtool=no \ + depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \ + $(CCDEPMODE) $(depcomp) \ + $(COMPILE) -c `cygpath -w $<` +CCDEPMODE = depmode=gcc +uninstall-info-am: + +man8dir = $(mandir)/man8 +install-man8: $(man8_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(man8dir) + @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.8*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ + done +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.8*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ + rm -f $(DESTDIR)$(man8dir)/$$inst; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || etags $(ETAGS_ARGS) $$tags $$unique $(LISP) + +GTAGS: + here=`CDPATH=: && cd $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH + +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + $(mkinstalldirs) "$(distdir)/$$dir"; \ + fi; \ + if test -d $$d/$$file; then \ + cp -pR $$d/$$file $(distdir) \ + || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(MANS) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(man8dir) + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]* + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-exec-am: install-sbinPROGRAMS + +install-info: install-info-am + +install-man: install-man8 + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +uninstall-am: uninstall-info-am uninstall-man uninstall-sbinPROGRAMS + +uninstall-man: uninstall-man8 + +.PHONY: GTAGS all all-am check check-am clean clean-generic \ + clean-sbinPROGRAMS distclean distclean-compile distclean-depend \ + distclean-generic distclean-tags distdir dvi dvi-am info \ + info-am install install-am install-data install-data-am \ + install-exec install-exec-am install-info install-info-am \ + install-man install-man8 install-sbinPROGRAMS install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic tags uninstall uninstall-am \ + uninstall-info-am uninstall-man uninstall-man8 \ + uninstall-sbinPROGRAMS + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..8dc8d62 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,8 @@ +sbin_PROGRAMS = killjail jails +killjail_SOURCES = killjail.c getjail.c getjail.h +killjail_LDADD = -lkvm +jails_SOURCES = jails.c getjail.c getjail.h +jails_LDADD = -lkvm +man_MANS = killjail.8 jails.8 +EXTRA_DIST = $(man_MANS) + diff --git a/src/getjail.c b/src/getjail.c new file mode 100644 index 0000000..9106557 --- /dev/null +++ b/src/getjail.c @@ -0,0 +1,69 @@ +/* +// AUTHOR +// N. Nielsen +// +// LICENSE +// This software is in the public domain. +// +// The software is provided "as is", without warranty of any kind, +// express or implied, including but not limited to the warranties +// of merchantability, fitness for a particular purpose, and +// noninfringement. In no event shall the author(s) be liable for any +// claim, damages, or other liability, whether in an action of +// contract, tort, or otherwise, arising from, out of, or in connection +// with the software or the use or other dealings in the software. +// +// SUPPORT +// Send bug reports to: +// +*/ + +#include +#include +#include +#include "getjail.h" + +#define PROC_STATUS_PATH "/proc/%d/status" + +int getpidjail(pid_t pid, char* buff) +{ + int fd; + size_t bytes; + off_t off; + + /* Format the file name */ + if(snprintf(buff, JAIL_BUFF_SIZE, PROC_STATUS_PATH, pid)) + { + /* Open the file */ + if((fd = open(buff, O_RDONLY)) >= 0) + { + /* Seek to the last bit */ + off = lseek(fd, SEEK_END, 0); + + if(off != -1) + { + off -= JAIL_BUFF_SIZE; + if(off < 0) off = 0; + lseek(fd, SEEK_SET, off); + + if((bytes = read(fd, buff, JAIL_BUFF_SIZE - 1)) > 0) + { + /* Okay now jailname should be the last token */ + while(isspace(buff[bytes - 1])) + bytes--; + + buff[bytes] = 0; + + while(!isspace(buff[bytes - 1])) + bytes--; + + memmove(buff, buff + bytes, JAIL_BUFF_SIZE - bytes); + return 0; + + } + } + } + } + + return -1; +} diff --git a/src/getjail.h b/src/getjail.h new file mode 100644 index 0000000..5e58542 --- /dev/null +++ b/src/getjail.h @@ -0,0 +1,35 @@ +/* +// AUTHOR +// N. Nielsen +// +// LICENSE +// This software is in the public domain. +// +// The software is provided "as is", without warranty of any kind, +// express or implied, including but not limited to the warranties +// of merchantability, fitness for a particular purpose, and +// noninfringement. In no event shall the author(s) be liable for any +// claim, damages, or other liability, whether in an action of +// contract, tort, or otherwise, arising from, out of, or in connection +// with the software or the use or other dealings in the software. +// +// SUPPORT +// Send bug reports to: +// +*/ + +#ifndef _GETJAIL_H_ +#define _GETJAIL_H_ + + + +#include +#include + +#define JAIL_BUFF_SIZE MAXHOSTNAMELEN + 2 + +int getpidjail(pid_t pid, char* buff); + + + +#endif /* _GETJAIL_H_ */ diff --git a/src/jails.8 b/src/jails.8 new file mode 100644 index 0000000..11de04f --- /dev/null +++ b/src/jails.8 @@ -0,0 +1,26 @@ +.\" Process this file with +.\" groff -man -Tascii jails.8 +.\" +.TH JAILS 8 "May 2002" FreeBSD "User Manual" +.SH NAME +.B jails +\- list all jails running on a system +.SH SYNOPSIS +.B jails + +.SH DESCRIPTION +The +.B jails +command will print a list of all the various jails running +on your system. The hostnames of those jails are printed. +The list is not ordered. + +.SH BUGS +I'm sure they're out there. + +.SH AUTHOR +Nate Nielsen + +.SH "SEE ALSO" +.BR jail (8), +.BR jailer (8) diff --git a/src/jails.c b/src/jails.c new file mode 100644 index 0000000..9c99743 --- /dev/null +++ b/src/jails.c @@ -0,0 +1,157 @@ +/* +// AUTHOR +// N. Nielsen +// +// LICENSE +// This software is in the public domain. +// +// The software is provided "as is", without warranty of any kind, +// express or implied, including but not limited to the warranties +// of merchantability, fitness for a particular purpose, and +// noninfringement. In no event shall the author(s) be liable for any +// claim, damages, or other liability, whether in an action of +// contract, tort, or otherwise, arising from, out of, or in connection +// with the software or the use or other dealings in the software. +// +// SUPPORT +// Send bug reports to: +// +// CHANGES +// 0.5.1 kvm_openfiles call uses /dev/null so non root users can use +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "getjail.h" + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +static int listJails(); +static void usage(); + +int main(int argc, char* argv[]) +{ + /* Nice main :) */ + return listJails() >= 0 ? 0 : 1; +} + + +int listJails() +{ + kvm_t *kd; + struct kinfo_proc* kp; + char errbuf[_POSIX2_LINE_MAX]; + char jailName[JAIL_BUFF_SIZE]; + int nentries, i; + + + char* jails = NULL; /* jail list buffer */ + size_t nextJail = 0; /* current write positon */ + size_t endJails = 0; /* size of buffer */ + int numJails = 0; /* return value */ + + + /* Open kernel interface */ + kd = kvm_openfiles(_PATH_DEVNULL, _PATH_DEVNULL, _PATH_DEVNULL, + O_RDONLY, errbuf); + if(kd == 0) + errx(1, "%s", errbuf); + + /* Get a process listing */ + if((kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nentries)) == 0) + errx(1, "%s", kvm_geterr(kd)); + + + /* Okay now loop through and look for the jails */ + for(i = 0; i < nentries; i++) + { + pid_t pid; + +#if __FreeBSD_version > 500000 + + /* Check the flags first */ + if(!(kp[i].ki_flag & P_JAILED)) + continue; + + pid = kp[i].ki_pid; + +#else + + /* Check the flags first */ + if(!(kp[i].kp_proc.p_flag & P_JAILED)) + continue; + + pid = kp[i].kp_proc.p_pid; + +#endif + + /* Get this processes jail name */ + if(getpidjail(pid, jailName) < 0) + continue; + + if(jails) + { + char* j; + + /* See if that jail name was already taken */ + for(j = jails; *j != NULL; j += strlen(j) + 1) + { + if(!strcmp(jailName, j)) + break; + } + + /* Can't do this in loop above */ + if(*j) + continue; + } + + + /* Okay we got a jail name */ + + + /* Allocate if necessary enough space for it */ + if(nextJail + strlen(jailName) + 2 > endJails) + { + endJails += (JAIL_BUFF_SIZE * 0x2); + jails = (char*)realloc(jails, endJails); + if(!jails) + errx(1, "out of memory"); + } + + + /* Put the jail name in the buffer */ + strcpy(jails + nextJail, jailName); + nextJail += strlen(jailName) + 1; + jails[nextJail] = 0; + numJails++; + + /* And print it */ + fprintf(stdout, "%s\n", jailName); + } + + kvm_close(kd); + + return numJails; +} + +static void usage() +{ + fprintf(stderr, "usage: jails\n"); + exit(2); +} + diff --git a/src/killjail.8 b/src/killjail.8 new file mode 100644 index 0000000..b0f73b0 --- /dev/null +++ b/src/killjail.8 @@ -0,0 +1,68 @@ +.\" Process this file with +.\" groff -man -Tascii killjail.8 +.\" +.TH KILLJAIL 8 "May 2002" FreeBSD "User Manual" +.SH NAME +.B killjail +\- stop or restart a jail +.SH SYNOPSIS +.B killjail +[ +.B -h +| +.B -r +] [ +.B -t +.I timeout +] [ +.B -fq +] +.I jailname ... +.SH DESCRIPTION +.B killjail +can either send signals to a +.BR jailer (8) +process to manage the shutdown or restart of a jail or it can kill all +the processes in a jail on it's own. + +When no options are given the jail is shutdown as follows: +.IP 1. 3 +A stop request (SIGTERM) is sent to the +.BR jailer (8) +process for the jail if there is one. This initiates an orderly shutdown. +.IP 2. 3 +Any remaining processes are killed with a SIGTERM. +.IP 3. 3 +If the +.B -f +option is specified, send a SIGKILL to any remaining processes. + +.SH OPTIONS +.IP -f +Force jail to shutdown sending a SIGKILL as a last resort. +.IP -h +Sends a halt request to a jail (SIGQUIT). The jail must have a +.BR jailer (8) +process running inside it. The +.BR jailer (8) +process remains running within the jail, but all other jailed +processes are shutdown in and orderly fashion. +.IP -q +Supress warnings. +.IP -r +Sends a restart request to a jail (SIGHUP). The jail must have a +.BR jailer (8) +process running inside it. +.IP "-t timeout" +The timeout in seconds to wait between steps 1, 2 and 3 above. Defaults to 3. + +.SH BUGS +I'm sure they're out there. Let me know. + +.SH AUTHOR +Nate Nielsen + +.SH "SEE ALSO" +.BR jail (8), +.BR jailer (8), +.BR kill (1) diff --git a/src/killjail.c b/src/killjail.c new file mode 100644 index 0000000..2b4eb7d --- /dev/null +++ b/src/killjail.c @@ -0,0 +1,387 @@ +/* +// AUTHOR +// N. Nielsen +// +// LICENSE +// This software is in the public domain. +// +// The software is provided "as is", without warranty of any kind, +// express or implied, including but not limited to the warranties +// of merchantability, fitness for a particular purpose, and +// noninfringement. In no event shall the author(s) be liable for any +// claim, damages, or other liability, whether in an action of +// contract, tort, or otherwise, arising from, out of, or in connection +// with the software or the use or other dealings in the software. +// +// SUPPORT +// Send bug reports to: +// +// CHANGES +// 0.5.1 kvm_openfiles uses /dev/null +// +// 0.5.3 +// Added quiet option +// Added force option +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "getjail.h" + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +/* The big long stop process */ +static int stopJail(char* jailName, int force); + +/* Signals the jailer for various requests */ +static int signalJail(char* jailName, int signal); + +static void killProcesses(pid_t* pids, int signal); +static int getJailProcesses(const char* jailName, pid_t* pidJailer, pid_t** pids); + +static void usage(); + + +/* The timeout to wait between kills */ +#define DEFAULT_TIMEOUT 10 +int g_timeout = DEFAULT_TIMEOUT; + +/* To find the jailer process look for this command */ +#define JAILER_COMMAND "jailer" + +/* Supress warnings */ +int g_quiet = 0; + +int main(int argc, char* argv[]) +{ + /* If this gets set then only signal jailer, no kill */ + int signal = 0; + int ch = 0; + int force = 0; + int ret = 0; + + while((ch = getopt(argc, argv, "fhqrt:")) != -1) + { + switch(ch) + { + /* Force jail to shutdown */ + case 'f': + force = 1; + break; + + case 'q': + g_quiet = 1; + break; + + /* Send halt request to jailer */ + case 'h': + signal = SIGQUIT; + break; + + /* Send restart request to jailer */ + case 'r': + signal = SIGHUP; + break; + + /* Timeout to use between kills */ + case 't': + g_timeout = atoi(optarg); + if(g_timeout <= 0) + errx(1, "invalid timeout argument: %s", optarg); + break; + + case '?': + default: + usage(); + } + } + + argc -= optind; + argv += optind; + + /* Make sure we have a jailName */ + if(argc == 0) + usage(); + + /* For each jail */ + while(argc > 0) + { + /* If a signal option was set above then signal, + otherwise kill */ + if(signal == 0) + { + if(stopJail(*argv, force) != 0) + ret = 1; + } + else + { + if(force) + errx(1, "-f option incompatible with -r or -h"); + + if(signalJail(*argv, signal) != 0) + ret = 1; + } + + argc--; + argv++; + } + + return ret; +} + + +int signalJail(char* jailName, int signal) +{ + pid_t jailerPid = 0; + + /* Only ask for jailer pid */ + getJailProcesses(jailName, &jailerPid, NULL); + + if(jailerPid == 0) + { + warnx("%s: jailer not running in jail", jailName); + return 1; + } + + if(kill(jailerPid, signal) < 0) + err(1, "%s: couldn't signal jailer", jailName); + + return 0; +} + + +int stopJail(char* jailName, int force) +{ + pid_t jailerPid = 0; + pid_t* jailProcesses = NULL; + int pass = 0; + int timeout = 0; + int ret = 0; + + /* + * Multiple passes are used to do different things. + * Each time the jails processes are listed. + */ + while(ret == 0 && + getJailProcesses(jailName, &jailerPid, &jailProcesses)) + { + + if(timeout > 0) + { + sleep(1); + timeout--; + } + + else + { + + switch(pass) + { + + /* First pass is killing the jailer */ + case 0: + + if(jailerPid == 0) + { + /* No jailer */ + if(!g_quiet) + warnx("%s: jailer not running in jail", jailName); + } + + else + { + if(kill(jailerPid, SIGTERM) < 0 && errno != ESRCH) + err(1, "%s: couldn't signal jailer:", jailName); + + else + timeout = g_timeout; + } + + break; + + + /* Okay now quit all processes in jail */ + case 1: + + /* If we get here, jailer looks like it's irresponsive */ + if(jailerPid != 0 && !g_quiet) + warnx("%s: jailer (pid %d) won't quit. terminating jail...", jailName, jailerPid); + + + killProcesses(jailProcesses, SIGTERM); + timeout = g_timeout; + break; + + + /* Okay now we force kill the processes if necessary */ + case 2: + + if(force) + { + /* If we get here, jailer looks like it's really irresponsive */ + if(!g_quiet) + warnx("%s: jail won't stop. forcing jail termination...", jailName); + + killProcesses(jailProcesses, SIGKILL); + timeout = g_timeout; + } + + break; + + + /* And if that didn't do it, well then give up */ + case 3: + + if(!g_quiet) + warnx("%s: couldn't stop jail, processes wouldn't die", jailName); + + ret = 1; + break; + + } + + pass++; + } + + if(jailProcesses) + free(jailProcesses); + + } + + if(pass == 0) + { + if(!g_quiet) + warnx("%s: jail not running", jailName); + + ret = 1; + } + + return ret; +} + +void killProcesses(pid_t* pids, int signal) +{ + /* Note that we assume pids is null terminated + this is what getJailProcesses returns */ + + while(*pids) + { + if(kill(*pids, signal) < 0) + { + /* We ignore missing process errors */ + if(errno != ESRCH) + err(1, "couldn't kill process: %d", *pids); + } + + pids++; + } +} + +int getJailProcesses(const char* jailName, pid_t* pidJailer, pid_t** pids) +{ + kvm_t *kd; + struct kinfo_proc* kp; + char errbuf[_POSIX2_LINE_MAX]; + char pidJail[JAIL_BUFF_SIZE]; + int nentries, i, j; + + /* Open the kernel interface */ + kd = kvm_openfiles(_PATH_DEVNULL, _PATH_DEVNULL, _PATH_DEVNULL, + O_RDONLY, errbuf); + if(kd == 0) + errx(1, "%s", errbuf); + + /* Get a process listing */ + if((kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nentries)) == 0) + errx(1, "%s", kvm_geterr(kd)); + + /* Allocate memory */ + if(pids) + { + if((*pids = (pid_t*)malloc((nentries + 1) * sizeof(pid_t))) == NULL) + err(1, "out of memory"); + } + + /* Okay now loop and look at each process' jail */ + for(i = 0, j = 0; i < nentries; i++) + { + pid_t pid; + +#if __FreeBSD_version > 500000 + + /* Check the flags first */ + if(!(kp[i].ki_flag & P_JAILED)) + continue; + + pid = kp[i].ki_pid; + +#else + + /* Check the flags first */ + if(!(kp[i].kp_proc.p_flag & P_JAILED)) + continue; + + pid = kp[i].kp_proc.p_pid; + +#endif + + /* Now actually get the jail name */ + if(getpidjail(pid, pidJail) < 0) + continue; + + if(strcmp(pidJail, jailName)) + continue; + + /* Copy the PID over */ + if(pids) + (*pids)[j++] = pid; + + /* If it's the jailer then copy that */ + if(pidJailer) + { +#if __FreeBSD_version > 500000 + if(strstr(kp[i].ki_comm, JAILER_COMMAND)) +#else + if(strstr(kp[i].kp_proc.p_comm, JAILER_COMMAND)) +#endif + *pidJailer = pid; + } + + } + + /* Null terminate pids array */ + if(pids) + (*pids)[j] = 0; + + kvm_close(kd); + + return j == 0 ? 0 : 1; +} + + + +static void usage() +{ + fprintf(stderr, "usage: killjail [ -h | -r ] [ -t timeout ] [ -qf ] jailname ...\n"); + exit(2); +} + -- cgit v1.2.3