xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] tools/xen-detect: try sysfs node for obtaining guest type
@ 2017-06-15  9:58 Juergen Gross
  2017-06-20 11:05 ` Wei Liu
  2017-06-21 14:24 ` Olaf Hering
  0 siblings, 2 replies; 6+ messages in thread
From: Juergen Gross @ 2017-06-15  9:58 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, wei.liu2, ian.jackson

Instead of relying on cpuid instruction behaviour to tell which domain
type we are just try asking the kernel via the appropriate sysfs node
(added in Linux kernel 4.13).

Keep the old detection logic as a fallback for older kernels.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 tools/misc/xen-detect.c | 129 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 121 insertions(+), 8 deletions(-)

diff --git a/tools/misc/xen-detect.c b/tools/misc/xen-detect.c
index 787b5da90d..a62747d316 100644
--- a/tools/misc/xen-detect.c
+++ b/tools/misc/xen-detect.c
@@ -24,6 +24,11 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -33,6 +38,15 @@
 #include <unistd.h>
 #include <getopt.h>
 
+enum guest_type {
+    XEN_PV = 1,
+    XEN_HVM = 2,
+    XEN_NONE = 3
+};
+
+static char *type;
+static char *ver;
+
 static void cpuid(uint32_t idx, uint32_t *regs, int pv_context)
 {
 #ifdef __i386__
@@ -75,6 +89,9 @@ static int check_for_xen(int pv_context)
 
  found:
     cpuid(base + 1, regs, pv_context);
+    if ( regs[0] )
+        asprintf(&ver, "V%u.%u",
+                 (uint16_t)(regs[0] >> 16), (uint16_t)regs[0]);
     return regs[0];
 }
 
@@ -91,14 +108,104 @@ static void usage(void)
     printf("  -h, --help    Display this information\n");
     printf("  -q, --quiet   Quiesce normal informational output\n");
     printf("  -P, --pv      Exit status 1 if not running as PV guest\n");
-    printf("  -H, --hvm     Exit status 1 if not running as HVM guest.\n");
+    printf("  -H, --hvm     Exit status 1 if not running as HVM or PVH guest.\n");
     printf("  -N, --none    Exit status 1 if running on Xen (PV or HVM)\n");
 }
 
+static bool check_dir(const char *filename)
+{
+    FILE *f;
+    struct stat stab;
+    bool res;
+
+    f = fopen(filename, "r");
+    if ( !f )
+        return false;
+    res = !fstat(fileno(f), &stab) && S_ISDIR(stab.st_mode);
+    fclose(f);
+
+    return res;
+}
+
+static char *read_file_content(const char *filename)
+{
+    FILE *f;
+    struct stat stab;
+    char *content = NULL;
+    int datalen;
+
+    f = fopen(filename, "r");
+    if ( !f )
+        return NULL;
+
+    if ( fstat(fileno(f), &stab) || !S_ISREG(stab.st_mode) ||
+         stab.st_size > INT_MAX || !stab.st_size )
+        goto out;
+
+    content = malloc(stab.st_size + 1);
+    if ( !content )
+        goto out;
+
+    /* For sysfs file, datalen is always PAGE_SIZE. 'read'
+     * will return the number of bytes of the actual content,
+     * rs <= datalen is expected.
+     */
+    datalen = fread(content, 1, stab.st_size, f);
+    content[datalen] = 0;
+    if ( ferror(f) )
+    {
+        free(content);
+        content = NULL;
+    }
+
+ out:
+    fclose(f);
+    return content;
+}
+
+static enum guest_type check_sysfs(void)
+{
+    char *str, *tmp;
+    enum guest_type res = XEN_NONE;
+
+    if ( !check_dir("/sys/hypervisor") )
+        return 0;
+
+    str = read_file_content("/sys/hypervisor/type");
+    if ( !str || strcmp(str, "xen\n") )
+        goto out;
+    free(str);
+
+    str = read_file_content("/sys/hypervisor/guest_type");
+    if ( !str )
+        return 0;
+    str[strlen(str) - 1] = 0;
+    type = str;
+    if ( !strcmp(type, "PV") )
+        res = XEN_PV;
+    else
+        res = XEN_HVM;
+
+    str = read_file_content("/sys/hypervisor/version/major");
+    if ( str )
+        str[strlen(str) - 1] = 0;
+    tmp = read_file_content("/sys/hypervisor/version/minor");
+    if ( tmp )
+        tmp[strlen(tmp) - 1] = 0;
+    if ( str && tmp )
+        asprintf(&ver, "V%s.%s", str, tmp);
+    else
+        ver = strdup("unknown version");
+    free(tmp);
+
+ out:
+    free(str);
+    return res;
+}
+
 int main(int argc, char **argv)
 {
-    enum { XEN_PV = 1, XEN_HVM = 2, XEN_NONE = 3 } detected = 0, expected = 0;
-    uint32_t version = 0;
+    enum guest_type detected, expected = 0;
     int ch, quiet = 0;
 
     const static char sopts[] = "hqPHN";
@@ -133,9 +240,14 @@ int main(int argc, char **argv)
         }
     }
 
