Skip to content

Commit

Permalink
b/334917514 - Add daos fs chown
Browse files Browse the repository at this point in the history
Example usage:
https://paste.googleplex.com/5995835690582016

Required-githooks: true

Signed-off-by: Justin Zhang <juszhan@google.com>
  • Loading branch information
juszhan1 committed Apr 18, 2024
1 parent a6bac14 commit 6fe9595
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 0 deletions.
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

0 comments on commit 6fe9595

Please sign in to comment.