[libvirt] [PATCH 1/6] util: Prepare helpers for unpriv_sgio setting

Osier Yang jyang at redhat.com
Tue Dec 18 14:46:04 UTC 2012


"virGetDeviceID" could be used across the sources, but it doesn't
relate with this series, and could be done later.

* src/util/util.h: (Declare virGetDeviceID, and
                    vir{Get,Set}DeviceUnprivSGIO)
* src/util/util.c: (Implement virGetDeviceID and
                    vir{Get,Set}DeviceUnprivSGIO)
* src/libvirt_private.syms: Export private symbols of upper helpers
---
 src/libvirt_private.syms |    3 +
 src/util/util.c          |  140 ++++++++++++++++++++++++++++++++++++++++++++++
 src/util/util.h          |   11 ++++
 3 files changed, 154 insertions(+), 0 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4ec19a0..e500ea9 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1283,6 +1283,8 @@ virFileWaitForDevices;
 virFileWriteStr;
 virFindFileInPath;
 virFormatIntDecimal;
+virGetDeviceID;
+virGetDeviceUnprivSGIO;
 virGetGroupID;
 virGetGroupName;
 virGetHostname;
@@ -1301,6 +1303,7 @@ virPipeReadUntilEOF;
 virScaleInteger;
 virSetBlocking;
 virSetCloseExec;
+virSetDeviceUnprivSGIO;
 virSetInherit;
 virSetNonBlock;
 virSetUIDGID;
diff --git a/src/util/util.c b/src/util/util.c
index 05e7ca7..06c7e33 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -3129,3 +3129,143 @@ virStrIsPrint(const char *str)
 
     return true;
 }
+
+#if defined(major) && defined(minor)
+int
+virGetDeviceID(const char *path, int *maj, int *min)
+{
+    struct stat sb;
+    char *canonical_path = NULL;
+
+    if (virFileResolveLink(path, &canonical_path) < 0)
+        return -errno;
+
+    if (stat(canonical_path, &sb) < 0) {
+        VIR_FREE(canonical_path);
+        return -errno;
+    }
+
+    if (!S_ISBLK(sb.st_mode)) {
+        VIR_FREE(canonical_path);
+        return -EINVAL;
+    }
+
+    if (maj)
+        *maj = major(sb.st_rdev);
+    if (min)
+        *min = minor(sb.st_rdev);
+
+    VIR_FREE(canonical_path);
+    return 0;
+}
+#else
+int
+virGetDeviceID(const char *path ATRRIBUTE_UNUSED,
+               int *maj ATRRIBUTE_UNUSED,
+               int *min ATRRIBUTE_UNUSED)
+{
+
+    return -ENOSYS;
+}
+#endif
+
+#define SYSFS_DEV_BLOCK_PATH "/sys/dev/block"
+
+static char *
+virGetUnprivSGIOSysfsPath(const char *path,
+                          const char *sysfs_dir)
+{
+    int maj, min;
+    char *sysfs_path = NULL;
+    int rc;
+
+    if ((rc = virGetDeviceID(path, &maj, &min)) < 0) {
+        virReportSystemError(-rc,
+                             _("Unable to get device ID '%s'"),
+                             path);
+        return NULL;
+    }
+
+    if (virAsprintf(&sysfs_path, "%s/%d:%d/queue/unpriv_sgio",
+                    sysfs_dir ? sysfs_dir : SYSFS_DEV_BLOCK_PATH,
+                    maj, min) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    return sysfs_path;
+}
+
+int
+virSetDeviceUnprivSGIO(const char *path,
+                       const char *sysfs_dir,
+                       int unpriv_sgio)
+{
+    char *sysfs_path = NULL;
+    char *val = NULL;
+    int ret = -1;
+    int rc;
+
+    if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path, sysfs_dir)))
+        return -1;
+
+    if (!virFileExists(sysfs_path)) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("unpriv_sgio is not supported by this kernel"));
+        goto cleanup;
+    }
+
+    if (virAsprintf(&val, "%d", unpriv_sgio) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if ((rc = virFileWriteStr(sysfs_path, val, 0)) < 0) {
+        virReportSystemError(-rc, _("failed to set %s"), sysfs_path);
+        goto cleanup;
+    }
+
+    ret = 0;
+cleanup:
+    VIR_FREE(sysfs_path);
+    VIR_FREE(val);
+    return ret;
+}
+
+int
+virGetDeviceUnprivSGIO(const char *path,
+                       const char *sysfs_dir,
+                       int *unpriv_sgio)
+{
+    char *sysfs_path = NULL;
+    char *buf = NULL;
+    char *tmp = NULL;
+    int ret = -1;
+
+    if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path, sysfs_dir)))
+        return -1;
+
+    if (!virFileExists(sysfs_path)) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("unpriv_sgio is not supported by this kernel"));
+        goto cleanup;
+    }
+
+    if (virFileReadAll(sysfs_path, 1024, &buf) < 0)
+        goto cleanup;
+
+    if ((tmp = strchr(buf, '\n')))
+        *tmp = '\0';
+
+    if (virStrToLong_i(buf, NULL, 10, unpriv_sgio) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("failed to parse value of %s"), sysfs_path);
+        goto cleanup;
+    }
+
+    ret = 0;
+cleanup:
+    VIR_FREE(sysfs_path);
+    VIR_FREE(buf);
+    return ret;
+}
diff --git a/src/util/util.h b/src/util/util.h
index 6d5dd03..71003f7 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -281,4 +281,15 @@ bool virIsDevMapperDevice(const char *dev_name) ATTRIBUTE_NONNULL(1);
 bool virValidateWWN(const char *wwn);
 
 bool virStrIsPrint(const char *str);
+
+int virGetDeviceID(const char *path,
+                   int *maj,
+                   int *min);
+int virSetDeviceUnprivSGIO(const char *path,
+                           const char *sysfs_dir,
+                           int unpriv_sgio);
+int virGetDeviceUnprivSGIO(const char *path,
+                           const char *sysfs_dir,
+                           int *unpriv_sgio);
+
 #endif /* __VIR_UTIL_H__ */
-- 
1.7.7.6




More information about the libvir-list mailing list