minor optimizations
[util-vserver.git] / util-vserver / vserver-start / main.c
1 // $Id$    --*- 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 "vserver-start.h"
24 #include "vshelper.h"
25 #include "pathconfig.h"
26 #include "interface.h"
27 #include "configuration.h"
28
29 #include "lib_internal/util.h"
30 #include "lib_internal/errinfo.h"
31 #include "lib/vserver.h"
32
33 #include <sys/file.h>
34
35 struct Options                  opts;
36 struct Configuration            cfg;
37 int                             wrapper_exit_code;
38
39 static void
40 env2Str(char const **var, char const *env, bool req)
41 {
42   char const *          tmp = getenv(env);
43   if (req && tmp==0) {
44     WRITE_MSG(2, "vserver.start: required environment variable $");
45     WRITE_STR(2, env);
46     WRITE_STR(2, " not set; aborting...\n");
47     exit(1);
48   }
49
50   *var = tmp;
51   unsetenv(env);
52 }
53
54 static void
55 env2Bool(bool *var, char const *env, bool req)
56 {
57   char const *  tmp;
58   env2Str(&tmp, env, req);
59   *var = !(tmp==0 || atoi(tmp)==0);
60 }
61
62 static void
63 initGlobals()
64 {
65   env2Str (&opts.VSERVER_DIR,       "VSERVER_DIR",       true);
66   env2Str (&opts.VSERVER_NAME,      "VSERVER_NAME",      true);
67   env2Bool(&opts.OPTION_DEBUG,      "OPTION_DEBUG",      false);
68   env2Bool(&opts.OPTION_DEFAULTTTY, "OPTION_DEFAULTTTY", false);  
69 }
70
71 static void
72 initLock()
73 {
74   size_t                        l   = strlen(opts.VSERVER_DIR);
75   char                          tmp[sizeof(LOCKDIR "/vserver..startup") + l];
76   char *                        ptr = tmp;
77   struct ErrorInformation       err = { .app = 0 };
78   int                           fd;
79
80   ptr  = Xmemcpy(ptr, LOCKDIR "/vserver.", sizeof(LOCKDIR "/vserver.")-1);
81   ((char *)(Xmemcpy(ptr, opts.VSERVER_DIR, l)))[0] = '\0';
82   ptr += canonifyVserverName(ptr);
83   ptr  = Xmemcpy(ptr, ".startup",  sizeof(".startup"));
84   *ptr = '\0';
85
86   if (!lockfile(&fd, tmp, LOCK_EX, 30, &err)) {
87     WRITE_MSG(2, "vserver.start: failed to lock '");
88     WRITE_STR(2, tmp);
89     WRITE_MSG(2, "': ");
90     ErrInfo_writeErrno(&err);
91     exit(1);
92   }
93 }
94
95 static void
96 checkConstraints()
97 {
98   xid_t                 xid;
99   bool                  is_running;
100   struct vc_vx_info     info;
101
102   xid = vc_getVserverCtx(opts.VSERVER_DIR, vcCFG_RECENT_FULL,
103                          true, &is_running);
104
105   if (xid!=VC_NOCTX && vc_get_vx_info(xid, &info)!=-1) {
106     WRITE_MSG(2, "vserver.start: vserver '");
107     WRITE_STR(2, opts.VSERVER_NAME);
108     WRITE_MSG(2, "' already running; aborting...\n");
109     exit(1);
110   }
111
112   Vshelper_doSanityCheck();
113 }
114
115 int main(int argc, char *argv[])
116 {
117   Cfg_init(&cfg);
118   
119   initGlobals();
120   initLock();
121   checkConstraints();
122
123   PathInfo      cfgdir = { .d = opts.VSERVER_DIR, .l = strlen(opts.VSERVER_DIR) };
124
125   getConfiguration(&cfg, &cfgdir);
126   execScriptlets(&cfgdir, opts.VSERVER_NAME, "prepre-start");
127   activateInterfaces();
128 }