unshare: new command
New utility allows to run process with separate mount, UTC, IPC or network namespaces. [kzak@redhat.com: - some cosmetic changes in usage() and err() usage - move "if BUILD_UNSHARE" to separate place in Makefile.am - add unshare to .gitignore] Signed-off-by: Mikhail Gusarov <dottedmag@dottedmag.net> Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
4629c03d34
commit
4205f1fda1
4
TODO
4
TODO
|
@ -41,10 +41,6 @@ fdisk(s)
|
||||||
misc
|
misc
|
||||||
----
|
----
|
||||||
|
|
||||||
* add a new command (unshare, clone, or so...) with all kinds of
|
|
||||||
clone(2) options.
|
|
||||||
http://thread.gmane.org/gmane.linux.utilities.util-linux-ng/2178
|
|
||||||
|
|
||||||
* add to lib/blkdev.c code for /proc/partitions parsing -- unfortunate we
|
* add to lib/blkdev.c code for /proc/partitions parsing -- unfortunate we
|
||||||
duplicate this code in many places. The parser has to support unlimited
|
duplicate this code in many places. The parser has to support unlimited
|
||||||
size (or 4096 bytes) of partition name.
|
size (or 4096 bytes) of partition name.
|
||||||
|
|
18
configure.ac
18
configure.ac
|
@ -372,6 +372,20 @@ AM_CONDITIONAL(HAVE_BLKID, test "x$have_blkid" = xyes)
|
||||||
|
|
||||||
AC_ARG_VAR([BLKID_LIBS_STATIC], [-l options for linking statically with blkid])
|
AC_ARG_VAR([BLKID_LIBS_STATIC], [-l options for linking statically with blkid])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([unshare],
|
||||||
|
AS_HELP_STRING([--disable-unshare], [do not build unshare]),
|
||||||
|
[], enable_unshare=check
|
||||||
|
)
|
||||||
|
build_unshare=yes
|
||||||
|
if test "x$enable_unshare" = xcheck; then
|
||||||
|
if test "x$linux_os" = xno; then
|
||||||
|
AC_MSG_WARN([non-linux system; do not build unshare])
|
||||||
|
build_unshare=no
|
||||||
|
fi
|
||||||
|
elif test "x$enable_unshare" = xno; then
|
||||||
|
build_unshare=no
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(BUILD_UNSHARE, test "x$build_unshare" = xyes)
|
||||||
|
|
||||||
UTIL_CHECK_LIB(util, openpty)
|
UTIL_CHECK_LIB(util, openpty)
|
||||||
UTIL_CHECK_LIB(termcap, tgetnum)
|
UTIL_CHECK_LIB(termcap, tgetnum)
|
||||||
|
@ -563,6 +577,10 @@ dnl fallocate could be available as libc function or as syscall only
|
||||||
UTIL_CHECK_SYSCALL([fallocate])
|
UTIL_CHECK_SYSCALL([fallocate])
|
||||||
AC_CHECK_FUNCS([fallocate])
|
AC_CHECK_FUNCS([fallocate])
|
||||||
|
|
||||||
|
dnl unshare could be available as libc function or as syscall only
|
||||||
|
UTIL_CHECK_SYSCALL([unshare])
|
||||||
|
AC_CHECK_FUNCS([unshare])
|
||||||
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
|
@ -39,5 +39,6 @@ sparc64.8
|
||||||
sparc.8
|
sparc.8
|
||||||
switch_root
|
switch_root
|
||||||
tunelp
|
tunelp
|
||||||
|
unshare
|
||||||
vidmode.8
|
vidmode.8
|
||||||
x86_64.8
|
x86_64.8
|
||||||
|
|
|
@ -38,6 +38,11 @@ sbin_PROGRAMS += switch_root
|
||||||
dist_man_MANS += switch_root.8
|
dist_man_MANS += switch_root.8
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if BUILD_UNSHARE
|
||||||
|
usrbin_exec_PROGRAMS += unshare
|
||||||
|
dist_man_MANS += unshare.1
|
||||||
|
endif
|
||||||
|
|
||||||
if BUILD_ARCH
|
if BUILD_ARCH
|
||||||
bin_PROGRAMS += arch
|
bin_PROGRAMS += arch
|
||||||
dist_man_MANS += arch.1
|
dist_man_MANS += arch.1
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
.\" Process this file with
|
||||||
|
.\" groff -man -Tascii lscpu.1
|
||||||
|
.\"
|
||||||
|
.TH UNSHARE 1 "OCTOBER 2008" Linux "User Manuals"
|
||||||
|
.SH NAME
|
||||||
|
unshare \- run program with some namespaces unshared from parent
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B unshare
|
||||||
|
.RI [ options ]
|
||||||
|
program
|
||||||
|
.RI [ arguments ]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Unshares specified namespaces from parent process and then executes specified
|
||||||
|
program. Unshareable namespaces are:
|
||||||
|
.TP
|
||||||
|
.BR "mount namespace"
|
||||||
|
mounting and unmounting filesystems will not affect rest of the system
|
||||||
|
(\fBCLONE_NEWNS\fP flag),
|
||||||
|
.TP
|
||||||
|
.BR "UTS namespace"
|
||||||
|
setting hostname, domainname will not affect rest of the system
|
||||||
|
(\fBCLONE_NEWUTS\fP flag),
|
||||||
|
.TP
|
||||||
|
.BR "IPC namespace"
|
||||||
|
process will have indpendent namespace for System V message queues, semaphore
|
||||||
|
sets and shared memory segments (\fBCLONE_NEWIPC\fP flag),
|
||||||
|
.TP
|
||||||
|
.BR "network namespace"
|
||||||
|
process will have independent IPv4 and IPv6 stacks, IP routing tables, firewall
|
||||||
|
rules, the \fI/proc/net\fP and \fI/sys/class/net\fP directory trees, sockets
|
||||||
|
etc. (\fBCLONE_NEWNET\fP flag).
|
||||||
|
.TP
|
||||||
|
See the clone(2) for exact semantics of the flags.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.BR \-h , " \-\-help"
|
||||||
|
Print a help message,
|
||||||
|
.TP
|
||||||
|
.BR \-m , " \-\-mount"
|
||||||
|
Unshare the mount namespace,
|
||||||
|
.TP
|
||||||
|
.BR \-u , " \-\-uts"
|
||||||
|
Unshare the UTC namespace,
|
||||||
|
.TP
|
||||||
|
.BR \-i , " \-\-ipc"
|
||||||
|
Unshare the IPC namespace,
|
||||||
|
.TP
|
||||||
|
.BR \-n , " \-\-net"
|
||||||
|
Unshare the network namespace.
|
||||||
|
.SH SEE ALSO
|
||||||
|
unshare(2), clone(2)
|
||||||
|
.SH BUGS
|
||||||
|
None known so far.
|
||||||
|
.SH AUTHOR
|
||||||
|
Mikhail Gusarov <dottedmag@dottedmag.net>
|
||||||
|
.SH AVAILABILITY
|
||||||
|
The unshare command is part of the util-linux-ng package and is available from
|
||||||
|
ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
|
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* unshare(1) - command-line interface for unshare(2)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Mikhail Gusarov <dottedmag@dottedmag.net>
|
||||||
|
*
|
||||||
|
* This program 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 2, or (at your option) any
|
||||||
|
* later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "nls.h"
|
||||||
|
|
||||||
|
#ifndef CLONE_NEWSNS
|
||||||
|
# define CLONE_NEWNS 0x00020000
|
||||||
|
#endif
|
||||||
|
#ifndef CLONE_NEWUTS
|
||||||
|
# define CLONE_NEWUTS 0x04000000
|
||||||
|
#endif
|
||||||
|
#ifndef CLONE_NEWIPC
|
||||||
|
# define CLONE_NEWIPC 0x08000000
|
||||||
|
#endif
|
||||||
|
#ifndef CLONE_NEWNET
|
||||||
|
# define CLONE_NEWNET 0x40000000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_UNSHARE
|
||||||
|
# include <sys/syscall.h>
|
||||||
|
|
||||||
|
static int unshare(int flags)
|
||||||
|
{
|
||||||
|
return syscall(SYS_unshare, flags);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void usage(int status)
|
||||||
|
{
|
||||||
|
FILE *out = status == EXIT_SUCCESS ? stdout : stderr;
|
||||||
|
|
||||||
|
fprintf(out, _("Usage: %s [options] <program> [args...]\n"),
|
||||||
|
program_invocation_short_name);
|
||||||
|
|
||||||
|
fputs(_("Run program with some namespaces unshared from parent\n\n"
|
||||||
|
" -h, --help usage information (this)\n"
|
||||||
|
" -m, --mount unshare mounts namespace\n"
|
||||||
|
" -u, --uts unshare UTS namespace (hostname etc)\n"
|
||||||
|
" -i, --ipc unshare System V IPC namespace\n"
|
||||||
|
" -n, --net unshare network namespace\n"), out);
|
||||||
|
|
||||||
|
fprintf(out, _("\nFor more information see unshare(1).\n"));
|
||||||
|
exit(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct option longopts[] = {
|
||||||
|
{ "help", no_argument, 0, 'h' },
|
||||||
|
{ "mount", no_argument, 0, 'm' },
|
||||||
|
{ "uts", no_argument, 0, 'u' },
|
||||||
|
{ "ipc", no_argument, 0, 'i' },
|
||||||
|
{ "net", no_argument, 0, 'n' },
|
||||||
|
};
|
||||||
|
|
||||||
|
int unshare_flags = 0;
|
||||||
|
|
||||||
|
int c;
|
||||||
|
|
||||||
|
setlocale(LC_MESSAGES, "");
|
||||||
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||||
|
textdomain(PACKAGE);
|
||||||
|
|
||||||
|
while((c = getopt_long(argc, argv, "hmuin", longopts, NULL)) != -1) {
|
||||||
|
switch(c) {
|
||||||
|
case 'h':
|
||||||
|
usage(EXIT_SUCCESS);
|
||||||
|
case 'm':
|
||||||
|
unshare_flags |= CLONE_NEWNS;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
unshare_flags |= CLONE_NEWUTS;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
unshare_flags |= CLONE_NEWIPC;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
unshare_flags |= CLONE_NEWNET;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(optind >= argc)
|
||||||
|
usage(EXIT_FAILURE);
|
||||||
|
|
||||||
|
if(-1 == unshare(unshare_flags))
|
||||||
|
err(EXIT_FAILURE, _("unshare failed"));
|
||||||
|
|
||||||
|
execvp(argv[optind], argv + optind);
|
||||||
|
|
||||||
|
err(EXIT_FAILURE, _("exec %s failed"), argv[optind]);
|
||||||
|
}
|
Loading…
Reference in New Issue