On Thu, Dec 23, 2010 at 09:05:58AM -0700, Eric Blake wrote:
> On 12/23/2010 02:07 AM, Hu Tao wrote:
> > ---
>
> No commit message beyond the title?
>
> > @@ -208,6 +211,7 @@ typedef struct __vshCmd {
> > typedef struct __vshControl {
> > char *name; /* connection name */
> > virConnectPtr conn; /* connection to hypervisor (MAY BE NULL)
> > */
> > + virDomainPtr dom;
>
> No comment as to it's purpose?
Will update it if I update the patch.
>
> > vshCmd *cmd; /* the current command */
> > char *cmdstr; /* string with command */
> > int imode; /* interactive mode? */
> > @@ -221,6 +225,9 @@ typedef struct __vshControl {
> > int log_fd; /* log file descriptor */
> > char *historydir; /* readline history directory name */
> > char *historyfile; /* readline history file name */
> > +
> > + virMutex mutex;
> > + virThreadPoolPtr threadPool;
>
> Likewise.
Will update it if I update the patch.
>
> > @@ -509,6 +518,44 @@ static void vshCatchDisconnect(int sig, siginfo_t *
> > siginfo,
> > if ((sig == SIGPIPE) || (siginfo->si_signo == SIGPIPE))
> > disconnected++;
> > }
> > +#endif
> > +
> > +#ifdef SIGINT
>
> Unnecessary ifdef - SIGINT is available on all platforms (it is required
> by C).
>
> > +static void vshCatchInt(int sig, siginfo_t *siginfo,
> > + void *context ATTRIBUTE_UNUSED) {
> > + vshControl *ctl = &_ctl;
> > + vshCmd *cmds, *c;
> > + char *cmdStr = NULL;
> > +
> > + virMutexLock(&ctl->mutex);
> > + if (!ctl->dom)
> > + goto error;
> > +
> > + if (virAsprintf(&cmdStr, "domjobabort %s", ctl->dom->name) < 0)
>
> _BIG_ no-no. virAsprintf calls malloc(), which is NOT signal-safe (that
> is, if the signal arrived while some other thread was in the middle of a
> malloc(), you've just caused deadlock). The only safe thing to do in a
> signal handler is to set some state variables that are then checked in
> the main processing loop, when you are back in a safe state to act on a
> (minimally-delayed) basis on the signal.
>
> See how daemon/libvirtd.c uses qemudDispatchSignalEvent (although that's
> being rewritten by danpb's factorization into a cleaner rpc
> server/client model).
>
> > + goto error;
> > +
> > + if ((sig == SIGINT) || (siginfo->si_signo == SIGINT)) {
> > + if (!vshConnectionUsability (ctl, ctl->conn))
> > + goto error;
> > +
> > + vshCommandStringParse(ctl, cmdStr);
> > + cmds = ctl->cmd;
> > + ctl->cmd = NULL;
> > + virMutexUnlock(&ctl->mutex);
> > + do {
> > + c = cmds;
> > + cmds = cmds->next;
> > + c->next = NULL;
> > + ignore_value(virThreadPoolSendJob(ctl->threadPool, c, true));
>
> Continuing in the vein of bad practice - blocking on another thread to
> complete inside a signal handler is crazy. But setting up a threadpool
I did a copy&paste and forgot to change true to false :)
> to handle signals in a separate thread means that your signal-handling
> thread is already independently available to cancel the job that is
> underway in the primary thread.
The intention of setting up a threadpool is to submit another command in
a seprate thread while there is already a command being processed. If we
do it in one thread, then we will end up with deaklock eventually. Take
dump as example:
1. submit command dump
2. polling for reply from RPC server
3. SIGINT(poll is interrupted)
4. submit command domjobabort form signal handler
5. (in remoteIO())there is a priv->waitDispatch, so go to
sleep(vifCondWait). The impl of remote driver is thread-aware, and
this thread (processing command domjobabort) is supposed to be
waken up by the thread that is having priv->waitDispatch(processing
command dump). But we are the same thread, so deadlock.
Well, I have to say that the patch is nasty. Do you (or anyone) have a
good idea to achieve the goal to cancel the active job if user presses
Ctrl-C? Thanks.
>
> > + } while (cmds);
> > + }
> > + VIR_FREE(cmdStr);
> > + return;
> > +error:
> > + virMutexUnlock(&ctl->mutex);
> > + VIR_FREE(cmdStr);
> > +}
> > +#endif
> >
> > /*
> > * vshSetupSignals:
> > @@ -520,17 +567,20 @@ static void
> > vshSetupSignals(void) {
> > struct sigaction sig_action;
> >
> > - sig_action.sa_sigaction = vshCatchDisconnect;
> > sig_action.sa_flags = SA_SIGINFO;
> > sigemptyset(&sig_action.sa_mask);
> >
> > +#ifdef SIGPIPE
>
> Might be unnecessary - gnulib guarantees that a working replacement for
> SIGPIPE is available on mingw, which is the only platform that lacks it
> natively. Oh, but that module is currently LGPLv3+, I'll have to ask on
> the gnulib list if people are willing to relax it to LGPLv2+ so we can
> use it.
>
> --
> Eric Blake [email protected] +1-801-349-2682
> Libvirt virtualization library http://libvirt.org
>
--
Thanks,
Hu Tao
--
libvir-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list