+ *_id = k;
+ return 1;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+/* Returns a short identifier for the various VM implementations */
+int detect_vm(const char **id) {
+ _cleanup_free_ char *domcap = NULL, *cpuinfo_contents = NULL;
+ static thread_local int cached_found = -1;
+ static thread_local const char *cached_id = NULL;
+ const char *_id = NULL;
+ int r;
+
+ if (_likely_(cached_found >= 0)) {
+
+ if (id)
+ *id = cached_id;
+
+ return cached_found;
+ }
+
+ /* Try xen capabilities file first, if not found try high-level hypervisor sysfs file:
+ *
+ * https://bugs.freedesktop.org/show_bug.cgi?id=77271 */
+ r = read_one_line_file("/proc/xen/capabilities", &domcap);
+ if (r >= 0) {
+ char *cap, *i = domcap;
+
+ while ((cap = strsep(&i, ",")))
+ if (streq(cap, "control_d"))
+ break;
+
+ if (!cap) {
+ _id = "xen";
+ r = 1;
+ }
+
+ goto finish;
+
+ } else if (r == -ENOENT) {
+ _cleanup_free_ char *hvtype = NULL;
+
+ r = read_one_line_file("/sys/hypervisor/type", &hvtype);
+ if (r >= 0) {
+ if (streq(hvtype, "xen")) {
+ _id = "xen";