Patchwork block/raw-posix: use a character device if a block device is given

login
register
mail settings
Submitter Christoph Egger
Date May 24, 2011, 9:30 a.m.
Message ID <4DDB7AB5.6010807@amd.com>
Download mbox | patch
Permalink /patch/97139/
State New
Headers show

Comments

Christoph Egger - May 24, 2011, 9:30 a.m.
On NetBSD a userland process is better with the character device
interface. In addition, a block device can't be opened twice; if a Xen
backend opens it, qemu can't and vice-versa.
Kevin Wolf - May 25, 2011, 10:43 a.m.
Am 24.05.2011 11:30, schrieb Christoph Egger:
> 
> On NetBSD a userland process is better with the character device
> interface. In addition, a block device can't be opened twice; if a Xen
> backend opens it, qemu can't and vice-versa.

If you provide a Signed-off-by, I think this patch is ready to be committed.

Kevin

> 
> diff --git a/block/raw-posix.c b/block/raw-posix.c
> index 6b72470..64dceb1 100644
> --- a/block/raw-posix.c
> +++ b/block/raw-posix.c
> @@ -136,12 +143,55 @@ static int64_t raw_getlength(BlockDriverState *bs);
>   static int cdrom_reopen(BlockDriverState *bs);
>   #endif
> 
> +#if defined(__NetBSD__)
> +static int raw_normalize_devicepath(const char **filename)
> +{
> +    static char namebuf[PATH_MAX];
> +    const char *dp, *fname;
> +    struct stat sb;
> +
> +    fname = *filename;
> +    dp = strrchr(fname, '/');
> +    if (lstat(fname, &sb) < 0) {
> +        fprintf(stderr, "%s: stat failed: %s\n",
> +            fname, strerror(errno));
> +        return -errno;
> +    }
> +
> +    if (!S_ISBLK(sb.st_mode)) {
> +        return 0;
> +    }
> +
> +    if (dp == NULL) {
> +        snprintf(namebuf, PATH_MAX, "r%s", fname);
> +    } else {
> +        snprintf(namebuf, PATH_MAX, "%.*s/r%s",
> +            (int)(dp - fname), fname, dp + 1);
> +    }
> +    fprintf(stderr, "%s is a block device", fname);
> +    *filename = namebuf;
> +    fprintf(stderr, ", using %s\n", *filename);
> +
> +    return 0;
> +}
> +#else
> +static int raw_normalize_devicepath(const char **filename)
> +{
> +    return 0;
> +}
> +#endif
> +
>   static int raw_open_common(BlockDriverState *bs, const char *filename,
>                              int bdrv_flags, int open_flags)
>   {
>       BDRVRawState *s = bs->opaque;
>       int fd, ret;
> 
> +    ret = raw_normalize_devicepath(&filename);
> +    if (ret != 0) {
> +        return ret;
> +    }
> +
>       s->open_flags = open_flags | O_BINARY;
>       s->open_flags &= ~O_ACCMODE;
>       if (bdrv_flags & BDRV_O_RDWR) {
> 
>
Christoph Egger - May 25, 2011, 12:19 p.m.
On 05/25/11 12:43, Kevin Wolf wrote:
> Am 24.05.2011 11:30, schrieb Christoph Egger:
>>
>> On NetBSD a userland process is better with the character device
>> interface. In addition, a block device can't be opened twice; if a Xen
>> backend opens it, qemu can't and vice-versa.
>
> If you provide a Signed-off-by, I think this patch is ready to be committed.

Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>

> Kevin
>
>>
>> diff --git a/block/raw-posix.c b/block/raw-posix.c
>> index 6b72470..64dceb1 100644
>> --- a/block/raw-posix.c
>> +++ b/block/raw-posix.c
>> @@ -136,12 +143,55 @@ static int64_t raw_getlength(BlockDriverState *bs);
>>    static int cdrom_reopen(BlockDriverState *bs);
>>    #endif
>>
>> +#if defined(__NetBSD__)
>> +static int raw_normalize_devicepath(const char **filename)
>> +{
>> +    static char namebuf[PATH_MAX];
>> +    const char *dp, *fname;
>> +    struct stat sb;
>> +
>> +    fname = *filename;
>> +    dp = strrchr(fname, '/');
>> +    if (lstat(fname,&sb)<  0) {
>> +        fprintf(stderr, "%s: stat failed: %s\n",
>> +            fname, strerror(errno));
>> +        return -errno;
>> +    }
>> +
>> +    if (!S_ISBLK(sb.st_mode)) {
>> +        return 0;
>> +    }
>> +
>> +    if (dp == NULL) {
>> +        snprintf(namebuf, PATH_MAX, "r%s", fname);
>> +    } else {
>> +        snprintf(namebuf, PATH_MAX, "%.*s/r%s",
>> +            (int)(dp - fname), fname, dp + 1);
>> +    }
>> +    fprintf(stderr, "%s is a block device", fname);
>> +    *filename = namebuf;
>> +    fprintf(stderr, ", using %s\n", *filename);
>> +
>> +    return 0;
>> +}
>> +#else
>> +static int raw_normalize_devicepath(const char **filename)
>> +{
>> +    return 0;
>> +}
>> +#endif
>> +
>>    static int raw_open_common(BlockDriverState *bs, const char *filename,
>>                               int bdrv_flags, int open_flags)
>>    {
>>        BDRVRawState *s = bs->opaque;
>>        int fd, ret;
>>
>> +    ret = raw_normalize_devicepath(&filename);
>> +    if (ret != 0) {
>> +        return ret;
>> +    }
>> +
>>        s->open_flags = open_flags | O_BINARY;
>>        s->open_flags&= ~O_ACCMODE;
>>        if (bdrv_flags&  BDRV_O_RDWR) {
>>
>>
>
>
Kevin Wolf - May 25, 2011, 1:01 p.m.
Am 25.05.2011 14:19, schrieb Christoph Egger:
> On 05/25/11 12:43, Kevin Wolf wrote:
>> Am 24.05.2011 11:30, schrieb Christoph Egger:
>>>
>>> On NetBSD a userland process is better with the character device
>>> interface. In addition, a block device can't be opened twice; if a Xen
>>> backend opens it, qemu can't and vice-versa.
>>
>> If you provide a Signed-off-by, I think this patch is ready to be committed.
> 
> Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>

Thanks, applied to the block branch.

Kevin

Patch

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 6b72470..64dceb1 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -136,12 +143,55 @@  static int64_t raw_getlength(BlockDriverState *bs);
  static int cdrom_reopen(BlockDriverState *bs);
  #endif

+#if defined(__NetBSD__)
+static int raw_normalize_devicepath(const char **filename)
+{
+    static char namebuf[PATH_MAX];
+    const char *dp, *fname;
+    struct stat sb;
+
+    fname = *filename;
+    dp = strrchr(fname, '/');
+    if (lstat(fname, &sb) < 0) {
+        fprintf(stderr, "%s: stat failed: %s\n",
+            fname, strerror(errno));
+        return -errno;
+    }
+
+    if (!S_ISBLK(sb.st_mode)) {
+        return 0;
+    }
+
+    if (dp == NULL) {
+        snprintf(namebuf, PATH_MAX, "r%s", fname);
+    } else {
+        snprintf(namebuf, PATH_MAX, "%.*s/r%s",
+            (int)(dp - fname), fname, dp + 1);
+    }
+    fprintf(stderr, "%s is a block device", fname);
+    *filename = namebuf;
+    fprintf(stderr, ", using %s\n", *filename);
+
+    return 0;
+}
+#else
+static int raw_normalize_devicepath(const char **filename)
+{
+    return 0;
+}
+#endif
+
  static int raw_open_common(BlockDriverState *bs, const char *filename,
                             int bdrv_flags, int open_flags)
  {
      BDRVRawState *s = bs->opaque;
      int fd, ret;

+    ret = raw_normalize_devicepath(&filename);
+    if (ret != 0) {
+        return ret;
+    }
+
      s->open_flags = open_flags | O_BINARY;
      s->open_flags &= ~O_ACCMODE;
      if (bdrv_flags & BDRV_O_RDWR) {