[libvirt] [PATCH v1 07/10] lock_daemon: Implement seclabel APIs
Michal Privoznik
mprivozn at redhat.com
Mon Sep 22 12:15:34 UTC 2014
On 19.09.2014 18:13, Daniel P. Berrange wrote:
> On Wed, Sep 10, 2014 at 03:26:13PM +0200, Michal Privoznik wrote:
>> The most interesting part where all the hard work takes place.
>>
>> For storing triplets of strings a two dimensional table would be
>> the most intuitive approach. Or, if the triplet is rearranged
>> into pair of one string and a pair, a hash table can be used. But
>> hey, we already have those! Excellent. In other words,
>>
>> <path, model, seclabel>
>>
>> is turned into:
>>
>> <path, <model, seclabel>>
>>
>> The @path is then the key that the hash table is filled with. The
>> inner pair is turned into linked list (hash table in a hash table
>> would be awful really). Moreover, we need to store yet another
>> item: reference counter.
>
> I wonder, since 'model' is mandatory and (path, model) should
> be unique, could we not avoid the linked list complexity by
> using a string of 'model:path' as the hash key, then we only
> have a single hash item too and O(1) access to values ?
>
>
>> int
>> -virLockDaemonRememberSeclabel(virLockDaemonPtr lockd ATTRIBUTE_UNUSED,
>> - const char *path ATTRIBUTE_UNUSED,
>> - const char *model ATTRIBUTE_UNUSED,
>> - const char *seclabel ATTRIBUTE_UNUSED)
>> +virLockDaemonRememberSeclabel(virLockDaemonPtr lockd,
>> + const char *path,
>> + const char *model,
>> + const char *seclabel)
>> {
>> - /* Implement me */
>> - return -1;
>> + int ret = -1;
>> + virSeclabelListPtr list = NULL;
>> + virSeclabelListPtr tmp = NULL;
>> + bool list_created = false;
>> +
>> + virMutexLock(&lockd->lock);
>> +
>> + if (!(list = virHashLookup(lockd->seclabels, path))) {
>> + if (VIR_ALLOC(list) < 0)
>> + goto cleanup;
>> +
>> + if (virHashAddEntry(lockd->seclabels, path, list) < 0)
>> + goto cleanup;
>> +
>> + list_created = true;
>> + }
>> +
>> + tmp = list;
>> + if (!(tmp = virSeclabelListFind(list, model))) {
>> + /* seclabel for @model doesn't exit yet */
>> + if (!(tmp = virSeclabelListAdd(list, model, seclabel)))
>> + goto cleanup;
>> + }
>> +
>> + /* Update refcount */
>> + ret = ++tmp->item->refcount;
>> +
>> + cleanup:
>> + virMutexUnlock(&lockd->lock);
>> + if (ret < 0 && list_created) {
>> + virHashRemoveEntry(lockd->seclabels, path);
>> + virSeclabelListFree(list);
>> + }
>> + return ret;
>> }
>
> What concerns me a little is that we don't have any association between
> the label, use count and the running VMs that triggered the need for the
> relabelling.
>
> Lets say that a virtualization host with VMs running crashes. The libvirtd
> and virtlocked on that host will loose all state. That's fine currently
> since you're not sharing the data across hosts. We're going to need to
> share the data though, so when we do that sharing, I think we're going
> to need to remember information about the VMs + hosts associated with
> the label, so that when a host crashes, we can have a chance of purging
> the now stale information.
I see.
>
> Now, as discussed on IRC it isn't critical to support multi-host mode
> right away, but this does impact on the RPC protocol, since the messages
> we are passing do not include any information about the VM or host.
>
> So I'm thinking that this series should record the VM name + uuid and
> the host name + uuid against the seclabels and plumb that through the
> RPC protocol at least.
Right, this would be great.
>
> If we did that now, I think we might not even need to add new RPC
> protocol for lockd, and instead just re-use the existing protocol
> messages and at least some of the client/dispatcher code too.
> It would be more like a case of just setting up a new lockspace
> for recording info about labels, instead of a completely new set
> of infrastructure side-by-side.
I was thinking about this prior to starting new implementation. The
problem I had found myself in was that in secdrivers we use pure
virDomainDefPtr but the VM's pid is stored in virDomainObjPtr. And I
don't think we want to refactor all the code just to tunnel the vm->pid
into function actually calling chown() or fsetfilecon_raw(). Or do we?
Michal
More information about the libvir-list
mailing list