Package: debianutils
Version: 3.4.3
Severity: wishlist
Tags: patch
A few maintainer scripts try to detect the presence of a chroot using
slightly different manners, some of them being buggy depending on the
operating system. I think it's time to have a binary in debianutils
which can be used by the maintainer scripts. This way it will be easy
to fix or improve the detection method without having to change all
the scripts.
The patch below adds a "ischroot" binary detecting a chroot. I am quite
open for using another name, or for fixes (especially in the comments
and manpage as I am not a native speaker). I have tested it on
GNU/Linux, GNU/kFreeBSD and GNU/Hurd.
diff -Nru a/debian/rules b/debian/rules
--- a/debian/rules
+++ b/debian/rules
@@ -64,7 +64,8 @@
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
strip --remove-section=.comment --remove-section=.note \
debian/tmp/bin/run-parts \
- debian/tmp/bin/tempfile
+ debian/tmp/bin/tempfile \
+ debian/tmp/usr/bin/ischroot
endif
ifneq ($(DEB_HOST_ARCH_OS),hurd)
@@ -91,7 +92,7 @@
cd debian/tmp && find * -type f ! -regex '^DEBIAN/.*' -print0 | xargs
-r0 md5sum > DEBIAN/md5sums
- dpkg-shlibdeps debian/tmp/bin/run-parts debian/tmp/bin/tempfile
+ dpkg-shlibdeps run-parts tempfile ischroot
dpkg-gencontrol -isp
dpkg --build debian/tmp ..
diff -Nru a/ischroot.1 b/ischroot.1
--- a/ischroot.1 1970-01-01 01:00:00.000000000 +0100
+++ b/ischroot.1
@@ -0,0 +1,37 @@
+.\" -*- nroff -*-
+.TH ISCHROOT 1 "17 May 2011" "Debian"
+.SH NAME
+ischroot \- detect if running in a chroot
+.SH SYNOPSIS
+.B ischroot
+[\-\-default\-false] [\-\-default\-true] [\-\-help] [\-\-version]
+.SH DESCRIPTION
+.PP
+.B ischroot
+detects if it is currently running in a chroot. The exit status is:
+.TP
+0
+if currently running in a chroot
+.TP
+1
+if currently not running in a chroot
+.TP
+2
+if the detection is not possible (On GNU/Linux in happens if the script
+is not run as root).
+.SH OPTIONS
+.TP
+.B "-f, --default-false "
+Exit with status 1 if the detection is not possible.
+.TP
+.B "-t, --default-true "
+Exit with status 0 if the detection is not possible.
+.TP
+.B "--help"
+Print a usage message on standard output and exit successfully.
+.TP
+.B "--version"
+Print version information on standard output and exit successfully.
+.SH BUGS
+On GNU/Linux, chroot detection is not possible as root. This works correctly
+on GNU/Hurd and GNU/kFreeBSD.
diff -Nru a/ischroot.c b/ischroot.c
--- a/ischroot.c 1970-01-01 01:00:00.000000000 +0100
+++ b/ischroot.c
@@ -0,0 +1,196 @@
+/* ischroot: detect if running in a chroot
+ *
+ * Debian ischroot program
+ * Copyright (C) 2011 Aurelien Jarno <[email protected]>
+ *
+ * This is free software; see the GNU General Public License version 2
+ * or later for copying conditions. There is NO warranty.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif /* HAVE_GETOPT_H */
+
+void version()
+{
+ fprintf(stderr, "Debian ischroot, version " PACKAGE_VERSION
+ "Copyright (C) 2011 Aurelien Jarno\n"
+ "This is free software; see the GNU General Public License version
2\n"
+ "or later for copying conditions. There is NO warranty.\n");
+ exit(0);
+}
+
+void usage()
+{
+ fprintf(stderr, "Usage: ischroot [OPTION]\n"
+ " -f, --default-false return false if detection fails\n"
+ " -t, --default-true return true if detection fails\n"
+ " -V, --version output version information and exit.\n"
+ " -h, --help display this help and exit.\n");
+ exit(0);
+}
+
+#if defined (__linux__)
+
+/* On Linux we can detect chroots by checking if the
+ * devicenumber/inode pair of / are the same as that of
+ * /sbin/init's. This may fail if not running as root or if
+ * /proc is not mounted, in which case 2 is returned.
+ */
+
+static int ischroot()
+{
+ struct stat st1, st2;
+
+ if (stat("/", &st1) || stat("/proc/1/root", &st2))
+ return 2;
+ else if ((st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino))
+ return 1;
+ else
+ return 0;
+}
+
+#elif defined (__FreeBSD_kernel__) || defined (__FreeBSD__)
+
+#include <sys/sysctl.h>
+#include <sys/user.h>
+
+/* On FreeBSD we can detect chroot by looking for a specific
+ * file descriptor pointing to the location of the chroot. There
+ * is not need to be root, so it is unlikely to fail in normal
+ * cases, but return 2 if a memory failure or the like happens. */
+
+static int ischroot()
+{
+ int mib[4];
+ size_t kf_len = 0;
+ char *kf_buf, *kf_bufp;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_FILEDESC;
+ mib[3] = getpid ();
+
+ if (sysctl (mib, 4, NULL, &kf_len, NULL, 0) != 0)
+ return 2;
+
+ kf_buf = kf_bufp = malloc (kf_len);
+ if (kf_buf == NULL)
+ return 2;
+
+ if (sysctl (mib, 4, kf_buf, &kf_len, NULL, 0) != 0)
+ {
+ free(kf_buf);
+ return 2;
+ }
+
+ while (kf_bufp < kf_buf + kf_len)
+ {
+ struct kinfo_file *kf = (struct kinfo_file *) (uintptr_t) kf_bufp;
+
+ if (kf->kf_fd == KF_FD_TYPE_JAIL)
+ {
+ free(kf_buf);
+ return 0;
+ }
+ kf_bufp += kf->kf_structsize;
+ }
+
+ free(kf_buf);
+ return 1;
+}
+
+#elif defined (__GNU__)
+
+/* On Hurd we can detect chroot by looking at the device number
+ * containing /. The device number of the first mounted filesystem
+ * equals 3, and due to bug http://savannah.gnu.org/bugs/?23213
+ * chroots have to be created on a different filesystem. Return 2
+ * if it is not possible to probe this device. */
+
+static int ischroot()
+{
+ struct stat st;
+
+ if (stat("/", &st))
+ return 2;
+ else if (st.st_dev == 3)
+ return 1;
+ else
+ return 0;
+}
+
+#else
+
+static int ischroot()
+{
+ return 2;
+}
+
+#warning unknown system, chroot detection will always fail
+
+#endif
+
+/* Process options */
+int main(int argc, char *argv[])
+{
+ int default_false = 0;
+ int default_true = 0;
+ int exit_status;
+
+ for (;;) {
+ int c;
+ int option_index = 0;
+
+ static struct option long_options[] = {
+ {"default-false", 0, 0, 'f'},
+ {"default-true", 0, 0, 't'},
+ {"help", 0, 0, 'h'},
+ {"version", 0, 0, 'V'},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, "fthV", long_options, &option_index);
+ if (c == EOF)
+ break;
+ switch (c) {
+ case 'f':
+ default_false = 1;
+ break;
+ case 't':
+ default_true = 1;
+ break;
+ case 'h':
+ usage();
+ break;
+ case 'V':
+ version();
+ break;
+ default:
+ fprintf(stderr, "Try `ischroot --help' for more information.\n");
+ exit(1);
+ }
+ }
+
+ if (default_false && default_true) {
+ fprintf(stderr, "Can't default to both true and false!\n");
+ fprintf(stderr, "Try `ischroot --help' for more information.\n");
+ exit(1);
+ }
+
+ exit_status = ischroot();
+
+ if (exit_status == 2) {
+ if (default_true)
+ exit_status = 0;
+ if (default_false)
+ exit_status = 1;
+ }
+
+ return exit_status;
+}
diff -Nru a/Makefile.am b/Makefile.am
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,9 +2,10 @@
SUBDIRS = po4a
-bin_PROGRAMS = run-parts tempfile
+bin_PROGRAMS = run-parts tempfile ischroot
run_parts_SOURCES = run-parts.c
tempfile_SOURCES = tempfile.c
+ischroot_SOURCES = ischroot.c
bin_SCRIPTS = which savelog
@@ -12,4 +13,5 @@
man_MANS = run-parts.8 \
installkernel.8 savelog.8 \
- tempfile.1 which.1 add-shell.8 remove-shell.8
+ tempfile.1 which.1 add-shell.8 \
+ remove-shell.8 ischroot.1
diff -Nru a/po4a/po4a.conf b/po4a/po4a.conf
--- a/po4a/po4a.conf
+++ b/po4a/po4a.conf
@@ -11,6 +11,10 @@
sl:sl/installkernel.8
add_sl:sl/translator_slovene.add \
de:de/installkernel.8
add_de:de/translator_german.add \
es:es/installkernel.8
+[type:man] ../ischroot.1 fr:fr/ischroot.1 add_fr:fr/ischroot.1.fr.add \
+ sl:sl/ischroot.1 add_sl:sl/translator_slovene.add \
+ de:de/ischroot.1 add_de:de/translator_german.add \
+ es:es/ischroot.1
# There is no mdoc module in po4a. This one is still translated manually
[type:man] ../remove-shell.8 fr:fr/remove-shell.8
add_fr:fr/translator_french.add \
sl:sl/remove-shell.8
add_sl:sl/translator_slovene.add \
-- System Information:
Debian Release: wheezy/sid
APT prefers unstable
APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.38-2-amd64 (SMP w/4 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages debianutils depends on:
ii libc6 2.13-2 Embedded GNU C Library: Shared lib
ii sensible-utils 0.0.6 Utilities for sensible alternative
debianutils recommends no packages.
debianutils suggests no packages.
-- no debconf information
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]