[libvirt PATCH 12/32] rpc: conditionalize signal handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The Windows platform does not have the signal handling
support we need, so it must be disabled in several parts
of the codebase.

Signed-off-by: Daniel P. Berrangé <berrange@xxxxxxxxxx>
---
 src/rpc/virnetclient.c | 33 ++++++++++++++++++++++--------
 src/rpc/virnetdaemon.c | 35 +++++++++++++++++++++++++++++---
 src/rpc/virnetdaemon.h |  4 ++++
 tools/virsh-domain.c   | 46 +++++++++++++++++++++++++++++++++++++-----
 tools/vsh.c            | 12 ++++++++++-
 5 files changed, 113 insertions(+), 17 deletions(-)

diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 50489b754c..eac02282e6 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -845,16 +845,19 @@ int virNetClientSetTLSSession(virNetClientPtr client,
     char buf[1];
     int len;
     struct pollfd fds[1];
+
+# ifndef WIN32
     sigset_t oldmask, blockedsigs;
 
     sigemptyset(&blockedsigs);
-# ifdef SIGWINCH
+#  ifdef SIGWINCH
     sigaddset(&blockedsigs, SIGWINCH);
-# endif
-# ifdef SIGCHLD
+#  endif
+#  ifdef SIGCHLD
     sigaddset(&blockedsigs, SIGCHLD);
-# endif
+#  endif
     sigaddset(&blockedsigs, SIGPIPE);
+# endif /* !WIN32 */
 
     virObjectLock(client);
 
@@ -880,19 +883,23 @@ int virNetClientSetTLSSession(virNetClientPtr client,
         else
             fds[0].events = POLLOUT;
 
+# ifndef WIN32
         /* Block SIGWINCH from interrupting poll in curses programs,
          * then restore the original signal mask again immediately
          * after the call (RHBZ#567931).  Same for SIGCHLD and SIGPIPE
          * at the suggestion of Paolo Bonzini and Daniel Berrange.
          */
         ignore_value(pthread_sigmask(SIG_BLOCK, &blockedsigs, &oldmask));
+# endif /* !WIN32 */
 
     repoll:
         ret = poll(fds, G_N_ELEMENTS(fds), -1);
         if (ret < 0 && (errno == EAGAIN || errno == EINTR))
             goto repoll;
 
+# ifndef WIN32
         ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL));
+# endif /* !WIN32 */
     }
 
     ret = virNetTLSContextCheckCertificate(tls, client->tls);
@@ -908,15 +915,19 @@ int virNetClientSetTLSSession(virNetClientPtr client,
     fds[0].revents = 0;
     fds[0].events = POLLIN;
 
+# ifndef WIN32
     /* Block SIGWINCH from interrupting poll in curses programs */
     ignore_value(pthread_sigmask(SIG_BLOCK, &blockedsigs, &oldmask));
+# endif /* !WIN32 */
 
     repoll2:
     ret = poll(fds, G_N_ELEMENTS(fds), -1);
     if (ret < 0 && (errno == EAGAIN || errno == EINTR))
         goto repoll2;
 
+# ifndef WIN32
     ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL));
+# endif /* !WIN32 */
 
     len = virNetTLSSessionRead(client->tls, buf, 1);
     if (len < 0 && errno != ENOMSG) {
@@ -1574,7 +1585,9 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
 
     for (;;) {
         char ignore;
+#ifndef WIN32
         sigset_t oldmask, blockedsigs;
+#endif /* !WIN32 */
         int timeout = -1;
         virNetMessagePtr msg = NULL;
 
@@ -1615,27 +1628,31 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
          * can stuff themselves on the queue */
         virObjectUnlock(client);
 
+#ifndef WIN32
         /* Block SIGWINCH from interrupting poll in curses programs,
          * then restore the original signal mask again immediately
          * after the call (RHBZ#567931).  Same for SIGCHLD and SIGPIPE
          * at the suggestion of Paolo Bonzini and Daniel Berrange.
          */
         sigemptyset(&blockedsigs);
-#ifdef SIGWINCH
+# ifdef SIGWINCH
         sigaddset(&blockedsigs, SIGWINCH);
-#endif
-#ifdef SIGCHLD
+# endif
+# ifdef SIGCHLD
         sigaddset(&blockedsigs, SIGCHLD);
-#endif
+# endif
         sigaddset(&blockedsigs, SIGPIPE);
         ignore_value(pthread_sigmask(SIG_BLOCK, &blockedsigs, &oldmask));
+#endif /* !WIN32 */
 
     repoll:
         ret = poll(fds, G_N_ELEMENTS(fds), timeout);
         if (ret < 0 && (errno == EAGAIN || errno == EINTR))
             goto repoll;
 
+#ifndef WIN32
         ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL));
