From 96551a8b8a39daa5465c17efd1af422bf2bf56c9 Mon Sep 17 00:00:00 2001 From: Enrico Scholz Date: Thu, 19 Aug 2004 15:02:57 +0000 Subject: [PATCH] initial checkin git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@1676 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- util-vserver/vserver-start/interface-print.c | 29 ++++ util-vserver/vserver-start/interface-remove.c | 29 ++++ util-vserver/vserver-start/mount.c | 184 ++++++++++++++++++++++++++ util-vserver/vserver-start/mount.h | 27 ++++ util-vserver/vserver-start/undo.c | 92 +++++++++++++ util-vserver/vserver-start/undo.h | 28 ++++ 6 files changed, 389 insertions(+) create mode 100644 util-vserver/vserver-start/interface-print.c create mode 100644 util-vserver/vserver-start/interface-remove.c create mode 100644 util-vserver/vserver-start/mount.c create mode 100644 util-vserver/vserver-start/mount.h create mode 100644 util-vserver/vserver-start/undo.c create mode 100644 util-vserver/vserver-start/undo.h diff --git a/util-vserver/vserver-start/interface-print.c b/util-vserver/vserver-start/interface-print.c new file mode 100644 index 0000000..9255eac --- /dev/null +++ b/util-vserver/vserver-start/interface-print.c @@ -0,0 +1,29 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "interface.h" + +void +Iface_print(struct Interface const *iface, int fd) +{ + +} diff --git a/util-vserver/vserver-start/interface-remove.c b/util-vserver/vserver-start/interface-remove.c new file mode 100644 index 0000000..18d33c2 --- /dev/null +++ b/util-vserver/vserver-start/interface-remove.c @@ -0,0 +1,29 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "interface.h" + +bool +Iface_remove(struct Interface const *iface) +{ + return true; +} diff --git a/util-vserver/vserver-start/mount.c b/util-vserver/vserver-start/mount.c new file mode 100644 index 0000000..43f3223 --- /dev/null +++ b/util-vserver/vserver-start/mount.c @@ -0,0 +1,184 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "mount.h" +#include "configuration.h" +#include "undo.h" + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#define ENSC_WRAPPERS_UNISTD 1 +#define ENSC_WRAPPERS_FCNTL 1 +#include + +static char const * +findMtab(char const *vserver_mtab) +{ + char const *tmp; + + if (utilvserver_isFile(vserver_mtab, true)) return vserver_mtab; + + tmp=CONFDIR "/.defaults/init/mtab"; + if (utilvserver_isFile(tmp, true)) return tmp; + + tmp=PKGLIBDEFAULTDIR "/mtab"; + if (utilvserver_isFile(tmp, true)) return tmp; + + return 0; +} + +static void +initMtab(struct Configuration const *cfg) +{ + ENSC_PI_DECLARE(mtab_subpath, "apps/init/mtab"); + PathInfo mtab_path = cfg->cfgdir; + char mtab_buf[ENSC_PI_APPSZ(mtab_path, mtab_subpath)]; + + PathInfo_append(&mtab_path, &mtab_subpath, mtab_buf); + char const * mtab = findMtab(mtab_path.d); + pid_t pid; + int p[2]; + + Epipe(p); + pid = Efork(); + if (pid==0) { + Undo_detach(); + Eclose(p[1]); + + Echdir(cfg->vdir); + Echroot("."); + + int fd = Eopen("/etc/mtab", O_WRONLY|O_CREAT, 0644); + for (;;) { + char buf[4096]; + ssize_t len = TEMP_FAILURE_RETRY(read(p[0], buf, sizeof buf)); + if (len==0) break; + if (len==-1) { + perror("vserver-start: initMtab/read():"); + _exit(1); + } + + Ewrite(fd, buf, len); + } + Eclose(fd); + Eclose(p[0]); + _exit(0); + } + else { + Eclose(p[0]); + + if (mtab!=0) { + int fd = Eopen(mtab, O_RDONLY, 0644); + + for (;;) { + char buf[4096]; + ssize_t len = TEMP_FAILURE_RETRY(read(fd, buf, sizeof buf)); + if (len==0) break; + if (len==-1) { + perror("vserver-start: initMtab/read():"); + _exit(1); + } + + Ewrite(p[1], buf, len); + } + + Eclose(fd); + } + + Eclose(p[1]); + + int status; + TEMP_FAILURE_RETRY(wait4(pid, &status, 0,0)); + + if (!WIFEXITED(status) || WEXITSTATUS(status)!=0) { + exit(1); + } + } +} + +static void +mountVserverInternal(struct Configuration const *cfg, + PathInfo const *path, bool use_chbind) +{ + if (!utilvserver_isFile(path->d,true)) return; + + pid_t pid = Efork(); + if (pid==0) { + Undo_detach(); + + Echdir(cfg->vdir); + + if (use_chbind) { + // TODO + } + + struct Command cmd; + char const * argv[] = { + PROG_SECURE_MOUNT, + "-a", + "--chroot", ".", + "--fstab", path->d, + 0 + }; + + Command_init(&cmd); + Command_setParams(&cmd, argv); + Command_exec(&cmd, false); + } + else { + int status; + TEMP_FAILURE_RETRY(wait4(pid, &status, 0,0)); + + if (!WIFEXITED(status) || WEXITSTATUS(status)!=0) + exit(1); + } +} + +void +mountVserver(struct Configuration const *cfg) +{ + ENSC_PI_DECLARE(fstab_subpath, "fstab"); + ENSC_PI_DECLARE(fstabl_subpath, "fstab.local"); + + PathInfo fstab_path = cfg->cfgdir; + char fstab_buf[ENSC_PI_APPSZ(fstab_path, fstab_subpath)]; + + PathInfo fstabl_path = cfg->cfgdir; + char fstabl_buf[ENSC_PI_APPSZ(fstabl_path, fstabl_subpath)]; + + + PathInfo_append(&fstab_path, &fstab_subpath, fstab_buf); + PathInfo_append(&fstabl_path, &fstabl_subpath, fstabl_buf); + initMtab(cfg); + + mountVserverInternal(cfg, &fstab_path, true); + mountVserverInternal(cfg, &fstabl_path, false); +} diff --git a/util-vserver/vserver-start/mount.h b/util-vserver/vserver-start/mount.h new file mode 100644 index 0000000..4113855 --- /dev/null +++ b/util-vserver/vserver-start/mount.h @@ -0,0 +1,27 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifndef H_UTIL_VSERVER_VSERVER_START_MOUNT_H +#define H_UTIL_VSERVER_VSERVER_START_MOUNT_H + +#include + +struct Configuration; +void mountVserver(struct Configuration const *cfg); + +#endif // H_UTIL_VSERVER_VSERVER_START_MOUNT_H diff --git a/util-vserver/vserver-start/undo.c b/util-vserver/vserver-start/undo.c new file mode 100644 index 0000000..a46ee72 --- /dev/null +++ b/util-vserver/vserver-start/undo.c @@ -0,0 +1,92 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "undo.h" + +#include +#include + +#include +#include +#include + +struct FuncData +{ + ExitFunction fn; + void const * args; +}; + +struct Undo +{ + pid_t pid_; + struct Vector funcs; +}; + + +static struct Undo undo_data = { + .pid_ = -1 +}; + +static void +atexitHandler() +{ + struct FuncData const * ptr; + + if (undo_data.pid_ != getpid()) + return; // skip 'exit()' from forked processes + + for (ptr=Vector_end(&undo_data.funcs); + ptr!=Vector_begin(&undo_data.funcs); + --ptr) + (ptr[-1].fn)(ptr[-1].args); +} + +void +Undo_init() +{ + if (undo_data.pid_!=-1) { + WRITE_MSG(2, "Undo already initialized; internal error...\n"); + _exit(1); + } + + undo_data.pid_ = getpid(); + Vector_init(&undo_data.funcs, sizeof(struct FuncData)); + + atexit(&atexitHandler); +} + +void +Undo_addTask(ExitFunction fn, void const *args) +{ + struct FuncData *tmp = Vector_pushback(&undo_data.funcs); + assert(tmp!=0); // Vector_pushback never returns a null-pointer + + tmp->fn = fn; + tmp->args = args; +} + +void +Undo_detach() +{ + Vector_free(&undo_data.funcs); + undo_data.pid_ = -1; +} diff --git a/util-vserver/vserver-start/undo.h b/util-vserver/vserver-start/undo.h new file mode 100644 index 0000000..64042bd --- /dev/null +++ b/util-vserver/vserver-start/undo.h @@ -0,0 +1,28 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifndef H_UTIL_VSERVER_VSERVER_START_UNDO_H +#define H_UTIL_VSERVER_VSERVER_START_UNDO_H + +typedef void (*ExitFunction)(void const *); + +void Undo_init(); +void Undo_addTask(ExitFunction fn, void const *args); +void Undo_detach(); + +#endif // H_UTIL_VSERVER_VSERVER_START_UNDO_H -- 1.8.1.5