// $Id: mount.c 1679 2004-08-25 00:11:50Z ensc $ --*- 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); }