Skip to content
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
5 changes: 4 additions & 1 deletion src/client/dfs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,14 @@ A-key: "DFS_CHUNK_SIZE"
single-value (uint64_t): Default chunk size for files in this container

A-key: "DFS_OBJ_CLASS"
single-value (uint16_t): Default object class for files in this container
single-value (uint16_t): Default object class for all objects in this container

A-key: "DFS_DIR_OBJ_CLASS"
single-value (uint16_t): Default object class for directories in this container

A-key: "DFS_FILE_OBJ_CLASS"
single-value (uint16_t): Default object class for files in this container

A-key: "DFS_MODE"
single-value (uint16_t): Consistency mode of this container (Relaxed vs Balanced)

Expand Down
50 changes: 36 additions & 14 deletions src/client/dfs/dfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
/** D-key name of SB metadata */
#define SB_DKEY "DFS_SB_METADATA"

#define SB_AKEYS 8
#define SB_AKEYS 9
/** A-key name of SB magic */
#define MAGIC_NAME "DFS_MAGIC"
/** A-key name of SB version */
Expand All @@ -38,10 +38,12 @@
#define LAYOUT_VER_NAME "DFS_LAYOUT_VERSION"
/** A-key name of Default chunk size */
#define CS_NAME "DFS_CHUNK_SIZE"
/** A-key name of Default Object Class for files */
#define FILE_OC_NAME "DFS_OBJ_CLASS"
/** A-key name of Default Object Class for objects */
#define OC_NAME "DFS_OBJ_CLASS"
/** A-key name of Default Object Class for directories */
#define DIR_OC_NAME "DFS_DIR_OBJ_CLASS"
/** A-key name of Default Object Class for files */
#define FILE_OC_NAME "DFS_FILE_OBJ_CLASS"
/** Consistency mode of the DFS container */
#define CONT_MODE_NAME "DFS_MODE"
/** A-key name of the object class hints */
Expand All @@ -51,10 +53,11 @@
#define SB_VER_IDX 1
#define LAYOUT_VER_IDX 2
#define CS_IDX 3
#define FILE_OC_IDX 4
#define OC_IDX 4
#define DIR_OC_IDX 5
#define CONT_MODE_IDX 6
#define CONT_HINT_IDX 7
#define FILE_OC_IDX 6
#define CONT_MODE_IDX 7
#define CONT_HINT_IDX 8

