Should've been part of the previous commit.
[util-vserver.git] / vserver-start / mount.c
1 // $Id: mount.c 1679 2004-08-25 00:11:50Z ensc $    --*- c -*--
2
3 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 //  
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; version 2 of the License.
8 //  
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //  
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18
19 #ifdef HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22
23 #include "mount.h"
24 #include "configuration.h"
25 #include "undo.h"
26
27 #include <pathconfig.h>
28
29 #include <lib/internal.h>
30 #include <lib_internal/command.h>
31
32 #include <unistd.h>
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <wait.h>
36 #include <string.h>
37
38 #define ENSC_WRAPPERS_UNISTD    1
39 #define ENSC_WRAPPERS_FCNTL     1
40 #include <ensc_wrappers/wrappers.h>
41
42 static char const *
43 findMtab(char const *vserver_mtab)
44 {
45   char const *tmp;
46   
47   if (utilvserver_isFile(vserver_mtab, true)) return vserver_mtab;
48
49   tmp=CONFDIR "/.defaults/init/mtab";
50   if (utilvserver_isFile(tmp, true)) return tmp;
51
52   tmp=PKGLIBDEFAULTDIR "/mtab";
53   if (utilvserver_isFile(tmp, true)) return tmp;
54
55   return 0;
56 }
57
58 static void
59 initMtab(struct Configuration const *cfg)
60 {
61   ENSC_PI_DECLARE(mtab_subpath,  "apps/init/mtab");
62   PathInfo              mtab_path  = cfg->cfgdir;
63   char                  mtab_buf[ENSC_PI_APPSZ(mtab_path, mtab_subpath)];
64
65   PathInfo_append(&mtab_path,  &mtab_subpath,  mtab_buf);
66   char const *          mtab = findMtab(mtab_path.d);
67   pid_t                 pid;
68   int                   p[2];
69
70   Epipe(p);
71   pid = Efork();
72   if (pid==0) {
73     Undo_detach();
74     Eclose(p[1]);
75     
76     Echdir(cfg->vdir);
77     Echroot(".");
78
79     int         fd = Eopen("/etc/mtab", O_WRONLY|O_CREAT, 0644);
80     for (;;) {
81       char      buf[4096];
82       ssize_t   len = TEMP_FAILURE_RETRY(read(p[0], buf, sizeof buf));
83       if (len==0) break;
84       if (len==-1) {
85         perror("vserver-start: initMtab/read():");
86         _exit(1);
87       }
88
89       Ewrite(fd, buf, len);
90     }
91     Eclose(fd);
92     Eclose(p[0]);
93     _exit(0);
94   }
95   else {
96     Eclose(p[0]);
97
98     if (mtab!=0) {
99       int               fd = Eopen(mtab, O_RDONLY, 0644);
100
101       for (;;) {
102         char    buf[4096];
103         ssize_t len = TEMP_FAILURE_RETRY(read(fd, buf, sizeof buf));
104         if (len==0) break;
105       if (len==-1) {
106         perror("vserver-start: initMtab/read():");
107         _exit(1);
108       }
109
110         Ewrite(p[1], buf, len);
111       }
112
113       Eclose(fd);
114     }
115
116     Eclose(p[1]);
117
118     int         status;
119     TEMP_FAILURE_RETRY(wait4(pid, &status, 0,0));
120
121     if (!WIFEXITED(status) || WEXITSTATUS(status)!=0) {
122       exit(1);
123     }
124   }
125 }
126
127 static void
128 mountVserverInternal(struct Configuration const *cfg,
129                      PathInfo const *path, bool use_chbind)
130 {
131   if (!utilvserver_isFile(path->d,true)) return;
132
133   pid_t         pid = Efork();
134   if (pid==0) {
135     Undo_detach();
136
137     Echdir(cfg->vdir);
138
139     if (use_chbind) {
140         // TODO
141     }
142
143     struct Command      cmd;
144     char const *        argv[] = {
145       PROG_SECURE_MOUNT,
146       "-a",
147       "--chroot",
148       "--fstab", path->d,
149       0
150     };
151
152     Command_init(&cmd);
153     Command_setParams(&cmd, argv);
154     Command_exec(&cmd, false);
155   }
156   else {
157     int         status;
158     TEMP_FAILURE_RETRY(wait4(pid, &status, 0,0));
159
160     if (!WIFEXITED(status) || WEXITSTATUS(status)!=0)
161       exit(1);
162   }
163 }
164
165 void
166 mountVserver(struct Configuration const *cfg)
167 {
168   ENSC_PI_DECLARE(fstab_subpath,  "fstab");
169   ENSC_PI_DECLARE(fstabl_subpath, "fstab.local");
170
171   PathInfo      fstab_path  = cfg->cfgdir;
172   char          fstab_buf[ENSC_PI_APPSZ(fstab_path, fstab_subpath)];
173
174   PathInfo      fstabl_path = cfg->cfgdir;
175   char          fstabl_buf[ENSC_PI_APPSZ(fstabl_path, fstabl_subpath)];
176
177   
178   PathInfo_append(&fstab_path,  &fstab_subpath,  fstab_buf);
179   PathInfo_append(&fstabl_path, &fstabl_subpath, fstabl_buf);
180   initMtab(cfg);
181
182   mountVserverInternal(cfg, &fstab_path,  true);
183   mountVserverInternal(cfg, &fstabl_path, false);
184 }