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>
54 #include <sys/socket.h>
60 fprintf (stderr,"rebootmgr version %s\n",VERSION);
61 fprintf (stderr,"\n");
62 fprintf (stderr,"rebootmgr [--pidfile file ] vserver-name [ vserver-name ...]\n");
65 static int rebootmgr_opensocket (const char *vname)
69 int fd = socket (AF_UNIX,SOCK_STREAM,0);
70 sprintf (sockn, DEFAULT_VSERVERDIR "/%s/dev/reboot",vname);
73 fprintf (stderr,"Can't create a unix domain socket (%s)\n"
76 struct sockaddr_un un;
77 un.sun_family = AF_UNIX;
78 strcpy (un.sun_path,sockn);
79 if (bind(fd,(struct sockaddr*)&un,sizeof(un))==-1){
80 fprintf (stderr,"Can't bind to file %s (%s)\n",sockn
85 code = listen (fd,10);
87 fprintf (stderr,"Can't listen to file %s (%s)\n",sockn
97 static int rebootmgr_process (int fd, const char *vname)
101 int len = read (fd,buf,sizeof(buf)-1);
102 // fprintf (stderr,"process %d %s len %d\n",fd,vname,len);
105 if (strcmp(buf,"reboot\n")==0){
107 syslog (LOG_NOTICE,"reboot vserver %s\n",vname);
108 snprintf (cmd,sizeof(cmd)-1, SBINDIR "/vserver %s restart >>/var/log/boot.log 2>&1", vname);
111 }else if (strcmp(buf,"halt\n")==0){
113 syslog (LOG_NOTICE,"halt vserver %s\n",vname);
114 snprintf (cmd,sizeof(cmd)-1, SBINDIR "/vserver %s stop >>/var/log/boot.log 2>&1", vname);
118 syslog (LOG_ERR,"Invalid request from vserver %s",vname);
125 int main (int argc, char *argv[])
134 int *sockets = alloca(argc * sizeof(int));
136 openlog ("rebootmgr",LOG_PID,LOG_DAEMON);
137 for (i=0; i<argc; i++){
138 const char *arg = argv[i];
139 if (strcmp(arg,"--pidfile")==0){
140 const char *pidfile = argv[i+1];
141 FILE *fout = fopen (pidfile,"w");
143 fprintf (stderr,"Can't open pidfile %s (%s)\n"
144 ,pidfile,strerror(errno));
147 syslog (LOG_ERR,"Can't open pidfile %s (%m)"
150 fprintf (fout,"%d\n",getpid());
155 }else if (strcmp(arg,"--")==0){
158 }else if (arg[0] == '-'){
159 fprintf (stderr,"Invalid argument %s\n",arg);
160 syslog (LOG_ERR,"Invalid argument %s",arg);
163 for (i=start; i<argc; i++){
164 int fd = rebootmgr_opensocket (argv[i]);
172 int maxhandles = argc*2;
176 } handles[maxhandles];
185 for (i=start; i<argc; i++){
187 if (fd > maxfd) maxfd = fd;
190 for (i=0; i<nbhandles; i++){
191 int fd = handles[i].handle;
192 if (fd > maxfd) maxfd = fd;
195 ok = select (maxfd+1,&fdin,NULL,NULL,NULL);
202 for (i=start; i<argc; i++){
204 if (FD_ISSET(fd,&fdin)){
205 struct sockaddr_un unc;
206 socklen_t len = sizeof(unc);
207 unc.sun_family = AF_UNIX;
208 fd = accept (fd,(struct sockaddr*)&unc,&len);
210 if (nbhandles == maxhandles){
212 // Overloaded, we close every handle
213 syslog (LOG_ERR,"%d sockets opened: Overloaded\n",nbhandles);
214 for (j=0; j<nbhandles; j++){
215 close (handles[j].handle);
219 handles[nbhandles].handle = fd;
220 handles[nbhandles].vname = argv[i];
222 // fprintf (stderr,"accept %d\n",nbhandles);
226 for (i=0; i<nbhandles; i++){
227 int fd = handles[i].handle;
228 if (FD_ISSET(fd,&fdin)){
229 if (rebootmgr_process (fd,handles[i].vname)==-1){
232 handles[dst++] = handles[i];
235 handles[dst++] = handles[i];