How to get the old value when do no operations on containers or leafs?

container demo {
    leaf user {
        type string;
    }   
    leaf pass {
        type string;
    }   
} 

here is my yang model, when config all the values
I print all the log in iter func:

-- VALUE_SET on /demo/pass with (oldv) Empty -> (newv) 2
-- VALUE_SET on /demo/user with (oldv) Empty -> (newv) 1

and then I change the values, I could get the old value,

-- VALUE_SET on /demo/pass with (oldv) 2 -> (newv) b
-- VALUE_SET on /demo/user with (oldv) 1 -> (newv) a

but when no all container (or no certain leaf)
localhost(config)# no demo
localhost(config)# commit

-- DELETED on /demo/pass with (oldv) Empty -> (newv) Empty
-- DELETED on /demo/user with (oldv) Empty -> (newv) Empty

I found the old value was not given, so how could I get the old value in iter callback of cdb_diff_iterate()?

During CDB subscription handling, you can start a session towards CDB_PRE_COMMIT_RUNNING which will allow your code to access what was in CDB before this transaction.

See the confd_lib_cdb(3) man page entry for:
int cdb_start_session(int sock, enum cdb_db_type db);
and CDB_PRE_COMMIT_RUNNING as the value for the “db” parameter.

Thanks for the suggestion. But I have to say sorry that I haven’t described my question clearly.
What I wanna know is that when I do the no operations is the iter able to store the old value in oldv like it does when do the operation of setting new value?

enum cdb_iter_ret (*iter) (confd_hkeypath_t *kp, enum cdb_iter_op op, confd_value_t *oldv,
confd_value_t *newv, void *state)

the following is the code flow:

epoll_handler()
{
    cdb_read_subscription_socket(fd, sub_points, &reslen);
    if (reslen > 0)
    {
        for (i = 0; i < reslen; i++)
        {
             cdb_diff_iterate(subsock, sub_points[i], cdb_iter, ITER_WANT_PREV, NULL);
        }
    }
}

static enum cdb_iter_ret cdb_iter(confd_hkeypath_t *kp, 
                                         enum cdb_iter_op op,
                                         confd_value_t *oldv,
                                         confd_value_t *newv,
                                         void *state)
{
    char xpath[BUFSIZ] = "Empty";
    char nval[BUFSIZ] = "Empty";
    char oval[BUFSIZ] = "Empty";

    if (kp) 
        confd_pp_kpath(xpath, BUFSIZ, kp); 

    if (newv)
        confd_pp_value(nval, BUFSIZ, newv);

    if (oldv)
        confd_pp_value(oval, BUFSIZ, oldv);

    switch (op)
    {
        case MOP_CREATED:
            _DBG("CREATED on %s with (oldv) %s -> (newv) %s\n", xpath, oval, nval);
            break;
        case MOP_DELETED:
            _DBG("DELETED on %s with (oldv) %s -> (newv) %s\n", xpath, oval, nval);
            break;
        case MOP_MODIFIED:
            _DBG("MODIFIED on %s with (oldv) %s -> (newv) %s\n", xpath, oval, nval);
            break;
        case MOP_VALUE_SET:
            _DBG("VALUE_SET on %s with (oldv) %s -> (newv) %s\n", xpath, oval, nval);
            break;
        default:
            printf("should never run here!\n");
            break;
    }
    return ITER_RECURSE;
}

You see, I didn’t start the any session myself, and just called cdb_diff_iterate() with the flag ITER_WANT_PREV, It works well as expected, when I set different value to the leaf,

-- VALUE_SET on /demo/pass with (oldv) 2 -> (newv) b
-- VALUE_SET on /demo/user with (oldv) 1 -> (newv) a

but It seems failed when no operations given, the oldv is Empty

-- DELETED on /demo/pass with (oldv) Empty -> (newv) Empty
-- DELETED on /demo/user with (oldv) Empty -> (newv) Empty

Do I have the call cdb_start_session(readsock, CDB_PRE_COMMIT_RUNNING) on readsock,with db type CDB_PRE_COMMIT_RUNNING, and get the old value myself?

You don’t get their old values when leafs are getting deleted. You will need to start a new CDB session towards CDB_PRE_COMMIT_RUNNING in order to read the old value.

However this was recently identified as a bug, and has been fixed - will be included in upcoming releases. From CHANGES-to-be:

If a leaf was deleted, the old value was not provided
in the MOP_DELETED invocation of the iter() function
for cdb_diff_iterate(). This has been fixed.

Thanks for the adaptable solution, I’ll try it.

It’s a good news, but I wanna know what and when will the fixed version be released? I‘m looking forward to it.

The fix will first be available in an upcoming minor release for ConfD Premium. The same fix will be available in the next ConfD Basic release. The tentative target date for the next ConfD Basic release is in the June 2016 time frame.