Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

b/334917514 - Add daos fs chown #14184

Merged
merged 1 commit into from
Apr 18, 2024
Merged
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
43 changes: 43 additions & 0 deletions src/control/cmd/daos/filesystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import "C"

import (
"fmt"
"math"

"github.com/pkg/errors"
)
Expand All @@ -38,6 +39,7 @@ type fsCmd struct {
ResetChunkSize fsResetChunkSizeCmd `command:"reset-chunk-size" description:"reset fs chunk size"`
ResetObjClass fsResetOclassCmd `command:"reset-oclass" description:"reset fs obj class"`
Chmod fsChmodCmd `command:"chmod" description:"change file mode bits"`
Chown fsChownCmd `command:"chown" description:"changes the owner"`
}

type fsCopyCmd struct {
Expand Down Expand Up @@ -461,3 +463,44 @@ func (cmd *fsChmodCmd) Execute(_ []string) error {

return nil
}

type fsChownCmd struct {
fsAttrCmd

UserId UserIdFlag `long:"user-id" short:"u" description:"user id"`
GroupId GroupIdFlag `long:"group-id" short:"g" description:"group id"`
}

func (cmd *fsChownCmd) Execute(_ []string) error {
ap, deallocCmdArgs, err := setupFSAttrCmd(&cmd.fsAttrCmd)
if err != nil {
return err
}
defer deallocCmdArgs()

if !cmd.UserId.Set && !cmd.GroupId.Set {
return errors.New("Missing --user-id and/or --group-id")
}

ap.user_id = math.MaxUint32
if cmd.UserId.Set {
ap.user_id = cmd.UserId.Id
}

ap.group_id = math.MaxUint32
if cmd.GroupId.Set {
ap.group_id = cmd.GroupId.Id
}

cleanup, err := cmd.resolveAndConnect(C.DAOS_COO_RW, ap)
if err != nil {
return errors.Wrapf(err, "failed to connect")
}
defer cleanup()

if err := dfsError(C.fs_chown_hdlr(ap)); err != nil {
return errors.Wrapf(err, "chown failed")
}

return nil
}
48 changes: 48 additions & 0 deletions src/control/cmd/daos/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,3 +300,51 @@ func (f *ModeBitsFlag) UnmarshalFlag(fv string) error {

return nil
}

type UserIdFlag struct {
Set bool
Id C.uid_t
}

func (f *UserIdFlag) UnmarshalFlag(fv string) error {
if fv == "" {
return errors.New("empty user id flag")
}

uid, err := strconv.ParseInt(fv, 10, 32)
if err != nil {
return errors.Errorf("invalid user id: %q", fv)
}
if uid < 0 {
return errors.Errorf("invalid user id: %q", fv)
}

f.Set = true
f.Id = C.uid_t(uid)

return nil
}

type GroupIdFlag struct {
Set bool
Id C.gid_t
}

func (f *GroupIdFlag) UnmarshalFlag(fv string) error {
if fv == "" {
return errors.New("empty group id flag")
}

gid, err := strconv.ParseInt(fv, 10, 32)
if err != nil {
return errors.Errorf("invalid group id: %q", fv)
}
if gid < 0 {
return errors.Errorf("invalid group id: %q", fv)
}

f.Set = true
f.Id = C.gid_t(gid)

return nil
}
80 changes: 80 additions & 0 deletions src/control/cmd/daos/flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,3 +614,83 @@ func TestFlags_ModeBitsFlag(t *testing.T) {
}

}

func TestFlags_UserIdFlag(t *testing.T) {
for name, tc := range map[string]struct {
arg string
expFlag *UserIdFlag
expErr error
}{
"unset": {
expErr: errors.New("empty user id flag"),
},
"not an integer": {
arg: "foo",
expErr: errors.New("invalid user id: \"foo\""),
},
"negative value": {
arg: "-1",
expErr: errors.New("invalid user id: \"-1\""),
},
"valid": {
arg: "1000",
expFlag: &UserIdFlag{
Set: true,
Id: 1000,
},
},
} {
t.Run(name, func(t *testing.T) {
f := UserIdFlag{}
gotErr := f.UnmarshalFlag(tc.arg)
test.CmpErr(t, tc.expErr, gotErr)
if tc.expErr != nil {
return
}

if diff := cmp.Diff(tc.expFlag, &f); diff != "" {
t.Fatalf("unexpected flag value: (-want, +got)\n%s\n", diff)
}
})
}
}

func TestFlags_GroupIdFlag(t *testing.T) {
for name, tc := range map[string]struct {
arg string
expFlag *GroupIdFlag
expErr error
}{
"unset": {
expErr: errors.New("empty group id flag"),
},
"not an integer": {
arg: "foo",
expErr: errors.New("invalid group id: \"foo\""),
},
"negative value": {
arg: "-1",
expErr: errors.New("invalid group id: \"-1\""),
},
"valid": {
arg: "1000",
expFlag: &GroupIdFlag{
Set: true,
Id: 1000,
},
},
} {
t.Run(name, func(t *testing.T) {
f := GroupIdFlag{}
gotErr := f.UnmarshalFlag(tc.arg)
test.CmpErr(t, tc.expErr, gotErr)
if tc.expErr != nil {
return
}

if diff := cmp.Diff(tc.expFlag, &f); diff != "" {
t.Fatalf("unexpected flag value: (-want, +got)\n%s\n", diff)
}
})
}
}
38 changes: 38 additions & 0 deletions src/utils/daos_dfs_hdlr.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,3 +345,41 @@ fs_chmod_hdlr(struct cmd_args_s *ap)
fprintf(ap->errstream, "failed to umount DFS container\n");
return rc;
}

int
fs_chown_hdlr(struct cmd_args_s *ap)
{
const int mflags = O_RDWR;
const int sflags = DFS_SYS_NO_LOCK | DFS_SYS_NO_CACHE;
dfs_sys_t *dfs_sys;
int rc = 0;
int rc2 = 0;

rc = dfs_sys_mount(ap->pool, ap->cont, mflags, sflags, &dfs_sys);
if (rc) {
fprintf(ap->errstream, "failed to mount container %s: %s (%d)\n",
ap->cont_str, strerror(rc), rc);
return rc;
}

if (ap->dfs_prefix) {
rc = dfs_sys_set_prefix(dfs_sys, ap->dfs_prefix);
if (rc) {
fprintf(ap->errstream, "failed to set path prefix %s: %s (%d)\n",
ap->dfs_prefix, strerror(rc), rc);
D_GOTO(out_umount, rc);
}
}

rc = dfs_sys_chown(dfs_sys, ap->dfs_path, ap->user_id, ap->group_id, 0 /* flags */);
if (rc) {
fprintf(ap->errstream, "failed to change owner for path %s: %s (%d)\n",
ap->dfs_path, strerror(rc), rc);
}

out_umount:
rc2 = dfs_sys_umount(dfs_sys);
if (rc2)
fprintf(ap->errstream, "failed to umount DFS container\n");
return rc;
}
4 changes: 4 additions & 0 deletions src/utils/daos_hdlr.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ enum fs_op {
FS_RESET_OCLASS,
FS_CHECK,
FS_CHMOD,
FS_CHOWN,
};

enum cont_op {
Expand Down Expand Up @@ -163,6 +164,8 @@ struct cmd_args_s {
char *entry; /* --entry for ACL */
char *principal; /* --principal for ACL */
mode_t object_mode; /* object mode bits */
uid_t user_id; /* user id */
gid_t group_id; /* group id */
};

#define ARGS_VERIFY_PATH_CREATE(ap, label, rcexpr) \
Expand Down Expand Up @@ -198,6 +201,7 @@ int fs_fix_entry_hdlr(struct cmd_args_s *ap, bool fix_entry);
int fs_recreate_sb_hdlr(struct cmd_args_s *ap);
int fs_relink_root_hdlr(struct cmd_args_s *ap);
int fs_chmod_hdlr(struct cmd_args_s *ap);
int fs_chown_hdlr(struct cmd_args_s *ap);

/* Container operations */
int cont_check_hdlr(struct cmd_args_s *ap);
Expand Down
Loading