Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 32 additions & 4 deletions src/control/common/file_utils.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
//
// (C) Copyright 2019-2024 Intel Corporation.
// (C) Copyright 2025 Hewlett Packard Enterprise Development LP
// (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//

package common

/*
#cgo CFLAGS: -I${SRCDIR}/../../include/
#include "daos_srv/control.h"
*/
import "C"

import (
"fmt"
"io"
Expand All @@ -20,9 +26,13 @@ import (
yaml "gopkg.in/yaml.v2"
)

// UtilLogDepth signifies stack depth, set calldepth on calls to logger so
// log message context refers to caller not callee.
const UtilLogDepth = 4
const (
// UtilLogDepth signifies stack depth, set calldepth on calls to logger so
// log message context refers to caller not callee.
UtilLogDepth = 4
DefaultFilePerm = C.DEFAULT_FILE_PERM
DefaultDirPerm = C.DEFAULT_DIR_PERM
)

// GetFilenames returns names of files in a directory.
func GetFilenames(dir string) ([]string, error) {
Expand Down Expand Up @@ -139,6 +149,13 @@ func writeFile(path string, data []byte, perm os.FileMode) (err error) {
}
}()

// The requested permissions may have been reduced by the umask.
// Using chmod ensures the requested permissions are applied.
err = os.Chmod(path, perm)
if err != nil {
return
}

n, err := f.Write(data)
if err != nil {
return
Expand Down Expand Up @@ -370,3 +387,14 @@ func HasPrefixPath(base, sub string) (bool, error) {

return true, nil
}

// Mkdir2 creates a new directory with the specified name and permission bits (umask ignored).
func Mkdir2(path string, perm os.FileMode) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a unit test for this would be good practice

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

err := os.Mkdir(path, perm)
if err != nil {
return err
}
// The requested permissions may have been reduced by the umask.
// Using Chmod ensures the requested permissions are applied.
return os.Chmod(path, perm)
}
23 changes: 23 additions & 0 deletions src/control/common/file_utils_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// (C) Copyright 2019-2022 Intel Corporation.
// (C) Copyright 2026 Hewlett Packard Enterprise Development LP
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
Expand Down Expand Up @@ -176,5 +177,27 @@ func TestUtils_HasPrefixPath(t *testing.T) {
if hp {
t.Fatalf("%q is not a prefix of %q", testDir, testPath)
}
}

func TestUtils_Mkdir2(t *testing.T) {
exp_perm := 0777

testDir, clean := CreateTestDir(t)
defer clean()

testPath := path.Join(testDir, "foo")
err := Mkdir2(testPath, os.FileMode(exp_perm))
if err != nil {
t.Fatalf("Unexpected error: %q", err)
}

info, err := os.Stat(testPath)
if err != nil {
t.Fatalf("Unexpected error: %q", err)
}

perm := int(info.Mode().Perm())
if perm != exp_perm {
t.Fatalf("Created directory has unexpected permissions: %04o instead of %04o", perm, exp_perm)
}
}
11 changes: 10 additions & 1 deletion src/control/provider/system/mocks.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// (C) Copyright 2022-2024 Intel Corporation.
// (C) Copyright 2025 Hewlett Packard Enterprise Development LP
// (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
Expand All @@ -12,6 +12,7 @@ import (
"strings"
"sync"

"github.com/daos-stack/daos/src/control/common"
"github.com/daos-stack/daos/src/control/logging"
)

Expand Down Expand Up @@ -247,6 +248,14 @@ func (msp *MockSysProvider) Mkdir(path string, flags os.FileMode) error {
return msp.cfg.MkdirErr
}

// Mkdir2 creates a new directory with the specified name and permission bits (umask ignored).
func (msp *MockSysProvider) Mkdir2(path string, flags os.FileMode) error {
if msp.cfg.RealMkdir {
return common.Mkdir2(path, flags)
}
return msp.cfg.MkdirErr
}

// RemoveAll removes path and any children it contains.
func (msp *MockSysProvider) RemoveAll(path string) error {
if msp.cfg.RealRemoveAll {
Expand Down
6 changes: 6 additions & 0 deletions src/control/provider/system/system_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"strings"
"syscall"

"github.com/daos-stack/daos/src/control/common"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
)
Expand Down Expand Up @@ -397,6 +398,11 @@ func (s LinuxProvider) Mkdir(name string, perm os.FileMode) error {
return os.Mkdir(name, perm)
}

// Mkdir2 creates a new directory with the specified name and permission bits (umask ignored).
func (s LinuxProvider) Mkdir2(path string, perm os.FileMode) error {
return common.Mkdir2(path, perm)
}

// RemoveAll removes path and any children it contains.
func (s LinuxProvider) RemoveAll(path string) error {
return os.RemoveAll(path)
Expand Down
4 changes: 2 additions & 2 deletions src/control/server/instance_superblock.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// (C) Copyright 2019-2024 Intel Corporation.
// (C) Copyright 2025 Hewlett Packard Enterprise Development LP
// (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
Expand Down Expand Up @@ -205,6 +205,6 @@ func WriteSuperblock(sbPath string, sb *Superblock) error {
return err
}

return errors.Wrapf(common.WriteFileAtomic(sbPath, data, 0600),
return errors.Wrapf(common.WriteFileAtomic(sbPath, data, common.DefaultFilePerm),
"Failed to write Superblock to %s", sbPath)
}
13 changes: 11 additions & 2 deletions src/control/server/storage/bdev/backend_class.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// (C) Copyright 2021-2024 Intel Corporation.
// (C) Copyright 2026 Hewlett Packard Enterprise Development LP
// (C) Copyright 2025 Google LLC
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
Expand All @@ -24,8 +25,8 @@ import (
)

const (
aioBlockSize = humanize.KiByte * 4 // device block size hardcoded to 4096 bytes
defaultAioFileMode = 0600 // AIO file permissions set to owner +rw
aioBlockSize = humanize.KiByte * 4 // device block size hardcoded to 4096 bytes
defaultAioFileMode = common.DefaultFilePerm // AIO file permissions
)

func createEmptyFile(log logging.Logger, path string, size uint64) error {
Expand Down Expand Up @@ -102,6 +103,14 @@ func writeConfigFile(log logging.Logger, buf *bytes.Buffer, req *storage.BdevWri
return errors.Wrap(err, "create")
}

// os.Create() above creates a file with 0666 permissions (before umask).
// Typical umask is 022 so the effective permissions of the created file is 0644.
// The os.Chmod ensures the final permissions for both the user and their group are the same.
err = os.Chmod(req.ConfigOutputPath, 0664)
if err != nil {
return errors.Wrap(err, "chmod")
}

defer func() {
if err := f.Close(); err != nil {
log.Errorf("closing %q: %s", req.ConfigOutputPath, err)
Expand Down
8 changes: 5 additions & 3 deletions src/control/server/storage/metadata/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type (
Getfs(device string) (string, error)
GetfsType(path string) (*system.FsType, error)
GetDeviceLabel(string) (string, error)
Mkdir(string, os.FileMode) error
Mkdir2(string, os.FileMode) error
Mkfs(req system.MkfsReq) error
RemoveAll(string) error
Stat(string) (os.FileInfo, error)
Expand Down Expand Up @@ -196,11 +196,13 @@ func (p *Provider) isUsableFS(fs *system.FsType, path string) bool {
}

func (p *Provider) setupDataDir(req storage.MetadataFormatRequest) error {
perms := os.FileMode(0775)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to have a constant somewhere indicating these new default perms? Same question applies at the engine level.

If we define the permission values in a C header file for the engines, we can import it in our Go package lib/daos.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not go all the way. We still use a variety of values e.g. there are directories 0770 and 0775. And I do not want to change it in this PR because I do not want to remove any permissions and I do want not grant more than it was agreed to be granted.

For now I created two constants in the Go code: DefaultFilePerm and DefaultDirPerm and I used them everywhere where the permissions were either 0770 or 0660. I left other cases unchanged.

We can discuss next steps in a separate ticket. I think the way is open assuming no opposition will come up. Please note we would have to possibly remove some permissions people were used to have. It is not obvious it would be a desirable change to have one set of permissions for all files and all directories across the project.


if err := p.sys.RemoveAll(req.DataPath); err != nil {
return errors.Wrap(err, "removing old control metadata subdirectory")
}

if err := p.sys.Mkdir(req.DataPath, 0755); err != nil {
if err := p.sys.Mkdir2(req.DataPath, perms); err != nil {
return errors.Wrap(err, "creating control metadata subdirectory")
}

Expand All @@ -210,7 +212,7 @@ func (p *Provider) setupDataDir(req storage.MetadataFormatRequest) error {

for _, idx := range req.EngineIdxs {
engPath := storage.ControlMetadataEngineDir(req.DataPath, idx)
if err := p.sys.Mkdir(engPath, 0755); err != nil {
if err := p.sys.Mkdir2(engPath, perms); err != nil {
return errors.Wrapf(err, "creating control metadata engine %d subdirectory", idx)
}

Expand Down
7 changes: 4 additions & 3 deletions src/control/server/storage/mount/provider.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// (C) Copyright 2022-2024 Intel Corporation.
// (C) Copyright 2026 Hewlett Packard Enterprise Development LP
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
Expand All @@ -19,7 +20,7 @@ import (
)

const (
defaultMountPointPerms = 0755
defaultMountPointPerms = 0775
defaultUnmountFlags = 0
)

Expand All @@ -33,7 +34,7 @@ type (
Chown(string, int, int) error
Getegid() int
Geteuid() int
Mkdir(string, os.FileMode) error
Mkdir2(string, os.FileMode) error
RemoveAll(string) error
Stat(string) (os.FileInfo, error)
}
Expand Down Expand Up @@ -173,7 +174,7 @@ func (p *Provider) MakeMountPath(path string, tgtUID, tgtGID int) error {
switch {
case os.IsNotExist(err):
// subdir missing, attempt to create and chown
if err := p.sys.Mkdir(ps, defaultMountPointPerms); err != nil {
if err := p.sys.Mkdir2(ps, defaultMountPointPerms); err != nil {
return errors.Wrapf(err, "failed to create directory %q", ps)
}
if err := p.sys.Chown(ps, tgtUID, tgtGID); err != nil {
Expand Down
9 changes: 8 additions & 1 deletion src/control/system/raft/raft.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// (C) Copyright 2020-2024 Intel Corporation.
// (C) Copyright 2025 Hewlett Packard Enterprise Development LP
// (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
Expand Down Expand Up @@ -267,6 +267,13 @@ func ConfigureComponents(log logging.Logger, dbCfg *DatabaseConfig) (*RaftCompon
return nil, errors.Wrapf(err, "failed to init boltdb at %s", dbCfg.DBFilePath())
}

// Boltdb file permissions on create are set to 0600.
// The os.Chmod ensures the final permissions for both the user and their group are the same.
err = os.Chmod(dbCfg.DBFilePath(), common.DefaultFilePerm)
if err != nil {
return nil, errors.Wrapf(err, "failed to set permissions for boltdb at %s", dbCfg.DBFilePath())
}

return &RaftComponents{
Logger: log,
Config: raftCfg,
Expand Down
4 changes: 3 additions & 1 deletion src/control/system/raft/raft_recovery.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// (C) Copyright 2022-2024 Intel Corporation.
// (C) Copyright 2026 Hewlett Packard Enterprise Development LP
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
Expand All @@ -21,6 +22,7 @@ import (
"github.com/pkg/errors"
"go.etcd.io/bbolt"

"github.com/daos-stack/daos/src/control/common"
"github.com/daos-stack/daos/src/control/lib/ranklist"
"github.com/daos-stack/daos/src/control/logging"
"github.com/daos-stack/daos/src/control/system"
Expand Down Expand Up @@ -86,7 +88,7 @@ func RecoverLocalReplica(log logging.Logger, cfg *DatabaseConfig) error {
}

func createRaftDir(dbPath string) error {
if err := os.Mkdir(dbPath, 0700); err != nil && !os.IsExist(err) {
if err := common.Mkdir2(dbPath, common.DefaultDirPerm); err != nil && !os.IsExist(err) {
return errors.Wrap(err, "failed to create raft directory")
}
return nil
Expand Down
7 changes: 7 additions & 0 deletions src/engine/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,13 @@ server_init(int argc, char *argv[])
int rc;
struct engine_metrics *metrics;

/**
* The typical umask is 022. The group portion is cleared, which allows the group
* permissions to be set freely. This setting is intended to remain in effect for the entire
* lifetime of the process.
*/
(void)umask(002);

/*
* Begin the HLC recovery as early as possible. Do not read the HLC
* before the hlc_recovery_end call below.
Expand Down
4 changes: 4 additions & 0 deletions src/include/daos_srv/control.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@
#include <stdbool.h>
#include <assert.h>
#include <string.h>
#include <sys/stat.h>
#include <daos/common.h>

#define DEFAULT_FILE_PERM (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)
#define DEFAULT_DIR_PERM (S_IRWXU | S_IRWXG)

#define NVME_PCI_DEV_TYPE_VMD "vmd"
#define NVME_DETAIL_BUFLEN 1024
/**
Expand Down
3 changes: 1 addition & 2 deletions src/mgmt/mgmt_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <daos_errno.h>
#include <daos_types.h>
Expand Down Expand Up @@ -124,7 +123,7 @@ ds_mgmt_tgt_recreate(uuid_t pool_uuid, daos_size_t scm_size, int tgt_nr, int *tg
DP_RC(rc));
goto out;
}
rc = mkdir(pool_newborns_path, 0700);
rc = mkdir(pool_newborns_path, DEFAULT_DIR_PERM);
if (rc < 0 && errno != EEXIST) {
rc = daos_errno2der(errno);
D_ERROR("failed to created pool directory: " DF_RC "\n", DP_RC(rc));
Expand Down
Loading
Loading