+    detected = check_sysfs();
+    if ( detected )
+        goto out;
+
     /* Check for execution in HVM context. */
     detected = XEN_HVM;
-    if ( (version = check_for_xen(0)) != 0 )
+    type = "HVM";
+    if ( check_for_xen(0) )
         goto out;
 
     /*
@@ -144,9 +256,10 @@ int main(int argc, char **argv)
      * will longjmp via the signal handler, and print "Not running on Xen".
      */
     detected = XEN_PV;
+    type = "PV";
     if ( !setjmp(sigill_jmp)
          && (signal(SIGILL, sigill_handler) != SIG_ERR)
-         && ((version = check_for_xen(1)) != 0) )
+         && check_for_xen(1) )
         goto out;
 
     detected = XEN_NONE;
@@ -157,9 +270,9 @@ int main(int argc, char **argv)
     else if ( detected == XEN_NONE )
         printf("Not running on Xen.\n");
     else
-        printf("Running in %s context on Xen v%d.%d.\n",
-               (detected == XEN_PV) ? "PV" : "HVM",
-               (uint16_t)(version >> 16), (uint16_t)version);
+        printf("Running in %s context on Xen %s.\n", type, ver);
+
+    free(ver);
 
     return expected && (expected != detected);
 }
-- 
2.12.3


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] tools/xen-detect: try sysfs node for obtaining guest type
  2017-06-15  9:58 [PATCH] tools/xen-detect: try sysfs node for obtaining guest type Juergen Gross
@ 2017-06-20 11:05 ` Wei Liu
  2017-06-21 14:24 ` Olaf Hering
  1 sibling, 0 replies; 6+ messages in thread
From: Wei Liu @ 2017-06-20 11:05 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, ian.jackson, wei.liu2

On Thu, Jun 15, 2017 at 11:58:27AM +0200, Juergen Gross wrote:
> Instead of relying on cpuid instruction behaviour to tell which domain
> type we are just try asking the kernel via the appropriate sysfs node
> (added in Linux kernel 4.13).
> 
> Keep the old detection logic as a fallback for older kernels.
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>

Acked-by: Wei Liu <wei.liu2@citrix.com>

I only skim-read this patch. I agree with the general approach.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] tools/xen-detect: try sysfs node for obtaining guest type
  2017-06-15  9:58 [PATCH] tools/xen-detect: try sysfs node for obtaining guest type Juergen Gross
  2017-06-20 11:05 ` Wei Liu
@ 2017-06-21 14:24 ` Olaf Hering
  2017-06-21 14:27   ` Wei Liu
  1 sibling, 1 reply; 6+ messages in thread
From: Olaf Hering @ 2017-06-21 14:24 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, wei.liu2, ian.jackson


[-- Attachment #1.1: Type: text/plain, Size: 514 bytes --]

On Thu, Jun 15, Juergen Gross wrote:

> +++ b/tools/misc/xen-detect.c

> +        asprintf(&ver, "V%u.%u",
> +                 (uint16_t)(regs[0] >> 16), (uint16_t)regs[0]);

> +        asprintf(&ver, "V%s.%s", str, tmp);

This fails to build:

xen-detect.c:196:17: error: ignoring return value of 'asprintf', declared with attribute warn_unused_result [-Werror=unused-result]
xen-detect.c:93:17: error: ignoring return value of 'asprintf', declared with attribute warn_unused_result [-Werror=unused-result]

Olaf

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

[-- Attachment #2: Type: text/plain, Size: 127 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] tools/xen-detect: try sysfs node for obtaining guest type
  2017-06-21 14:24 ` Olaf Hering
