error "failed to pcc pin $file"
do_facet $SINGLEAGT getfattr $file -d -m $xattrname
xattrvalue=$(do_facet $SINGLEAGT getfattr $file -d -m $xattrname --only-values)
- [[ "$xattrvalue" =~ "hsm: $HSM_ARCHIVE_NUMBER" ]] ||
+ [[ "$xattrvalue" =~ "{\"hsm\":$HSM_ARCHIVE_NUMBER}" ]] ||
error "incorrect xattr $xattrname=$xattrvalue"
# pin with id=100
error "failed to pcc pin $file"
do_facet $SINGLEAGT getfattr $file -d -m $xattrname
xattrvalue=$(do_facet $SINGLEAGT getfattr $file -d -m $xattrname --only-values)
- [[ "$xattrvalue" =~ "hsm: $HSM_ARCHIVE_NUMBER" &&
- "$xattrvalue" =~ "hsm: 100" ]] ||
+ [[ "$xattrvalue" =~ "{\"hsm\":$HSM_ARCHIVE_NUMBER}" &&
+ "$xattrvalue" =~ "{\"hsm\":100}" ]] ||
error "incorrect xattr $xattrname=$xattrvalue"
# pin with id=2 again to check if duplicate entries added
error "failed to pcc unpin $file"
do_facet $SINGLEAGT getfattr $file -d -m $xattrname
xattrvalue=$(do_facet $SINGLEAGT getfattr $file -d -m $xattrname --only-values)
- [[ "$xattrvalue" =~ "hsm: $HSM_ARCHIVE_NUMBER" ]] ||
+ [[ "$xattrvalue" =~ "{\"hsm\":$HSM_ARCHIVE_NUMBER}" ]] ||
error "incorrect xattr $xattrname=$xattrvalue"
# unpin id=2
xattrvalue=$(do_facet $SINGLEAGT getfattr $file -d -m $xattrname --only-values)
[[ -z "$xattrvalue" ]] || error "incorrect xattr $xattrname=$xattrvalue"
+ # set the xattr with unknown element
+ do_facet $SINGLEAGT setfattr $file -n trusted.pin -v '[{\\\"pool\\\":\\\"ddn_ssd\\\"}]' ||
+ error "failed to set xattr"
+ do_facet $SINGLEAGT getfattr $file -d -m $xattrname
+ # pin with id=2
+ do_facet $SINGLEAGT $LFS pcc pin -i $HSM_ARCHIVE_NUMBER $file ||
+ error "failed to pcc pin $file"
+ do_facet $SINGLEAGT getfattr $file -d -m $xattrname
+ xattrvalue=$(do_facet $SINGLEAGT getfattr $file -d -m $xattrname --only-values)
+ [[ "$xattrvalue" =~ "{\"hsm\":$HSM_ARCHIVE_NUMBER}" ]] ||
+ error "incorrect xattr $xattrname=$xattrvalue"
+ # unpin id=2
+ do_facet $SINGLEAGT $LFS pcc unpin -i $HSM_ARCHIVE_NUMBER $file ||
+ error "failed to pcc unpin $file"
+ do_facet $SINGLEAGT getfattr $file -d -m $xattrname
+ xattrvalue=$(do_facet $SINGLEAGT getfattr $file -d -m $xattrname --only-values)
+ [[ "$xattrvalue" =~ "{\"hsm\":$HSM_ARCHIVE_NUMBER}" ]] &&
+ error "incorrect xattr $xattrname=$xattrvalue"
+
# pin/unpin operation should NOT trigger autocache
check_lpcc_state $file "none"
do_facet $SINGLEAGT $LFS pcc pin $file || error "failed to pin $file"
do_facet $SINGLEAGT getfattr $file -n $xattrname
xattrvalue=$(do_facet $SINGLEAGT getfattr $file -n $xattrname --only-values)
- [[ "$xattrvalue" =~ "hsm: $HSM_ARCHIVE_NUMBER" ]] ||
+ [[ "$xattrvalue" =~ "{\"hsm\":$HSM_ARCHIVE_NUMBER}" ]] ||
error "incorrect xattr $xattrname=$xattrvalue"
do_facet $SINGLEAGT $LFS pcc unpin $file || error "failed to PCC unpin $file"
error "failed to attach $file with --pin option"
check_lpcc_state $file "readonly"
xattrvalue=$(do_facet $SINGLEAGT getfattr $file -n $xattrname --only-values)
- [[ "$xattrvalue" =~ "hsm: $HSM_ARCHIVE_NUMBER" ]] ||
+ [[ "$xattrvalue" =~ "{\"hsm\":$HSM_ARCHIVE_NUMBER}" ]] ||
error "incorrect xattr $xattrname=$xattrvalue"
# attach_fid --pin without archive id
error "failed to attach fid $fid with --pin option"
check_lpcc_state $file "readonly"
xattrvalue=$(do_facet $SINGLEAGT getfattr $file -n $xattrname --only-values)
- [[ "$xattrvalue" =~ "hsm: $HSM_ARCHIVE_NUMBER" ]] ||
+ [[ "$xattrvalue" =~ "{\"hsm\":$HSM_ARCHIVE_NUMBER}" ]] ||
error "incorrect xattr $xattrname=$xattrvalue"
}
run_test 204c "attach/attach_fid with --pin option"
endif
endif # UTILS
+LIBLUSTREAPI = liblustreapi.la -ljson-c
lib_LIBRARIES =
noinst_LIBRARIES =
if LDISKFS_ENABLED
if SERVER
lctl_SOURCES += lustre_lfsck.c lsnapshot.c
endif
-lctl_LDADD := liblustreapi.la $(PTHREAD_LIBS) -lyaml
+lctl_LDADD := $(LIBLUSTREAPI) $(PTHREAD_LIBS) -lyaml
lctl_DEPENDENCIES := liblustreapi.la
lfs_SOURCES = lfs.c lfs_project.c lfs_project.h
lfs_CFLAGS := -fPIC $(AM_CFLAGS) -I $(top_builddir)/lnet/utils
-lfs_LDADD := liblustreapi.la -lz
+lfs_LDADD := $(LIBLUSTREAPI) -lz
lfs_LDADD += $(top_builddir)/lnet/utils/lnetconfig/liblnetconfig.la
lfs_DEPENDENCIES := liblustreapi.la
lustre_rsync_SOURCES = lustre_rsync.c lustre_rsync.h callvpe.c callvpe.h
-lustre_rsync_LDADD := liblustreapi.la $(PTHREAD_LIBS)
+lustre_rsync_LDADD := $(LIBLUSTREAPI) $(PTHREAD_LIBS)
lustre_rsync_DEPENDENCIES := liblustreapi.la
-llsom_sync_LDADD := liblustreapi.la
+llsom_sync_LDADD := $(LIBLUSTREAPI)
llsom_sync_DEPENDENCIES := liblustreapi.la
lshowmount_SOURCES = lshowmount.c nidlist.c nidlist.h
-lshowmount_LDADD := liblustreapi.la
+lshowmount_LDADD := $(LIBLUSTREAPI)
if EXT2FS_DEVEL
EXT2FSLIB = -lext2fs
endif # UTILS
llog_reader_SOURCES = llog_reader.c
-llog_reader_LDADD := liblustreapi.la
+llog_reader_LDADD := $(LIBLUSTREAPI)
llog_reader_DEPENDENCIES := liblustreapi.la
lr_reader_SOURCES = lr_reader.c
l_getidentity_DEPENDENCIES := $(top_builddir)/libcfs/libcfs/libcfs.la
lhsmtool_posix_SOURCES = lhsmtool_posix.c pid_file.c pid_file.h
-lhsmtool_posix_LDADD := liblustreapi.la $(PTHREAD_LIBS) \
+lhsmtool_posix_LDADD := $(LIBLUSTREAPI) $(PTHREAD_LIBS) \
$(top_builddir)/lnet/utils/lnetconfig/liblnetconfig.la
lhsmtool_posix_DEPENDENCIES := liblustreapi.la
l_getsepol_SOURCES = l_getsepol.c
-l_getsepol_LDADD := liblustreapi.la -lcrypto $(SELINUX)
+l_getsepol_LDADD := $(LIBLUSTREAPI) -lcrypto $(SELINUX)
l_getsepol_DEPENDENCIES := liblustreapi.la
wirecheck_SOURCES = wirecheck.c
#include <stdlib.h>
#include <sys/ioctl.h>
#include <lnetconfig/cyaml.h>
+#include <json-c/json.h>
+
#include "lustreapi_internal.h"
#include "libhsm_scanner.h"
return rc;
}
-#define PIN_YAML_HSM_STR "hsm"
+#define PIN_JSON_HSM_STR "hsm"
-static int verify_pin_xattr_object(struct cYAML *yaml)
+static int verify_pin_xattr_object(struct json_object *obj)
{
- struct cYAML *node = NULL;
+ int i;
+ struct json_object *node = NULL;
- if (yaml->cy_type != CYAML_TYPE_OBJECT)
+ if (!json_object_is_type(obj, json_type_array))
return -EINVAL;
- for (node = yaml->cy_child; node != NULL; node = node->cy_next) {
- if (node->cy_type != CYAML_TYPE_NUMBER)
+ for (i = 0; i < json_object_array_length(obj); i++) {
+ node = json_object_array_get_idx(obj, i);
+ if (!json_object_is_type(node, json_type_object))
return -EINVAL;
}
return 0;
}
-static int dump_pin_object(struct cYAML *yaml, char *buff, int buflen)
+static struct json_object *read_pin_xattr_object(const char *path)
{
- int rc = 0, remained;
- struct cYAML *node;
- char *p = buff;
-
- if (yaml->cy_child == NULL) {
- buff[0] = '\0';
- goto out;
- }
-
- *p++ = '[';
- for(node = yaml->cy_child; node != NULL; node = node->cy_next) {
- if (node != yaml->cy_child)
- *p++ = ',';
-
- remained = buff + buflen - p - 1;
- rc = snprintf(p, remained, "%s: %ld",
- node->cy_string, node->cy_valueint);
- if (rc <= 0) {
- rc = -errno;
- goto out;
- } else if (rc > remained) {
- rc = -EOVERFLOW;
- goto out;
- }
- p += rc;
- }
- *p++ = ']';
- *p = '\0';
-
- rc = 0;
-out:
- return rc;
-}
-
-static struct cYAML *read_pin_xattr_object(const char *path)
-{
- int rc, i;
- struct cYAML *yaml = NULL;
+ int rc;
+ struct json_object *obj = NULL;
char buff[XATTR_SIZE_MAX];
rc = getxattr(path, XATTR_LUSTRE_PIN, buff, sizeof(buff));
if (rc < 0)
goto out;
+ buff[rc] = '\0';
- if (buff[0] != '[' || buff[rc - 1] != ']') {
- llapi_error(LLAPI_MSG_ERROR, EINVAL,
- "invalid pin string '%s'.", buff);
- rc = -EINVAL;
- goto out;
- }
-
- for (i = 0; i < rc; i++)
- if (buff[i] == ',')
- buff[i] = '\n';
-
- yaml = cYAML_build_tree(NULL, buff + 1, rc - 2, NULL, false);
- if (yaml == NULL) {
- llapi_error(LLAPI_MSG_ERROR, EINVAL,
- "invalid pin string '%s'.", buff);
+ obj = json_tokener_parse(buff);
+ if (obj == NULL) {
+ llapi_error(LLAPI_MSG_ERROR, -EINVAL,
+ "failed to parse pin xattr '%s'.", buff);
errno = -EINVAL;
goto out;
}
- rc = verify_pin_xattr_object(yaml);
+ rc = verify_pin_xattr_object(obj);
if (rc) {
- llapi_error(LLAPI_MSG_ERROR, -rc, "Invalid pin object.");
- cYAML_free_tree(yaml);
- yaml = NULL;
+ llapi_error(LLAPI_MSG_ERROR, -rc, "invalid pin object.");
+ json_object_put(obj);
+ obj = NULL;
errno = -rc;
goto out;
}
out:
- return yaml;
+ return obj;
}
int llapi_pcc_pin_file(const char *path, __u32 id)
{
- int rc = 0;
- struct cYAML *yaml, *node;
- char buff[XATTR_SIZE_MAX];
+ int rc = 0, i;
+ struct json_object *obj = NULL, *node, *val;
+ const char *str = NULL;
+ bool found;
- yaml = read_pin_xattr_object(path);
+ obj = read_pin_xattr_object(path);
- if (yaml == NULL && errno == ENODATA) {
- sprintf(buff, "[%s: %d]", PIN_YAML_HSM_STR, id);
- goto set;
+ if (obj == NULL && errno == ENODATA) {
+ obj = json_object_new_array();
+ goto add_entry;
}
- if (yaml == NULL) {
+ if (obj == NULL) {
llapi_error(LLAPI_MSG_ERROR, errno,
"cannot read or parse pin xattr of file '%s'.",
path);
}
/* Now we have an valid pin object, search for existing entry */
- for (node = yaml->cy_child; node != NULL; node = node->cy_next) {
- if (strcmp(node->cy_string, PIN_YAML_HSM_STR) == 0 &&
- node->cy_valueint == id)
+ for (i = 0; i < json_object_array_length(obj); i++) {
+ node = json_object_array_get_idx(obj, i);
+ found = json_object_object_get_ex(node, PIN_JSON_HSM_STR, &val);
+ if (found && json_object_get_int64(val) == id)
break;
}
- if (node != NULL) {
+ /* found existing entry, do nothing and return success */
+ if (i < json_object_array_length(obj)) {
rc = 0;
goto out;
}
- node = cYAML_create_number(yaml, PIN_YAML_HSM_STR, id);
- if (node == NULL) {
- rc = -errno;
- goto out;
- }
-
- rc = dump_pin_object(yaml, buff, sizeof(buff));
- if (rc)
- goto out;
+add_entry:
+ /* add a new entry */
+ node = json_object_new_object();
+ json_object_object_add(node, PIN_JSON_HSM_STR, json_object_new_int64(id));
+ json_object_array_add(obj, node);
+ str = json_object_to_json_string_ext(obj, 0);
-set:
- rc = setxattr(path, XATTR_LUSTRE_PIN, buff, strlen(buff), 0);
+ rc = setxattr(path, XATTR_LUSTRE_PIN, str, strlen(str), 0);
if (rc < 0)
rc = -errno;
out:
+ json_object_put(obj);
return rc;
}
int llapi_pcc_unpin_file(const char *path, __u32 id)
{
- int rc = 0;
- struct cYAML *yaml, *node;
- char buff[XATTR_SIZE_MAX];
+ int rc = 0, i;
+ struct json_object *obj = NULL, *new_obj = NULL, *node, *node2, *val;
+ const char *str;
+ bool found;
- yaml = read_pin_xattr_object(path);
+ obj = read_pin_xattr_object(path);
- if (yaml == NULL && errno == ENODATA) {
+ if (obj == NULL && errno == ENODATA) {
rc = 0;
goto out;
}
- if (yaml == NULL) {
+ if (obj == NULL) {
llapi_error(LLAPI_MSG_ERROR, errno,
"cannot read or parse pin xattr of file '%s'.",
path);
goto out;
}
- /* Now we have an valid pin object, search for the entry to be deleted */
- for (node = yaml->cy_child; node != NULL; node = node->cy_next) {
- if (strcmp(node->cy_string, PIN_YAML_HSM_STR) == 0 &&
- node->cy_valueint == id)
- break;
- }
- if (node == NULL) {
- rc = 0;
- goto out;
+ /* search and delete the entry */
+ new_obj = json_object_new_array();
+ for (i = 0; i < json_object_array_length(obj); i++) {
+ node = json_object_array_get_idx(obj, i);
+ found = json_object_object_get_ex(node, PIN_JSON_HSM_STR, &val);
+ if (found && json_object_get_int64(val) == id)
+ continue;
+ node2 = json_tokener_parse(json_object_to_json_string(node));
+ json_object_array_add(new_obj, node2);
}
- /* Remove the node */
- if (node == yaml->cy_child) {
- /* the first child */
- if (node->cy_next)
- node->cy_next->cy_prev = NULL;
- yaml->cy_child = node->cy_next;
+ if (json_object_array_length(new_obj) == 0) {
+ rc = removexattr(path, XATTR_LUSTRE_PIN);
} else {
- /* not the first child */
- node->cy_prev->cy_next = node->cy_next;
- if (node->cy_next)
- node->cy_next->cy_prev = node->cy_prev;
+ str = json_object_to_json_string_ext(new_obj, 0);
+ rc = setxattr(path, XATTR_LUSTRE_PIN, str, strlen(str), 0);
}
- node->cy_prev = node->cy_next = NULL;
- cYAML_free_tree(node);
-
- rc = dump_pin_object(yaml, buff, sizeof(buff));
- if (rc)
- goto out;
-
- if (strlen(buff) == 0)
- rc = removexattr(path, XATTR_LUSTRE_PIN);
- else
- rc = setxattr(path, XATTR_LUSTRE_PIN, buff, strlen(buff), 0);
if (rc < 0)
rc = -errno;
out:
+ json_object_put(obj);
+ json_object_put(new_obj);
return rc;
}
bool llapi_pcc_is_pinned_file(const char *path, __u32 id)
{
- struct cYAML *yaml, *node;
+ struct json_object *obj, *node, *val;
+ int i;
+ bool found;
- yaml = read_pin_xattr_object(path);
+ obj = read_pin_xattr_object(path);
- if (yaml == NULL && errno == ENODATA) {
+ if (obj == NULL && errno == ENODATA) {
errno = 0;
return false;
}
- if (yaml == NULL) {
+ if (obj == NULL) {
llapi_error(LLAPI_MSG_ERROR, errno,
"cannot read or parse pin xattr of file '%s'.",
path);
}
/* Now we have an valid pin object, search for the entry */
- for (node = yaml->cy_child; node != NULL; node = node->cy_next) {
- if (strcmp(node->cy_string, PIN_YAML_HSM_STR) == 0 &&
- node->cy_valueint == id)
+ for (i = 0; i < json_object_array_length(obj); i++) {
+ node = json_object_array_get_idx(obj, i);
+ found = json_object_object_get_ex(node, PIN_JSON_HSM_STR, &val);
+ if (found && json_object_get_int64(val) == id) {
+ json_object_put(obj);
return true;
+ }
}
+ json_object_put(obj);
errno = 0;
return false;
}