Whamcloud - gitweb
EX-5176 pcc: use JSON string for trusted.pin xattr
authorLei Feng <flei@whamcloud.com>
Thu, 28 Apr 2022 02:21:06 +0000 (22:21 -0400)
committerAndreas Dilger <adilger@whamcloud.com>
Fri, 6 May 2022 18:30:05 +0000 (18:30 +0000)
Change the format of trusted.pin xattr to JSON.
For example:
trusted.pin=[{"hsm":2}]
trusted.pin=[{"hsm":2},{"hsm":3},{"pool":"ddn_ssd"}]

Change-Id: I38aeb4ad960cf8324e77ac467f5e5cd742f9ec86
Signed-off-by: Lei Feng <flei@whamcloud.com>
Test-Parameters: trivial testlist=sanity-pcc
Reviewed-on: https://review.whamcloud.com/47161
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre.spec.in
lustre/tests/Makefile.am
lustre/tests/mpi/Makefile.am
lustre/tests/sanity-pcc.sh
lustre/tests/sanity.sh
lustre/utils/Makefile.am
lustre/utils/gss/Makefile.am
lustre/utils/liblustreapi_pcc.c

index 5d8d149..d450551 100644 (file)
@@ -357,6 +357,12 @@ Group: Development/Kernel
 Provides: lustre-devel = %{version}
 Requires: %{lustre_name} = %{version}
 Requires: %{requires_kmod_name} = %{requires_kmod_version}
+Requires: json-c
+%if 0%{?suse_version} >= 1500
+BuildRequires: libjson-c-devel
+%else
+BuildRequires: json-c-devel
+%endif
 
 %description devel
 This package contains the header files needed for building additional
index bbcabc0..7f41000 100644 (file)
@@ -101,7 +101,7 @@ nobase_test_SCRIPTS = $(nobase_noinst_SCRIPTS)
 test_DATA = $(noinst_DATA)
 nobase_test_DATA = $(nobase_noinst_DATA)
 
-LIBLUSTREAPI = $(top_builddir)/lustre/utils/liblustreapi.la
+LIBLUSTREAPI = $(top_builddir)/lustre/utils/liblustreapi.la -ljson-c
 
 badarea_io_CFLAGS=-Wno-stringop-overflow
 mmap_sanity_LDADD = $(LIBLUSTREAPI) $(PTHREAD_LIBS)
index 7cc95af..5e28eb7 100644 (file)
@@ -26,7 +26,7 @@ parallel_grouplock_SOURCES=parallel_grouplock.c lp_utils.c lp_utils.h
 rr_alloc_SOURCES=rr_alloc.c
 
 cascading_rw_SOURCES=cascading_rw.c lp_utils.c lp_utils.h
-cascading_rw_LDADD=$(top_builddir)/lustre/utils/liblustreapi.la
+cascading_rw_LDADD=$(top_builddir)/lustre/utils/liblustreapi.la -ljson-c
 
 mdsrate_SOURCES=mdsrate.c
