util: Prepare helpers for unpriv_sgio setting

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

* src/util/virutil.h: (Declare virGetDeviceID, and
                       vir{Get,Set}DeviceUnprivSGIO)
* src/util/virutil.c: (Implement virGetDeviceID and
                       vir{Get,Set}DeviceUnprivSGIO)
* src/libvirt_private.syms: Export private symbols of upper helpers
This commit is contained in:
Osier Yang 2013-01-02 22:37:06 +08:00
parent 731a5a4df7
commit ba72cb12fa
3 changed files with 154 additions and 0 deletions

View File

@ -1279,6 +1279,8 @@ virFileWaitForDevices;
virFileWriteStr;
virFindFileInPath;
virFormatIntDecimal;
virGetDeviceID;
virGetDeviceUnprivSGIO;
virGetGroupID;
virGetGroupName;
virGetHostname;
@ -1297,6 +1299,7 @@ virPipeReadUntilEOF;
virScaleInteger;
virSetBlocking;
virSetCloseExec;
virSetDeviceUnprivSGIO;
virSetInherit;
virSetNonBlock;
virSetUIDGID;

View File

@ -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;
}

View File

@ -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__ */