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 "pathconfig.h"
48 #include <sys/types.h>
53 #include <sys/socket.h>
59 fprintf (stderr,"rebootmgr version %s\n",VERSION);
60 fprintf (stderr,"\n");
61 fprintf (stderr,"rebootmgr [--pidfile file ] vserver-name [ vserver-name ...]\n");
64 static int rebootmgr_opensocket (const char *vname)
68 int fd = socket (AF_UNIX,SOCK_STREAM,0);
69 sprintf (sockn, DEFAULT_VSERVERDIR "/%s/dev/reboot",vname);
72 fprintf (stderr,"Can't create a unix domain socket (%s)\n"
75 struct sockaddr_un un;
76 un.sun_family = AF_UNIX;
77 strcpy (un.sun_path,sockn);
78 if (bind(fd,(struct sockaddr*)&un,sizeof(un))==-1){
79 fprintf (stderr,"Can't bind to file %s (%s)\n",sockn
84 code = listen (fd,10);
86 fprintf (stderr,"Can't listen to file %s (%s)\n",sockn
96 static int rebootmgr_process (int fd, const char *vname)
100 int len = read (fd,buf,sizeof(buf)-1);
101 // fprintf (stderr,"process %d %s len %d\n",fd,vname,len);
104 if (strcmp(buf,"reboot\n")==0){
106 syslog (LOG_NOTICE,"reboot vserver %s\n",vname);
107 snprintf (cmd,sizeof(cmd)-1, SBINDIR "/vserver %s restart >>/var/log/boot.log 2>&1", vname);
110 }else if (strcmp(buf,"halt\n")==0){
112 syslog (LOG_NOTICE,"halt vserver %s\n",vname);
113 snprintf (cmd,sizeof(cmd)-1, SBINDIR "/vserver %s stop >>/var/log/boot.log 2>&1", vname);
117 syslog (LOG_ERR,"Invalid request from vserver %s",vname);
124 int main (int argc, char *argv[])
133 int *sockets = alloca(argc * sizeof(int));
135 openlog ("rebootmgr",LOG_PID,LOG_DAEMON);
136 for (i=0; i<argc; i++){
137 const char *arg = argv[i];
138 if (strcmp(arg,"--pidfile")==0){
139 const char *pidfile = argv[i+1];
140 FILE *fout = fopen (pidfile,"w");
142 fprintf (stderr,"Can't open pidfile %s (%s)\n"
143 ,pidfile,strerror(errno));
146 syslog (LOG_ERR,"Can't open pidfile %s (%m)"
149 fprintf (fout,"%d\n",getpid());
154 }else if (strcmp(arg,"--")==0){
157 }else if (arg[0] == '-'){
158 fprintf (stderr,"Invalid argument %s\n",arg);
159 syslog (LOG_ERR,"Invalid argument %s",arg);
162 for (i=start; i<argc; i++){
163 int fd = rebootmgr_opensocket (argv[i]);
171 int maxhandles = argc*2;
175 } handles[maxhandles];
184 for (i=start; i<argc; i++){
186 if (fd > maxfd) maxfd = fd;
189 for (i=0; i<nbhandles; i++){
190 int fd = handles[i].handle;
191 if (fd > maxfd) maxfd = fd;
194 ok = select (maxfd+1,&fdin,NULL,NULL,NULL);
201 for (i=start; i<argc; i++){
203 if (FD_ISSET(fd,&fdin)){
204 struct sockaddr_un unc;
205 socklen_t len = sizeof(unc);
206 unc.sun_family = AF_UNIX;
207 fd = accept (fd,(struct sockaddr*)&unc,&len);
209 if (nbhandles == maxhandles){
211 // Overloaded, we close every handle
212 syslog (LOG_ERR,"%d sockets opened: Overloaded\n",nbhandles);
213 for (j=0; j<nbhandles; j++){
214 close (handles[j].handle);
218 handles[nbhandles].handle = fd;
219 handles[nbhandles].vname = argv[i];
221 // fprintf (stderr,"accept %d\n",nbhandles);
225 for (i=0; i<nbhandles; i++){
226 int fd = handles[i].handle;
227 if (FD_ISSET(fd,&fdin)){
228 if (rebootmgr_process (fd,handles[i].vname)==-1){
231 handles[dst++] = handles[i];
234 handles[dst++] = handles[i];