]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
dn2id fixes, slapadd working
authorHoward Chu <hyc@openldap.org>
Fri, 19 Aug 2011 03:29:01 +0000 (20:29 -0700)
committerHoward Chu <hyc@openldap.org>
Fri, 19 Aug 2011 03:29:01 +0000 (20:29 -0700)
servers/slapd/back-mdb/dn2entry.c
servers/slapd/back-mdb/dn2id.c
servers/slapd/back-mdb/init.c
servers/slapd/back-mdb/libmdb
servers/slapd/back-mdb/nextid.c
servers/slapd/back-mdb/proto-mdb.h
servers/slapd/back-mdb/tools.c

index 448593c553841c58018d7fd77b0139d25e1ee37e..e2da3dca9a16c3ee20cc8a560cde09c40690fd41 100644 (file)
@@ -43,13 +43,9 @@ mdb_dn2entry(
 
        *e = NULL;
 
-       rc = mdb_dn2id( op, tid, dn, &id );
+       rc = mdb_dn2id( op, tid, dn, &id, matched );
        if ( rc ) {
                *e = NULL;
-               if ( matched && rc == MDB_NOTFOUND ) {
-                       /* Get the parent's DN */
-                       mdb_id2name( op, tid, id, matched, NULL );
-               }
        } else {
                rc = mdb_id2entry( op, tid, id, e );
        }
index 6f53ec3edd892515cc0ca2ebbff1413f4f443fd7..b18ab47a45be8881d624e9e9c494246888195aa2 100644 (file)
@@ -253,87 +253,99 @@ func_leave:
        return rc;
 }
 
