/* Copyright Jacques Gelinas jack@solucorp.qc.ca Distributed under the Gnu Public License, see the License file in this package. */ /* The reboot manager allow a virtual server administrator to request a complete restart of his vserver. This means that all services are terminated, all remaining processes are killed and then all services are started. This is done by issuing /usr/sbin/vserver vserver restart The rebootmgr installs a unix domain socket in each vservers and listen for the reboot messages. All other message are discarded. The unix domain socket is placed in /vservers/N/dev/reboot and is turned immutable. The vreboot utility is used to send the signal from the vserver environment. */ #include #include #include #include #include #include #include #include #include #include #include "vutil.h" static void usage() { fprintf (stderr,"rebootmgr version %s\n",VERSION); fprintf (stderr,"\n"); fprintf (stderr,"rebootmgr [--pidfile file ] vserver-name [ vserver-name ...]\n"); } static int rebootmgr_opensocket (const char *vname) { int ret = -1; VSERVER_CONF conf; if (vutil_readconf (vname,conf) != -1){ char sockn[PATH_MAX]; sprintf (sockn,"%s/dev/reboot",conf.vserverdir.c_str()); unlink (sockn); int fd = socket (AF_UNIX,SOCK_STREAM,0); if (fd == -1){ fprintf (stderr,"Can't create a unix domain socket (%s)\n" ,strerror(errno)); }else{ struct sockaddr_un un; un.sun_family = AF_UNIX; strcpy (un.sun_path,sockn); if (bind(fd,(struct sockaddr*)&un,sizeof(un))==-1){ fprintf (stderr,"Can't bind to file %s (%s)\n",sockn ,strerror(errno)); }else{ chmod (sockn,0600); int code = ::listen (fd,10); if (code == -1){ fprintf (stderr,"Can't listen to file %s (%s)\n",sockn ,strerror(errno)); }else{ ret = fd; } } } } return ret; } static int rebootmgr_process (int fd, const char *vname) { int ret = -1; char buf[100]; int len = read (fd,buf,sizeof(buf)-1); // fprintf (stderr,"process %d %s len %d\n",fd,vname,len); if (len > 0){ buf[len] = '\0'; if (strcmp(buf,"reboot\n")==0){ syslog (LOG_NOTICE,"reboot vserver %s\n",vname); char cmd[1000]; snprintf (cmd,sizeof(cmd)-1,"/usr/sbin/vserver %s restart >>/var/log/boot.log 2>&1",vname); system (cmd); ret = 0; }else if (strcmp(buf,"halt\n")==0){ syslog (LOG_NOTICE,"halt vserver %s\n",vname); char cmd[1000]; snprintf (cmd,sizeof(cmd)-1,"/usr/sbin/vserver %s stop >>/var/log/boot.log 2>&1",vname); system (cmd); ret = 0; }else{ syslog (LOG_ERR,"Invalid request from vserver %s",vname); } } return ret; } int main (int argc, char *argv[]) { int ret = -1; if (argc < 2){ usage(); }else{ openlog ("rebootmgr",LOG_PID,LOG_DAEMON); int error = 0; int start = 1; for (int i=0; i maxfd) maxfd = fd; FD_SET (fd,&fdin); } for (int i=0; i maxfd) maxfd = fd; FD_SET (fd,&fdin); } int ok = select (maxfd+1,&fdin,NULL,NULL,NULL); if (ok <= 0){ break; }else{ for (int i=start; i