3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 // based on rebootmgr.cc by Jacques Gelinas
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2, or (at your option)
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 The reboot manager allow a virtual server administrator to request
22 a complete restart of his vserver. This means that all services
23 are terminated, all remaining processes are killed and then
24 all services are started.
26 This is done by issuing
28 /usr/sbin/vserver vserver restart
31 The rebootmgr installs a unix domain socket in each vservers
32 and listen for the reboot messages. All other message are discarded.
34 The unix domain socket is placed in /vservers/N/dev/reboot and is
37 The vreboot utility is used to send the signal from the vserver
43 #include <sys/types.h>
48 #include <sys/socket.h>
54 fprintf (stderr,"rebootmgr version %s\n",VERSION);
55 fprintf (stderr,"\n");
56 fprintf (stderr,"rebootmgr [--pidfile file ] vserver-name [ vserver-name ...]\n");
59 static int rebootmgr_opensocket (const char *vname)
63 int fd = socket (AF_UNIX,SOCK_STREAM,0);
64 sprintf (sockn,"/vservers/%s/dev/reboot",vname);
67 fprintf (stderr,"Can't create a unix domain socket (%s)\n"
70 struct sockaddr_un un;
71 un.sun_family = AF_UNIX;
72 strcpy (un.sun_path,sockn);
73 if (bind(fd,(struct sockaddr*)&un,sizeof(un))==-1){
74 fprintf (stderr,"Can't bind to file %s (%s)\n",sockn
79 code = listen (fd,10);
81 fprintf (stderr,"Can't listen to file %s (%s)\n",sockn
91 static int rebootmgr_process (int fd, const char *vname)
95 int len = read (fd,buf,sizeof(buf)-1);
96 // fprintf (stderr,"process %d %s len %d\n",fd,vname,len);
99 if (strcmp(buf,"reboot\n")==0){
101 syslog (LOG_NOTICE,"reboot vserver %s\n",vname);
102 snprintf (cmd,sizeof(cmd)-1,"/usr/sbin/vserver %s restart >>/var/log/boot.log 2>&1",vname);
105 }else if (strcmp(buf,"halt\n")==0){
107 syslog (LOG_NOTICE,"halt vserver %s\n",vname);
108 snprintf (cmd,sizeof(cmd)-1,"/usr/sbin/vserver %s stop >>/var/log/boot.log 2>&1",vname);
112 syslog (LOG_ERR,"Invalid request from vserver %s",vname);
119 int main (int argc, char *argv[])
128 int *sockets = alloca(argc * sizeof(int));
130 openlog ("rebootmgr",LOG_PID,LOG_DAEMON);
131 for (i=0; i<argc; i++){
132 const char *arg = argv[i];
133 if (strcmp(arg,"--pidfile")==0){
134 const char *pidfile = argv[i+1];
135 FILE *fout = fopen (pidfile,"w");
137 fprintf (stderr,"Can't open pidfile %s (%s)\n"
138 ,pidfile,strerror(errno));
141 syslog (LOG_ERR,"Can't open pidfile %s (%m)"
144 fprintf (fout,"%d\n",getpid());
149 }else if (strcmp(arg,"--")==0){
152 }else if (arg[0] == '-'){
153 fprintf (stderr,"Invalid argument %s\n",arg);
154 syslog (LOG_ERR,"Invalid argument %s",arg);
157 for (i=start; i<argc; i++){
158 int fd = rebootmgr_opensocket (argv[i]);
166 int maxhandles = argc*2;
170 } handles[maxhandles];
179 for (i=start; i<argc; i++){
181 if (fd > maxfd) maxfd = fd;
184 for (i=0; i<nbhandles; i++){
185 int fd = handles[i].handle;
186 if (fd > maxfd) maxfd = fd;
189 ok = select (maxfd+1,&fdin,NULL,NULL,NULL);
196 for (i=start; i<argc; i++){
198 if (FD_ISSET(fd,&fdin)){
199 struct sockaddr_un unc;
200 size_t len = sizeof(unc);
201 unc.sun_family = AF_UNIX;
202 fd = accept (fd,(struct sockaddr*)&unc,&len);
204 if (nbhandles == maxhandles){
206 // Overloaded, we close every handle
207 syslog (LOG_ERR,"%d sockets opened: Overloaded\n",nbhandles);
208 for (j=0; j<nbhandles; j++){
209 close (handles[j].handle);
213 handles[nbhandles].handle = fd;
214 handles[nbhandles].vname = argv[i];
216 // fprintf (stderr,"accept %d\n",nbhandles);
220 for (i=0; i<nbhandles; i++){
221 int fd = handles[i].handle;
222 if (FD_ISSET(fd,&fdin)){
223 if (rebootmgr_process (fd,handles[i].vname)==-1){
226 handles[dst++] = handles[i];
229 handles[dst++] = handles[i];