@ 2017-06-21 14:27   ` Wei Liu
  2017-06-21 14:32     ` Olaf Hering
  2017-06-21 15:00     ` Ian Jackson
  0 siblings, 2 replies; 6+ messages in thread
From: Wei Liu @ 2017-06-21 14:27 UTC (permalink / raw)
  To: Olaf Hering; +Cc: Juergen Gross, xen-devel, wei.liu2, ian.jackson

On Wed, Jun 21, 2017 at 04:24:33PM +0200, Olaf Hering wrote:
> On Thu, Jun 15, Juergen Gross wrote:
> 
> > +++ b/tools/misc/xen-detect.c
> 
> > +        asprintf(&ver, "V%u.%u",
> > +                 (uint16_t)(regs[0] >> 16), (uint16_t)regs[0]);
> 
> > +        asprintf(&ver, "V%s.%s", str, tmp);
> 
> This fails to build:
> 
> xen-detect.c:196:17: error: ignoring return value of 'asprintf', declared with attribute warn_unused_result [-Werror=unused-result]
> xen-detect.c:93:17: error: ignoring return value of 'asprintf', declared with attribute warn_unused_result [-Werror=unused-result]

Hmm... your gcc seems to be rather strict. :-)

> 
> Olaf



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] tools/xen-detect: try sysfs node for obtaining guest type
  2017-06-21 14:27   ` Wei Liu
@ 2017-06-21 14:32     ` Olaf Hering
  2017-06-21 15:00     ` Ian Jackson
  1 sibling, 0 replies; 6+ messages in thread
From: Olaf Hering @ 2017-06-21 14:32 UTC (permalink / raw)
  To: Wei Liu; +Cc: Juergen Gross, xen-devel, ian.jackson


[-- Attachment #1.1: Type: text/plain, Size: 188 bytes --]

On Wed, Jun 21, Wei Liu wrote:

> Hmm... your gcc seems to be rather strict. :-)

Yes, all of them:

https://build.opensuse.org/package/show/home:olh:xen-unstable/xen

All red. :-)


Olaf

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

[-- Attachment #2: Type: text/plain, Size: 127 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] tools/xen-detect: try sysfs node for obtaining guest type
  2017-06-21 14:27   ` Wei Liu
  2017-06-21 14:32     ` Olaf Hering
@ 2017-06-21 15:00     ` Ian Jackson
  1 sibling, 0 replies; 6+ messages in thread
From: Ian Jackson @ 2017-06-21 15:00 UTC (permalink / raw)
  To: Wei Liu; +Cc: Juergen Gross, xen-devel, Olaf Hering

Wei Liu writes ("Re: [Xen-devel] [PATCH] tools/xen-detect: try sysfs node for obtaining guest type"):
> On Wed, Jun 21, 2017 at 04:24:33PM +0200, Olaf Hering wrote:
> > On Thu, Jun 15, Juergen Gross wrote:
> > > +++ b/tools/misc/xen-detect.c
> > 
> > > +        asprintf(&ver, "V%u.%u",
> > > +                 (uint16_t)(regs[0] >> 16), (uint16_t)regs[0]);
> > 
> > > +        asprintf(&ver, "V%s.%s", str, tmp);
> > 
> > This fails to build:
> > 
> > xen-detect.c:196:17: error: ignoring return value of 'asprintf', declared with attribute warn_unused_result [-Werror=unused-result]
> > xen-detect.c:93:17: error: ignoring return value of 'asprintf', declared with attribute warn_unused_result [-Werror=unused-result]
> 
> Hmm... your gcc seems to be rather strict. :-)

gcc is correct.

asprintf can fail if its malloc fails.

Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-06-21 15:01 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-15  9:58 [PATCH] tools/xen-detect: try sysfs node for obtaining guest type Juergen Gross
2017-06-20 11:05 ` Wei Liu
2017-06-21 14:24 ` Olaf Hering
2017-06-21 14:27   ` Wei Liu
2017-06-21 14:32     ` Olaf Hering
2017-06-21 15:00     ` Ian Jackson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).