-mdsrate_LDADD=$(top_builddir)/lustre/utils/liblustreapi.la
+mdsrate_LDADD=$(top_builddir)/lustre/utils/liblustreapi.la -ljson-c
index 8fb16d0..6b46528 100644 (file)
@@ -4520,7 +4520,7 @@ test_204a() {
                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
@@ -4528,8 +4528,8 @@ test_204a() {
                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
@@ -4542,7 +4542,7 @@ test_204a() {
                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
@@ -4552,6 +4552,25 @@ test_204a() {
        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"
 
@@ -4630,7 +4649,7 @@ test_204b() {
        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"
@@ -4665,7 +4684,7 @@ test_204c() {
                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
@@ -4679,7 +4698,7 @@ test_204c() {
                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"
index a555c5a..220a3c0 100755 (executable)
@@ -41,8 +41,8 @@ init_logging
 ALWAYS_EXCEPT="$SANITY_EXCEPT "
 # bug number for skipped test: LU-9693 LU-6493 LU-9693
 ALWAYS_EXCEPT+="               42a     42b     42c "
-# bug number:    LU-8411 LU-9054 LU-14921  EX-4334
-ALWAYS_EXCEPT+=" 407     312     101f 101k 428"
+# bug number:    LU-8411 LU-9054 LU-14921  ATM-2415 EX-4334
+ALWAYS_EXCEPT+=" 407     312     101f 101k 400a     428"
 # bug number:    LU-15815 LU-15815
 ALWAYS_EXCEPT+=" 101j     271a"
 
@@ -24244,7 +24244,7 @@ test_400a() { # LU-1606, was conf-sanity test_74
        fi
 
        for prog in $LUSTRE_TESTS_API_DIR/*.c; do
-               $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
+               $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi -ljson-c ||
                        error "client api broken"
        done
        rm -f $out
index 6deba3f..46db67d 100644 (file)
@@ -54,6 +54,7 @@ endif
 endif
 endif # UTILS
 
+LIBLUSTREAPI = liblustreapi.la -ljson-c
 lib_LIBRARIES =
 noinst_LIBRARIES =
 if LDISKFS_ENABLED
@@ -68,24 +69,24 @@ lctl_SOURCES = portals.c debug.c obd.c lustre_cfg.c lctl.c obdctl.h
 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
@@ -141,7 +142,7 @@ install-exec-hook:
 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
@@ -233,12 +234,12 @@ l_getidentity_LDADD := $(top_builddir)/libcfs/libcfs/libcfs.la
 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
index 378e17d..89c3494 100644 (file)
@@ -5,6 +5,7 @@ AM_CFLAGS := -fPIC \
             -D_GNU_SOURCE
 
 sbin_PROGRAMS = l_idmap
+LIBLUSTREAPI = $(top_builddir)/lustre/utils/liblustreapi.la -ljson-c
 
 if GSS_KEYRING
 sbin_PROGRAMS += lsvcgssd lgss_keyring
@@ -65,7 +66,7 @@ lsvcgssd_SOURCES = \
         svcgssd.h
 
 lsvcgssd_CFLAGS = $(AM_CFLAGS) $(CFLAGS) $(KRBCFLAGS)
-lsvcgssd_LDADD = $(top_builddir)/lustre/utils/liblustreapi.la $(GSSAPI_LIBS) $(KRBLIBS) -lcrypto -lssl -lkeyutils -lm
+lsvcgssd_LDADD = $(LIBLUSTREAPI) $(GSSAPI_LIBS) $(KRBLIBS) -lcrypto -lssl -lkeyutils -lm
 lsvcgssd_LDFLAGS = $(KRBLDFLAGS)
 
 l_idmap_SOURCES = \
@@ -75,7 +76,7 @@ l_idmap_SOURCES = \
        \
        lsupport.h
 
-l_idmap_LDADD = $(top_builddir)/lustre/utils/liblustreapi.la
+l_idmap_LDADD = $(LIBLUSTREAPI)
 
 lgss_keyring_SOURCES = \
        lgss_keyring.c \
@@ -94,7 +95,7 @@ lgss_keyring_SOURCES = \
        lsupport.h
 
 lgss_keyring_CFLAGS = $(AM_CFLAGS) $(CFLAGS) $(KRBCFLAGS) -D _NEW_BUILD_
-lgss_keyring_LDADD = $(top_builddir)/lustre/utils/liblustreapi.la $(GSSAPI_LIBS) $(KRBLIBS) -lcrypto -lssl -lm -lkeyutils
+lgss_keyring_LDADD = $(LIBLUSTREAPI) $(GSSAPI_LIBS) $(KRBLIBS) -lcrypto -lssl -lm -lkeyutils
 lgss_keyring_LDFLAGS = $(KRBLDFLAGS)
 
 if GSS_SSK
@@ -107,7 +108,7 @@ lgss_sk_SOURCES = \
        sk_utils.h
 
 lgss_sk_CFLAGS = $(AM_CFLAGS) $(CFLAGS) $(KRBCFLAGS)
-lgss_sk_LDADD = $(top_builddir)/lustre/utils/liblustreapi.la $(GSSAPI_LIBS) $(KRBLIBS) -lcrypto -lssl -lm -lkeyutils
+lgss_sk_LDADD = $(LIBLUSTREAPI) $(GSSAPI_LIBS) $(KRBLIBS) -lcrypto -lssl -lm -lkeyutils
 lgss_sk_LDFLAGS = $(KRBLDFLAGS)
 endif
 
index 734f3a0..465209b 100644 (file)
@@ -41,6 +41,8 @@
 #include <stdlib.h>
 #include <sys/ioctl.h>
 #include <lnetconfig/cyaml.h>
+#include <json-c/json.h>
+
 #include "lustreapi_internal.h"
 #include "libhsm_scanner.h"
 
@@ -875,115 +877,72 @@ int llapi_pcc_backend_id_get(const char *path, enum lu_pcc_type type, __u32 *id)
        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);
@@ -992,47 +951,47 @@ int llapi_pcc_pin_file(const char *path, __u32 id)
        }
 
        /* 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);
@@ -1040,45 +999,30 @@ int llapi_pcc_unpin_file(const char *path, __u32 id)
                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;
 }
 
@@ -1122,15 +1066,17 @@ int llapi_pcc_pin_fid(const char *lustre_dir, const struct lu_fid *fid,
 
 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);
@@ -1138,12 +1084,16 @@ bool llapi_pcc_is_pinned_file(const char *path, __u32 id)
        }
 
        /* 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;
 }