+#endif /* !WIN32 */
 
         virObjectLock(client);
 
diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c
index 570930436a..9634e93b52 100644
--- a/src/rpc/virnetdaemon.c
+++ b/src/rpc/virnetdaemon.c
@@ -45,6 +45,7 @@
 
 VIR_LOG_INIT("rpc.netdaemon");
 
+#ifndef WIN32
 typedef struct _virNetDaemonSignal virNetDaemonSignal;
 typedef virNetDaemonSignal *virNetDaemonSignalPtr;
 
@@ -54,17 +55,20 @@ struct _virNetDaemonSignal {
     virNetDaemonSignalFunc func;
     void *opaque;
 };
+#endif /* !WIN32 */
 
 struct _virNetDaemon {
     virObjectLockable parent;
 
     bool privileged;
 
+#ifndef WIN32
     size_t nsignals;
     virNetDaemonSignalPtr *signals;
     int sigread;
     int sigwrite;
     int sigwatch;
+#endif /* !WIN32 */
 
     virHashTablePtr servers;
     virJSONValuePtr srvObject;
@@ -84,10 +88,9 @@ static void
 virNetDaemonDispose(void *obj)
 {
     virNetDaemonPtr dmn = obj;
+#ifndef WIN32
     size_t i;
 
-    VIR_FORCE_CLOSE(dmn->autoShutdownInhibitFd);
-
     for (i = 0; i < dmn->nsignals; i++) {
         sigaction(dmn->signals[i]->signum, &dmn->signals[i]->oldaction, NULL);
         VIR_FREE(dmn->signals[i]);
@@ -97,6 +100,9 @@ virNetDaemonDispose(void *obj)
     VIR_FORCE_CLOSE(dmn->sigwrite);
     if (dmn->sigwatch > 0)
         virEventRemoveHandle(dmn->sigwatch);
+#endif /* !WIN32 */
+
+    VIR_FORCE_CLOSE(dmn->autoShutdownInhibitFd);
 
     virHashFree(dmn->servers);
 
@@ -119,7 +125,9 @@ virNetDaemonPtr
 virNetDaemonNew(void)
 {
     virNetDaemonPtr dmn;
+#ifndef WIN32
     struct sigaction sig_action;
+#endif /* !WIN32 */
 
     if (virNetDaemonInitialize() < 0)
         return NULL;
@@ -130,16 +138,21 @@ virNetDaemonNew(void)
     if (!(dmn->servers = virHashCreate(5, virObjectFreeHashData)))
         goto error;
 
+#ifndef WIN32
     dmn->sigwrite = dmn->sigread = -1;
+#endif /* !WIN32 */
+
     dmn->privileged = geteuid() == 0;
     dmn->autoShutdownInhibitFd = -1;
 
     if (virEventRegisterDefaultImpl() < 0)
         goto error;
 
+#ifndef WIN32
     memset(&sig_action, 0, sizeof(sig_action));
     sig_action.sa_handler = SIG_IGN;
     sigaction(SIGPIPE, &sig_action, NULL);
+#endif /* !WIN32 */
 
     return dmn;
 
@@ -587,7 +600,7 @@ virNetDaemonRemoveShutdownInhibition(virNetDaemonPtr dmn)
 }
 
 
-
+#ifndef WIN32
 static sig_atomic_t sigErrors;
 static int sigLastErrno;
 static int sigWrite = -1;
@@ -689,6 +702,7 @@ virNetDaemonSignalSetup(virNetDaemonPtr dmn)
     return -1;
 }
 
+
 int
 virNetDaemonAddSignalHandler(virNetDaemonPtr dmn,
                              int signum,
@@ -731,6 +745,21 @@ virNetDaemonAddSignalHandler(virNetDaemonPtr dmn,
     return -1;
 }
 
+#else /* WIN32 */
+
+int
+virNetDaemonAddSignalHandler(virNetDaemonPtr dmn G_GNUC_UNUSED,
+                             int signum G_GNUC_UNUSED,
+                             virNetDaemonSignalFunc func G_GNUC_UNUSED,
+                             void *opaque G_GNUC_UNUSED)
+{
+    virReportSystemError(ENOSYS, "%s",
+                         _("Signal handling not available on this platform"));
+    return -1;
+}
+
+#endif /* WIN32 */
+
 
 static void
 virNetDaemonAutoShutdownTimer(int timerid G_GNUC_UNUSED,
diff --git a/src/rpc/virnetdaemon.h b/src/rpc/virnetdaemon.h
index 5a9842bee6..c2c7767037 100644
--- a/src/rpc/virnetdaemon.h
+++ b/src/rpc/virnetdaemon.h
@@ -55,6 +55,10 @@ void virNetDaemonAutoShutdown(virNetDaemonPtr dmn,
 void virNetDaemonAddShutdownInhibition(virNetDaemonPtr dmn);
 void virNetDaemonRemoveShutdownInhibition(virNetDaemonPtr dmn);
 
+#ifdef WIN32
+# define siginfo_t void
+#endif
+
 typedef void (*virNetDaemonSignalFunc)(virNetDaemonPtr dmn, siginfo_t *info, void *opaque);
 
 int virNetDaemonAddSignalHandler(virNetDaemonPtr dmn,
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index e64e08e5da..df4a03290f 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -1697,12 +1697,14 @@ virshPrintJobProgress(const char *label, unsigned long long remaining,
 
 static volatile sig_atomic_t intCaught;
 
+#ifndef WIN32
 static void virshCatchInt(int sig G_GNUC_UNUSED,
                           siginfo_t *siginfo G_GNUC_UNUSED,
                           void *context G_GNUC_UNUSED)
 {
     intCaught = 1;
 }
+#endif /* !WIN32 */
 
 
 typedef struct _virshBlockJobWaitData virshBlockJobWaitData;
@@ -1842,11 +1844,11 @@ virshBlockJobWait(virshBlockJobWaitDataPtr data)
      * the event to the given block job we will wait for the number of retries
      * before claiming that we entered synchronised phase */
     unsigned int retries = 5;
-
+#ifndef WIN32
     struct sigaction sig_action;
     struct sigaction old_sig_action;
     sigset_t sigmask, oldsigmask;
-
+#endif /* !WIN32 */
     unsigned long long start = 0;
     unsigned long long curr = 0;
 
@@ -1861,6 +1863,7 @@ virshBlockJobWait(virshBlockJobWaitDataPtr data)
     if (data->async_abort)
         abort_flags |= VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC;
 
+#ifndef WIN32
     sigemptyset(&sigmask);
     sigaddset(&sigmask, SIGINT);
 
@@ -1869,6 +1872,7 @@ virshBlockJobWait(virshBlockJobWaitDataPtr data)
     sig_action.sa_flags = SA_SIGINFO;
     sigemptyset(&sig_action.sa_mask);
     sigaction(SIGINT, &sig_action, &old_sig_action);
+#endif /* !WIN32 */
 
     if (data->timeout && virTimeMillisNow(&start) < 0) {
         vshSaveLibvirtError();
@@ -1878,9 +1882,13 @@ virshBlockJobWait(virshBlockJobWaitDataPtr data)
     last.cur = last.end = 0;
 
     while (true) {
+#ifndef WIN32
         pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask);
+#endif /* !WIN32 */
         result = virDomainGetBlockJobInfo(data->dom, data->dev, &info, 0);
+#ifndef WIN32
         pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL);
+#endif /* !WIN32 */
 
         if (result < 0) {
             vshError(data->ctl, _("failed to query job for disk %s"), data->dev);
@@ -1944,7 +1952,9 @@ virshBlockJobWait(virshBlockJobWaitDataPtr data)
         virshPrintJobProgress(data->job_name, 0, 1);
 
  cleanup:
+#ifndef WIN32
     sigaction(SIGINT, &old_sig_action, NULL);
+#endif /* !WIN32 */
     return ret;
 }
 
@@ -4226,12 +4236,14 @@ doSave(void *opaque)
     unsigned int flags = 0;
     const char *xmlfile = NULL;
     char *xml = NULL;
+#ifndef WIN32
     sigset_t sigmask, oldsigmask;
 
     sigemptyset(&sigmask);
     sigaddset(&sigmask, SIGINT);
     if (pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask) < 0)
         goto out_sig;
+#endif /* !WIN32 */
 
     if (vshCommandOptStringReq(ctl, cmd, "file", &to) < 0)
         goto out;
@@ -4265,8 +4277,10 @@ doSave(void *opaque)
     ret = '0';
 
  out:
+#ifndef WIN32
     pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL);
  out_sig:
+#endif /* !WIN32 */
     virshDomainFree(dom);
     VIR_FREE(xml);
     ignore_value(safewrite(data->writefd, &ret, sizeof(ret)));
@@ -4285,8 +4299,11 @@ virshWatchJob(vshControl *ctl,
               void *opaque,
               const char *label)
 {
+#ifndef WIN32
     struct sigaction sig_action;
     struct sigaction old_sig_action;
+    sigset_t sigmask, oldsigmask;
+#endif /* !WIN32 */
     struct pollfd pollfd[2] = {{.fd = pipe_fd, .events = POLLIN, .revents = 0},
                                {.fd = STDIN_FILENO, .events = POLLIN, .revents = 0}};
     unsigned long long start_us, curr_us;
@@ -4294,10 +4311,10 @@ virshWatchJob(vshControl *ctl,
     int ret = -1;
     char retchar;
     bool functionReturn = false;
-    sigset_t sigmask, oldsigmask;
     bool jobStarted = false;
     nfds_t npollfd = 2;
 
+#ifndef WIN32
     sigemptyset(&sigmask);
     sigaddset(&sigmask, SIGINT);
 
@@ -4306,6 +4323,7 @@ virshWatchJob(vshControl *ctl,
     sig_action.sa_flags = SA_SIGINFO;
     sigemptyset(&sig_action.sa_mask);
     sigaction(SIGINT, &sig_action, &old_sig_action);
+#endif /* !WIN32 */
 
     /* don't poll on STDIN if we are not using a terminal */
     if (!vshTTYAvailable(ctl))
@@ -4355,9 +4373,13 @@ virshWatchJob(vshControl *ctl,
         }
 
         if (verbose || !jobStarted) {
+#ifndef WIN32
             pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask);
+#endif /* !WIN32 */
             ret = virDomainGetJobInfo(dom, &jobinfo);
+#ifndef WIN32
             pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL);
+#endif /* !WIN32 */
             if (ret == 0) {
                 if (verbose && jobinfo.dataTotal > 0)
                     virshPrintJobProgress(label, jobinfo.dataRemaining,
@@ -4378,7 +4400,9 @@ virshWatchJob(vshControl *ctl,
     functionReturn = true;
 
  cleanup:
+#ifndef WIN32
     sigaction(SIGINT, &old_sig_action, NULL);
+#endif /* !WIN32 */
     vshTTYRestore(ctl);
     return functionReturn;
 }
@@ -4662,12 +4686,14 @@ doManagedsave(void *opaque)
     virDomainPtr dom = NULL;
     const char *name;
     unsigned int flags = 0;
+#ifndef WIN32
     sigset_t sigmask, oldsigmask;
 
     sigemptyset(&sigmask);
     sigaddset(&sigmask, SIGINT);
     if (pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask) < 0)
         goto out_sig;
+#endif /* !WIN32 */
 
     if (vshCommandOptBool(cmd, "bypass-cache"))
         flags |= VIR_DOMAIN_SAVE_BYPASS_CACHE;
@@ -4686,8 +4712,10 @@ doManagedsave(void *opaque)
 
     ret = '0';
  out:
+#ifndef WIN32
     pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL);
  out_sig:
+#endif /* !WIN32 */
     virshDomainFree(dom);
     ignore_value(safewrite(data->writefd, &ret, sizeof(ret)));
 }
@@ -5340,17 +5368,19 @@ doDump(void *opaque)
     vshControl *ctl = data->ctl;
     const vshCmd *cmd = data->cmd;
     virDomainPtr dom = NULL;
-    sigset_t sigmask, oldsigmask;
     const char *name = NULL;
     const char *to = NULL;
     unsigned int flags = 0;
     const char *format = NULL;
     unsigned int dumpformat = VIR_DOMAIN_CORE_DUMP_FORMAT_RAW;
+#ifndef WIN32
+    sigset_t sigmask, oldsigmask;
 
     sigemptyset(&sigmask);
     sigaddset(&sigmask, SIGINT);
     if (pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask) < 0)
         goto out_sig;
+#endif /* !WIN32 */
 
     if (vshCommandOptStringReq(ctl, cmd, "file", &to) < 0)
         goto out;
@@ -5407,8 +5437,10 @@ doDump(void *opaque)
 
     ret = '0';
  out:
+#ifndef WIN32
     pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL);
  out_sig:
+#endif /* !WIN32 */
     if (dom)
         virshDomainFree(dom);
     ignore_value(safewrite(data->writefd, &ret, sizeof(ret)));
@@ -10601,7 +10633,6 @@ doMigrate(void *opaque)
     virshCtrlData *data = opaque;
     vshControl *ctl = data->ctl;
     const vshCmd *cmd = data->cmd;
-    sigset_t sigmask, oldsigmask;
     virTypedParameterPtr params = NULL;
     int nparams = 0;
     int maxparams = 0;
@@ -10609,11 +10640,14 @@ doMigrate(void *opaque)
     unsigned long long ullOpt = 0;
     int rv;
     virConnectPtr dconn = data->dconn;
+#ifndef WIN32
+    sigset_t sigmask, oldsigmask;
 
     sigemptyset(&sigmask);
     sigaddset(&sigmask, SIGINT);
     if (pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask) < 0)
         goto out_sig;
+#endif /* !WIN32 */
 
     if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
         goto out;
@@ -10881,8 +10915,10 @@ doMigrate(void *opaque)
     }
 
  out:
+#ifndef WIN32
     pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL);
  out_sig:
+#endif /* !WIN32 */
     virTypedParamsFree(params, nparams);
     virshDomainFree(dom);
     ignore_value(safewrite(data->writefd, &ret, sizeof(ret)));
diff --git a/tools/vsh.c b/tools/vsh.c
index 949c8dad7b..39bb75f192 100644
--- a/tools/vsh.c
+++ b/tools/vsh.c
@@ -2013,6 +2013,7 @@ vshEventLoop(void *opaque)
 
 /* We want to use SIGINT to cancel a wait; but as signal handlers
  * don't have an opaque argument, we have to use static storage.  */
+#ifndef WIN32
 static int vshEventFd = -1;
 static struct sigaction vshEventOldAction;
 
@@ -2027,6 +2028,7 @@ vshEventInt(int sig G_GNUC_UNUSED,
     if (vshEventFd >= 0)
         ignore_value(safewrite(vshEventFd, &reason, 1));
 }
+#endif /* !WIN32 */
 
 
 /* Event loop handler used to limit length of waiting for any other event. */
@@ -2057,10 +2059,13 @@ vshEventTimeout(int timer G_GNUC_UNUSED,
 int
 vshEventStart(vshControl *ctl, int timeout_ms)
 {
+#ifndef WIN32
     struct sigaction action;
+    assert(vshEventFd == -1);
+#endif /* !WIN32 */
 
     assert(ctl->eventPipe[0] == -1 && ctl->eventPipe[1] == -1 &&
-           vshEventFd == -1 && ctl->eventTimerId >= 0);
+           ctl->eventTimerId >= 0);
     if (pipe2(ctl->eventPipe, O_CLOEXEC) < 0) {
         char ebuf[1024];
 
@@ -2068,12 +2073,15 @@ vshEventStart(vshControl *ctl, int timeout_ms)
                  virStrerror(errno, ebuf, sizeof(ebuf)));
         return -1;
     }
+
+#ifndef WIN32
     vshEventFd = ctl->eventPipe[1];
 
     action.sa_sigaction = vshEventInt;
     action.sa_flags = SA_SIGINFO;
     sigemptyset(&action.sa_mask);
     sigaction(SIGINT, &action, &vshEventOldAction);
+#endif /* !WIN32 */
 
     if (timeout_ms)
         virEventUpdateTimeout(ctl->eventTimerId, timeout_ms);
@@ -2140,10 +2148,12 @@ vshEventWait(vshControl *ctl)
 void
 vshEventCleanup(vshControl *ctl)
 {
+#ifndef WIN32
     if (vshEventFd >= 0) {
         sigaction(SIGINT, &vshEventOldAction, NULL);
         vshEventFd = -1;
     }
+#endif /* !WIN32 */
     VIR_FORCE_CLOSE(ctl->eventPipe[0]);
     VIR_FORCE_CLOSE(ctl->eventPipe[1]);
     virEventUpdateTimeout(ctl->eventTimerId, -1);
-- 
2.24.1





[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux