From: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org, kaber@trash.net
Subject: Re: [RFC v2] nf_tables: Transaction API proposal
Date: Tue, 02 Apr 2013 11:26:23 +0300 [thread overview]
Message-ID: <515A962F.5010504@linux.intel.com> (raw)
In-Reply-To: <20130328170217.GA8859@localhost>
Hi Pablo,
>> About the commit, you are right Pablo: only one at a time, this is mandatory.
>> I missed the point on my first proposal.
>>
>> To do so I introduced a mutex. If it's already locked it return -EAGAIN, so it's up
>> to the client to retry. I guess this is anyway not going to happen very often.
>> I don't know if we could get something better here, at least now no client can
>> lock up the other indefinitely, it enables per-client transaction...
> Races may still occur if we try to support simultaneous transactions.
>
> client 1
> start transaction client 2
> add rule X1, table Y1, chain Z1 start transaction
> ... more rule updates delete all rules in table Y1, chain Z1
> ... more rule updates commit
1 line is missing
notifications (other rules deleted) notifications (ok chain Z1
has no rules)
> commit
and:
notifications (own rules added) notifications (hum, new rules
added. ok)
> client 2 will see rules in table Y1, chain Z1 after its commit but
> will not know why. However, if it hits -EBUSY because another client
> was performing a transaction, it can retry a fresh update with the
> current rule-set, not based on the stale one.
Your example is wrong: it is valid, as it would be also in a unique
transaction based approach as your are proposing:
client 2 - start / delete all rules / commit
client 2 - notifications: see no rules
client 1 - start / add rules / commit
client 2 - notifications: see rules again.
=> exact same result, which is a legitimate one in both case.
As long as transaction n cannot mess up with any other transaction m,
there is definitely no race condition between transactions.
It would be a race condition in your example if client 2 can delete the
rule updates of client 1.
But this must not be the case, and that's also why we should not dump
the non-active rules to anybody BUT to the owner.
--> As long as a rule is not active: it does not exist but in a transaction.
With transaction you never know the result as long as it did not end up
to a commit, so there is no point to tell everybody about it before.
I still think it's really wrong to propose unique transaction approach:
if the client is bogus (and they will! ^^) and never commit/abort its
transaction, it locks all others.
Anyway, there are issues in my proposal I agree: it's an RFC not a patch.
For instance:
In your proposal, as long a the transaction is "going on" no other
manipulation can be done to the rule base. It's wrong because it locks
all other clients (even on untouched tables/chains by the transaction)
but it "fixes" the case where non-transaction based manipulation could
be done: these are locked as well. And it does that to all
manipulations, whatever table/chain is in the game.
--> in my RFC, getting non-transaction based manipulation could lead to
troubles: what if a non-atomic manipulation removes all rules and the
chain itself, where a transaction was working? (yes that one is a valid
race condition ;-) )
Here we could fix it, if there is a transaction going on in that
specific chain, either by killing the entire transaction and notifying
its owner (I would prefer that one), or like you are doing: return
ebusy. But I don't like the idea of a transaction being able to lock
anyone (I repeat myself, sorry).
To me, non-transaction (so non-atomic) based manipulation should always
have the highest priority versus any transactions, unless a commit is
going on of course. We have to maintain this difference of transaction
and non-transaction based manipulation.
We have to think properly about that: how we store the transaction in an
efficient way so it would not be a performance issue to look-up for a
table/chain in transaction list. Things like that.
I am sure we can get something still simple and reliable from API point
of view but way more flexible than your approach. And with nobody being
able to lock this subsystem. We are not in a hurry anyway.
> +
> +static void nf_tables_transaction_remove(struct nft_transaction *transaction)
> +{
> + nfnl_lock();
> Won't work. nfnl_lock is already held when calling this function. Note
> that all nfnetlink functions are currently protected by nfnl_lock.
Indeed, did that patch too quickly. Loosely looked at nf_tables_expressions.
> + /* Check if a commit is on-going */
> + if (mutex_trylock(&nf_tables_commit_lock))
> + return -EAGAIN;
> You should use -EBUSY. -EAGAIN is used internally by nfnetlink to
> retry on module autoload.
Ok good to know.
Br,
Tomasz
prev parent reply other threads:[~2013-04-02 8:26 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-28 23:08 [PATCH 1/2] netfilter: nf_tables: partially rework commit and abort operation pablo
2013-02-28 23:08 ` [PATCH 2/2] netfilter: nf_tables: don't skip inactive rules and dump generation mask pablo
2013-03-04 12:22 ` [PATCH 1/2] netfilter: nf_tables: partially rework commit and abort operation Tomasz Bursztyka
2013-03-26 10:19 ` [RFC] Atomic rule manipulation part of transactions Tomasz Bursztyka
2013-03-26 10:19 ` [PATCH] nf_tables: Transaction API proposal Tomasz Bursztyka
2013-03-27 16:35 ` Pablo Neira Ayuso
2013-03-27 16:42 ` Pablo Neira Ayuso
2013-03-28 8:01 ` Tomasz Bursztyka
2013-03-28 10:04 ` Pablo Neira Ayuso
2013-03-28 13:52 ` [RFC v2] " Tomasz Bursztyka
2013-03-28 17:02 ` Pablo Neira Ayuso
2013-04-02 8:26 ` Tomasz Bursztyka [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=515A962F.5010504@linux.intel.com \
--to=tomasz.bursztyka@linux.intel.com \
--cc=kaber@trash.net \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).