/** Magic Value */
#define DFS_SB_MAGIC 0xda05df50da05df50
Expand Down Expand Up @@ -1277,7 +1280,7 @@ open_file(dfs_t *dfs, dfs_obj_t *parent, int flags, daos_oclass_id_t cid,
/** set oclass for file. order: API, parent dir, cont default */
if (cid == 0) {
if (parent->d.oclass == 0)
cid = dfs->attr.da_oclass_id;
cid = dfs->attr.da_file_oclass_id;
else
cid = parent->d.oclass;
}
Expand Down Expand Up @@ -1648,6 +1651,7 @@ set_sb_params(bool for_update, daos_iod_t *iods, daos_key_t *dkey)
set_daos_iod(for_update, &iods[SB_VER_IDX], SB_VER_NAME, sizeof(dfs_sb_ver_t));
set_daos_iod(for_update, &iods[LAYOUT_VER_IDX], LAYOUT_VER_NAME, sizeof(dfs_layout_ver_t));
set_daos_iod(for_update, &iods[CS_IDX], CS_NAME, sizeof(daos_size_t));
set_daos_iod(for_update, &iods[OC_IDX], OC_NAME, sizeof(daos_oclass_id_t));
set_daos_iod(for_update, &iods[FILE_OC_IDX], FILE_OC_NAME, sizeof(daos_oclass_id_t));
set_daos_iod(for_update, &iods[DIR_OC_IDX], DIR_OC_NAME, sizeof(daos_oclass_id_t));
set_daos_iod(for_update, &iods[CONT_MODE_IDX], CONT_MODE_NAME, sizeof(uint32_t));
Expand All @@ -1668,6 +1672,7 @@ open_sb(daos_handle_t coh, bool create, daos_obj_id_t super_oid,
daos_size_t chunk_size = 0;
daos_oclass_id_t oclass = OC_UNKNOWN;
daos_oclass_id_t dir_oclass = OC_UNKNOWN;
daos_oclass_id_t file_oclass = OC_UNKNOWN;
uint32_t mode;
char hints[DAOS_CONT_HINT_MAX_LEN];
int i, rc;
Expand All @@ -1685,7 +1690,8 @@ open_sb(daos_handle_t coh, bool create, daos_obj_id_t super_oid,
d_iov_set(&sg_iovs[SB_VER_IDX], &sb_ver, sizeof(dfs_sb_ver_t));
d_iov_set(&sg_iovs[LAYOUT_VER_IDX], &layout_ver, sizeof(dfs_layout_ver_t));
d_iov_set(&sg_iovs[CS_IDX], &chunk_size, sizeof(daos_size_t));
d_iov_set(&sg_iovs[FILE_OC_IDX], &oclass, sizeof(daos_oclass_id_t));
d_iov_set(&sg_iovs[OC_IDX], &oclass, sizeof(daos_oclass_id_t));
d_iov_set(&sg_iovs[FILE_OC_IDX], &file_oclass, sizeof(daos_oclass_id_t));
d_iov_set(&sg_iovs[DIR_OC_IDX], &dir_oclass, sizeof(daos_oclass_id_t));
d_iov_set(&sg_iovs[CONT_MODE_IDX], &mode, sizeof(uint32_t));

Expand Down Expand Up @@ -1721,6 +1727,7 @@ open_sb(daos_handle_t coh, bool create, daos_obj_id_t super_oid,

oclass = attr->da_oclass_id;
dir_oclass = attr->da_dir_oclass_id;
file_oclass = attr->da_file_oclass_id;
mode = attr->da_mode;

rc = daos_obj_update(*oh, DAOS_TX_NONE, DAOS_COND_DKEY_INSERT, &dkey, num_iods,
Expand Down Expand Up @@ -1774,6 +1781,7 @@ open_sb(daos_handle_t coh, bool create, daos_obj_id_t super_oid,
attr->da_chunk_size = (chunk_size) ? chunk_size : DFS_DEFAULT_CHUNK_SIZE;
attr->da_oclass_id = oclass;
attr->da_dir_oclass_id = dir_oclass;
attr->da_file_oclass_id = file_oclass;
attr->da_mode = mode;
if (iods[CONT_HINT_IDX].iod_size != 0)
strcpy(attr->da_hints, hints);
Expand Down Expand Up @@ -1850,8 +1858,14 @@ dfs_cont_create(daos_handle_t poh, uuid_t *cuuid, dfs_attr_t *attr,
}

if (attr) {
dattr.da_oclass_id = attr->da_oclass_id;
dattr.da_dir_oclass_id = attr->da_dir_oclass_id;
if (attr->da_oclass_id) {
dattr.da_dir_oclass_id = attr->da_oclass_id;
dattr.da_file_oclass_id = attr->da_oclass_id;
}
if (attr->da_file_oclass_id)
dattr.da_file_oclass_id = attr->da_file_oclass_id;
if (attr->da_dir_oclass_id)
dattr.da_dir_oclass_id = attr->da_dir_oclass_id;

/** check non default mode */
if ((attr->da_mode & MODE_MASK) == DFS_RELAXED ||
Expand All @@ -1873,6 +1887,7 @@ dfs_cont_create(daos_handle_t poh, uuid_t *cuuid, dfs_attr_t *attr,
} else {
dattr.da_oclass_id = 0;
dattr.da_dir_oclass_id = 0;
dattr.da_file_oclass_id = 0;
dattr.da_mode = DFS_RELAXED;
dattr.da_chunk_size = DFS_DEFAULT_CHUNK_SIZE;
}
Expand All @@ -1893,8 +1908,8 @@ dfs_cont_create(daos_handle_t poh, uuid_t *cuuid, dfs_attr_t *attr,
if (cont_tf < 0)
D_GOTO(err_prop, rc = EINVAL);

if (dattr.da_oclass_id) {
rc = daos_oclass_cid2allowedfailures(dattr.da_oclass_id, &cid_tf);
if (dattr.da_file_oclass_id) {
rc = daos_oclass_cid2allowedfailures(dattr.da_file_oclass_id, &cid_tf);
if (rc) {
D_ERROR("Invalid oclass OID\n");
D_GOTO(err_prop, rc = daos_der2errno(rc));
Expand Down Expand Up @@ -2621,6 +2636,7 @@ struct dfs_glob {
daos_size_t chunk_size;
daos_oclass_id_t oclass;
daos_oclass_id_t dir_oclass;
daos_oclass_id_t file_oclass;
uuid_t cont_uuid;
uuid_t coh_uuid;
daos_obj_id_t super_oid;
Expand All @@ -2641,6 +2657,8 @@ swap_dfs_glob(struct dfs_glob *dfs_params)
D_SWAP64S(&dfs_params->id);
D_SWAP64S(&dfs_params->chunk_size);
D_SWAP16S(&dfs_params->oclass);
D_SWAP16S(&dfs_params->dir_oclass);
D_SWAP16S(&dfs_params->file_oclass);
/* skip cont_uuid */
/* skip coh_uuid */
}
Expand Down Expand Up @@ -2710,6 +2728,7 @@ dfs_local2global(dfs_t *dfs, d_iov_t *glob)
dfs_params->chunk_size = dfs->attr.da_chunk_size;
dfs_params->oclass = dfs->attr.da_oclass_id;
dfs_params->dir_oclass = dfs->attr.da_dir_oclass_id;
dfs_params->file_oclass = dfs->attr.da_file_oclass_id;
uuid_copy(dfs_params->coh_uuid, coh_uuid);
uuid_copy(dfs_params->cont_uuid, cont_uuid);

Expand Down Expand Up @@ -2777,6 +2796,7 @@ dfs_global2local(daos_handle_t poh, daos_handle_t coh, int flags, d_iov_t glob,
dfs->attr.da_chunk_size = dfs_params->chunk_size;
dfs->attr.da_oclass_id = dfs_params->oclass;
dfs->attr.da_dir_oclass_id = dfs_params->dir_oclass;
dfs->attr.da_file_oclass_id = dfs_params->file_oclass;

dfs->super_oid = dfs_params->super_oid;
dfs->root.oid = dfs_params->root_oid;
Expand Down Expand Up @@ -3148,15 +3168,17 @@ dfs_obj_set_oclass(dfs_t *dfs, dfs_obj_t *obj, int flags, daos_oclass_id_t cid)
daos_key_t dkey;
int rc;

if (dfs == NULL || !dfs->mounted)
return EINVAL;
if (obj == NULL)
return EINVAL;
if (!S_ISDIR(obj->mode))
return ENOTSUP;
if (cid == 0)
cid = dfs->attr.da_oclass_id;
/** 0 is default, allow setting it */
if (cid != 0 && !daos_oclass_is_valid(cid))
return EINVAL;
if (cid == 0)
cid = dfs->attr.da_dir_oclass_id;

/** Open parent object and fetch entry of obj from it */
rc = daos_obj_open(dfs->coh, obj->parent_oid, DAOS_OO_RO, &oh, NULL);
Expand Down
1 change: 1 addition & 0 deletions src/client/dfs/duns.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,7 @@ create_cont(daos_handle_t poh, struct duns_attr_t *attrp, bool create_with_label
dfs_attr.da_id = 0;
dfs_attr.da_oclass_id = attrp->da_oclass_id;
dfs_attr.da_dir_oclass_id = attrp->da_dir_oclass_id;
dfs_attr.da_file_oclass_id = attrp->da_file_oclass_id;
dfs_attr.da_chunk_size = attrp->da_chunk_size;
dfs_attr.da_props = attrp->da_props;
if (attrp->da_hints[0] != 0)
Expand Down
35 changes: 23 additions & 12 deletions src/control/cmd/daos/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ func (cmd *containerBaseCmd) queryContainer() (*containerInfo, error) {
var attr C.dfs_attr_t
var oclass [C.MAX_OBJ_CLASS_NAME_LEN]C.char
var dir_oclass [C.MAX_OBJ_CLASS_NAME_LEN]C.char
var file_oclass [C.MAX_OBJ_CLASS_NAME_LEN]C.char

rc := C.dfs_mount(cmd.cPoolHandle, cmd.cContHandle, C.O_RDONLY, &dfs)
if err := dfsError(rc); err != nil {
Expand All @@ -178,6 +179,8 @@ func (cmd *containerBaseCmd) queryContainer() (*containerInfo, error) {
ci.ObjectClass = C.GoString(&oclass[0])
C.daos_oclass_id2name(attr.da_dir_oclass_id, &dir_oclass[0])
ci.DirObjectClass = C.GoString(&dir_oclass[0])
C.daos_oclass_id2name(attr.da_file_oclass_id, &file_oclass[0])
ci.FileObjectClass = C.GoString(&file_oclass[0])
ci.CHints = C.GoString(&attr.da_hints[0])
ci.ChunkSize = uint64(attr.da_chunk_size)

Expand Down Expand Up @@ -208,18 +211,19 @@ func (cmd *containerBaseCmd) connectPool(flags C.uint, ap *C.struct_cmd_args_s)
type containerCreateCmd struct {
containerBaseCmd

Type ContTypeFlag `long:"type" short:"t" description:"container type"`
Path string `long:"path" short:"d" description:"container namespace path"`
ChunkSize ChunkSizeFlag `long:"chunk-size" short:"z" description:"container chunk size"`
ObjectClass ObjClassFlag `long:"oclass" short:"o" description:"default file object class"`
DirObjectClass ObjClassFlag `long:"dir_oclass" short:"a" description:"default directory object class"`
CHints string `long:"hints" short:"h" description:"container hints"`
Properties CreatePropertiesFlag `long:"properties" description:"container properties"`
Mode ConsModeFlag `long:"mode" short:"M" description:"DFS consistency mode"`
ACLFile string `long:"acl-file" short:"A" description:"input file containing ACL"`
User string `long:"user" short:"u" description:"user who will own the container (username@[domain])"`
Group string `long:"group" short:"g" description:"group who will own the container (group@[domain])"`
Args struct {
Type ContTypeFlag `long:"type" short:"t" description:"container type"`
Path string `long:"path" short:"p" description:"container namespace path"`
ChunkSize ChunkSizeFlag `long:"chunk-size" short:"z" description:"container chunk size"`
ObjectClass ObjClassFlag `long:"oclass" short:"o" description:"default object class"`
DirObjectClass ObjClassFlag `long:"dir_oclass" short:"d" description:"default directory object class"`
FileObjectClass ObjClassFlag `long:"file_oclass" short:"f" description:"default file object class"`
CHints string `long:"hints" short:"h" description:"container hints"`
Properties CreatePropertiesFlag `long:"properties" description:"container properties"`
Mode ConsModeFlag `long:"mode" short:"M" description:"DFS consistency mode"`
ACLFile string `long:"acl-file" short:"A" description:"input file containing ACL"`
User string `long:"user" short:"u" description:"user who will own the container (username@[domain])"`
Group string `long:"group" short:"g" description:"group who will own the container (group@[domain])"`
Args struct {
Label string `positional-arg-name:"label"`
} `positional-args:"yes"`
}
Expand Down Expand Up @@ -300,6 +304,9 @@ func (cmd *containerCreateCmd) Execute(_ []string) (err error) {
if cmd.DirObjectClass.Set {
ap.dir_oclass = cmd.DirObjectClass.Class
}
if cmd.FileObjectClass.Set {
ap.file_oclass = cmd.FileObjectClass.Class
}
if cmd.Mode.Set {
ap.mode = cmd.Mode.Mode
}
Expand Down Expand Up @@ -748,6 +755,9 @@ func printContainerInfo(out io.Writer, ci *containerInfo, verbose bool) error {
if ci.DirObjectClass != "" {
rows = append(rows, txtfmt.TableRow{"Dir Object Class": ci.DirObjectClass})
}
if ci.FileObjectClass != "" {
rows = append(rows, txtfmt.TableRow{"File Object Class": ci.FileObjectClass})
}
if ci.CHints != "" {
rows = append(rows, txtfmt.TableRow{"Hints": ci.CHints})
}
Expand All @@ -772,6 +782,7 @@ type containerInfo struct {
Type string `json:"container_type"`
ObjectClass string `json:"object_class,omitempty"`
DirObjectClass string `json:"dir_object_class,omitempty"`
FileObjectClass string `json:"file_object_class,omitempty"`
CHints string `json:"hints,omitempty"`
ChunkSize uint64 `json:"chunk_size,omitempty"`
}
Expand Down
4 changes: 3 additions & 1 deletion src/include/daos_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ typedef struct {
uint64_t da_id;
/** Default Chunk size for all files in container */
daos_size_t da_chunk_size;
/** Default Object Class for all files in the container */
/** Default Object Class for all objects in the container */
daos_oclass_id_t da_oclass_id;
/** DAOS properties on the DFS container */
daos_prop_t *da_props;
Expand All @@ -74,6 +74,8 @@ typedef struct {
uint32_t da_mode;
/** Default Object Class for all directories in the container */
daos_oclass_id_t da_dir_oclass_id;
/** Default Object Class for all files in the container */
daos_oclass_id_t da_file_oclass_id;
/**
* Comma separated hints for POSIX container creation of the format: "type:hint".
* examples include: "file:single,dir:max", "directory:single,file:max", etc.
Expand Down
4 changes: 3 additions & 1 deletion src/include/daos_uns.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ enum {
struct duns_attr_t {
/** IN/OUT: Container layout (POSIX, HDF5, Python, etc.) */
daos_cont_layout_t da_type;
/** IN: (Optional) For a POSIX container, set a default object class for all files. */
/** IN: (Optional) For a POSIX container, set a default object class for all objects. */
daos_oclass_id_t da_oclass_id;
/** IN: (Optional) For a POSIX container, set a default chunk size for all files. */
daos_size_t da_chunk_size;
Expand Down Expand Up @@ -116,6 +116,8 @@ struct duns_attr_t {
uuid_t da_cuuid;
/** IN: (Optional) For a POSIX container, set a default object class for all directories. */
daos_oclass_id_t da_dir_oclass_id;
/** IN: (Optional) For a POSIX container, set a default object class for all files. */
daos_oclass_id_t da_file_oclass_id;
/** IN: (Optional) For a POSIX container, set hints for file and dir object classes. */
char da_hints[DAOS_CONT_HINT_MAX_LEN];
};
Expand Down
2 changes: 2 additions & 0 deletions src/utils/daos_hdlr.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ cont_create_hdlr(struct cmd_args_s *ap)
attr.da_id = 0;
attr.da_oclass_id = ap->oclass;
attr.da_dir_oclass_id = ap->dir_oclass;
attr.da_file_oclass_id = ap->file_oclass;
attr.da_chunk_size = ap->chunk_size;
attr.da_props = ap->props;
attr.da_mode = ap->mode;
Expand Down Expand Up @@ -615,6 +616,7 @@ cont_create_uns_hdlr(struct cmd_args_s *ap)
dattr.da_type = ap->type;
dattr.da_oclass_id = ap->oclass;
dattr.da_dir_oclass_id = ap->dir_oclass;
dattr.da_file_oclass_id = ap->file_oclass;
dattr.da_chunk_size = ap->chunk_size;
if (ap->hints)
strncpy(dattr.da_hints, ap->hints, DAOS_CONT_HINT_MAX_LEN - 1);
Expand Down
1 change: 1 addition & 0 deletions src/utils/daos_hdlr.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ struct cmd_args_s {
daos_cont_layout_t type; /* --type cont type */
daos_oclass_id_t oclass; /* --oclass object class */
daos_oclass_id_t dir_oclass; /* --dir_oclass object class */
daos_oclass_id_t file_oclass; /* --file_oclass object class */
uint32_t mode; /* --posix consistency mode */
char *hints; /* --posix hints */
daos_size_t chunk_size; /* --chunk_size of cont objs */
Expand Down
8 changes: 6 additions & 2 deletions utils/node_local_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1437,6 +1437,7 @@ def create_cont(conf,
path=None,
oclass=None,
dir_oclass=None,
file_oclass=None,
hints=None,
valgrind=False,
log_check=True,
Expand Down Expand Up @@ -1464,6 +1465,9 @@ def create_cont(conf,
if dir_oclass:
cmd.extend(['--dir_oclass', dir_oclass])

if file_oclass:
cmd.extend(['--file_oclass', file_oclass])

if hints:
cmd.extend(['--hints', hints])

Expand Down Expand Up @@ -1694,7 +1698,7 @@ def test_oclass(self):
"""Test container object class options"""

container = create_cont(self.conf, self.pool.id(), ctype="POSIX", label='oclass_test',
oclass='S1', dir_oclass='S2')
oclass='S1', dir_oclass='S2', file_oclass='S4')
run_daos_cmd(self.conf,
['container', 'query',
self.pool.id(), container],
Expand Down Expand Up @@ -1724,7 +1728,7 @@ def test_oclass(self):
assert rc.returncode == 0
print(rc)
output = rc.stdout.decode('utf-8')
assert check_dfs_tool_output(output, 'S1', '1048576')
assert check_dfs_tool_output(output, 'S4', '1048576')

if dfuse.stop():
self.fatal_errors = True
Expand Down