[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