]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Create storage pool directories with proper uid/gid/mode
authorLaine Stump <laine@laine.org>
Wed, 20 Jan 2010 23:46:32 +0000 (00:46 +0100)
committerDaniel Veillard <veillard@redhat.com>
Wed, 20 Jan 2010 23:46:32 +0000 (00:46 +0100)
Previously the uid/gid/mode in the xml was ignored when creating new
storage pool directories. This commit attempts to honor the requested
permissions, and spits out an error if it can't.

Note that when creating the directory, the rest of the path leading up
to the final element is created using current uid/gid/mode, and the
final element gets the settings from xml. It is NOT an error for the
directory to already exist; in this case, the perms for the existing
directory are just set (if necessary).

* src/storage/storage_backend_fs.c: update the virStorageBackendFileSystemBuild
  function to check the directory hierarchy separately then create the
  leaf directory with the right attributes

src/storage/storage_backend_fs.c

index cc26f2f487b129f60229d8e8d4aa4e4c033c6c0f..0d1c7a7fc785ef0a12087ddff3d13025d1c2e449 100644 (file)
@@ -505,15 +505,50 @@ virStorageBackendFileSystemBuild(virConnectPtr conn,
                                  virStoragePoolObjPtr pool,
                                  unsigned int flags ATTRIBUTE_UNUSED)
 {
-    int err;
-    if ((err = virFileMakePath(pool->def->target.path)) < 0) {
-        virReportSystemError(conn, err,
-                             _("cannot create path '%s'"),
-                             pool->def->target.path);
-        return -1;
+    int err, ret = -1;
+    char *parent;
+    char *p;
+
+    if ((parent = strdup(pool->def->target.path)) == NULL) {
+        virReportOOMError(conn);
+        goto error;
+    }
+    if (!(p = strrchr(parent, '/'))) {
+        virStorageReportError(conn, VIR_ERR_INVALID_ARG,
+                              _("path '%s' is not absolute"),
+                              pool->def->target.path);
+        goto error;
+    }
+
+    if (p != parent) {
+        /* assure all directories in the path prior to the final dir
+         * exist, with default uid/gid/mode. */
+        *p = '\0';
+        if ((err = virFileMakePath(parent)) != 0) {
+            virReportSystemError(conn, err, _("cannot create path '%s'"),
+                                 parent);
+            goto error;
+        }
     }
 
-    return 0;
+    /* Now create the final dir in the path with the uid/gid/mode
+     * requested in the config. If the dir already exists, just set
+     * the perms. */
+    if ((err = virDirCreate(pool->def->target.path,
+                            pool->def->target.perms.mode,
+                            pool->def->target.perms.uid,
+                            pool->def->target.perms.gid,
+                            VIR_FILE_CREATE_ALLOW_EXIST |
+                            (pool->def->type == VIR_STORAGE_POOL_NETFS
+                             ? VIR_FILE_CREATE_AS_UID : 0)) != 0)) {
+        virReportSystemError(conn, err, _("cannot create path '%s'"),
+                             pool->def->target.path);
+        goto error;
+    }
+    ret = 0;
+error:
+    VIR_FREE(parent);
+    return ret;
 }