Ignore:
Timestamp:
Apr 9, 2010, 3:20:58 PM (15 years ago)
Author:
Silvan Scherrer
Message:

Samba 3.5.x: update to 3.5.2

Location:
vendor/current/source3/lib
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/lib/ctdbd_conn.c

    r414 r427  
    362362                }
    363363
    364                 if (msg->srvid == CTDB_SRVID_RECONFIGURE) {
    365                         DEBUG(0,("Got cluster reconfigure message in ctdb_read_req\n"));
     364                if ((msg->srvid == CTDB_SRVID_RECONFIGURE)
     365                    || (msg->srvid == CTDB_SRVID_SAMBA_NOTIFY)) {
     366
     367                        DEBUG(1, ("ctdb_read_req: Got %s message\n",
     368                                  (msg->srvid == CTDB_SRVID_RECONFIGURE)
     369                                  ? "cluster reconfigure" : "SAMBA_NOTIFY"));
     370
    366371                        messaging_send(conn->msg_ctx, procid_self(),
    367372                                       MSG_SMB_BRL_VALIDATE, &data_blob_null);
     373                        messaging_send(conn->msg_ctx, procid_self(),
     374                                       MSG_DBWRAP_G_LOCK_RETRY,
     375                                       &data_blob_null);
    368376                        TALLOC_FREE(hdr);
    369377                        goto next_pkt;
     
    494502        }
    495503
     504        status = register_with_ctdbd(conn, CTDB_SRVID_SAMBA_NOTIFY);
     505        if (!NT_STATUS_IS_OK(status)) {
     506                goto fail;
     507        }
     508
    496509        *pconn = conn;
    497510        return NT_STATUS_OK;
     
    500513        TALLOC_FREE(conn);
    501514        return status;
     515}
     516
     517struct messaging_context *ctdb_conn_msg_ctx(struct ctdbd_connection *conn)
     518{
     519        return conn->msg_ctx;
     520}
     521
     522int ctdbd_conn_get_fd(struct ctdbd_connection *conn)
     523{
     524        return packet_get_fd(conn->pkt);
    502525}
    503526
     
    534557        SMB_ASSERT(conn->msg_ctx != NULL);
    535558
    536         if (msg->srvid == CTDB_SRVID_RECONFIGURE) {
     559        if ((msg->srvid == CTDB_SRVID_RECONFIGURE)
     560            || (msg->srvid == CTDB_SRVID_SAMBA_NOTIFY)){
    537561                DEBUG(0,("Got cluster reconfigure message\n"));
    538562                /*
    539                  * when the cluster is reconfigured, we need to clean the brl
    540                  * database
     563                 * when the cluster is reconfigured or someone of the
     564                 * family has passed away (SAMBA_NOTIFY), we need to
     565                 * clean the brl database
    541566                 */
    542567                messaging_send(conn->msg_ctx, procid_self(),
    543568                               MSG_SMB_BRL_VALIDATE, &data_blob_null);
    544569
    545                 /*
    546                  * it's possible that we have just rejoined the cluster after
    547                  * an outage. In that case our pending locks could have been
    548                  * removed from the lockdb, so retry them once more
    549                  */
    550                 message_send_all(conn->msg_ctx, MSG_SMB_UNLOCK, NULL, 0, NULL);
     570                messaging_send(conn->msg_ctx, procid_self(),
     571                               MSG_DBWRAP_G_LOCK_RETRY,
     572                               &data_blob_null);
    551573
    552574                TALLOC_FREE(buf);
    553 
    554575                return NT_STATUS_OK;
    555576        }
     
    13111332}
    13121333
     1334NTSTATUS ctdb_watch_us(struct ctdbd_connection *conn)
     1335{
     1336        struct ctdb_client_notify_register reg_data;
     1337        size_t struct_len;
     1338        NTSTATUS status;
     1339        int cstatus;
     1340
     1341        reg_data.srvid = CTDB_SRVID_SAMBA_NOTIFY;
     1342        reg_data.len = 1;
     1343        reg_data.notify_data[0] = 0;
     1344
     1345        struct_len = offsetof(struct ctdb_client_notify_register,
     1346                              notify_data) + reg_data.len;
     1347
     1348        status = ctdbd_control_local(
     1349                conn, CTDB_CONTROL_REGISTER_NOTIFY, conn->rand_srvid, 0,
     1350                make_tdb_data((uint8_t *)&reg_data, struct_len),
     1351                NULL, NULL, &cstatus);
     1352        if (!NT_STATUS_IS_OK(status)) {
     1353                DEBUG(1, ("ctdbd_control_local failed: %s\n",
     1354                          nt_errstr(status)));
     1355        }
     1356        return status;
     1357}
     1358
     1359NTSTATUS ctdb_unwatch(struct ctdbd_connection *conn)
     1360{
     1361        struct ctdb_client_notify_deregister dereg_data;
     1362        NTSTATUS status;
     1363        int cstatus;
     1364
     1365        dereg_data.srvid = CTDB_SRVID_SAMBA_NOTIFY;
     1366
     1367        status = ctdbd_control_local(
     1368                conn, CTDB_CONTROL_DEREGISTER_NOTIFY, conn->rand_srvid, 0,
     1369                make_tdb_data((uint8_t *)&dereg_data, sizeof(dereg_data)),
     1370                NULL, NULL, &cstatus);
     1371        if (!NT_STATUS_IS_OK(status)) {
     1372                DEBUG(1, ("ctdbd_control_local failed: %s\n",
     1373                          nt_errstr(status)));
     1374        }
     1375        return status;
     1376}
     1377
    13131378#else
    13141379
  • vendor/current/source3/lib/dbwrap_ctdb.c

    r414 r427  
    22   Unix SMB/CIFS implementation.
    33   Database interface wrapper around ctdbd
    4    Copyright (C) Volker Lendecke 2007
     4   Copyright (C) Volker Lendecke 2007-2009
     5   Copyright (C) Michael Adam 2009
    56
    67   This program is free software; you can redistribute it and/or modify
     
    2324#include "ctdb_private.h"
    2425#include "ctdbd_conn.h"
     26#include "g_lock.h"
    2527
    2628struct db_ctdb_transaction_handle {
    2729        struct db_ctdb_ctx *ctx;
    28         bool in_replay;
    2930        /*
    3031         * we store the reads and writes done under a transaction:
     
    3637        uint32_t nesting;
    3738        bool nested_cancel;
     39        char *lock_name;
    3840};
    3941
     
    4345        uint32 db_id;
    4446        struct db_ctdb_transaction_handle *transaction;
     47        struct g_lock_ctx *lock_ctx;
    4548};
    4649
     
    4952        struct ctdb_ltdb_header header;
    5053};
    51 
    52 static struct db_record *fetch_locked_internal(struct db_ctdb_ctx *ctx,
    53                                                TALLOC_CTX *mem_ctx,
    54                                                TDB_DATA key,
    55                                                bool persistent);
    5654
    5755static NTSTATUS tdb_error_to_ntstatus(struct tdb_context *tdb)
     
    298296}
    299297
    300 
    301 static int32_t db_ctdb_transaction_active(uint32_t db_id)
    302 {
    303         int32_t status;
    304         NTSTATUS ret;
    305         TDB_DATA indata;
    306 
    307         indata.dptr = (uint8_t *)&db_id;
    308         indata.dsize = sizeof(db_id);
    309 
    310         ret = ctdbd_control_local(messaging_ctdbd_connection(),
    311                                   CTDB_CONTROL_TRANS2_ACTIVE, 0, 0,
    312                                   indata, NULL, NULL, &status);
    313 
    314         if (!NT_STATUS_IS_OK(ret)) {
    315                 DEBUG(2, ("ctdb control TRANS2_ACTIVE failed\n"));
    316                 return -1;
    317         }
    318 
    319         return status;
    320 }
    321 
    322 
    323298/**
    324299 * CTDB transaction destructor
     
    326301static int db_ctdb_transaction_destructor(struct db_ctdb_transaction_handle *h)
    327302{
    328         tdb_transaction_cancel(h->ctx->wtdb->tdb);
     303        NTSTATUS status;
     304
     305        status = g_lock_unlock(h->ctx->lock_ctx, h->lock_name);
     306        if (!NT_STATUS_IS_OK(status)) {
     307                DEBUG(0, ("g_lock_unlock failed: %s\n", nt_errstr(status)));
     308                return -1;
     309        }
    329310        return 0;
    330311}
    331 
    332 /**
    333  * start a transaction on a ctdb database:
    334  * - lock the transaction lock key
    335  * - start the tdb transaction
    336  */
    337 static int db_ctdb_transaction_fetch_start(struct db_ctdb_transaction_handle *h)
    338 {
    339         struct db_record *rh;
    340         struct db_ctdb_rec *crec;
    341         TDB_DATA key;
    342         TALLOC_CTX *tmp_ctx;
    343         const char *keyname = CTDB_TRANSACTION_LOCK_KEY;
    344         int ret;
    345         struct db_ctdb_ctx *ctx = h->ctx;
    346         TDB_DATA data;
    347         pid_t pid;
    348         NTSTATUS status;
    349         struct ctdb_ltdb_header header;
    350         int32_t transaction_status;
    351 
    352         key.dptr = (uint8_t *)discard_const(keyname);
    353         key.dsize = strlen(keyname);
    354 
    355 again:
    356         tmp_ctx = talloc_new(h);
    357 
    358         rh = fetch_locked_internal(ctx, tmp_ctx, key, true);
    359         if (rh == NULL) {
    360                 DEBUG(0,(__location__ " Failed to fetch_lock database\n"));             
    361                 talloc_free(tmp_ctx);
    362                 return -1;
    363         }
    364         crec = talloc_get_type_abort(rh->private_data, struct db_ctdb_rec);
    365 
    366         transaction_status = db_ctdb_transaction_active(ctx->db_id);
    367         if (transaction_status == 1) {
    368                 unsigned long int usec = (1000 + random()) % 100000;
    369                 DEBUG(3, ("Transaction already active on db_id[0x%08x]."
    370                           "Re-trying after %lu microseconds...",
    371                           ctx->db_id, usec));
    372                 talloc_free(tmp_ctx);
    373                 usleep(usec);
    374                 goto again;
    375         }
    376 
    377         /*
    378          * store the pid in the database:
    379          * it is not enought that the node is dmaster...
    380          */
    381         pid = getpid();
    382         data.dptr = (unsigned char *)&pid;
    383         data.dsize = sizeof(pid_t);
    384         crec->header.rsn++;
    385         crec->header.dmaster = get_my_vnn();
    386         status = db_ctdb_ltdb_store(ctx, key, &(crec->header), data);
    387         if (!NT_STATUS_IS_OK(status)) {
    388                 DEBUG(0, (__location__ " Failed to store pid in transaction "
    389                           "record: %s\n", nt_errstr(status)));
    390                 talloc_free(tmp_ctx);
    391                 return -1;
    392         }
    393 
    394         talloc_free(rh);
    395 
    396         ret = tdb_transaction_start(ctx->wtdb->tdb);
    397         if (ret != 0) {
    398                 DEBUG(0,(__location__ " Failed to start tdb transaction\n"));
    399                 talloc_free(tmp_ctx);
    400                 return -1;
    401         }
    402 
    403         status = db_ctdb_ltdb_fetch(ctx, key, &header, tmp_ctx, &data);
    404         if (!NT_STATUS_IS_OK(status)) {
    405                 DEBUG(0, (__location__ " failed to refetch transaction lock "
    406                           "record inside transaction: %s - retrying\n",
    407                           nt_errstr(status)));
    408                 tdb_transaction_cancel(ctx->wtdb->tdb);
    409                 talloc_free(tmp_ctx);
    410                 goto again;
    411         }
    412 
    413         if (header.dmaster != get_my_vnn()) {
    414                 DEBUG(3, (__location__ " refetch transaction lock record : "
    415                           "we are not dmaster any more "
    416                           "(dmaster[%u] != my_vnn[%u]) - retrying\n",
    417                           header.dmaster, get_my_vnn()));
    418                 tdb_transaction_cancel(ctx->wtdb->tdb);
    419                 talloc_free(tmp_ctx);
    420                 goto again;
    421         }
    422 
    423         if ((data.dsize != sizeof(pid_t)) || (*(pid_t *)(data.dptr) != pid)) {
    424                 DEBUG(3, (__location__ " refetch transaction lock record: "
    425                           "another local process has started a transaction "
    426                           "(stored pid [%u] != my pid [%u]) - retrying\n",
    427                           *(pid_t *)(data.dptr), pid));
    428                 tdb_transaction_cancel(ctx->wtdb->tdb);
    429                 talloc_free(tmp_ctx);
    430                 goto again;
    431         }
    432 
    433         talloc_free(tmp_ctx);
    434 
    435         return 0;
    436 }
    437 
    438312
    439313/**
     
    444318{
    445319        struct db_ctdb_transaction_handle *h;
    446         int ret;
     320        NTSTATUS status;
    447321        struct db_ctdb_ctx *ctx = talloc_get_type_abort(db->private_data,
    448322                                                        struct db_ctdb_ctx);
     
    467341        h->ctx = ctx;
    468342
    469         ret = db_ctdb_transaction_fetch_start(h);
    470         if (ret != 0) {
    471                 talloc_free(h);
     343        h->lock_name = talloc_asprintf(h, "transaction_db_0x%08x",
     344                                       (unsigned int)ctx->db_id);
     345        if (h->lock_name == NULL) {
     346                DEBUG(0, ("talloc_asprintf failed\n"));
     347                TALLOC_FREE(h);
    472348                return -1;
    473349        }
    474350
     351        /*
     352         * Wait a day, i.e. forever...
     353         */
     354        status = g_lock_lock(ctx->lock_ctx, h->lock_name, G_LOCK_WRITE,
     355                             timeval_set(86400, 0));
     356        if (!NT_STATUS_IS_OK(status)) {
     357                DEBUG(0, ("g_lock_lock failed: %s\n", nt_errstr(status)));
     358                TALLOC_FREE(h);
     359                return -1;
     360        }
     361
    475362        talloc_set_destructor(h, db_ctdb_transaction_destructor);
    476363
     
    482369}
    483370
    484 
     371static bool pull_newest_from_marshall_buffer(struct ctdb_marshall_buffer *buf,
     372                                             TDB_DATA key,
     373                                             struct ctdb_ltdb_header *pheader,
     374                                             TALLOC_CTX *mem_ctx,
     375                                             TDB_DATA *pdata)
     376{
     377        struct ctdb_rec_data *rec = NULL;
     378        struct ctdb_ltdb_header h;
     379        bool found = false;
     380        TDB_DATA data;
     381        int i;
     382
     383        if (buf == NULL) {
     384                return false;
     385        }
     386
     387        ZERO_STRUCT(h);
     388        ZERO_STRUCT(data);
     389
     390        /*
     391         * Walk the list of records written during this
     392         * transaction. If we want to read one we have already
     393         * written, return the last written sample. Thus we do not do
     394         * a "break;" for the first hit, this record might have been
     395         * overwritten later.
     396         */
     397
     398        for (i=0; i<buf->count; i++) {
     399                TDB_DATA tkey, tdata;
     400                uint32_t reqid;
     401                struct ctdb_ltdb_header hdr;
     402
     403                ZERO_STRUCT(hdr);
     404
     405                rec = db_ctdb_marshall_loop_next(buf, rec, &reqid, &hdr, &tkey,
     406                                                 &tdata);
     407                if (rec == NULL) {
     408                        return false;
     409                }
     410
     411                if (tdb_data_equal(key, tkey)) {
     412                        found = true;
     413                        data = tdata;
     414                        h = hdr;
     415                }
     416        }
     417
     418        if (!found) {
     419                return false;
     420        }
     421
     422        if (pdata != NULL) {
     423                data.dptr = (uint8_t *)talloc_memdup(mem_ctx, data.dptr,
     424                                                     data.dsize);
     425                if ((data.dsize != 0) && (data.dptr == NULL)) {
     426                        return false;
     427                }
     428                *pdata = data;
     429        }
     430
     431        if (pheader != NULL) {
     432                *pheader = h;
     433        }
     434
     435        return true;
     436}
    485437
    486438/*
     
    493445        struct db_ctdb_transaction_handle *h = db->transaction;
    494446        NTSTATUS status;
     447        bool found;
     448
     449        found = pull_newest_from_marshall_buffer(h->m_write, key, NULL,
     450                                                 mem_ctx, data);
     451        if (found) {
     452                return 0;
     453        }
    495454
    496455        status = db_ctdb_ltdb_fetch(h->ctx, key, NULL, mem_ctx, data);
     
    502461        }
    503462
    504         if (!h->in_replay) {
    505                 h->m_all = db_ctdb_marshall_add(h, h->m_all, h->ctx->db_id, 1, key, NULL, *data);
    506                 if (h->m_all == NULL) {
    507                         DEBUG(0,(__location__ " Failed to add to marshalling record\n"));
    508                         data->dsize = 0;
    509                         talloc_free(data->dptr);
    510                         return -1;
    511                 }
     463        h->m_all = db_ctdb_marshall_add(h, h->m_all, h->ctx->db_id, 1, key,
     464                                        NULL, *data);
     465        if (h->m_all == NULL) {
     466                DEBUG(0,(__location__ " Failed to add to marshalling "
     467                         "record\n"));
     468                data->dsize = 0;
     469                talloc_free(data->dptr);
     470                return -1;
    512471        }
    513472
     
    543502        result->store = db_ctdb_store_transaction;
    544503        result->delete_rec = db_ctdb_delete_transaction;
     504
     505        if (pull_newest_from_marshall_buffer(ctx->transaction->m_write, key,
     506                                             NULL, result, &result->value)) {
     507                return result;
     508        }
    545509
    546510        ctdb_data = tdb_fetch(ctx->wtdb->tdb, key);
     
    616580  stores a record inside a transaction
    617581 */
    618 static int db_ctdb_transaction_store(struct db_ctdb_transaction_handle *h,
    619                                      TDB_DATA key, TDB_DATA data)
     582static NTSTATUS db_ctdb_transaction_store(struct db_ctdb_transaction_handle *h,
     583                                          TDB_DATA key, TDB_DATA data)
    620584{
    621585        TALLOC_CTX *tmp_ctx = talloc_new(h);
    622         int ret;
    623586        TDB_DATA rec;
    624587        struct ctdb_ltdb_header header;
    625         NTSTATUS status;
     588
     589        ZERO_STRUCT(header);
    626590
    627591        /* we need the header so we can update the RSN */
    628         rec = tdb_fetch(h->ctx->wtdb->tdb, key);
    629         if (rec.dptr == NULL) {
    630                 /* the record doesn't exist - create one with us as dmaster.
    631                    This is only safe because we are in a transaction and this
    632                    is a persistent database */
    633                 ZERO_STRUCT(header);
    634         } else {
    635                 memcpy(&header, rec.dptr, sizeof(struct ctdb_ltdb_header));
    636                 rec.dsize -= sizeof(struct ctdb_ltdb_header);
    637                 /* a special case, we are writing the same data that is there now */
    638                 if (data.dsize == rec.dsize &&
    639                     memcmp(data.dptr, rec.dptr + sizeof(struct ctdb_ltdb_header), data.dsize) == 0) {
    640                         SAFE_FREE(rec.dptr);
    641                         talloc_free(tmp_ctx);
    642                         return 0;
     592
     593        if (!pull_newest_from_marshall_buffer(h->m_write, key, &header,
     594                                              NULL, NULL)) {
     595
     596                rec = tdb_fetch(h->ctx->wtdb->tdb, key);
     597
     598                if (rec.dptr != NULL) {
     599                        memcpy(&header, rec.dptr,
     600                               sizeof(struct ctdb_ltdb_header));
     601                        rec.dsize -= sizeof(struct ctdb_ltdb_header);
     602
     603                        /*
     604                         * a special case, we are writing the same
     605                         * data that is there now
     606                         */
     607                        if (data.dsize == rec.dsize &&
     608                            memcmp(data.dptr,
     609                                   rec.dptr + sizeof(struct ctdb_ltdb_header),
     610                                   data.dsize) == 0) {
     611                                SAFE_FREE(rec.dptr);
     612                                talloc_free(tmp_ctx);
     613                                return NT_STATUS_OK;
     614                        }
    643615                }
    644616                SAFE_FREE(rec.dptr);
     
    648620        header.rsn++;
    649621
    650         if (!h->in_replay) {
    651                 h->m_all = db_ctdb_marshall_add(h, h->m_all, h->ctx->db_id, 0, key, NULL, data);
    652                 if (h->m_all == NULL) {
    653                         DEBUG(0,(__location__ " Failed to add to marshalling record\n"));
    654                         talloc_free(tmp_ctx);
    655                         return -1;
    656                 }
     622        h->m_all = db_ctdb_marshall_add(h, h->m_all, h->ctx->db_id, 0, key,
     623                                        NULL, data);
     624        if (h->m_all == NULL) {
     625                DEBUG(0,(__location__ " Failed to add to marshalling "
     626                         "record\n"));
     627                talloc_free(tmp_ctx);
     628                return NT_STATUS_NO_MEMORY;
    657629        }
    658630
     
    661633                DEBUG(0,(__location__ " Failed to add to marshalling record\n"));
    662634                talloc_free(tmp_ctx);
    663                 return -1;
    664         }
    665 
    666         status = db_ctdb_ltdb_store(h->ctx, key, &header, data);
    667         if (NT_STATUS_IS_OK(status)) {
    668                 ret = 0;
    669         } else {
    670                 ret = -1;
     635                return NT_STATUS_NO_MEMORY;
    671636        }
    672637
    673638        talloc_free(tmp_ctx);
    674 
    675         return ret;
     639        return NT_STATUS_OK;
    676640}
    677641
     
    684648        struct db_ctdb_transaction_handle *h = talloc_get_type_abort(
    685649                rec->private_data, struct db_ctdb_transaction_handle);
    686         int ret;
    687 
    688         ret = db_ctdb_transaction_store(h, rec->key, data);
    689         if (ret != 0) {
    690                 return tdb_error_to_ntstatus(h->ctx->wtdb->tdb);
    691         }
    692         return NT_STATUS_OK;
     650        NTSTATUS status;
     651
     652        status = db_ctdb_transaction_store(h, rec->key, data);
     653        return status;
    693654}
    694655
     
    700661        struct db_ctdb_transaction_handle *h = talloc_get_type_abort(
    701662                rec->private_data, struct db_ctdb_transaction_handle);
    702         int ret;
    703 
    704         ret = db_ctdb_transaction_store(h, rec->key, tdb_null);
    705         if (ret != 0) {
    706                 return tdb_error_to_ntstatus(h->ctx->wtdb->tdb);
    707         }
    708         return NT_STATUS_OK;
    709 }
    710 
    711 
    712 /*
    713   replay a transaction
    714  */
    715 static int ctdb_replay_transaction(struct db_ctdb_transaction_handle *h)
    716 {
    717         int ret, i;
    718         struct ctdb_rec_data *rec = NULL;
    719 
    720         h->in_replay = true;
    721         talloc_free(h->m_write);
    722         h->m_write = NULL;
    723 
    724         ret = db_ctdb_transaction_fetch_start(h);
    725         if (ret != 0) {
    726                 return ret;
    727         }
    728 
    729         for (i=0;i<h->m_all->count;i++) {
    730                 TDB_DATA key, data;
    731 
    732                 rec = db_ctdb_marshall_loop_next(h->m_all, rec, NULL, NULL, &key, &data);
    733                 if (rec == NULL) {
    734                         DEBUG(0, (__location__ " Out of records in ctdb_replay_transaction?\n"));
    735                         goto failed;
    736                 }
    737 
    738                 if (rec->reqid == 0) {
    739                         /* its a store */
    740                         if (db_ctdb_transaction_store(h, key, data) != 0) {
    741                                 goto failed;
    742                         }
    743                 } else {
    744                         TDB_DATA data2;
    745                         TALLOC_CTX *tmp_ctx = talloc_new(h);
    746 
    747                         if (db_ctdb_transaction_fetch(h->ctx, tmp_ctx, key, &data2) != 0) {
    748                                 talloc_free(tmp_ctx);
    749                                 goto failed;
    750                         }
    751                         if (data2.dsize != data.dsize ||
    752                             memcmp(data2.dptr, data.dptr, data.dsize) != 0) {
    753                                 /* the record has changed on us - we have to give up */
    754                                 talloc_free(tmp_ctx);
    755                                 goto failed;
    756                         }
    757                         talloc_free(tmp_ctx);
    758                 }
    759         }
    760 
    761         return 0;
    762 
    763 failed:
    764         tdb_transaction_cancel(h->ctx->wtdb->tdb);
    765         return -1;
    766 }
    767 
     663        NTSTATUS status;
     664
     665        status = db_ctdb_transaction_store(h, rec->key, tdb_null);
     666        return status;
     667}
     668
     669/**
     670 * Fetch the db sequence number of a persistent db directly from the db.
     671 */
     672static NTSTATUS db_ctdb_fetch_db_seqnum_from_db(struct db_ctdb_ctx *db,
     673                                                uint64_t *seqnum)
     674{
     675        NTSTATUS status;
     676        const char *keyname = CTDB_DB_SEQNUM_KEY;
     677        TDB_DATA key;
     678        TDB_DATA data;
     679        struct ctdb_ltdb_header header;
     680        TALLOC_CTX *mem_ctx = talloc_stackframe();
     681
     682        if (seqnum == NULL) {
     683                return NT_STATUS_INVALID_PARAMETER;
     684        }
     685
     686        key = string_term_tdb_data(keyname);
     687
     688        status = db_ctdb_ltdb_fetch(db, key, &header, mem_ctx, &data);
     689        if (!NT_STATUS_IS_OK(status) &&
     690            !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND))
     691        {
     692                goto done;
     693        }
     694
     695        status = NT_STATUS_OK;
     696
     697        if (data.dsize != sizeof(uint64_t)) {
     698                *seqnum = 0;
     699                goto done;
     700        }
     701
     702        *seqnum = *(uint64_t *)data.dptr;
     703
     704done:
     705        TALLOC_FREE(mem_ctx);
     706        return status;
     707}
     708
     709/**
     710 * Store the database sequence number inside a transaction.
     711 */
     712static NTSTATUS db_ctdb_store_db_seqnum(struct db_ctdb_transaction_handle *h,
     713                                        uint64_t seqnum)
     714{
     715        NTSTATUS status;
     716        const char *keyname = CTDB_DB_SEQNUM_KEY;
     717        TDB_DATA key;
     718        TDB_DATA data;
     719
     720        key = string_term_tdb_data(keyname);
     721
     722        data.dptr = (uint8_t *)&seqnum;
     723        data.dsize = sizeof(uint64_t);
     724
     725        status = db_ctdb_transaction_store(h, key, data);
     726
     727        return status;
     728}
    768729
    769730/*
     
    775736                                                        struct db_ctdb_ctx);
    776737        NTSTATUS rets;
     738        int status;
     739        struct db_ctdb_transaction_handle *h = ctx->transaction;
     740        uint64_t old_seqnum, new_seqnum;
    777741        int ret;
    778         int status;
    779         int retries = 0;
    780         struct db_ctdb_transaction_handle *h = ctx->transaction;
    781         enum ctdb_controls failure_control = CTDB_CONTROL_TRANS2_ERROR;
    782742
    783743        if (h == NULL) {
     
    797757        }
    798758
     759        if (h->m_write == NULL) {
     760                /*
     761                 * No changes were made, so don't change the seqnum,
     762                 * don't push to other node, just exit with success.
     763                 */
     764                ret = 0;
     765                goto done;
     766        }
     767
    799768        DEBUG(5,(__location__ " Commit transaction on db 0x%08x\n", ctx->db_id));
    800769
    801         talloc_set_destructor(h, NULL);
    802 
    803         /* our commit strategy is quite complex.
    804 
    805            - we first try to commit the changes to all other nodes
    806 
    807            - if that works, then we commit locally and we are done
    808 
    809            - if a commit on another node fails, then we need to cancel
    810              the transaction, then restart the transaction (thus
    811              opening a window of time for a pending recovery to
    812              complete), then replay the transaction, checking all the
    813              reads and writes (checking that reads give the same data,
    814              and writes succeed). Then we retry the transaction to the
    815              other nodes
    816         */
     770        /*
     771         * As the last db action before committing, bump the database sequence
     772         * number. Note that this undoes all changes to the seqnum records
     773         * performed under the transaction. This record is not meant to be
     774         * modified by user interaction. It is for internal use only...
     775         */
     776        rets = db_ctdb_fetch_db_seqnum_from_db(ctx, &old_seqnum);
     777        if (!NT_STATUS_IS_OK(rets)) {
     778                DEBUG(1, (__location__ " failed to fetch the db sequence number "
     779                          "in transaction commit on db 0x%08x\n", ctx->db_id));
     780                ret = -1;
     781                goto done;
     782        }
     783
     784        new_seqnum = old_seqnum + 1;
     785
     786        rets = db_ctdb_store_db_seqnum(h, new_seqnum);
     787        if (!NT_STATUS_IS_OK(rets)) {
     788                DEBUG(1, (__location__ "failed to store the db sequence number "
     789                          " in transaction commit on db 0x%08x\n", ctx->db_id));
     790                ret = -1;
     791                goto done;
     792        }
    817793
    818794again:
    819         if (h->m_write == NULL) {
    820                 /* no changes were made, potentially after a retry */
    821                 tdb_transaction_cancel(h->ctx->wtdb->tdb);
    822                 talloc_free(h);
    823                 ctx->transaction = NULL;
    824                 return 0;
    825         }
    826 
    827795        /* tell ctdbd to commit to the other nodes */
    828         rets = ctdbd_control_local(messaging_ctdbd_connection(), 
    829                                    retries==0?CTDB_CONTROL_TRANS2_COMMIT:CTDB_CONTROL_TRANS2_COMMIT_RETRY,
     796        rets = ctdbd_control_local(messaging_ctdbd_connection(),
     797                                   CTDB_CONTROL_TRANS3_COMMIT,
    830798                                   h->ctx->db_id, 0,
    831                                    db_ctdb_marshall_finish(h->m_write), NULL, NULL, &status);
     799                                   db_ctdb_marshall_finish(h->m_write),
     800                                   NULL, NULL, &status);
    832801        if (!NT_STATUS_IS_OK(rets) || status != 0) {
    833                 tdb_transaction_cancel(h->ctx->wtdb->tdb);
    834                 sleep(1);
    835 
     802                /*
     803                 * The TRANS3_COMMIT control should only possibly fail when a
     804                 * recovery has been running concurrently. In any case, the db
     805                 * will be the same on all nodes, either the new copy or the
     806                 * old copy.  This can be detected by comparing the old and new
     807                 * local sequence numbers.
     808                 */
     809                rets = db_ctdb_fetch_db_seqnum_from_db(ctx, &new_seqnum);
    836810                if (!NT_STATUS_IS_OK(rets)) {
    837                         failure_control = CTDB_CONTROL_TRANS2_ERROR;                   
    838                 } else {
    839                         /* work out what error code we will give if we
    840                            have to fail the operation */
    841                         switch ((enum ctdb_trans2_commit_error)status) {
    842                         case CTDB_TRANS2_COMMIT_SUCCESS:
    843                         case CTDB_TRANS2_COMMIT_SOMEFAIL:
    844                         case CTDB_TRANS2_COMMIT_TIMEOUT:
    845                                 failure_control = CTDB_CONTROL_TRANS2_ERROR;
    846                                 break;
    847                         case CTDB_TRANS2_COMMIT_ALLFAIL:
    848                                 failure_control = CTDB_CONTROL_TRANS2_FINISHED;
    849                                 break;
    850                         }
    851                 }
    852 
    853                 if (++retries == 100) {
    854                         DEBUG(0,(__location__ " Giving up transaction on db 0x%08x after %d retries failure_control=%u\n",
    855                                  h->ctx->db_id, retries, (unsigned)failure_control));
    856                         ctdbd_control_local(messaging_ctdbd_connection(), failure_control,
    857                                             h->ctx->db_id, CTDB_CTRL_FLAG_NOREPLY,
    858                                             tdb_null, NULL, NULL, NULL);
    859                         h->ctx->transaction = NULL;
    860                         talloc_free(h);
    861                         ctx->transaction = NULL;
    862                         return -1;                     
    863                 }
    864 
    865                 if (ctdb_replay_transaction(h) != 0) {
    866                         DEBUG(0,(__location__ " Failed to replay transaction failure_control=%u\n",
    867                                  (unsigned)failure_control));
    868                         ctdbd_control_local(messaging_ctdbd_connection(), failure_control,
    869                                             h->ctx->db_id, CTDB_CTRL_FLAG_NOREPLY,
    870                                             tdb_null, NULL, NULL, NULL);
    871                         h->ctx->transaction = NULL;
    872                         talloc_free(h);
    873                         ctx->transaction = NULL;
    874                         return -1;
    875                 }
    876                 goto again;
    877         } else {
    878                 failure_control = CTDB_CONTROL_TRANS2_ERROR;
    879         }
    880 
    881         /* do the real commit locally */
    882         ret = tdb_transaction_commit(h->ctx->wtdb->tdb);
    883         if (ret != 0) {
    884                 DEBUG(0,(__location__ " Failed to commit transaction failure_control=%u\n",
    885                          (unsigned)failure_control));
    886                 ctdbd_control_local(messaging_ctdbd_connection(), failure_control, h->ctx->db_id,
    887                                     CTDB_CTRL_FLAG_NOREPLY, tdb_null, NULL, NULL, NULL);
    888                 h->ctx->transaction = NULL;
    889                 talloc_free(h);
    890                 return ret;
    891         }
    892 
    893         /* tell ctdbd that we are finished with our local commit */
    894         ctdbd_control_local(messaging_ctdbd_connection(), CTDB_CONTROL_TRANS2_FINISHED,
    895                             h->ctx->db_id, CTDB_CTRL_FLAG_NOREPLY,
    896                             tdb_null, NULL, NULL, NULL);
     811                        DEBUG(1, (__location__ " failed to refetch db sequence "
     812                                  "number after failed TRANS3_COMMIT\n"));
     813                        ret = -1;
     814                        goto done;
     815                }
     816
     817                if (new_seqnum == old_seqnum) {
     818                        /* Recovery prevented all our changes: retry. */
     819                        goto again;
     820                } else if (new_seqnum != (old_seqnum + 1)) {
     821                        DEBUG(0, (__location__ " ERROR: new_seqnum[%lu] != "
     822                                  "old_seqnum[%lu] + (0 or 1) after failed "
     823                                  "TRANS3_COMMIT - this should not happen!\n",
     824                                  (unsigned long)new_seqnum,
     825                                  (unsigned long)old_seqnum));
     826                        ret = -1;
     827                        goto done;
     828                }
     829                /*
     830                 * Recovery propagated our changes to all nodes, completing
     831                 * our commit for us - succeed.
     832                 */
     833        }
     834
     835        ret = 0;
     836
     837done:
    897838        h->ctx->transaction = NULL;
    898839        talloc_free(h);
    899         return 0;
     840        return ret;
    900841}
    901842
     
    976917static struct db_record *fetch_locked_internal(struct db_ctdb_ctx *ctx,
    977918                                               TALLOC_CTX *mem_ctx,
    978                                                TDB_DATA key,
    979                                                bool persistent)
     919                                               TDB_DATA key)
    980920{
    981921        struct db_record *result;
     
    11051045        }
    11061046
    1107         return fetch_locked_internal(ctx, mem_ctx, key, db->persistent);
     1047        return fetch_locked_internal(ctx, mem_ctx, key);
    11081048}
    11091049
     
    13151255        struct db_ctdb_ctx *db_ctdb;
    13161256        char *db_path;
     1257        struct ctdbd_connection *conn;
    13171258
    13181259        if (!lp_clustering()) {
     
    13361277        db_ctdb->db = result;
    13371278
    1338         if (!NT_STATUS_IS_OK(ctdbd_db_attach(messaging_ctdbd_connection(),name, &db_ctdb->db_id, tdb_flags))) {
     1279        conn = messaging_ctdbd_connection();
     1280
     1281        if (!NT_STATUS_IS_OK(ctdbd_db_attach(conn, name, &db_ctdb->db_id, tdb_flags))) {
    13391282                DEBUG(0, ("ctdbd_db_attach failed for %s\n", name));
    13401283                TALLOC_FREE(result);
     
    13421285        }
    13431286
    1344         db_path = ctdbd_dbpath(messaging_ctdbd_connection(), db_ctdb, db_ctdb->db_id);
     1287        db_path = ctdbd_dbpath(conn, db_ctdb, db_ctdb->db_id);
    13451288
    13461289        result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
     
    13611304        }
    13621305        talloc_free(db_path);
     1306
     1307        if (result->persistent) {
     1308                db_ctdb->lock_ctx = g_lock_ctx_init(db_ctdb,
     1309                                                    ctdb_conn_msg_ctx(conn));
     1310                if (db_ctdb->lock_ctx == NULL) {
     1311                        DEBUG(0, ("g_lock_ctx_init failed\n"));
     1312                        TALLOC_FREE(result);
     1313                        return NULL;
     1314                }
     1315        }
    13631316
    13641317        result->private_data = (void *)db_ctdb;
  • vendor/current/source3/lib/events.c

    r414 r427  
    106106        if ((ev->timer_events != NULL)
    107107            && (timeval_compare(&now, &ev->timer_events->next_event) >= 0)) {
     108                /* this older events system did not auto-free timed
     109                   events on running them, and had a race condition
     110                   where the event could be called twice if the
     111                   talloc_free of the te happened after the callback
     112                   made a call which invoked the event loop. To avoid
     113                   this while still allowing old code which frees the
     114                   te, we need to create a temporary context which
     115                   will be used to ensure the te is freed. We also
     116                   remove the te from the timed event list before we
     117                   call the handler, to ensure we can't loop */
     118
     119                struct tevent_timer *te = ev->timer_events;
     120                TALLOC_CTX *tmp_ctx = talloc_new(ev);
    108121
    109122                DEBUG(10, ("Running timed event \"%s\" %p\n",
    110123                           ev->timer_events->handler_name, ev->timer_events));
    111124
    112                 ev->timer_events->handler(ev, ev->timer_events, now,
    113                                           ev->timer_events->private_data);
     125                DLIST_REMOVE(ev->timer_events, te);
     126                talloc_steal(tmp_ctx, te);
     127
     128                te->handler(ev, te, now, te->private_data);
     129
     130                talloc_free(tmp_ctx);
    114131                return true;
    115132        }
  • vendor/current/source3/lib/system.c

    r414 r427  
    884884#if defined(HAVE_POSIX_CAPABILITIES)
    885885
    886 /* This define hasn't made it into the glibc capabilities header yet. */
    887 #ifndef SECURE_NO_SETUID_FIXUP
    888 #define SECURE_NO_SETUID_FIXUP          2
    889 #endif
    890 
    891886/**************************************************************************
    892887 Try and abstract process capabilities (for systems that have them).
     
    919914#endif
    920915
    921 #if defined(HAVE_PRCTL) && defined(PR_SET_SECUREBITS) && defined(SECURE_NO_SETUID_FIXUP)
    922         /* New way of setting capabilities as "sticky". */
    923 
    924         /*
    925          * Use PR_SET_SECUREBITS to prevent setresuid()
    926          * atomically dropping effective capabilities on
    927          * uid change. Only available in Linux kernels
    928          * 2.6.26 and above.
    929          *
    930          * See here:
    931          * http://www.kernel.org/doc/man-pages/online/pages/man7/capabilities.7.html
    932          * for details.
    933          *
    934          * Specifically the CAP_KILL capability we need
    935          * to allow Linux threads under different euids
    936          * to send signals to each other.
    937          */
    938 
    939         if (prctl(PR_SET_SECUREBITS, 1 << SECURE_NO_SETUID_FIXUP)) {
    940                 DEBUG(0,("set_process_capability: "
    941                         "prctl PR_SET_SECUREBITS failed with error %s\n",
    942                         strerror(errno) ));
    943                 return false;
    944         }
    945 #endif
    946 
    947916        cap = cap_get_proc();
    948917        if (cap == NULL) {
     
    973942#endif
    974943                        break;
    975                 case KILL_CAPABILITY:
    976 #ifdef CAP_KILL
    977                         cap_vals[num_cap_vals++] = CAP_KILL;
    978 #endif
    979                         break;
    980944        }
    981945
     
    987951        }
    988952
    989         /*
    990          * Ensure the capability is effective. We assume that as a root
    991          * process it's always permitted.
    992          */
    993 
    994         if (cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals,
    995                         enable ? CAP_SET : CAP_CLEAR) == -1) {
    996                 DEBUG(0, ("set_process_capability: cap_set_flag effective "
    997                         "failed (%d): %s\n",
    998                         (int)capability,
    999                         strerror(errno)));
    1000                 cap_free(cap);
    1001                 return false;
    1002         }
     953        cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals,
     954                enable ? CAP_SET : CAP_CLEAR);
    1003955
    1004956        /* We never want to pass capabilities down to our children, so make
    1005957         * sure they are not inherited.
    1006958         */
    1007         if (cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals,
    1008                         cap_vals, CAP_CLEAR) == -1) {
    1009                 DEBUG(0, ("set_process_capability: cap_set_flag inheritable "
    1010                         "failed (%d): %s\n",
    1011                         (int)capability,
    1012                         strerror(errno)));
    1013                 cap_free(cap);
    1014                 return false;
    1015         }
     959        cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR);
    1016960
    1017961        if (cap_set_proc(cap) == -1) {
    1018                 DEBUG(0, ("set_process_capability: cap_set_flag (%d) failed: %s\n",
    1019                         (int)capability,
     962                DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
    1020963                        strerror(errno)));
    1021964                cap_free(cap);
Note: See TracChangeset for help on using the changeset viewer.