diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h index 5d71cde33a..56643fbb2d 100644 --- a/src/storage/storage_backend.h +++ b/src/storage/storage_backend.h @@ -198,6 +198,10 @@ typedef ssize_t typedef const char * (*virStorageFileBackendGetUniqueIdentifier)(virStorageSourcePtr src); +typedef int +(*virStorageFileBackendAccess)(virStorageSourcePtr src, + int mode); + virStorageFileBackendPtr virStorageFileBackendForType(int type, int protocol); @@ -220,6 +224,7 @@ struct _virStorageFileBackend { virStorageFileBackendCreate storageFileCreate; virStorageFileBackendUnlink storageFileUnlink; virStorageFileBackendStat storageFileStat; + virStorageFileBackendAccess storageFileAccess; }; #endif /* __VIR_STORAGE_BACKEND_H__ */ diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c index aed07a688e..414f2c76fe 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -1433,6 +1433,15 @@ virStorageFileBackendFileGetUniqueIdentifier(virStorageSourcePtr src) } +static int +virStorageFileBackendFileAccess(virStorageSourcePtr src, + int mode) +{ + return virFileAccessibleAs(src->path, mode, + src->drv->uid, src->drv->gid); +} + + virStorageFileBackend virStorageFileBackendFile = { .type = VIR_STORAGE_TYPE_FILE, @@ -1442,6 +1451,7 @@ virStorageFileBackend virStorageFileBackendFile = { .storageFileUnlink = virStorageFileBackendFileUnlink, .storageFileStat = virStorageFileBackendFileStat, .storageFileReadHeader = virStorageFileBackendFileReadHeader, + .storageFileAccess = virStorageFileBackendFileAccess, .storageFileGetUniqueIdentifier = virStorageFileBackendFileGetUniqueIdentifier, }; @@ -1455,6 +1465,7 @@ virStorageFileBackend virStorageFileBackendBlock = { .storageFileStat = virStorageFileBackendFileStat, .storageFileReadHeader = virStorageFileBackendFileReadHeader, + .storageFileAccess = virStorageFileBackendFileAccess, .storageFileGetUniqueIdentifier = virStorageFileBackendFileGetUniqueIdentifier, }; @@ -1466,6 +1477,8 @@ virStorageFileBackend virStorageFileBackendDir = { .backendInit = virStorageFileBackendFileInit, .backendDeinit = virStorageFileBackendFileDeinit, + .storageFileAccess = virStorageFileBackendFileAccess, + .storageFileGetUniqueIdentifier = virStorageFileBackendFileGetUniqueIdentifier, }; diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_backend_gluster.c index af6792fb14..3db4e66729 100644 --- a/src/storage/storage_backend_gluster.c +++ b/src/storage/storage_backend_gluster.c @@ -703,6 +703,16 @@ virStorageFileBackendGlusterReadHeader(virStorageSourcePtr src, } +static int +virStorageFileBackendGlusterAccess(virStorageSourcePtr src, + int mode) +{ + virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; + + return glfs_access(priv->vol, src->path, mode); +} + + virStorageFileBackend virStorageFileBackendGluster = { .type = VIR_STORAGE_TYPE_NETWORK, .protocol = VIR_STORAGE_NET_PROTOCOL_GLUSTER, @@ -713,4 +723,5 @@ virStorageFileBackend virStorageFileBackendGluster = { .storageFileUnlink = virStorageFileBackendGlusterUnlink, .storageFileStat = virStorageFileBackendGlusterStat, .storageFileReadHeader = virStorageFileBackendGlusterReadHeader, + .storageFileAccess = virStorageFileBackendGlusterAccess, }; diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 0c779c5201..f66c25946b 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -3017,3 +3017,27 @@ virStorageFileGetUniqueIdentifier(virStorageSourcePtr src) return src->drv->backend->storageFileGetUniqueIdentifier(src); } + + +/** + * virStorageFileAccess: Check accessibility of a storage file + * + * @src: storage file to check access permissions + * @mode: accessibility check options (see man 2 access) + * + * Returns 0 on success, -1 on error and sets errno. No libvirt + * error is reported. Returns -2 if the operation isn't supported + * by libvirt storage backend. + */ +int +virStorageFileAccess(virStorageSourcePtr src, + int mode) +{ + if (!virStorageFileIsInitialized(src) || + !src->drv->backend->storageFileAccess) { + errno = ENOSYS; + return -2; + } + + return src->drv->backend->storageFileAccess(src, mode); +} diff --git a/src/storage/storage_driver.h b/src/storage/storage_driver.h index 9280ef0e22..5452df21a4 100644 --- a/src/storage/storage_driver.h +++ b/src/storage/storage_driver.h @@ -42,6 +42,7 @@ ssize_t virStorageFileReadHeader(virStorageSourcePtr src, ssize_t max_len, char **buf); const char *virStorageFileGetUniqueIdentifier(virStorageSourcePtr src); +int virStorageFileAccess(virStorageSourcePtr src, int mode); int storageRegister(void);