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
28 changes: 24 additions & 4 deletions src/control/common/file_utils.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 All @@ -20,9 +20,11 @@ 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
)

// GetFilenames returns names of files in a directory.
func GetFilenames(dir string) ([]string, error) {
Expand Down Expand Up @@ -139,6 +141,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 +379,14 @@ func HasPrefixPath(base, sub string) (bool, error) {

return true, nil
}

// MkdirForcePerm creates a new directory with the specified name and permission bits (umask ignored).
func MkdirForcePerm(path string, perm os.FileMode) error {
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_MkdirForcePerm(t *testing.T) {
expPerm := 0777

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

testPath := path.Join(testDir, "foo")
err := MkdirForcePerm(testPath, os.FileMode(expPerm))
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 != expPerm {
t.Fatalf("Created directory has unexpected permissions: %04o instead of %04o", perm, expPerm)
}
}
7 changes: 7 additions & 0 deletions src/control/lib/daos/constants.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// (C) Copyright 2022 Intel Corporation.
// (C) Copyright 2026 Hewlett Packard Enterprise Development LP
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
Expand All @@ -8,6 +9,7 @@ package daos

/*
#include <daos_types.h>
#include <daos_srv/control.h>
*/
import "C"

Expand All @@ -20,3 +22,8 @@ const (
// MaxAttributeNameLength defines the maximum length of an attribute name.
MaxAttributeNameLength = C.DAOS_ATTR_NAME_MAX
)

const (
DefaultFilePerm = C.DEFAULT_FILE_PERM
DefaultDirPerm = C.DEFAULT_DIR_PERM
)
8 changes: 4 additions & 4 deletions 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 @@ -238,11 +239,10 @@ func (msp *MockSysProvider) Getegid() int {
return msp.cfg.GetegidRes
}

// Mkdir creates a new directory with the specified name and permission
// bits (before umask).
// Mkdir creates a new directory with the specified name and permission bits (umask ignored).
func (msp *MockSysProvider) Mkdir(path string, flags os.FileMode) error {
if msp.cfg.RealMkdir {
return os.Mkdir(path, flags)
return common.MkdirForcePerm(path, flags)
}
return msp.cfg.MkdirErr
}
Expand Down
8 changes: 4 additions & 4 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 @@ -391,10 +392,9 @@ func (s LinuxProvider) Getegid() int {
return os.Getegid()
}

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

// RemoveAll removes path and any children it contains.
Expand Down
5 changes: 3 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 All @@ -17,6 +17,7 @@ import (
"gopkg.in/yaml.v2"

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

Expand Down Expand Up @@ -205,6 +206,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, daos.DefaultFilePerm),
"Failed to write Superblock to %s", sbPath)
}
14 changes: 12 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 @@ -19,13 +20,14 @@ import (
"github.com/pkg/errors"

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

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 = daos.DefaultFilePerm // AIO file permissions
)

func createEmptyFile(log logging.Logger, path string, size uint64) error {
Expand Down Expand Up @@ -102,6 +104,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)
Comment thread
janekmi marked this conversation as resolved.
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
6 changes: 4 additions & 2 deletions src/control/server/storage/metadata/provider.go
Original file line number Diff line number Diff line change
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)

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.Mkdir(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.Mkdir(engPath, perms); err != nil {
return errors.Wrapf(err, "creating control metadata engine %d subdirectory", idx)
}

Expand Down
3 changes: 2 additions & 1 deletion 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 Down
10 changes: 9 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 All @@ -24,6 +24,7 @@ import (
"google.golang.org/grpc"

"github.com/daos-stack/daos/src/control/common"
"github.com/daos-stack/daos/src/control/lib/daos"
"github.com/daos-stack/daos/src/control/logging"
"github.com/daos-stack/daos/src/control/system"
"github.com/daos-stack/daos/src/control/system/checker"
Expand Down Expand Up @@ -267,6 +268,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(), daos.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
5 changes: 4 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,8 @@ 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/daos"
"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 +89,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.MkdirForcePerm(dbPath, daos.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