diff mbox

[01/35] libxl: add LIBXL_LOGD_* and LOG*D function families.

Message ID 20161115101913.10396-2-cbosdonnat@suse.com (mailing list archive)
State New, archived
Headers show

Commit Message

Cedric Bosdonnat Nov. 15, 2016, 10:18 a.m. UTC
From: Cédric Bosdonnat <cedric.bosdonnat@free.fr>

These functions should be used to log messages when the domain
id is known. libxl__log will now prepend the log message by
"Domain %PRIu32:" if the domain id is a valid one.

This aims at helping consumers filter logs on domain IDs.

Signed-off-by: Cédric Bosdonnat <cbosdonnat@suse.com>
---
 tools/libxl/libxl_event.c    |  6 +++---
 tools/libxl/libxl_internal.c | 16 ++++++++++------
 tools/libxl/libxl_internal.h | 38 +++++++++++++++++++++++++++++++-------
 3 files changed, 44 insertions(+), 16 deletions(-)

Comments

Wei Liu Nov. 17, 2016, 2:41 p.m. UTC | #1
On Tue, Nov 15, 2016 at 11:18:39AM +0100, Cédric Bosdonnat wrote:
> From: Cédric Bosdonnat <cedric.bosdonnat@free.fr>
> 
> These functions should be used to log messages when the domain
> id is known. libxl__log will now prepend the log message by
> "Domain %PRIu32:" if the domain id is a valid one.
> 
> This aims at helping consumers filter logs on domain IDs.
> 
> Signed-off-by: Cédric Bosdonnat <cbosdonnat@suse.com>
> ---
>  tools/libxl/libxl_event.c    |  6 +++---
>  tools/libxl/libxl_internal.c | 16 ++++++++++------
>  tools/libxl/libxl_internal.h | 38 +++++++++++++++++++++++++++++++-------
>  3 files changed, 44 insertions(+), 16 deletions(-)
> 
> diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
> index 02b39e6..fc9bdc9 100644
> --- a/tools/libxl/libxl_event.c
> +++ b/tools/libxl/libxl_event.c
> @@ -1362,7 +1362,7 @@ void libxl__event_disaster(libxl__egc *egc, const char *msg, int errnoval,
>  {
>      EGC_GC;
>  
> -    libxl__log(CTX, XTL_CRITICAL, errnoval, file, line, func,
> +    libxl__log(CTX, XTL_CRITICAL, errnoval, file, line, func, INVALID_DOMID,
>                 "DISASTER in event loop: %s%s%s%s",
>                 msg,
>                 type ? " (relates to event type " : "",
> @@ -1943,7 +1943,7 @@ libxl__ao *libxl__ao_create(libxl_ctx *ctx, uint32_t domid,
>          ao->poller = libxl__poller_get(&ao->gc);
>          if (!ao->poller) goto out;
>      }
> -    libxl__log(ctx,XTL_DEBUG,-1,file,line,func,
> +    libxl__log(ctx,XTL_DEBUG,-1,file,line,func,domid,
>                 "ao %p: create: how=%p callback=%p poller=%p",
>                 ao, how, ao->how.callback, ao->poller);
>  
> @@ -1968,7 +1968,7 @@ int libxl__ao_inprogress(libxl__ao *ao,
>      assert(ao->in_initiator);
>      ao->constructing = 0;
>  
> -    libxl__log(CTX,XTL_DEBUG,-1,file,line,func,
> +    libxl__log(CTX,XTL_DEBUG,-1,file,line,func,INVALID_DOMID,

You should be able to use ao->domid here, right?

>                 "ao %p: inprogress: poller=%p, flags=%s%s%s%s",
>                 ao, ao->poller,
>                 ao->constructing ? "o" : "",
> diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c
> index 448dd61..78ed2f6 100644
> --- a/tools/libxl/libxl_internal.c
> +++ b/tools/libxl/libxl_internal.c
> @@ -22,7 +22,7 @@ void libxl__alloc_failed(libxl_ctx *ctx, const char *func,
>  #define M "libxl: FATAL ERROR: memory allocation failure"
>  #define L (size ? M " (%s, %lu x %lu)\n" : M " (%s)\n"), \
>            func, (unsigned long)nmemb, (unsigned long)size
> -    libxl__log(ctx, XTL_CRITICAL, ENOMEM, 0,0, func, L);
> +    libxl__log(ctx, XTL_CRITICAL, ENOMEM, 0,0, func, INVALID_DOMID, L);
>      fprintf(stderr, L);
>      fflush(stderr);
>      _exit(-1);
> @@ -202,7 +202,7 @@ char *libxl__dirname(libxl__gc *gc, const char *s)
>  
>  void libxl__logv(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
>               const char *file, int line, const char *func,
> -             const char *fmt, va_list ap)
> +             uint32_t domid, const char *fmt, va_list ap)
>  {
>      /* WARNING this function may not call any libxl-provided
>       * memory allocation function, as those may
> @@ -211,6 +211,7 @@ void libxl__logv(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
>      char *base = NULL;
>      int rc, esave;
>      char fileline[256];
> +    char domain[256];
>  
>      esave = errno;
>  
> @@ -221,22 +222,25 @@ void libxl__logv(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
>      if (file) snprintf(fileline, sizeof(fileline), "%s:%d",file,line);
>      fileline[sizeof(fileline)-1] = 0;
>  
> +    domain[0] = 0;
> +    if (domid != INVALID_DOMID) snprintf(domain, sizeof(domain), "Domain %"PRIu32":", domid);

Coding style issue, please put snprintf in a new line.

> +    domain[sizeof(domain)-1] = 0;

This probably does do what you want it to do - sizeof(domain) -> 256.  I
don't think you need this at all because IIRC snprintf puts a \0 at the
end.

Overall I think this is in line with what we discussed before.

Wei.
Cedric Bosdonnat Nov. 17, 2016, 4:01 p.m. UTC | #2
On Thu, 2016-11-17 at 14:41 +0000, Wei Liu wrote:
> On Tue, Nov 15, 2016 at 11:18:39AM +0100, Cédric Bosdonnat wrote:
> > From: Cédric Bosdonnat <cedric.bosdonnat@free.fr>
> > 
> > These functions should be used to log messages when the domain
> > id is known. libxl__log will now prepend the log message by
> > "Domain %PRIu32:" if the domain id is a valid one.
> > 
> > This aims at helping consumers filter logs on domain IDs.
> > 
> > Signed-off-by: Cédric Bosdonnat <cbosdonnat@suse.com>
> > ---
> >  tools/libxl/libxl_event.c    |  6 +++---
> >  tools/libxl/libxl_internal.c | 16 ++++++++++------
> >  tools/libxl/libxl_internal.h | 38 +++++++++++++++++++++++++++++++-------
> >  3 files changed, 44 insertions(+), 16 deletions(-)
> > 
> > diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
> > index 02b39e6..fc9bdc9 100644
> > --- a/tools/libxl/libxl_event.c
> > +++ b/tools/libxl/libxl_event.c
> > @@ -1362,7 +1362,7 @@ void libxl__event_disaster(libxl__egc *egc, const char *msg, int errnoval,
> >  {
> >      EGC_GC;
> >  
> > -    libxl__log(CTX, XTL_CRITICAL, errnoval, file, line, func,
> > +    libxl__log(CTX, XTL_CRITICAL, errnoval, file, line, func, INVALID_DOMID,
> >                 "DISASTER in event loop: %s%s%s%s",
> >                 msg,
> >                 type ? " (relates to event type " : "",
> > @@ -1943,7 +1943,7 @@ libxl__ao *libxl__ao_create(libxl_ctx *ctx, uint32_t domid,
> >          ao->poller = libxl__poller_get(&ao->gc);
> >          if (!ao->poller) goto out;
> >      }
> > -    libxl__log(ctx,XTL_DEBUG,-1,file,line,func,
> > +    libxl__log(ctx,XTL_DEBUG,-1,file,line,func,domid,
> >                 "ao %p: create: how=%p callback=%p poller=%p",
> >                 ao, how, ao->how.callback, ao->poller);
> >  
> > @@ -1968,7 +1968,7 @@ int libxl__ao_inprogress(libxl__ao *ao,
> >      assert(ao->in_initiator);
> >      ao->constructing = 0;
> >  
> > -    libxl__log(CTX,XTL_DEBUG,-1,file,line,func,
> > +    libxl__log(CTX,XTL_DEBUG,-1,file,line,func,INVALID_DOMID,
> 
> You should be able to use ao->domid here, right?

Oh indeed. I discovered this one after writing this patch and forgot
about it here. Could it be possible that ao->domid is not the publicly
known domain id?

> >                 "ao %p: inprogress: poller=%p, flags=%s%s%s%s",
> >                 ao, ao->poller,
> >                 ao->constructing ? "o" : "",
> > diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c
> > index 448dd61..78ed2f6 100644
> > --- a/tools/libxl/libxl_internal.c
> > +++ b/tools/libxl/libxl_internal.c
> > @@ -22,7 +22,7 @@ void libxl__alloc_failed(libxl_ctx *ctx, const char *func,
> >  #define M "libxl: FATAL ERROR: memory allocation failure"
> >  #define L (size ? M " (%s, %lu x %lu)\n" : M " (%s)\n"), \
> >            func, (unsigned long)nmemb, (unsigned long)size
> > -    libxl__log(ctx, XTL_CRITICAL, ENOMEM, 0,0, func, L);
> > +    libxl__log(ctx, XTL_CRITICAL, ENOMEM, 0,0, func, INVALID_DOMID, L);
> >      fprintf(stderr, L);
> >      fflush(stderr);
> >      _exit(-1);
> > @@ -202,7 +202,7 @@ char *libxl__dirname(libxl__gc *gc, const char *s)
> >  
> >  void libxl__logv(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
> >               const char *file, int line, const char *func,
> > -             const char *fmt, va_list ap)
> > +             uint32_t domid, const char *fmt, va_list ap)
> >  {
> >      /* WARNING this function may not call any libxl-provided
> >       * memory allocation function, as those may
> > @@ -211,6 +211,7 @@ void libxl__logv(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
> >      char *base = NULL;
> >      int rc, esave;
> >      char fileline[256];
> > +    char domain[256];
> >  
> >      esave = errno;
> >  
> > @@ -221,22 +222,25 @@ void libxl__logv(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
> >      if (file) snprintf(fileline, sizeof(fileline), "%s:%d",file,line);
> >      fileline[sizeof(fileline)-1] = 0;
> >  
> > +    domain[0] = 0;
> > +    if (domid != INVALID_DOMID) snprintf(domain, sizeof(domain), "Domain %"PRIu32":", domid);
> 
> Coding style issue, please put snprintf in a new line.

I've mimicked what is a few lines above (see first line of the hunk context).
I agree it doesn't look too pretty. but then may be I should reformat the one above ;)

> > +    domain[sizeof(domain)-1] = 0;
> 
> This probably does do what you want it to do - sizeof(domain) -> 256.  I
> don't think you need this at all because IIRC snprintf puts a \0 at the
> end.

Oh indeed. I'll remove it then.

> Overall I think this is in line with what we discussed before.

I expected to send a v2 anyway, I'll resend with the changes.
--
Cedric
Wei Liu Nov. 17, 2016, 4:12 p.m. UTC | #3
On Thu, Nov 17, 2016 at 05:01:08PM +0100, Cedric Bosdonnat wrote:
> On Thu, 2016-11-17 at 14:41 +0000, Wei Liu wrote:
> > On Tue, Nov 15, 2016 at 11:18:39AM +0100, Cédric Bosdonnat wrote:
> > > From: Cédric Bosdonnat <cedric.bosdonnat@free.fr>
> > > 
> > > These functions should be used to log messages when the domain
> > > id is known. libxl__log will now prepend the log message by
> > > "Domain %PRIu32:" if the domain id is a valid one.
> > > 
> > > This aims at helping consumers filter logs on domain IDs.
> > > 
> > > Signed-off-by: Cédric Bosdonnat <cbosdonnat@suse.com>
> > > ---
> > >  tools/libxl/libxl_event.c    |  6 +++---
> > >  tools/libxl/libxl_internal.c | 16 ++++++++++------
> > >  tools/libxl/libxl_internal.h | 38 +++++++++++++++++++++++++++++++-------
> > >  3 files changed, 44 insertions(+), 16 deletions(-)
> > > 
> > > diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
> > > index 02b39e6..fc9bdc9 100644
> > > --- a/tools/libxl/libxl_event.c
> > > +++ b/tools/libxl/libxl_event.c
> > > @@ -1362,7 +1362,7 @@ void libxl__event_disaster(libxl__egc *egc, const char *msg, int errnoval,
> > >  {
> > >      EGC_GC;
> > >  
> > > -    libxl__log(CTX, XTL_CRITICAL, errnoval, file, line, func,
> > > +    libxl__log(CTX, XTL_CRITICAL, errnoval, file, line, func, INVALID_DOMID,
> > >                 "DISASTER in event loop: %s%s%s%s",
> > >                 msg,
> > >                 type ? " (relates to event type " : "",
> > > @@ -1943,7 +1943,7 @@ libxl__ao *libxl__ao_create(libxl_ctx *ctx, uint32_t domid,
> > >          ao->poller = libxl__poller_get(&ao->gc);
> > >          if (!ao->poller) goto out;
> > >      }
> > > -    libxl__log(ctx,XTL_DEBUG,-1,file,line,func,
> > > +    libxl__log(ctx,XTL_DEBUG,-1,file,line,func,domid,
> > >                 "ao %p: create: how=%p callback=%p poller=%p",
> > >                 ao, how, ao->how.callback, ao->poller);
> > >  
> > > @@ -1968,7 +1968,7 @@ int libxl__ao_inprogress(libxl__ao *ao,
> > >      assert(ao->in_initiator);
> > >      ao->constructing = 0;
> > >  
> > > -    libxl__log(CTX,XTL_DEBUG,-1,file,line,func,
> > > +    libxl__log(CTX,XTL_DEBUG,-1,file,line,func,INVALID_DOMID,
> > 
> > You should be able to use ao->domid here, right?
> 
> Oh indeed. I discovered this one after writing this patch and forgot
> about it here. Could it be possible that ao->domid is not the publicly
> known domain id?

I think it is the publicly known domain id -- it was initialised in
libxl__ao_create which got domid from caller.

Wei.
Ian Jackson Nov. 17, 2016, 4:29 p.m. UTC | #4
Cedric Bosdonnat writes ("Re: [PATCH 01/35] libxl: add LIBXL_LOGD_* and LOG*D function families."):
> On Thu, 2016-11-17 at 14:41 +0000, Wei Liu wrote:
> > You should be able to use ao->domid here, right?
> 
> Oh indeed. I discovered this one after writing this patch and forgot
> about it here. Could it be possible that ao->domid is not the publicly
> known domain id?

I think it might conceivably sometimes be a stubdom id.  That depends
on who sets it when and whether they make a nested ao for a stubdom...

Ian.
Wei Liu Nov. 17, 2016, 4:34 p.m. UTC | #5
On Thu, Nov 17, 2016 at 04:29:35PM +0000, Ian Jackson wrote:
> Cedric Bosdonnat writes ("Re: [PATCH 01/35] libxl: add LIBXL_LOGD_* and LOG*D function families."):
> > On Thu, 2016-11-17 at 14:41 +0000, Wei Liu wrote:
> > > You should be able to use ao->domid here, right?
> > 
> > Oh indeed. I discovered this one after writing this patch and forgot
> > about it here. Could it be possible that ao->domid is not the publicly
> > known domain id?
> 
> I think it might conceivably sometimes be a stubdom id.  That depends
> on who sets it when and whether they make a nested ao for a stubdom...
> 

Oh, yes. I misunderstood. In that case libxl_is_stubdom could be handy.

> Ian.
Ian Jackson Nov. 17, 2016, 4:36 p.m. UTC | #6
Wei Liu writes ("Re: [PATCH 01/35] libxl: add LIBXL_LOGD_* and LOG*D function families."):
> Oh, yes. I misunderstood. In that case libxl_is_stubdom could be handy.

How about this: check whether the ao is a nested ao, and if so, fish
the domid out of its parent ?

Ian.
Wei Liu Nov. 17, 2016, 4:38 p.m. UTC | #7
On Thu, Nov 17, 2016 at 04:36:54PM +0000, Ian Jackson wrote:
> Wei Liu writes ("Re: [PATCH 01/35] libxl: add LIBXL_LOGD_* and LOG*D function families."):
> > Oh, yes. I misunderstood. In that case libxl_is_stubdom could be handy.
> 
> How about this: check whether the ao is a nested ao, and if so, fish
> the domid out of its parent ?
> 

Yes, this is better than calling libxl_is_stubdom.

> Ian.
diff mbox

Patch

diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index 02b39e6..fc9bdc9 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -1362,7 +1362,7 @@  void libxl__event_disaster(libxl__egc *egc, const char *msg, int errnoval,
 {
     EGC_GC;
 
-    libxl__log(CTX, XTL_CRITICAL, errnoval, file, line, func,
+    libxl__log(CTX, XTL_CRITICAL, errnoval, file, line, func, INVALID_DOMID,
                "DISASTER in event loop: %s%s%s%s",
                msg,
                type ? " (relates to event type " : "",
@@ -1943,7 +1943,7 @@  libxl__ao *libxl__ao_create(libxl_ctx *ctx, uint32_t domid,
         ao->poller = libxl__poller_get(&ao->gc);
         if (!ao->poller) goto out;
     }
-    libxl__log(ctx,XTL_DEBUG,-1,file,line,func,
+    libxl__log(ctx,XTL_DEBUG,-1,file,line,func,domid,
                "ao %p: create: how=%p callback=%p poller=%p",
                ao, how, ao->how.callback, ao->poller);
 
@@ -1968,7 +1968,7 @@  int libxl__ao_inprogress(libxl__ao *ao,
     assert(ao->in_initiator);
     ao->constructing = 0;
 
-    libxl__log(CTX,XTL_DEBUG,-1,file,line,func,
+    libxl__log(CTX,XTL_DEBUG,-1,file,line,func,INVALID_DOMID,
                "ao %p: inprogress: poller=%p, flags=%s%s%s%s",
                ao, ao->poller,
                ao->constructing ? "o" : "",
diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c
index 448dd61..78ed2f6 100644
--- a/tools/libxl/libxl_internal.c
+++ b/tools/libxl/libxl_internal.c
@@ -22,7 +22,7 @@  void libxl__alloc_failed(libxl_ctx *ctx, const char *func,
 #define M "libxl: FATAL ERROR: memory allocation failure"
 #define L (size ? M " (%s, %lu x %lu)\n" : M " (%s)\n"), \
           func, (unsigned long)nmemb, (unsigned long)size
-    libxl__log(ctx, XTL_CRITICAL, ENOMEM, 0,0, func, L);
+    libxl__log(ctx, XTL_CRITICAL, ENOMEM, 0,0, func, INVALID_DOMID, L);
     fprintf(stderr, L);
     fflush(stderr);
     _exit(-1);
@@ -202,7 +202,7 @@  char *libxl__dirname(libxl__gc *gc, const char *s)
 
 void libxl__logv(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
              const char *file, int line, const char *func,
-             const char *fmt, va_list ap)
+             uint32_t domid, const char *fmt, va_list ap)
 {
     /* WARNING this function may not call any libxl-provided
      * memory allocation function, as those may
@@ -211,6 +211,7 @@  void libxl__logv(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
     char *base = NULL;
     int rc, esave;
     char fileline[256];
+    char domain[256];
 
     esave = errno;
 
@@ -221,22 +222,25 @@  void libxl__logv(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
     if (file) snprintf(fileline, sizeof(fileline), "%s:%d",file,line);
     fileline[sizeof(fileline)-1] = 0;
 
+    domain[0] = 0;
+    if (domid != INVALID_DOMID) snprintf(domain, sizeof(domain), "Domain %"PRIu32":", domid);
+    domain[sizeof(domain)-1] = 0;
  x:
     xtl_log(ctx->lg, msglevel, errnoval, "libxl",
-            "%s%s%s%s" "%s",
+            "%s%s%s%s%s" "%s",
             fileline, func&&file?":":"", func?func:"", func||file?": ":"",
-            base);
+            domain, base);
     if (base != enomem) free(base);
     errno = esave;
 }
 
 void libxl__log(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
             const char *file, int line, const char *func,
-            const char *fmt, ...)
+            uint32_t domid, const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
-    libxl__logv(ctx, msglevel, errnoval, file, line, func, fmt, ap);
+    libxl__logv(ctx, msglevel, errnoval, file, line, func, domid, fmt, ap);
     va_end(ap);
 }
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 8366fee..5f46578 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -152,13 +152,22 @@ 
 #define LIBXL__LOGGING_ENABLED
 
 #ifdef LIBXL__LOGGING_ENABLED
-#define LIBXL__LOG(ctx, loglevel, _f, _a...)   libxl__log(ctx, loglevel, -1, __FILE__, __LINE__, __func__, _f, ##_a)
-#define LIBXL__LOG_ERRNO(ctx, loglevel, _f, _a...)   libxl__log(ctx, loglevel, errno, __FILE__, __LINE__, __func__, _f, ##_a)
-#define LIBXL__LOG_ERRNOVAL(ctx, loglevel, errnoval, _f, _a...)   libxl__log(ctx, loglevel, errnoval, __FILE__, __LINE__, __func__, _f, ##_a)
+#define LIBXL__LOG(ctx, loglevel, _f, _a...)   libxl__log(ctx, loglevel, -1, __FILE__, __LINE__, __func__, INVALID_DOMID, _f, ##_a)
+#define LIBXL__LOG_ERRNO(ctx, loglevel, _f, _a...)   libxl__log(ctx, loglevel, errno, __FILE__, __LINE__, __func__, INVALID_DOMID, _f, ##_a)
+#define LIBXL__LOG_ERRNOVAL(ctx, loglevel, errnoval, _f, _a...)   libxl__log(ctx, loglevel, errnoval, __FILE__, __LINE__, __func__, INVALID_DOMID, _f, ##_a)
+
+/* Same log functions as above, but with _d being a domain id. */
+#define LIBXL__LOGD(ctx, loglevel, _d, _f, _a...)   libxl__log(ctx, loglevel, -1, __FILE__, __LINE__, __func__, _d, _f, ##_a)
+#define LIBXL__LOGD_ERRNO(ctx, loglevel, _d, _f, _a...)   libxl__log(ctx, loglevel, errno, __FILE__, __LINE__, __func__, _d, _f, ##_a)
+#define LIBXL__LOGD_ERRNOVAL(ctx, loglevel, errnoval, _d, _f, _a...)   libxl__log(ctx, loglevel, errnoval, __FILE__, __LINE__, __func__, _d, _f, ##_a)
 #else
 #define LIBXL__LOG(ctx, loglevel, _f, _a...)
 #define LIBXL__LOG_ERRNO(ctx, loglevel, _f, _a...)
 #define LIBXL__LOG_ERRNOVAL(ctx, loglevel, errnoval, _f, _a...)
+
+#define LIBXLD__LOG(ctx, loglevel, _d, _f, _a...)
+#define LIBXLD__LOG_ERRNO(ctx, loglevel, _d, _f, _a...)
+#define LIBXLD__LOG_ERRNOVAL(ctx, loglevel, errnoval, _d, _f, _a...)
 #endif
   /* all of these macros preserve errno (saving and restoring) */
 
@@ -169,14 +178,16 @@ 
 _hidden void libxl__logv(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
              const char *file /* may be 0 */, int line /* ignored if !file */,
              const char *func /* may be 0 */,
+             uint32_t domid /* may be INVALID_DOMID */,
              const char *fmt, va_list al)
-     __attribute__((format(printf,7,0)));
+     __attribute__((format(printf,8,0)));
 
 _hidden void libxl__log(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
             const char *file /* may be 0 */, int line /* ignored if !file */,
             const char *func /* may be 0 */,
+            uint32_t domid /* may be INVALID_DOMID */,
             const char *fmt, ...)
-     __attribute__((format(printf,7,8)));
+     __attribute__((format(printf,8,9)));
 
      /* these functions preserve errno (saving and restoring) */
 
@@ -3875,22 +3886,35 @@  _hidden void libxl__remus_restore_setup(libxl__egc *egc,
  *    void LOG(<xtl_level_suffix>, const char *fmt, ...);
  *    void LOGE(<xtl_level_suffix>, const char *fmt, ...);
  *    void LOGEV(<xtl_level_suffix>, int errnoval, const char *fmt, ...);
+ *
+ *    void LOGD(<xtl_level_suffix>, uint32_t domid, const char *fmt, ...);
+ *    void LOGED(<xtl_level_suffix>, uint32_t domid, const char *fmt, ...);
+ *    void LOGEVD(<xtl_level_suffix>, int errnoval, uint32_t domid, const char *fmt, ...);
  * Use
  *    libxl__gc *gc;
  *
- * Trivial convenience wrappers for LIBXL__LOG, LIBXL__LOG_ERRNO and
- * LIBXL__LOG_ERRNOVAL, respectively (and thus for libxl__log).
+ * Trivial convenience wrappers for LIBXL__LOG, LIBXL__LOG_ERRNO,
+ * LIBXL__LOG_ERRNOVAL, LIBXL__LOGD, LIBXL__LOGD_ERRNO and
+ * LIBXL__LOGD_ERRNOVAL respectively (and thus for libxl__log).
  *
  * XTL_<xtl_level_suffix> should exist and be an xentoollog.h log level
  * So <xtl_level_suffix> should be one of
  *   DEBUG VERBOSE DETAIL PROGRESS INFO NOTICE WARN ERROR ERROR CRITICAL
  * Of these, most of libxl uses
  *   DEBUG INFO WARN ERROR
+ *
+ * The LOG*D family will preprend the log message with a string formatted
+ * as follows: 'Domain %PRIu32:'. This should help better automatic sorting
+ * of log messages per domain.
  */
 #define LOG(l,f, ...)     LIBXL__LOG(CTX,XTL_##l,(f),##__VA_ARGS__)
 #define LOGE(l,f, ...)    LIBXL__LOG_ERRNO(CTX,XTL_##l,(f),##__VA_ARGS__)
 #define LOGEV(l,e,f, ...) LIBXL__LOG_ERRNOVAL(CTX,XTL_##l,(e),(f),##__VA_ARGS__)
 
+#define LOGD(l,d,f, ...)     LIBXL__LOGD(CTX,XTL_##l,(d),(f),##__VA_ARGS__)
+#define LOGED(l,d,f, ...)    LIBXL__LOGD_ERRNO(CTX,XTL_##l,(d),(f),##__VA_ARGS__)
+#define LOGEVD(l,e,d,f, ...) LIBXL__LOGD_ERRNOVAL(CTX,XTL_##l,(e),(d),(f),##__VA_ARGS__)
+
 
 /* Locking functions.  See comment for "lock" member of libxl__ctx. */