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
47 #include <sys/types.h>
52 #include <sys/socket.h>
58 fprintf (stderr,"rebootmgr version %s\n",VERSION);
59 fprintf (stderr,"\n");
60 fprintf (stderr,"rebootmgr [--pidfile file ] vserver-name [ vserver-name ...]\n");
63 static int rebootmgr_opensocket (const char *vname)
67 int fd = socket (AF_UNIX,SOCK_STREAM,0);
68 sprintf (sockn,"/vservers/%s/dev/reboot",vname);
71 fprintf (stderr,"Can't create a unix domain socket (%s)\n"
74 struct sockaddr_un un;
75 un.sun_family = AF_UNIX;
76 strcpy (un.sun_path,sockn);
77 if (bind(fd,(struct sockaddr*)&un,sizeof(un))==-1){
78 fprintf (stderr,"Can't bind to file %s (%s)\n",sockn
83 code = listen (fd,10);
85 fprintf (stderr,"Can't listen to file %s (%s)\n",sockn
95 static int rebootmgr_process (int fd, const char *vname)
99 int len = read (fd,buf,sizeof(buf)-1);
100 // fprintf (stderr,"process %d %s len %d\n",fd,vname,len);
103 if (strcmp(buf,"reboot\n")==0){
105 syslog (LOG_NOTICE,"reboot vserver %s\n",vname);
106 snprintf (cmd,sizeof(cmd)-1,"/usr/sbin/vserver %s restart >>/var/log/boot.log 2>&1",vname);
109 }else if (strcmp(buf,"halt\n")==0){
111 syslog (LOG_NOTICE,"halt vserver %s\n",vname);
112 snprintf (cmd,sizeof(cmd)-1,"/usr/sbin/vserver %s stop >>/var/log/boot.log 2>&1",vname);
116 syslog (LOG_ERR,"Invalid request from vserver %s",vname);
123 int main (int argc, char *argv[])
132 int *sockets = alloca(argc * sizeof(int));
134 openlog ("rebootmgr",LOG_PID,LOG_DAEMON);
135 for (i=0; i<argc; i++){
136 const char *arg = argv[i];
137 if (strcmp(arg,"--pidfile")==0){
138 const char *pidfile = argv[i+1];
139 FILE *fout = fopen (pidfile,"w");
141 fprintf (stderr,"Can't open pidfile %s (%s)\n"
142 ,pidfile,strerror(errno));
145 syslog (LOG_ERR,"Can't open pidfile %s (%m)"
148 fprintf (fout,"%d\n",getpid());
153 }else if (strcmp(arg,"--")==0){
156 }else if (arg[0] == '-'){
157 fprintf (stderr,"Invalid argument %s\n",arg);
158 syslog (LOG_ERR,"Invalid argument %s",arg);
161 for (i=start; i<argc; i++){
162 int fd = rebootmgr_opensocket (argv[i]);
170 int maxhandles = argc*2;
174 } handles[maxhandles];
183 for (i=start; i<argc; i++){
185 if (fd > maxfd) maxfd = fd;
188 for (i=0; i<nbhandles; i++){
189 int fd = handles[i].handle;
190 if (fd > maxfd) maxfd = fd;
193 ok = select (maxfd+1,&fdin,NULL,NULL,NULL);
200 for (i=start; i<argc; i++){
202 if (FD_ISSET(fd,&fdin)){
203 struct sockaddr_un unc;
204 socklen_t len = sizeof(unc);
205 unc.sun_family = AF_UNIX;
206 fd = accept (fd,(struct sockaddr*)&unc,&len);
208 if (nbhandles == maxhandles){
210 // Overloaded, we close every handle
211 syslog (LOG_ERR,"%d sockets opened: Overloaded\n",nbhandles);
212 for (j=0; j<nbhandles; j++){
213 close (handles[j].handle);
217 handles[nbhandles].handle = fd;
218 handles[nbhandles].vname = argv[i];
220 // fprintf (stderr,"accept %d\n",nbhandles);
224 for (i=0; i<nbhandles; i++){
225 int fd = handles[i].handle;
226 if (FD_ISSET(fd,&fdin)){
227 if (rebootmgr_process (fd,handles[i].vname)==-1){
230 handles[dst++] = handles[i];
233 handles[dst++] = handles[i];