[libvirt] [PATCH] LXC: support block devices for container

Gao feng gaofeng at cn.fujitsu.com
Mon Apr 9 01:41:14 UTC 2012


于 2012年04月06日 18:38, Daniel P. Berrange 写道:
> On Fri, Apr 06, 2012 at 02:31:54PM +0800, Gao feng wrote:
>> This patch allows to config block device for container.
>> the disk node is used to point out source device and target device
>> source device is the device path in host,
>> and target device is the device name in container.
>> such as
>> <disk type='block' device='disk'>
>>     <driver name="lxc"/>
>>     <source dev='/dev/sda2'/>
>>     <target dev='sda1'/>
> 
> Here you have different source + target dev names - the way this is
> implemented, they must match.
>

sorry,I don't know what you mean here,I have implemented this,and with my test,
it works well.

>> </disk>
>>
>> Unfortunately it's no use to config readonly in disk node now.
> 
> Can't you support readonly mode via cgroups. You set an ACL
> of 'rwm' for the disk, which could just be set to 'r' for
> <readonly/> mode.
> 

When only set an ACL of 'r' for the disk,we will have no right to mknod for the disk.
and the container can not mount the disk.I think this is useless.

>>
>> Signed-off-by: Gao feng <gaofeng at cn.fujitsu.com>
> 
> While this patch works, and I've considered doing this myself
> too, I was half wondering whether we should instead be doing
> this using  <hostdev>, since the way we're implementing this
> is really direct host device assignment to the container.

I agree with you,but the hostdev node has different format of xml.
I don't know how to implement this with using hostdev.
> 
> The vast majority of the data associated with the <disk>
> element cannot be used in this scenario, since we can't
> modify what the host device already uses.
> 
>> diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
>> index 9bb6218..062cc8f 100644
>> --- a/src/lxc/lxc_container.c
>> +++ b/src/lxc/lxc_container.c
>> @@ -581,6 +581,80 @@ static int lxcContainerMountFSDevPTS(virDomainFSDefPtr root)
>>      return rc;
>>  }
>>  
>> +static int lxcContainerAddDisk(virDomainDiskDefPtr disk,
>> +                               const char *srcprefix)
>> +{
>> +    char *srcPath = NULL;
>> +    char *dstPath = NULL;
>> +    struct stat sb;
>> +    dev_t dev;
>> +    int ret = -1;
>> +    switch (disk->device) {
>> +    case VIR_DOMAIN_DISK_DEVICE_DISK:
>> +    case VIR_DOMAIN_DISK_DEVICE_LUN:
>> +        if (virAsprintf(&srcPath, "%s/%s", srcprefix, disk->src) < 0) {
>> +            virReportOOMError();
>> +            return ret;
>> +        }
>> +        if (virAsprintf(&dstPath, "/dev/%s", disk->dst) < 0) {
>> +            virReportOOMError();
>> +            goto cleanup;
>> +        }
>> +        if (stat(srcPath, &sb) < 0) {
>> +            ret = -errno;
>> +            goto cleanup;
>> +        }
>> +        dev = makedev(major(sb.st_rdev), minor(sb.st_rdev));
>> +        if (mknod(dstPath, S_ISCHR(sb.st_mode) ? S_IFCHR : S_IFBLK, dev) < 0 ||
>> +            chmod(dstPath, sb.st_mode)) {
>> +            virReportSystemError(errno,
>> +                                 _("Failed to make device %s"),
>> +                                 dstPath);
>> +            goto cleanup;
>> +        }
>> +        ret = 0;
>> +        break;
>> +    default:
>> +        lxcError(VIR_ERR_CONFIG_UNSUPPORTED,
>> +                 _("unsupported disk device type '%s'."),
>> +                 virDomainDiskDeviceTypeToString(disk->device));
>> +        break;
>> +    }
>> +
>> +cleanup:
>> +    VIR_FREE(srcPath);
>> +    VIR_FREE(dstPath);
>> +    return ret;
>> +}
>> +static int lxcContainerAddDevices(virDomainDefPtr vmDef,
>> +                                 const char *srcprefix)
>> +{
>> +    int ret = -1;
>> +    size_t i;
>> +
>> +    for (i=0 ; i<vmDef->ndisks ; i++) {
>> +        virDomainDiskDefPtr disk = vmDef->disks[i];
>> +
>> +        if (disk->driverName !=NULL && !STREQ(disk->driverName, "lxc")) {
>> +            lxcError(VIR_ERR_CONFIG_UNSUPPORTED,
>> +		     _("unsupported driver name '%s' for disk '%s'"),
>> +		     disk->driverName, disk->src);
>> +            continue;
>> +        }
>> +        if (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK) {
>> +            lxcError(VIR_ERR_CONFIG_UNSUPPORTED,
>> +                     _("unsupported disk type '%s'"),
>> +                     virDomainDiskTypeToString(disk->type));
>> +            continue;
>> +        }
>> +        if (lxcContainerAddDisk(disk, srcprefix) < 0)
>> +            goto cleanup;
>> +    }
>> +    ret = 0;
>> +cleanup:
>> +    return ret;
>> +}
>> +
>>  static int lxcContainerPopulateDevices(char **ttyPaths, size_t nttyPaths)
>>  {
>>      size_t i;
>> @@ -1144,6 +1218,10 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
>>      if (lxcContainerMountFSDevPTS(root) < 0)
>>          return -1;
>>  
>> +    /* Create devices */
>> +    if (lxcContainerAddDevices(vmDef, "/.oldroot") <0)
>> +        return -1;
>> +
>>      /* Populates device nodes in /dev/ */
>>      if (lxcContainerPopulateDevices(ttyPaths, nttyPaths) < 0)
>>          return -1;
>> diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
>> index bbc9d9c..5576f99 100644
>> --- a/src/lxc/lxc_controller.c
>> +++ b/src/lxc/lxc_controller.c
>> @@ -545,6 +545,21 @@ static int lxcSetContainerDeviceACL(virCgroupPtr cgroup, virDomainDefPtr def)
>>          }
>>      }
>>  
>> +    for (i = 0 ; i < def->ndisks ; i++) {
>> +        if (def->disks[i]->type != VIR_DOMAIN_DISK_TYPE_BLOCK)
>> +            continue;
>> +
>> +        rc = virCgroupAllowDevicePath(cgroup,
>> +                                      def->disks[i]->src,
>> +                                      VIR_CGROUP_DEVICE_RWM);
>> +        if (rc != 0) {
>> +            virReportSystemError(-rc,
>> +                                 _("Unable to allow device %s for domain %s"),
>> +                                 def->disks[i]->src, def->name);
>> +            goto cleanup;
>> +        }
>> +    }
>> +
>>      rc = virCgroupAllowDeviceMajor(cgroup, 'c', LXC_DEV_MAJ_PTY,
>>                                     VIR_CGROUP_DEVICE_RWM);
>>      if (rc != 0) {
> 
> 
> 
> Daniel





More information about the libvir-list mailing list