-
+/* return last found ID in *id if no match */
 int
 mdb_dn2id(
        Operation       *op,
        MDB_txn *txn,
        struct berval   *in,
-       ID      *id )
+       ID      *id,
+       struct berval   *matched )
 {
        struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
+       MDB_cursor *cursor;
        MDB_dbi dbi = mdb->mi_dn2id->mdi_dbi;
        MDB_val         key, data;
        int             rc = 0, nrlen;
        diskNode *d;
        char    *ptr;
        unsigned char dlen[2];
-       ID idp, parentID;
+       ID pid, nid;
+       struct berval tmp;
 
-#if 0
        Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2id(\"%s\")\n", in->bv_val, 0, 0 );
 
-       nrlen = dn_rdnlen( op->o_bd, in );
-       if (!nrlen) nrlen = in->bv_len;
+       if ( !in->bv_len ) {
+               *id = 0;
+               nid = 0;
+               goto done;
+       }
 
-       DBTzero(&key);
-       key.size = sizeof(ID);
-       key.data = &idp;
-       key.ulen = sizeof(ID);
-       key.flags = DB_DBT_USERMEM;
-       parentID = ( ei->bei_parent != NULL ) ? ei->bei_parent->bei_id : 0;
-       MDB_ID2DISK( parentID, &idp );
+       tmp = *in;
 
-       DBTzero(&data);
-       data.size = sizeof(diskNode) + nrlen - sizeof(ID) - 1;
-       data.ulen = data.size * 3;
-       data.dlen = data.ulen;
-       data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
+       nrlen = tmp.bv_len - op->o_bd->be_nsuffix[0].bv_len;
+       tmp.bv_val += nrlen;
+       tmp.bv_len = op->o_bd->be_nsuffix[0].bv_len;
+       nid = 0;
+       key.mv_size = sizeof(ID);
 
-       rc = db->cursor( db, txn, cursor, mdb->bi_db_opflags );
+       rc = mdb_cursor_open( txn, dbi, &cursor );
        if ( rc ) return rc;
 
-       d = op->o_tmpalloc( data.size * 3, op->o_tmpmemctx );
-       d->nrdnlen[1] = nrlen & 0xff;
-       d->nrdnlen[0] = (nrlen >> 8) | 0x80;
-       dlen[0] = d->nrdnlen[0];
-       dlen[1] = d->nrdnlen[1];
-       ptr = lutil_strncopy( d->nrdn, in->bv_val, nrlen );
-       *ptr = '\0';
-       data.data = d;
-
-       rc = (*cursor)->c_get( *cursor, &key, &data, DB_GET_BOTH_RANGE );
-       if ( rc == 0 && (dlen[1] != d->nrdnlen[1] || dlen[0] != d->nrdnlen[0] ||
-               strncmp( d->nrdn, in->bv_val, nrlen ))) {
-               rc = DB_NOTFOUND;
-       }
-       if ( rc == 0 ) {
-               ptr = (char *) data.data + data.size - sizeof(ID);
-               MDB_DISK2ID( ptr, &ei->bei_id );
-               ei->bei_rdn.bv_len = data.size - sizeof(diskNode) - nrlen;
-               ptr = d->nrdn + nrlen + 1;
-               ber_str2bv( ptr, ei->bei_rdn.bv_len, 1, &ei->bei_rdn );
-               if ( ei->bei_parent != NULL && !ei->bei_parent->bei_dkids ) {
-                       db_recno_t dkids;
-                       /* How many children does the parent have? */
-                       /* FIXME: do we need to lock the parent
-                        * entryinfo? Seems safe...
-                        */
-                       (*cursor)->c_count( *cursor, &dkids, 0 );
-                       ei->bei_parent->bei_dkids = dkids;
+       for (;;) {
+               key.mv_data = &pid;
+               pid = nid;
+
+               data.mv_size = sizeof(diskNode) + tmp.bv_len;
+               d = op->o_tmpalloc( data.mv_size, op->o_tmpmemctx );
+               d->nrdnlen[1] = tmp.bv_len & 0xff;
+               d->nrdnlen[0] = (tmp.bv_len >> 8) | 0x80;
+               ptr = lutil_strncopy( d->nrdn, tmp.bv_val, tmp.bv_len );
+               *ptr = '\0';
+               data.mv_data = d;
+               rc = mdb_cursor_get( cursor, &key, &data, MDB_GET_BOTH );
+               if ( rc == MDB_NOTFOUND ) {
+                       if ( matched ) {
+                               int len;
+                               matched->bv_val = tmp.bv_val + tmp.bv_len + 1;
+                               len = in->bv_len - ( matched->bv_val - in->bv_val );
+                               if ( len <= 0 ) {
+                                       BER_BVZERO( matched );
+                               } else {
+                                       matched->bv_len = len;
+                               }
+                       }
+               }
+               op->o_tmpfree( d, op->o_tmpmemctx );
+               if ( rc ) {
+                       mdb_cursor_close( cursor );
+                       break;
+               }
+               ptr = (char *) data.mv_data + data.mv_size - sizeof(ID);
+               memcpy( &nid, ptr, sizeof(ID));
+               if ( tmp.bv_val > in->bv_val ) {
+                       for (ptr = tmp.bv_val - 2; ptr > in->bv_val &&
+                               !DN_SEPARATOR(*ptr); ptr--)     /* empty */;
+                       if ( ptr >= in->bv_val ) {
+                               if (DN_SEPARATOR(*ptr)) ptr++;
+                               tmp.bv_len = tmp.bv_val - ptr - 1;
+                               tmp.bv_val = ptr;
+                       }
+               } else {
+                       break;
                }
        }
+       *id = nid; 
 
-       op->o_tmpfree( d, op->o_tmpmemctx );
+done:
        if( rc != 0 ) {
                Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id: get failed: %s (%d)\n",
-                       db_strerror( rc ), rc, 0 );
+                       mdb_strerror( rc ), rc, 0 );
        } else {
                Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id: got id=0x%lx\n",
-                       ei->bei_id, 0, 0 );
+                       nid, 0, 0 );
        }
 
-#endif
        return rc;
 }
 
index f3dbe6751b6f8efa6f8e1d97e4f22b8fbac49e32..e51b34bd6217198ccb224114ec5f2bef9489eb4f 100644 (file)
@@ -217,6 +217,9 @@ mdb_db_open( BackendDB *be, ConfigReply *cr )
                        goto fail;
                }
 
