}
+/*
+ * Allows caller to silently ignore files with improper mode
+ *
+ * Returns -1 on error, -2 if file mode is unexpected.
+ */
int
-virStorageBackendUpdateVolTargetInfo(virStorageVolTargetPtr target,
- unsigned long long *allocation,
- unsigned long long *capacity)
+virStorageBackendVolOpenCheckMode(const char *path, unsigned int flags)
{
- int ret, fd;
+ int fd, mode = 0;
+ struct stat sb;
- if ((fd = open(target->path, O_RDONLY)) < 0) {
+ if ((fd = open(path, O_RDONLY|O_NONBLOCK|O_NOCTTY)) < 0) {
virReportSystemError(errno,
_("cannot open volume '%s'"),
- target->path);
+ path);
return -1;
}
+ if (fstat(fd, &sb) < 0) {
+ virReportSystemError(errno,
+ _("cannot stat file '%s'"),
+ path);
+ close(fd);
+ return -1;
+ }
+
+ if (S_ISREG(sb.st_mode))
+ mode = VIR_STORAGE_VOL_OPEN_REG;
+ else if (S_ISCHR(sb.st_mode))
+ mode = VIR_STORAGE_VOL_OPEN_CHAR;
+ else if (S_ISBLK(sb.st_mode))
+ mode = VIR_STORAGE_VOL_OPEN_BLOCK;
+
+ if (!(mode & flags)) {
+ close(fd);
+
+ if (mode & VIR_STORAGE_VOL_OPEN_ERROR) {
+ virStorageReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected storage mode for '%s'"), path);
+ return -1;
+ }
+
+ return -2;
+ }
+
+ return fd;
+}
+
+int virStorageBackendVolOpen(const char *path)
+{
+ return virStorageBackendVolOpenCheckMode(path,
+ VIR_STORAGE_VOL_OPEN_DEFAULT);
+}
+
+int
+virStorageBackendUpdateVolTargetInfo(virStorageVolTargetPtr target,
+ unsigned long long *allocation,
+ unsigned long long *capacity)
+{
+ int ret, fd;
+
+ if ((ret = virStorageBackendVolOpen(target->path)) < 0)
+ return ret;
+
+ fd = ret;
ret = virStorageBackendUpdateVolTargetInfoFD(target,
fd,
allocation,
* virStorageBackendUpdateVolTargetInfoFD:
* @conn: connection to report errors on
* @target: target definition ptr of volume to update
- * @fd: fd of storage volume to update
+ * @fd: fd of storage volume to update, via virStorageBackendOpenVol*
* @allocation: If not NULL, updated allocation information will be stored
* @capacity: If not NULL, updated capacity info will be stored
*
- * Returns 0 for success-1 on a legitimate error condition,
- * -2 if passed FD isn't a regular, char, or block file.
+ * Returns 0 for success, -1 on a legitimate error condition.
*/
int
virStorageBackendUpdateVolTargetInfoFD(virStorageVolTargetPtr target,
return -1;
}
- if (!S_ISREG(sb.st_mode) &&
- !S_ISCHR(sb.st_mode) &&
- !S_ISBLK(sb.st_mode))
- return -2;
-
if (allocation) {
if (S_ISREG(sb.st_mode)) {
#ifndef WIN32
virStorageBackendPtr virStorageBackendForType(int type);
+int virStorageBackendVolOpen(const char *path)
+ATTRIBUTE_RETURN_CHECK
+ATTRIBUTE_NONNULL(1);
+
+/* VolOpenCheckMode flags */
+enum {
+ VIR_STORAGE_VOL_OPEN_ERROR = 1 << 0, /* warn if unexpected type
+ * encountered */
+ VIR_STORAGE_VOL_OPEN_REG = 1 << 1, /* regular files okay */
+ VIR_STORAGE_VOL_OPEN_BLOCK = 1 << 2, /* block files okay */
+ VIR_STORAGE_VOL_OPEN_CHAR = 1 << 3, /* char files okay */
+};
+
+#define VIR_STORAGE_VOL_OPEN_DEFAULT (VIR_STORAGE_VOL_OPEN_ERROR |\
+ VIR_STORAGE_VOL_OPEN_REG |\
+ VIR_STORAGE_VOL_OPEN_CHAR |\
+ VIR_STORAGE_VOL_OPEN_BLOCK)
+
+int virStorageBackendVolOpenCheckMode(const char *path, unsigned int flags)
+ATTRIBUTE_RETURN_CHECK
+ATTRIBUTE_NONNULL(1);
int virStorageBackendUpdateVolInfo(virStorageVolDefPtr vol,
int withCapacity);
if (encryption)
*encryption = NULL;
- if ((fd = open(target->path, O_RDONLY)) < 0) {
- virReportSystemError(errno,
- _("cannot open volume '%s'"),
- target->path);
- return -1;
- }
+ if ((ret = virStorageBackendVolOpenCheckMode(target->path,
+ (VIR_STORAGE_VOL_OPEN_DEFAULT & ~VIR_STORAGE_VOL_OPEN_ERROR))) < 0)
+ return ret; /* Take care to propagate ret, it is not always -1 */
+ fd = ret;
if ((ret = virStorageBackendUpdateVolTargetInfoFD(target, fd,
allocation,
capacity)) < 0) {
close(fd);
- return ret; /* Take care to propagate ret, it is not always -1 */
+ return -1;
}
memset(&meta, 0, sizeof(meta));
virStoragePoolObjPtr pool,
virStorageVolDefPtr vol)
{
- int fd = -1;
+ int fdret, fd = -1;
char size[100];
const char *cmdargvnew[] = {
LVCREATE, "--name", vol->name, "-L", size,
if (virRun(cmdargv, NULL) < 0)
return -1;
- if ((fd = open(vol->target.path, O_RDONLY)) < 0) {
- virReportSystemError(errno,
- _("cannot read path '%s'"),
- vol->target.path);
+ if ((fdret = virStorageBackendVolOpen(vol->target.path)) < 0)
goto cleanup;
- }
+ fd = fdret;
/* We can only chown/grp if root */
if (getuid() == 0) {