[libvirt] [PATCH 1/8] util: Prepare helpers for unpriv_sgio setting
Osier Yang
jyang at redhat.com
Fri Dec 14 14:19:10 UTC 2012
On 2012年12月14日 21:13, Jiri Denemark wrote:
> On Fri, Dec 14, 2012 at 03:05:36 +0800, Osier Yang wrote:
>> "virGetDevice{Major,Minor}" could be used across the sources,
>> but it doesn't relate with this series, and could be done later.
>>
>> * src/util/util.h: (Declare virGetDevice{Major,Minor}, and
>> vir{Get,Set}DeviceUnprivSGIO)
>> * src/util/util.c: (New internal helper virCanonicalizeDiskPath to
>> canonicalize the disk path; Implement
>> virGetDevice{Major,Minor} and
>> vir{Get,Set}DeviceUnprivSGIO)
>> * src/libvirt_private.syms: Export private symbols of upper helpers
>> ---
>> src/libvirt_private.syms | 4 +
>> src/util/util.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++
>> src/util/util.h | 8 ++
>> 3 files changed, 192 insertions(+), 0 deletions(-)
> ...
>> diff --git a/src/util/util.c b/src/util/util.c
>> index 05e7ca7..8c6d43c 100644
>> --- a/src/util/util.c
>> +++ b/src/util/util.c
>> @@ -3129,3 +3129,183 @@ virStrIsPrint(const char *str)
>>
>> return true;
>> }
>> +
>> +static char *
>> +virCanonicalizeDiskPath(const char *path)
>> +{
>> + char *canonical_path = NULL;
>> +
>> + if (STRPREFIX(path, "/dev/disk/by-path") ||
>> + STRPREFIX(path, "/dev/disk/by-uuid") ||
>> + STRPREFIX(path, "/dev/disk/by-id")) {
>> + if (virFileResolveLink(path,&canonical_path)< 0)
>> + return NULL;
>> + } else {
>> + canonical_path = strdup(path);
>> + }
>> +
>> + return canonical_path;
>> +}
>
> There's no reason to restrict virFileResolveLink only to disk paths that
> start with /dev/disk/by-*. Symlinks to devices can be anywhere; just
> call it unconditionally.
>
>> +
>> +#if defined(major)&& defined(minor)
>> +int
>> +virGetDeviceMajor(const char *path)
>> +{
>> + struct stat sb;
>> + char *canonical_path = NULL;
>> +
>> + if (!(canonical_path = virCanonicalizeDiskPath(path)))
>> + 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;
>> + }
>> +
>> + VIR_FREE(canonical_path);
>> + return major(sb.st_rdev);
>> +}
>> +
>> +int
>> +virGetDeviceMinor(const char *path)
>> +{
>> + struct stat sb;
>> + char *canonical_path = NULL;
>> +
>> + if (!(canonical_path = virCanonicalizeDiskPath(path)))
>> + 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;
>> + }
>> +
>> + VIR_FREE(canonical_path);
>> + return minor(sb.st_rdev);
>> +}
>
> Oh, this is horrible. Why did you create two functions for getting major
> and minor numbers? Creating
>
> int virGetDeviceID(const char *path, int *major, int *minor)
>
> that would extract both at one go (since you want to get both of them
> anyway and if not, you can allow NULL to be passed for either) seems to
> be a better approach. And while at it, you can just remove the
> virCanonicalizeDiskPath helper and call virFileResolveLink directly in
> virGetDeviceID.
Okay, it's indeed for getting only one of them purpose. It won't
be only used by this patch set. But yes, I agreed with using
one function, for the potential race pointed by Eric.
>
>> +#else
>> +int
>> +virGetDeviceMajor(const char *path)
>> +{
>> + return -ENOSYS;
>> +}
>> +
>> +int
>> +virGetDeviceMinor(const char *path)
>> +{
>> + return -ENOSYS;
>> +}
>> +#endif
>> +
>> +static char *
>> +virGetUnprivSGIOSysfsPath(const char *path)
>> +{
>> + int major, minor;
>> + char *sysfs_path = NULL;
>> +
>> + if ((major = virGetDeviceMajor(path))< 0) {
>> + virReportSystemError(-major,
>> + _("Unable to get major number of device '%s'"),
>> + path);
>> + return NULL;
>> + }
>> +
>> + if ((minor = virGetDeviceMinor(path))< 0) {
>> + virReportSystemError(-minor,
>> + _("Unable to get minor number of device '%s'"),
>> + path);
>> + return NULL;
>> + }
>> +
>> + if (virAsprintf(&sysfs_path, "/sys/dev/block/%d:%d/queue/unpriv_sgio",
>> + major, minor)< 0) {
>> + virReportOOMError();
>> + return NULL;
>> + }
>> +
>> + return sysfs_path;
>> +}
>> +
>> +int
>> +virSetDeviceUnprivSGIO(const char *path,
>> + int unpriv_sgio)
>> +{
>> + char *sysfs_path = NULL;
>> + char *val = NULL;
>> + int ret = -1;
>> + int rc = -1;
>
> Nit: no need to initalize rc.
Okay.
>
>> +
>> + if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path)))
>> + 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,
>> + int *unpriv_sgio)
>> +{
>> + char *sysfs_path = NULL;
>> + char *buf = NULL;
>> + char *tmp = NULL;
>
> Nit: sysfs_path and tmp do not really need be initialized.
That's just personal habit.
>
>> + int ret = -1;
>> + int rc = -1;
>> +
>> + if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path)))
>> + 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 ((rc = virStrToLong_i(buf, NULL, 10,
>> + unpriv_sgio))< 0) {
>> + virReportError(VIR_ERR_INTERNAL_ERROR,
>> + _("failed to parse value of %s"), sysfs_path);
>> + goto cleanup;
>> + }
>
> rc is completely useless in this function.
Okay.
>
>> + ret = 0;
>> +cleanup:
>> + VIR_FREE(sysfs_path);
>> + VIR_FREE(buf);
>> + return ret;
>> +}
>
> Jirka
More information about the libvir-list
mailing list