+               if ( i == MDB_DN2ID )
+                       mdb_set_dupsort( txn, db->mdi_dbi, mdb_dup_compare );
+
                db->mdi_name = mdmi_databases[i];
                mdb->mi_databases[i] = db;
        }
index 319a976a50058efc6232eb240c929850ed583671..aa436167624c27c74dc8559a9e0b40d318bdba86 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 319a976a50058efc6232eb240c929850ed583671
+Subproject commit aa436167624c27c74dc8559a9e0b40d318bdba86
index b62ad15c03f8e0423fd33079bf89da2aac50cd41..e98ca0cf46ff51d25571dea6913032937eac10c2 100644 (file)
@@ -43,7 +43,7 @@ int mdb_next_id( BackendDB *be, MDB_txn *tid, ID *out )
                *out = 1;
                break;
        case 0:
-               memcpy( key.mv_data, &id, sizeof( id ));
+               memcpy( &id, key.mv_data, sizeof( id ));
                *out = ++id;
                break;
 
index 6b62482f2d8aa8c2d0af2fcc009725e30522d053..2942ff3bddf4610cfa34dad65694a96339754af1 100644 (file)
@@ -74,7 +74,8 @@ int mdb_dn2id(
        Operation *op,
        MDB_txn *txn,
        struct berval *dn,
-       ID *id );
+       ID *id,
+       struct berval *matched );
 
 int mdb_dn2id_add(
        Operation *op,
index 4b9e6e73a9df456a90b1bdcd45a06a96b649190c..1d8a19379ef267ec1970e3f604eeb45e4a069050 100644 (file)
@@ -245,7 +245,7 @@ ID mdb_tool_dn2id_get(
        op.o_tmpmemctx = NULL;
        op.o_tmpmfuncs = &ch_mfuncs;
 
-       rc = mdb_dn2id( &op, txn, dn, &id );
+       rc = mdb_dn2id( &op, txn, dn, &id, NULL );
        if ( rc == MDB_NOTFOUND )
                return NOID;
        
@@ -344,8 +344,8 @@ static int mdb_tool_next_id(
 {
        struct berval dn = e->e_name;
        struct berval ndn = e->e_nname;
-       struct berval pdn, npdn;
-       ID id, pid;
+       struct berval pdn, npdn, matched;
+       ID id, pid = 0;
        int rc;
 
        if (ndn.bv_len == 0) {
@@ -353,26 +353,30 @@ static int mdb_tool_next_id(
                return 0;
        }
 
-       rc = mdb_dn2id( op, tid, &ndn, &id );
+       rc = mdb_dn2id( op, tid, &ndn, &id, &matched );
        if ( rc == MDB_NOTFOUND ) {
                if ( !be_issuffix( op->o_bd, &ndn ) ) {
                        ID eid = e->e_id;
-                       dnParent( &dn, &pdn );
                        dnParent( &ndn, &npdn );
-                       e->e_name = pdn;
-                       e->e_nname = npdn;
-                       rc = mdb_tool_next_id( op, tid, e, text, 1 );
-                       e->e_name = dn;
-                       e->e_nname = ndn;
-                       if ( rc ) {
-                               return rc;
-                       }
-                       /* If parent didn't exist, it was created just now
-                        * and its ID is now in e->e_id. Make sure the current
-                        * entry gets added under the new parent ID.
-                        */
-                       if ( eid != e->e_id ) {
-                               pid = e->e_id;
+                       if ( matched.bv_len != npdn.bv_len ) {
+                               dnParent( &dn, &pdn );
+                               e->e_name = pdn;
+                               e->e_nname = npdn;
+                               rc = mdb_tool_next_id( op, tid, e, text, 1 );
+                               e->e_name = dn;
+                               e->e_nname = ndn;
+                               if ( rc ) {
+                                       return rc;
+                               }
+                               /* If parent didn't exist, it was created just now
+                                * and its ID is now in e->e_id. Make sure the current
+                                * entry gets added under the new parent ID.
+                                */
+                               if ( eid != e->e_id ) {
+                                       pid = e->e_id;
+                               }
+                       } else {
+                               pid = id;
                        }
                }
                rc = mdb_next_id( op->o_bd, tid, &e->e_id );