[PATCH v8] Emulate dip switch language layout settings on SUN keyboard

Henrik Carlqvist posted 1 patch 10 months, 1 week ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20230623203007.56d3d182.hc981@poolhem.se
Maintainers: "Marc-André Lureau" <marcandre.lureau@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>
docs/system/device-emulation.rst |   1 +
docs/system/devices/keyboard.rst | 129 +++++++++++++++++++++++++++++++
docs/system/target-sparc.rst     |   2 +-
hw/char/escc.c                   |  76 +++++++++++++++++-
include/hw/char/escc.h           |   1 +
5 files changed, 207 insertions(+), 2 deletions(-)
create mode 100644 docs/system/devices/keyboard.rst
[PATCH v8] Emulate dip switch language layout settings on SUN keyboard
Posted by Henrik Carlqvist 10 months, 1 week ago
SUN Type 4, 5 and 5c keyboards have dip switches to choose the language layout 
of the keyboard. Solaris makes an ioctl to query the value of the dipswitches 
and uses that value to select keyboard layout.  Also the SUN bios like the one 
in the file ss5.bin uses this value to support at least some keyboard layouts. 
However, the OpenBIOS provided with qemu is hardcoded to always use an US 
keyboard layout.

Before this patch, qemu allways gave dip switch value 0x21 (US keyboard),
this patch uses a command line switch like
"-global escc.chnA-sunkbd-layout=de" to select dip switch value. A table is
used to lookup values from arguments like:

-global escc.chnA-sunkbd-layout=fr
-global escc.chnA-sunkbd-layout=es

But the patch also accepts numeric dip switch values directly:

-global escc.chnA-sunkbd-layout=0x2b
-global escc.chnA-sunkbd-layout=43

Both values above are the same and select swedish keyboard as explained in
table 3-15 at
https://docs.oracle.com/cd/E19683-01/806-6642/new-43/index.html

Unless you want to do a full Solaris installation but happen to have
access to a Sun bios file, the easiest way to test that the patch works
is to:

qemu-system-sparc -global escc.chnA-sunkbd-layout=sv -bios /path/to/ss5.bin

If you already happen to have a Solaris installation in a qemu disk image
file you can easily try different keyboard layouts after this patch is
applied.

Signed-off-by: Henrik Carlqvist <hc1245@poolhem.se>
---

In this version 8 of my patch I have fixed and moved some .rst files as 
suggested.

Best regards Henrik

 docs/system/device-emulation.rst |   1 +
 docs/system/devices/keyboard.rst | 129 +++++++++++++++++++++++++++++++
 docs/system/target-sparc.rst     |   2 +-
 hw/char/escc.c                   |  76 +++++++++++++++++-
 include/hw/char/escc.h           |   1 +
 5 files changed, 207 insertions(+), 2 deletions(-)
 create mode 100644 docs/system/devices/keyboard.rst

diff --git a/docs/system/device-emulation.rst b/docs/system/device-emulation.rst
index 8d4a1821fa..4491c4cbf7 100644
--- a/docs/system/device-emulation.rst
+++ b/docs/system/device-emulation.rst
@@ -86,6 +86,7 @@ Emulated Devices
    devices/ccid.rst
    devices/cxl.rst
    devices/ivshmem.rst
+   devices/keyboard.rst
    devices/net.rst
    devices/nvme.rst
    devices/usb.rst
diff --git a/docs/system/devices/keyboard.rst b/docs/system/devices/keyboard.rst
new file mode 100644
index 0000000000..84ea660d50
--- /dev/null
+++ b/docs/system/devices/keyboard.rst
@@ -0,0 +1,129 @@
+.. _keyboard:
+
+Sparc32 keyboard
+----------------
+SUN Type 4, 5 and 5c keyboards have dip switches to choose the language layout 
+of the keyboard. Solaris makes an ioctl to query the value of the dipswitches 
+and uses that value to select keyboard layout. Also the SUN bios like the one 
+in the file ss5.bin uses this value to support at least some keyboard layouts. 
+However, the OpenBIOS provided with qemu is hardcoded to always use an 
+US keyboard layout.
+
+With the escc.chnA-sunkbd-layout driver property it is possible to select
+keyboard layout. Example:
+
+-global escc.chnA-sunkbd-layout=de
+
+Depending on type of keyboard, the keyboard can have 6 or 5 dip-switches to
+select keyboard layout, giving up to 64 different layouts. Not all
+combinations are supported by Solaris and even less by Sun OpenBoot BIOS.
+
+The dip switch settings can be given as hexadecimal number, decimal number
+or in some cases as a language string. Examples:
+
+-global escc.chnA-sunkbd-layout=0x2b
+
+-global escc.chnA-sunkbd-layout=43
+
+-global escc.chnA-sunkbd-layout=sv
+
+The above 3 examples all select a swedish keyboard layout. Table 3-15 at
+https://docs.oracle.com/cd/E19683-01/806-6642/new-43/index.html explains which
+keytable file is used for different dip switch settings. The information
+in that table can be summarized in this table:
+
+.. list-table:: Language selection values for escc.chnA-sunkbd-layout
+   :widths: 10 10 10
+   :header-rows: 1
+
+   * - Hexadecimal value
+     - Decimal value
+     - Language code
+   * - 0x21
+     - 33
+     - en-us
+   * - 0x23
+     - 35
+     - fr
+   * - 0x24
+     - 36
+     - da
+   * - 0x25
+     - 37
+     - de
+   * - 0x26
+     - 38
+     - it
+   * - 0x27
+     - 39
+     - nl
+   * - 0x28
+     - 40
+     - no
+   * - 0x29
+     - 41
+     - pt
+   * - 0x2a
+     - 42
+     - es
+   * - 0x2b
+     - 43
+     - sv
+   * - 0x2c
+     - 44
+     - fr-ch
+   * - 0x2d
+     - 45
+     - de-ch
+   * - 0x2e
+     - 46
+     - en-gb
+   * - 0x2f
+     - 47
+     - ko
+   * - 0x30
+     - 48
+     - tw
+   * - 0x31
+     - 49
+     - ja
+   * - 0x32
+     - 50
+     - fr-ca
+   * - 0x33
+     - 51
+     - hu
+   * - 0x34
+     - 52
+     - pl
+   * - 0x35
+     - 53
+     - cz
+   * - 0x36
+     - 54
+     - ru
+   * - 0x37
+     - 55
+     - lv
+   * - 0x38
+     - 56
+     - tr
+   * - 0x39
+     - 57
+     - gr
+   * - 0x3a
+     - 58
+     - ar
+   * - 0x3b
+     - 59
+     - lt
+   * - 0x3c
+     - 60
+     - nl-be
+   * - 0x3c
+     - 60
+     - be
+
+Not all dip switch values have a corresponding language code and both "be" and
+"nl-be" correspond to the same dip switch value. By default, if no value is
+given to escc.chnA-sunkbd-layout 0x21 (en-us) will be used.
diff --git a/docs/system/target-sparc.rst b/docs/system/target-sparc.rst
index b55f8d09e9..9ec8c90c14 100644
--- a/docs/system/target-sparc.rst
+++ b/docs/system/target-sparc.rst
@@ -38,7 +38,7 @@ QEMU emulates the following sun4m peripherals:
 -  Non Volatile RAM M48T02/M48T08
 
 -  Slave I/O: timers, interrupt controllers, Zilog serial ports,
-   keyboard and power/reset logic
+   :ref:`keyboard` and power/reset logic
 
 -  ESP SCSI controller with hard disk and CD-ROM support
 
diff --git a/hw/char/escc.c b/hw/char/escc.c
index 17a908c59b..463b3d2e93 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -31,6 +31,8 @@
 #include "qemu/module.h"
 #include "hw/char/escc.h"
 #include "ui/console.h"
+
+#include "qemu/cutils.h"
 #include "trace.h"
 
 /*
@@ -190,6 +192,7 @@
 #define R_MISC1I 14
 #define R_EXTINT 15
 
+static unsigned char sunkbd_layout_dip_switch(const char *sunkbd_layout);
 static void handle_kbd_command(ESCCChannelState *s, int val);
 static int serial_can_receive(void *opaque);
 static void serial_receive_byte(ESCCChannelState *s, int ch);
@@ -846,6 +849,75 @@ static QemuInputHandler sunkbd_handler = {
     .event = sunkbd_handle_event,
 };
 
+static unsigned char sunkbd_layout_dip_switch(const char *kbd_layout)
+{
+    /* Return the value of the dip-switches in a SUN Type 5 keyboard */
+    static unsigned char ret = 0xff;
+
+    if ((ret == 0xff) && kbd_layout) {
+        int i;
+        struct layout_values {
+            const char *lang;
+            unsigned char dip;
+        } languages[] =
+    /* Dip values from table 3-16 Layouts for Type 4, 5, and 5c Keyboards */
+            {
+                {"en-us", 0x21}, /* U.S.A. (US5.kt) */
+                                 /* 0x22 is some other US (US_UNIX5.kt)*/
+                {"fr",    0x23}, /* France (France5.kt) */
+                {"da",    0x24}, /* Denmark (Denmark5.kt) */
+                {"de",    0x25}, /* Germany (Germany5.kt) */
+                {"it",    0x26}, /* Italy (Italy5.kt) */
+                {"nl",    0x27}, /* The Netherlands (Netherland5.kt) */
+                {"no",    0x28}, /* Norway (Norway.kt) */
+                {"pt",    0x29}, /* Portugal (Portugal5.kt) */
+                {"es",    0x2a}, /* Spain (Spain5.kt) */
+                {"sv",    0x2b}, /* Sweden (Sweden5.kt) */
+                {"fr-ch", 0x2c}, /* Switzerland/French (Switzer_Fr5.kt) */
+                {"de-ch", 0x2d}, /* Switzerland/German (Switzer_Ge5.kt) */
+                {"en-gb", 0x2e}, /* Great Britain (UK5.kt) */
+                {"ko",    0x2f}, /* Korea (Korea5.kt) */
+                {"tw",    0x30}, /* Taiwan (Taiwan5.kt) */
+                {"ja",    0x31}, /* Japan (Japan5.kt) */
+                {"fr-ca", 0x32}, /* Canada/French (Canada_Fr5.kt) */
+                {"hu",    0x33}, /* Hungary (Hungary5.kt) */
+                {"pl",    0x34}, /* Poland (Poland5.kt) */
+                {"cz",    0x35}, /* Czech (Czech5.kt) */
+                {"ru",    0x36}, /* Russia (Russia5.kt) */
+                {"lv",    0x37}, /* Latvia (Latvia5.kt) */
+                {"tr",    0x38}, /* Turkey-Q5 (TurkeyQ5.kt) */
+                {"gr",    0x39}, /* Greece (Greece5.kt) */
+                {"ar",    0x3a}, /* Arabic (Arabic5.kt) */
+                {"lt",    0x3b}, /* Lithuania (Lithuania5.kt) */
+                {"nl-be", 0x3c}, /* Belgium (Belgian5.kt) */
+                {"be",    0x3c}, /* Belgium (Belgian5.kt) */
+            };
+
+        for (i = 0;
+             i < sizeof(languages) / sizeof(struct layout_values);
+             i++) {
+            if (!strcmp(kbd_layout, languages[i].lang)) {
+                ret = languages[i].dip;
+                return ret;
+            }
+        }
+        /* Found no known language code */
+
+        if ((kbd_layout[0] >= '0') && (kbd_layout[0] <= '9')) {
+            unsigned int tmp;
+            /* As a fallback we also accept numeric dip switch value */
+            if (!qemu_strtoui(kbd_layout, NULL, 0, &tmp)) {
+                ret = (unsigned char)tmp;
+            }
+        }
+    }
+    if (ret == 0xff) {
+        /* Final fallback if keyboard_layout was not set or recognized */
+        ret = 0x21; /* en-us layout */
+    }
+    return ret;
+}
+
 static void handle_kbd_command(ESCCChannelState *s, int val)
 {
     trace_escc_kbd_command(val);
@@ -867,7 +939,7 @@ static void handle_kbd_command(ESCCChannelState *s, int val)
     case 0xf:
         clear_queue(s);
         put_queue(s, 0xfe);
-        put_queue(s, 0x21); /*  en-us layout */
+        put_queue(s, sunkbd_layout_dip_switch(s->sunkbd_layout));
         break;
     default:
         break;
@@ -976,6 +1048,8 @@ static Property escc_properties[] = {
     DEFINE_PROP_UINT32("chnAtype",  ESCCState, chn[1].type, 0),
     DEFINE_PROP_CHR("chrB", ESCCState, chn[0].chr),
     DEFINE_PROP_CHR("chrA", ESCCState, chn[1].chr),
+    DEFINE_PROP_STRING("chnA-sunkbd-layout", ESCCState,
+		       chn[1].sunkbd_layout),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/char/escc.h b/include/hw/char/escc.h
index 7e9482dee2..5669a5b811 100644
--- a/include/hw/char/escc.h
+++ b/include/hw/char/escc.h
@@ -45,6 +45,7 @@ typedef struct ESCCChannelState {
     ESCCChnType type;
     uint8_t rx, tx;
     QemuInputHandlerState *hs;
+    char *sunkbd_layout;
 } ESCCChannelState;
 
 struct ESCCState {
-- 
2.35.1
Re: [PATCH v8] Emulate dip switch language layout settings on SUN keyboard
Posted by Mark Cave-Ayland 10 months ago
On 23/06/2023 19:30, Henrik Carlqvist wrote:

> SUN Type 4, 5 and 5c keyboards have dip switches to choose the language layout
> of the keyboard. Solaris makes an ioctl to query the value of the dipswitches
> and uses that value to select keyboard layout.  Also the SUN bios like the one
> in the file ss5.bin uses this value to support at least some keyboard layouts.
> However, the OpenBIOS provided with qemu is hardcoded to always use an US
> keyboard layout.
> 
> Before this patch, qemu allways gave dip switch value 0x21 (US keyboard),
> this patch uses a command line switch like
> "-global escc.chnA-sunkbd-layout=de" to select dip switch value. A table is
> used to lookup values from arguments like:
> 
> -global escc.chnA-sunkbd-layout=fr
> -global escc.chnA-sunkbd-layout=es
> 
> But the patch also accepts numeric dip switch values directly:
> 
> -global escc.chnA-sunkbd-layout=0x2b
> -global escc.chnA-sunkbd-layout=43
> 
> Both values above are the same and select swedish keyboard as explained in
> table 3-15 at
> https://docs.oracle.com/cd/E19683-01/806-6642/new-43/index.html
> 
> Unless you want to do a full Solaris installation but happen to have
> access to a Sun bios file, the easiest way to test that the patch works
> is to:
> 
> qemu-system-sparc -global escc.chnA-sunkbd-layout=sv -bios /path/to/ss5.bin
> 
> If you already happen to have a Solaris installation in a qemu disk image
> file you can easily try different keyboard layouts after this patch is
> applied.
> 
> Signed-off-by: Henrik Carlqvist <hc1245@poolhem.se>
> ---
> 
> In this version 8 of my patch I have fixed and moved some .rst files as
> suggested.
> 
> Best regards Henrik
> 
>   docs/system/device-emulation.rst |   1 +
>   docs/system/devices/keyboard.rst | 129 +++++++++++++++++++++++++++++++
>   docs/system/target-sparc.rst     |   2 +-
>   hw/char/escc.c                   |  76 +++++++++++++++++-
>   include/hw/char/escc.h           |   1 +
>   5 files changed, 207 insertions(+), 2 deletions(-)
>   create mode 100644 docs/system/devices/keyboard.rst
> 
> diff --git a/docs/system/device-emulation.rst b/docs/system/device-emulation.rst
> index 8d4a1821fa..4491c4cbf7 100644
> --- a/docs/system/device-emulation.rst
> +++ b/docs/system/device-emulation.rst
> @@ -86,6 +86,7 @@ Emulated Devices
>      devices/ccid.rst
>      devices/cxl.rst
>      devices/ivshmem.rst
> +   devices/keyboard.rst
>      devices/net.rst
>      devices/nvme.rst
>      devices/usb.rst
> diff --git a/docs/system/devices/keyboard.rst b/docs/system/devices/keyboard.rst
> new file mode 100644
> index 0000000000..84ea660d50
> --- /dev/null
> +++ b/docs/system/devices/keyboard.rst
> @@ -0,0 +1,129 @@
> +.. _keyboard:
> +
> +Sparc32 keyboard
> +----------------
> +SUN Type 4, 5 and 5c keyboards have dip switches to choose the language layout
> +of the keyboard. Solaris makes an ioctl to query the value of the dipswitches
> +and uses that value to select keyboard layout. Also the SUN bios like the one
> +in the file ss5.bin uses this value to support at least some keyboard layouts.
> +However, the OpenBIOS provided with qemu is hardcoded to always use an
> +US keyboard layout.
> +
> +With the escc.chnA-sunkbd-layout driver property it is possible to select
> +keyboard layout. Example:
> +
> +-global escc.chnA-sunkbd-layout=de
> +
> +Depending on type of keyboard, the keyboard can have 6 or 5 dip-switches to
> +select keyboard layout, giving up to 64 different layouts. Not all
> +combinations are supported by Solaris and even less by Sun OpenBoot BIOS.
> +
> +The dip switch settings can be given as hexadecimal number, decimal number
> +or in some cases as a language string. Examples:
> +
> +-global escc.chnA-sunkbd-layout=0x2b
> +
> +-global escc.chnA-sunkbd-layout=43
> +
> +-global escc.chnA-sunkbd-layout=sv
> +
> +The above 3 examples all select a swedish keyboard layout. Table 3-15 at
> +https://docs.oracle.com/cd/E19683-01/806-6642/new-43/index.html explains which
> +keytable file is used for different dip switch settings. The information
> +in that table can be summarized in this table:
> +
> +.. list-table:: Language selection values for escc.chnA-sunkbd-layout
> +   :widths: 10 10 10
> +   :header-rows: 1
> +
> +   * - Hexadecimal value
> +     - Decimal value
> +     - Language code
> +   * - 0x21
> +     - 33
> +     - en-us
> +   * - 0x23
> +     - 35
> +     - fr
> +   * - 0x24
> +     - 36
> +     - da
> +   * - 0x25
> +     - 37
> +     - de
> +   * - 0x26
> +     - 38
> +     - it
> +   * - 0x27
> +     - 39
> +     - nl
> +   * - 0x28
> +     - 40
> +     - no
> +   * - 0x29
> +     - 41
> +     - pt
> +   * - 0x2a
> +     - 42
> +     - es
> +   * - 0x2b
> +     - 43
> +     - sv
> +   * - 0x2c
> +     - 44
> +     - fr-ch
> +   * - 0x2d
> +     - 45
> +     - de-ch
> +   * - 0x2e
> +     - 46
> +     - en-gb
> +   * - 0x2f
> +     - 47
> +     - ko
> +   * - 0x30
> +     - 48
> +     - tw
> +   * - 0x31
> +     - 49
> +     - ja
> +   * - 0x32
> +     - 50
> +     - fr-ca
> +   * - 0x33
> +     - 51
> +     - hu
> +   * - 0x34
> +     - 52
> +     - pl
> +   * - 0x35
> +     - 53
> +     - cz
> +   * - 0x36
> +     - 54
> +     - ru
> +   * - 0x37
> +     - 55
> +     - lv
> +   * - 0x38
> +     - 56
> +     - tr
> +   * - 0x39
> +     - 57
> +     - gr
> +   * - 0x3a
> +     - 58
> +     - ar
> +   * - 0x3b
> +     - 59
> +     - lt
> +   * - 0x3c
> +     - 60
> +     - nl-be
> +   * - 0x3c
> +     - 60
> +     - be
> +
> +Not all dip switch values have a corresponding language code and both "be" and
> +"nl-be" correspond to the same dip switch value. By default, if no value is
> +given to escc.chnA-sunkbd-layout 0x21 (en-us) will be used.
> diff --git a/docs/system/target-sparc.rst b/docs/system/target-sparc.rst
> index b55f8d09e9..9ec8c90c14 100644
> --- a/docs/system/target-sparc.rst
> +++ b/docs/system/target-sparc.rst
> @@ -38,7 +38,7 @@ QEMU emulates the following sun4m peripherals:
>   -  Non Volatile RAM M48T02/M48T08
>   
>   -  Slave I/O: timers, interrupt controllers, Zilog serial ports,
> -   keyboard and power/reset logic
> +   :ref:`keyboard` and power/reset logic
>   
>   -  ESP SCSI controller with hard disk and CD-ROM support
>   
> diff --git a/hw/char/escc.c b/hw/char/escc.c
> index 17a908c59b..463b3d2e93 100644
> --- a/hw/char/escc.c
> +++ b/hw/char/escc.c
> @@ -31,6 +31,8 @@
>   #include "qemu/module.h"
>   #include "hw/char/escc.h"
>   #include "ui/console.h"
> +
> +#include "qemu/cutils.h"
>   #include "trace.h"
>   
>   /*
> @@ -190,6 +192,7 @@
>   #define R_MISC1I 14
>   #define R_EXTINT 15
>   
> +static unsigned char sunkbd_layout_dip_switch(const char *sunkbd_layout);
>   static void handle_kbd_command(ESCCChannelState *s, int val);
>   static int serial_can_receive(void *opaque);
>   static void serial_receive_byte(ESCCChannelState *s, int ch);
> @@ -846,6 +849,75 @@ static QemuInputHandler sunkbd_handler = {
>       .event = sunkbd_handle_event,
>   };
>   
> +static unsigned char sunkbd_layout_dip_switch(const char *kbd_layout)
> +{
> +    /* Return the value of the dip-switches in a SUN Type 5 keyboard */
> +    static unsigned char ret = 0xff;
> +
> +    if ((ret == 0xff) && kbd_layout) {
> +        int i;
> +        struct layout_values {
> +            const char *lang;
> +            unsigned char dip;
> +        } languages[] =
> +    /* Dip values from table 3-16 Layouts for Type 4, 5, and 5c Keyboards */
> +            {
> +                {"en-us", 0x21}, /* U.S.A. (US5.kt) */
> +                                 /* 0x22 is some other US (US_UNIX5.kt)*/
> +                {"fr",    0x23}, /* France (France5.kt) */
> +                {"da",    0x24}, /* Denmark (Denmark5.kt) */
> +                {"de",    0x25}, /* Germany (Germany5.kt) */
> +                {"it",    0x26}, /* Italy (Italy5.kt) */
> +                {"nl",    0x27}, /* The Netherlands (Netherland5.kt) */
> +                {"no",    0x28}, /* Norway (Norway.kt) */
> +                {"pt",    0x29}, /* Portugal (Portugal5.kt) */
> +                {"es",    0x2a}, /* Spain (Spain5.kt) */
> +                {"sv",    0x2b}, /* Sweden (Sweden5.kt) */
> +                {"fr-ch", 0x2c}, /* Switzerland/French (Switzer_Fr5.kt) */
> +                {"de-ch", 0x2d}, /* Switzerland/German (Switzer_Ge5.kt) */
> +                {"en-gb", 0x2e}, /* Great Britain (UK5.kt) */
> +                {"ko",    0x2f}, /* Korea (Korea5.kt) */
> +                {"tw",    0x30}, /* Taiwan (Taiwan5.kt) */
> +                {"ja",    0x31}, /* Japan (Japan5.kt) */
> +                {"fr-ca", 0x32}, /* Canada/French (Canada_Fr5.kt) */
> +                {"hu",    0x33}, /* Hungary (Hungary5.kt) */
> +                {"pl",    0x34}, /* Poland (Poland5.kt) */
> +                {"cz",    0x35}, /* Czech (Czech5.kt) */
> +                {"ru",    0x36}, /* Russia (Russia5.kt) */
> +                {"lv",    0x37}, /* Latvia (Latvia5.kt) */
> +                {"tr",    0x38}, /* Turkey-Q5 (TurkeyQ5.kt) */
> +                {"gr",    0x39}, /* Greece (Greece5.kt) */
> +                {"ar",    0x3a}, /* Arabic (Arabic5.kt) */
> +                {"lt",    0x3b}, /* Lithuania (Lithuania5.kt) */
> +                {"nl-be", 0x3c}, /* Belgium (Belgian5.kt) */
> +                {"be",    0x3c}, /* Belgium (Belgian5.kt) */
> +            };
> +
> +        for (i = 0;
> +             i < sizeof(languages) / sizeof(struct layout_values);
> +             i++) {
> +            if (!strcmp(kbd_layout, languages[i].lang)) {
> +                ret = languages[i].dip;
> +                return ret;
> +            }
> +        }
> +        /* Found no known language code */
> +
> +        if ((kbd_layout[0] >= '0') && (kbd_layout[0] <= '9')) {
> +            unsigned int tmp;
> +            /* As a fallback we also accept numeric dip switch value */
> +            if (!qemu_strtoui(kbd_layout, NULL, 0, &tmp)) {
> +                ret = (unsigned char)tmp;
> +            }
> +        }
> +    }
> +    if (ret == 0xff) {
> +        /* Final fallback if keyboard_layout was not set or recognized */
> +        ret = 0x21; /* en-us layout */
> +    }
> +    return ret;
> +}
> +
>   static void handle_kbd_command(ESCCChannelState *s, int val)
>   {
>       trace_escc_kbd_command(val);
> @@ -867,7 +939,7 @@ static void handle_kbd_command(ESCCChannelState *s, int val)
>       case 0xf:
>           clear_queue(s);
>           put_queue(s, 0xfe);
> -        put_queue(s, 0x21); /*  en-us layout */
> +        put_queue(s, sunkbd_layout_dip_switch(s->sunkbd_layout));
>           break;
>       default:
>           break;
> @@ -976,6 +1048,8 @@ static Property escc_properties[] = {
>       DEFINE_PROP_UINT32("chnAtype",  ESCCState, chn[1].type, 0),
>       DEFINE_PROP_CHR("chrB", ESCCState, chn[0].chr),
>       DEFINE_PROP_CHR("chrA", ESCCState, chn[1].chr),
> +    DEFINE_PROP_STRING("chnA-sunkbd-layout", ESCCState,
> +		       chn[1].sunkbd_layout),
>       DEFINE_PROP_END_OF_LIST(),
>   };
>   
> diff --git a/include/hw/char/escc.h b/include/hw/char/escc.h
> index 7e9482dee2..5669a5b811 100644
> --- a/include/hw/char/escc.h
> +++ b/include/hw/char/escc.h
> @@ -45,6 +45,7 @@ typedef struct ESCCChannelState {
>       ESCCChnType type;
>       uint8_t rx, tx;
>       QemuInputHandlerState *hs;
> +    char *sunkbd_layout;
>   } ESCCChannelState;
>   
>   struct ESCCState {

I think this is about ready to merge: the only thing I'd like to change is to swap 
unsigned char to uint8_t in the signature of sunkbd_layout_dip_switch(), but I can 
fix that up myself and queue it to my qemu-sparc branch.

Thanks for your patience with this patchset!


ATB,

Mark.
Re: [PATCH v8] Emulate dip switch language layout settings on SUN keyboard
Posted by Henrik Carlqvist 10 months ago
On Tue, 27 Jun 2023 07:33:46 +0100
Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> wrote:
> I think this is about ready to merge: the only thing I'd like to change is
> to swap unsigned char to uint8_t in the signature of
> sunkbd_layout_dip_switch(), but I can fix that up myself and queue it to my
> qemu-sparc branch.

Thanks for accepting my patch! Please let me know if you want me to do
anything more!

Best regards Henrik
Re: [PATCH v8] Emulate dip switch language layout settings on SUN keyboard
Posted by Daniel P. Berrangé 10 months, 1 week ago
On Fri, Jun 23, 2023 at 08:30:07PM +0200, Henrik Carlqvist wrote:
> SUN Type 4, 5 and 5c keyboards have dip switches to choose the language layout 
> of the keyboard. Solaris makes an ioctl to query the value of the dipswitches 
> and uses that value to select keyboard layout.  Also the SUN bios like the one 
> in the file ss5.bin uses this value to support at least some keyboard layouts. 
> However, the OpenBIOS provided with qemu is hardcoded to always use an US 
> keyboard layout.
> 
> Before this patch, qemu allways gave dip switch value 0x21 (US keyboard),
> this patch uses a command line switch like
> "-global escc.chnA-sunkbd-layout=de" to select dip switch value. A table is
> used to lookup values from arguments like:
> 
> -global escc.chnA-sunkbd-layout=fr
> -global escc.chnA-sunkbd-layout=es
> 
> But the patch also accepts numeric dip switch values directly:
> 
> -global escc.chnA-sunkbd-layout=0x2b
> -global escc.chnA-sunkbd-layout=43
> 
> Both values above are the same and select swedish keyboard as explained in
> table 3-15 at
> https://docs.oracle.com/cd/E19683-01/806-6642/new-43/index.html
> 
> Unless you want to do a full Solaris installation but happen to have
> access to a Sun bios file, the easiest way to test that the patch works
> is to:
> 
> qemu-system-sparc -global escc.chnA-sunkbd-layout=sv -bios /path/to/ss5.bin
> 
> If you already happen to have a Solaris installation in a qemu disk image
> file you can easily try different keyboard layouts after this patch is
> applied.
> 
> Signed-off-by: Henrik Carlqvist <hc1245@poolhem.se>
> ---

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|


[PATCH v1] Allowing setting and overriding parameters in smb.conf
Posted by Henrik Carlqvist 9 months ago
From c480f787981308067a059213a1a7ce9c70ab668e Mon Sep 17 00:00:00 2001
From: Henrik Carlqvist <hc1245@poolhem.se>
Date: Tue, 1 Aug 2023 23:00:15 +0200
Subject: [PATCH] Allowing setting and overriding parameters in smb.conf

Signed-off-by: Henrik Carlqvist <hc1245@poolhem.se>
---

It would be nice to be able to change settings in smb.conf from the qemu 
command line. A kludge to edit the qemu smb.conf of a running smbd process 
is described at https://wiki.archlinux.org/title/QEMU , but IMHO my patch
provides a cleaner solution where parameters can be initially set to the
preferred values.

Best regards Henrik

 net/slirp.c     | 44 ++++++++++++++++++++++++++++++++++++++------
 qapi/net.json   |  3 +++
 qemu-options.hx | 15 ++++++++++++---
 3 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index c33b3e02e7..f860ea48f6 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -106,7 +106,8 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp);
 
 #if defined(CONFIG_SMBD_COMMAND)
 static int slirp_smb(SlirpState *s, const char *exported_dir,
-                     struct in_addr vserver_addr, Error **errp);
+                     struct in_addr vserver_addr, const char *smbparams,
+                     Error **errp);
 static void slirp_smb_cleanup(SlirpState *s);
 #else
 static inline void slirp_smb_cleanup(SlirpState *s) { }
@@ -424,6 +425,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
                           const char *bootfile, const char *vdhcp_start,
                           const char *vnameserver, const char *vnameserver6,
                           const char *smb_export, const char *vsmbserver,
+                          const char *smbparams,
                           const char **dnssearch, const char *vdomainname,
                           const char *tftp_server_name,
                           Error **errp)
@@ -678,7 +680,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
     }
 #if defined(CONFIG_SMBD_COMMAND)
     if (smb_export) {
-        if (slirp_smb(s, smb_export, smbsrv, errp) < 0) {
+        if (slirp_smb(s, smb_export, smbsrv, smbparams, errp) < 0) {
             goto error;
         }
     }
@@ -891,7 +893,8 @@ static void slirp_smb_cleanup(SlirpState *s)
 }
 
 static int slirp_smb(SlirpState* s, const char *exported_dir,
-                     struct in_addr vserver_addr, Error **errp)
+                     struct in_addr vserver_addr, const char *smbparams,
+                     Error **errp)
 {
     char *smb_conf;
     char *smb_cmdline;
@@ -950,10 +953,11 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
             "printing = bsd\n"
             "disable spoolss = yes\n"
             "usershare max shares = 0\n"
-            "[qemu]\n"
-            "path=%s\n"
             "read only=no\n"
             "guest ok=yes\n"
+           "%s"
+            "[qemu]\n"
+            "path=%s\n"
             "force user=%s\n",
             s->smb_dir,
             s->smb_dir,
@@ -963,6 +967,7 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
             s->smb_dir,
             s->smb_dir,
             s->smb_dir,
+            smbparams,
             exported_dir,
             passwd->pw_name
             );
@@ -1143,6 +1148,29 @@ static const char **slirp_dnssearch(const StringList *dnsname)
     return ret;
 }
 
+static char *slirp_smbparams(const StringList *smbparam)
+{
+    const StringList *c = smbparam;
+    size_t i = 1; /* for string terminating 0 */
+    char *ret;
+
+    while (c) {
+        i += strlen(c->value->str);
+        i++; /* for \n */
+        c = c->next;
+    }
+    ret = g_malloc(i * sizeof(*ret));
+    ret[0]=0; /* Start with empty string */
+
+    c = smbparam;
+    while (c) {
+        pstrcat(ret, i * sizeof(*ret), c->value->str);
+        pstrcat(ret, i * sizeof(*ret), "\n");
+        c = c->next;
+    }
+    return ret;
+}
+
 int net_init_slirp(const Netdev *netdev, const char *name,
                    NetClientState *peer, Error **errp)
 {
@@ -1151,6 +1179,7 @@ int net_init_slirp(const Netdev *netdev, const char *name,
     int ret;
     const NetdevUserOptions *user;
     const char **dnssearch;
+    char *smbparams;
     bool ipv4 = true, ipv6 = true;
 
     assert(netdev->type == NET_CLIENT_DRIVER_USER);
@@ -1170,6 +1199,7 @@ int net_init_slirp(const Netdev *netdev, const char *name,
            NULL;
 
     dnssearch = slirp_dnssearch(user->dnssearch);
+    smbparams = slirp_smbparams(user->smbparam);
 
     /* all optional fields are initialized to "all bits zero" */
 
@@ -1182,7 +1212,8 @@ int net_init_slirp(const Netdev *netdev, const char *name,
                          user->ipv6_host, user->hostname, user->tftp,
                          user->bootfile, user->dhcpstart,
                          user->dns, user->ipv6_dns, user->smb,
-                         user->smbserver, dnssearch, user->domainname,
+                         user->smbserver, smbparams,
+                         dnssearch, user->domainname,
                          user->tftp_server_name, errp);
 
     while (slirp_configs) {
@@ -1193,6 +1224,7 @@ int net_init_slirp(const Netdev *netdev, const char *name,
 
     g_free(vnet);
     g_free(dnssearch);
+    g_free(smbparams);
 
     return ret;
 }
diff --git a/qapi/net.json b/qapi/net.json
index 313c8a606e..163091719c 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -156,6 +156,8 @@
 #
 # @smbserver: IP address of the built-in SMB server
 #
+# @smbparam: list of parameters with values for smb.conf
+#
 # @hostfwd: redirect incoming TCP or UDP host connections to guest
 #     endpoints
 #
@@ -186,6 +188,7 @@
     '*ipv6-dns':         'str',
     '*smb':       'str',
     '*smbserver': 'str',
+    '*smbparam': ['String'],
     '*hostfwd':   ['String'],
     '*guestfwd':  ['String'],
     '*tftp-server-name': 'str' } }
diff --git a/qemu-options.hx b/qemu-options.hx
index 29b98c3d4c..7b92d08c3e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2758,9 +2758,9 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
     "         [,ipv6=on|off][,ipv6-net=addr[/int]][,ipv6-host=addr]\n"
     "         [,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
     "         [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,domainname=domain]\n"
-    "         [,tftp=dir][,tftp-server-name=name][,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
+    "         [,tftp=dir][,tftp-server-name=name][,bootfile=f][,hostfwd=rule][,guestfwd=rule]\n"
 #ifndef _WIN32
-                                             "[,smb=dir[,smbserver=addr]]\n"
+    "         [,smb=dir[,smbserver=addr][,smbparam=parameter=value]]\n"
 #endif
     "                configure a user mode network backend with ID 'str',\n"
     "                its DHCP server and optional services\n"
@@ -3062,7 +3062,7 @@ SRST
             |qemu_system| -hda linux.img -boot n -device e1000,netdev=n1 \\
                 -netdev user,id=n1,tftp=/path/to/tftp/files,bootfile=/pxelinux.0
 
-    ``smb=dir[,smbserver=addr]``
+    ``smb=dir[,smbserver=addr][,smbparam=parameter=value]``
         When using the user mode network stack, activate a built-in SMB
         server so that Windows OSes can access to the host files in
         ``dir`` transparently. The IP address of the SMB server can be
@@ -3081,6 +3081,15 @@ SRST
 
         Then ``dir`` can be accessed in ``\\smbserver\qemu``.
 
+        It is possible to set samba parameters in the generated smb.conf
+        with one or more ``smbparam=parameter=value``. Example:
+
+        .. parsed-literal::
+
+            |qemu_system| -nic user,smb=/tmp,smbparam="read only"=yes,smbparam="server min protocol"=NT1
+
+        See the man page of smb.conf for a complete listing of parameters.
+
         Note that a SAMBA server must be installed on the host OS.
 
     ``hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport``
-- 
2.35.1
Re: [PATCH v1] Allowing setting and overriding parameters in smb.conf
Posted by Samuel Thibault 9 months ago
Henrik Carlqvist, le mar. 01 août 2023 23:27:25 +0200, a ecrit:
> @@ -950,10 +953,11 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
>              "printing = bsd\n"
>              "disable spoolss = yes\n"
>              "usershare max shares = 0\n"
> -            "[qemu]\n"
> -            "path=%s\n"
>              "read only=no\n"
>              "guest ok=yes\n"
> +           "%s"
> +            "[qemu]\n"
> +            "path=%s\n"

?This is moving read only and guest ok to the global section?

Samuel

Re: [PATCH v1] Allowing setting and overriding parameters in smb.conf
Posted by Henrik Carlqvist 9 months ago
On Wed, 2 Aug 2023 21:53:56 +0200
Samuel Thibault <samuel.thibault@gnu.org> wrote:

> Henrik Carlqvist, le mar. 01 août 2023 23:27:25 +0200, a ecrit:
> > @@ -950,10 +953,11 @@ static int slirp_smb(SlirpState* s, const char
> > *exported_dir,
> >              "printing = bsd\n"
> >              "disable spoolss = yes\n"
> >              "usershare max shares = 0\n"
> > -            "[qemu]\n"
> > -            "path=%s\n"
> >              "read only=no\n"
> >              "guest ok=yes\n"
> > +           "%s"
> > +            "[qemu]\n"
> > +            "path=%s\n"
> 
> ?This is moving read only and guest ok to the global section?

Thanks for your quick reply!

Yes, I thought that would be OK because the [qemu] share will inherit those
settings from the global section. By placing those in the global section it is
possible to override them with later contradicting statements like 
"read only=yes\n" in the %s before the [qemu] section.

If I wouldn't have moved them to the global section there could have been a
need to be able to alter parameters both in the global section and the [qemu]
share section as any setting in a share section overrides any global settings.

By only adding custom parameter settings to the end of the global section the
user interface was kept in a more simple way.

regards Henrik
Re: [PATCH v1] Allowing setting and overriding parameters in smb.conf
Posted by Samuel Thibault 9 months ago
Henrik Carlqvist, le jeu. 03 août 2023 01:09:09 +0200, a ecrit:
> On Wed, 2 Aug 2023 21:53:56 +0200
> Samuel Thibault <samuel.thibault@gnu.org> wrote:
> 
> > Henrik Carlqvist, le mar. 01 août 2023 23:27:25 +0200, a ecrit:
> > > @@ -950,10 +953,11 @@ static int slirp_smb(SlirpState* s, const char
> > > *exported_dir,
> > >              "printing = bsd\n"
> > >              "disable spoolss = yes\n"
> > >              "usershare max shares = 0\n"
> > > -            "[qemu]\n"
> > > -            "path=%s\n"
> > >              "read only=no\n"
> > >              "guest ok=yes\n"
> > > +           "%s"
> > > +            "[qemu]\n"
> > > +            "path=%s\n"
> > 
> > ?This is moving read only and guest ok to the global section?
> 
> Thanks for your quick reply!
> 
> Yes, I thought that would be OK because the [qemu] share will inherit those
> settings from the global section. By placing those in the global section it is
> possible to override them with later contradicting statements like 
> "read only=yes\n" in the %s before the [qemu] section.

Ok, it would be useful to mention that in the changelog.

Thanks,
Samuel

Re: [PATCH v1] Allowing setting and overriding parameters in smb.conf
Posted by Henrik Carlqvist 9 months ago
On Thu, 3 Aug 2023 01:13:24 +0200
Samuel Thibault <samuel.thibault@gnu.org> wrote:

> Henrik Carlqvist, le jeu. 03 août 2023 01:09:09 +0200, a ecrit:
> > On Wed, 2 Aug 2023 21:53:56 +0200
> > Samuel Thibault <samuel.thibault@gnu.org> wrote:
> > 
> > > Henrik Carlqvist, le mar. 01 août 2023 23:27:25 +0200, a ecrit:
> > > > @@ -950,10 +953,11 @@ static int slirp_smb(SlirpState* s, const char
> > > > *exported_dir,
> > > >              "printing = bsd\n"
> > > >              "disable spoolss = yes\n"
> > > >              "usershare max shares = 0\n"
> > > > -            "[qemu]\n"
> > > > -            "path=%s\n"
> > > >              "read only=no\n"
> > > >              "guest ok=yes\n"
> > > > +           "%s"
> > > > +            "[qemu]\n"
> > > > +            "path=%s\n"
> > > 
> > > ?This is moving read only and guest ok to the global section?
> > 
> > Thanks for your quick reply!
> > 
> > Yes, I thought that would be OK because the [qemu] share will inherit
> > those settings from the global section. By placing those in the global
> > section it is possible to override them with later contradicting
> > statements like "read only=yes\n" in the %s before the [qemu] section.
> 
> Ok, it would be useful to mention that in the changelog.

Is there a changelog in the repo? Or do you mean that I should mention that in
the git commit message?

Best regards Henrik
Re: [PATCH v1] Allowing setting and overriding parameters in smb.conf
Posted by Samuel Thibault 9 months ago
Henrik Carlqvist, le jeu. 03 août 2023 01:26:02 +0200, a ecrit:
> On Thu, 3 Aug 2023 01:13:24 +0200
> Samuel Thibault <samuel.thibault@gnu.org> wrote:
> 
> > Henrik Carlqvist, le jeu. 03 août 2023 01:09:09 +0200, a ecrit:
> > > On Wed, 2 Aug 2023 21:53:56 +0200
> > > Samuel Thibault <samuel.thibault@gnu.org> wrote:
> > > 
> > > > Henrik Carlqvist, le mar. 01 août 2023 23:27:25 +0200, a ecrit:
> > > > > @@ -950,10 +953,11 @@ static int slirp_smb(SlirpState* s, const char
> > > > > *exported_dir,
> > > > >              "printing = bsd\n"
> > > > >              "disable spoolss = yes\n"
> > > > >              "usershare max shares = 0\n"
> > > > > -            "[qemu]\n"
> > > > > -            "path=%s\n"
> > > > >              "read only=no\n"
> > > > >              "guest ok=yes\n"
> > > > > +           "%s"
> > > > > +            "[qemu]\n"
> > > > > +            "path=%s\n"
> > > > 
> > > > ?This is moving read only and guest ok to the global section?
> > > 
> > > Thanks for your quick reply!
> > > 
> > > Yes, I thought that would be OK because the [qemu] share will inherit
> > > those settings from the global section. By placing those in the global
> > > section it is possible to override them with later contradicting
> > > statements like "read only=yes\n" in the %s before the [qemu] section.
> > 
> > Ok, it would be useful to mention that in the changelog.
> 
> Is there a changelog in the repo? Or do you mean that I should mention that in
> the git commit message?

I mean the latter, yes.

Samuel

Re: [PATCH v1] Allowing setting and overriding parameters in smb.conf
Posted by Henrik Carlqvist 9 months ago
On Thu, 3 Aug 2023 01:34:04 +0200
Samuel Thibault <samuel.thibault@gnu.org> wrote:

> Henrik Carlqvist, le jeu. 03 août 2023 01:26:02 +0200, a ecrit:
> > On Thu, 3 Aug 2023 01:13:24 +0200
> > Samuel Thibault <samuel.thibault@gnu.org> wrote:
> > 
> > > Henrik Carlqvist, le jeu. 03 août 2023 01:09:09 +0200, a ecrit:
> > > > On Wed, 2 Aug 2023 21:53:56 +0200
> > > > Samuel Thibault <samuel.thibault@gnu.org> wrote:
> > > > 
> > > > > Henrik Carlqvist, le mar. 01 août 2023 23:27:25 +0200, a
> > > > > ecrit:
> > > > > > @@ -950,10 +953,11 @@ static int slirp_smb(SlirpState* s, const
> > > > > > char*exported_dir,
> > > > > >              "printing = bsd\n"
> > > > > >              "disable spoolss = yes\n"
> > > > > >              "usershare max shares = 0\n"
> > > > > > -            "[qemu]\n"
> > > > > > -            "path=%s\n"
> > > > > >              "read only=no\n"
> > > > > >              "guest ok=yes\n"
> > > > > > +           "%s"
> > > > > > +            "[qemu]\n"
> > > > > > +            "path=%s\n"
> > > > > 
> > > > > ?This is moving read only and guest ok to the global section?
> > > > 
> > > > Thanks for your quick reply!
> > > > 
> > > > Yes, I thought that would be OK because the [qemu] share will inherit
> > > > those settings from the global section. By placing those in the global
> > > > section it is possible to override them with later contradicting
> > > > statements like "read only=yes\n" in the %s before the [qemu] section.
> > > 
> > > Ok, it would be useful to mention that in the changelog.
> > 
> > Is there a changelog in the repo? Or do you mean that I should mention
> > that in the git commit message?
> 
> I mean the latter, yes.

Thanks for your feedback! I will provide a new patch tomorrow.

Best regards Henrik
[PATCH v2] Allowing setting and overriding parameters in smb.conf
Posted by Henrik Carlqvist 8 months, 4 weeks ago
From a6dfb322a88965281e3bba00a92f8d5e437bfa95 Mon Sep 17 00:00:00 2001
From: Henrik Carlqvist <hc1245@poolhem.se>
Date: Thu, 3 Aug 2023 16:52:25 +0200
Subject: [PATCH] Allowing setting and overriding parameters in smb.conf,
 moving some parameters from the [qemu] section to the [global] section to
 allow them to get overridden by custom user settings.

Signed-off-by: Henrik Carlqvist <hc1245@poolhem.se>
---

In this second version of the patch I have moved also the "force user" 
parameter to the global section of smb.conf. Even though I do not self see the
usefullness of altering that parameter we might just as well give the users
the freedom to alter anything in smb.conf. Maybe someone else will see the 
need to alter that parameter.

Best regards Henrik

 net/slirp.c     | 50 ++++++++++++++++++++++++++++++++++++++++---------
 qapi/net.json   |  3 +++
 qemu-options.hx | 15 ++++++++++++---
 3 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index c33b3e02e7..e27d115bc4 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -106,7 +106,8 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp);
 
 #if defined(CONFIG_SMBD_COMMAND)
 static int slirp_smb(SlirpState *s, const char *exported_dir,
-                     struct in_addr vserver_addr, Error **errp);
+                     struct in_addr vserver_addr, const char *smbparams,
+                     Error **errp);
 static void slirp_smb_cleanup(SlirpState *s);
 #else
 static inline void slirp_smb_cleanup(SlirpState *s) { }
@@ -424,6 +425,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
                           const char *bootfile, const char *vdhcp_start,
                           const char *vnameserver, const char *vnameserver6,
                           const char *smb_export, const char *vsmbserver,
+                          const char *smbparams,
                           const char **dnssearch, const char *vdomainname,
                           const char *tftp_server_name,
                           Error **errp)
@@ -678,7 +680,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
     }
 #if defined(CONFIG_SMBD_COMMAND)
     if (smb_export) {
-        if (slirp_smb(s, smb_export, smbsrv, errp) < 0) {
+        if (slirp_smb(s, smb_export, smbsrv, smbparams, errp) < 0) {
             goto error;
         }
     }
@@ -891,7 +893,8 @@ static void slirp_smb_cleanup(SlirpState *s)
 }
 
 static int slirp_smb(SlirpState* s, const char *exported_dir,
-                     struct in_addr vserver_addr, Error **errp)
+                     struct in_addr vserver_addr, const char *smbparams,
+                     Error **errp)
 {
     char *smb_conf;
     char *smb_cmdline;
@@ -950,11 +953,12 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
             "printing = bsd\n"
             "disable spoolss = yes\n"
             "usershare max shares = 0\n"
-            "[qemu]\n"
-            "path=%s\n"
             "read only=no\n"
             "guest ok=yes\n"
-            "force user=%s\n",
+            "force user=%s\n"
+	    "%s"
+            "[qemu]\n"
+            "path=%s\n",
             s->smb_dir,
             s->smb_dir,
             s->smb_dir,
@@ -963,8 +967,9 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
             s->smb_dir,
             s->smb_dir,
             s->smb_dir,
-            exported_dir,
-            passwd->pw_name
+            passwd->pw_name,
+            smbparams,
+            exported_dir
             );
     fclose(f);
 
@@ -1143,6 +1148,29 @@ static const char **slirp_dnssearch(const StringList *dnsname)
     return ret;
 }
 
+static char *slirp_smbparams(const StringList *smbparam)
+{
+    const StringList *c = smbparam;
+    size_t i = 1; /* for string terminating 0 */
+    char *ret;
+
+    while (c) {
+        i += strlen(c->value->str);
+        i++; /* for \n */
+        c = c->next;
+    }
+    ret = g_malloc(i * sizeof(*ret));
+    ret[0]=0; /* Start with empty string */
+
+    c = smbparam;
+    while (c) {
+        pstrcat(ret, i * sizeof(*ret), c->value->str);
+        pstrcat(ret, i * sizeof(*ret), "\n");
+        c = c->next;
+    }
+    return ret;
+}
+
 int net_init_slirp(const Netdev *netdev, const char *name,
                    NetClientState *peer, Error **errp)
 {
@@ -1151,6 +1179,7 @@ int net_init_slirp(const Netdev *netdev, const char *name,
     int ret;
     const NetdevUserOptions *user;
     const char **dnssearch;
+    char *smbparams;
     bool ipv4 = true, ipv6 = true;
 
     assert(netdev->type == NET_CLIENT_DRIVER_USER);
@@ -1170,6 +1199,7 @@ int net_init_slirp(const Netdev *netdev, const char *name,
            NULL;
 
     dnssearch = slirp_dnssearch(user->dnssearch);
+    smbparams = slirp_smbparams(user->smbparam);
 
     /* all optional fields are initialized to "all bits zero" */
 
@@ -1182,7 +1212,8 @@ int net_init_slirp(const Netdev *netdev, const char *name,
                          user->ipv6_host, user->hostname, user->tftp,
                          user->bootfile, user->dhcpstart,
                          user->dns, user->ipv6_dns, user->smb,
-                         user->smbserver, dnssearch, user->domainname,
+                         user->smbserver, smbparams,
+                         dnssearch, user->domainname,
                          user->tftp_server_name, errp);
 
     while (slirp_configs) {
@@ -1193,6 +1224,7 @@ int net_init_slirp(const Netdev *netdev, const char *name,
 
     g_free(vnet);
     g_free(dnssearch);
+    g_free(smbparams);
 
     return ret;
 }
diff --git a/qapi/net.json b/qapi/net.json
index 313c8a606e..163091719c 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -156,6 +156,8 @@
 #
 # @smbserver: IP address of the built-in SMB server
 #
+# @smbparam: list of parameters with values for smb.conf
+#
 # @hostfwd: redirect incoming TCP or UDP host connections to guest
 #     endpoints
 #
@@ -186,6 +188,7 @@
     '*ipv6-dns':         'str',
     '*smb':       'str',
     '*smbserver': 'str',
+    '*smbparam': ['String'],
     '*hostfwd':   ['String'],
     '*guestfwd':  ['String'],
     '*tftp-server-name': 'str' } }
diff --git a/qemu-options.hx b/qemu-options.hx
index 29b98c3d4c..7b92d08c3e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2758,9 +2758,9 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
     "         [,ipv6=on|off][,ipv6-net=addr[/int]][,ipv6-host=addr]\n"
     "         [,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
     "         [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,domainname=domain]\n"
-    "         [,tftp=dir][,tftp-server-name=name][,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
+    "         [,tftp=dir][,tftp-server-name=name][,bootfile=f][,hostfwd=rule][,guestfwd=rule]\n"
 #ifndef _WIN32
-                                             "[,smb=dir[,smbserver=addr]]\n"
+    "         [,smb=dir[,smbserver=addr][,smbparam=parameter=value]]\n"
 #endif
     "                configure a user mode network backend with ID 'str',\n"
     "                its DHCP server and optional services\n"
@@ -3062,7 +3062,7 @@ SRST
             |qemu_system| -hda linux.img -boot n -device e1000,netdev=n1 \\
                 -netdev user,id=n1,tftp=/path/to/tftp/files,bootfile=/pxelinux.0
 
-    ``smb=dir[,smbserver=addr]``
+    ``smb=dir[,smbserver=addr][,smbparam=parameter=value]``
         When using the user mode network stack, activate a built-in SMB
         server so that Windows OSes can access to the host files in
         ``dir`` transparently. The IP address of the SMB server can be
@@ -3081,6 +3081,15 @@ SRST
 
         Then ``dir`` can be accessed in ``\\smbserver\qemu``.
 
+        It is possible to set samba parameters in the generated smb.conf
+        with one or more ``smbparam=parameter=value``. Example:
+
+        .. parsed-literal::
+
+            |qemu_system| -nic user,smb=/tmp,smbparam="read only"=yes,smbparam="server min protocol"=NT1
+
+        See the man page of smb.conf for a complete listing of parameters.
+
         Note that a SAMBA server must be installed on the host OS.
 
     ``hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport``
-- 
2.35.1
Ping: [PATCH v2] Allowing setting and overriding parameters in smb.conf
Posted by Henrik Carlqvist 7 months, 3 weeks ago
I'm just wondering if there are any plans to apply my patch in this version or
if you would like me to change anything more in the patch? I am aware that
during this time of the year many have been away on vacation and it has also
been a new release 8.1 which has blocked any submitted patches but bug fixes.
However, now might be a good time to push this patch towards master?

Best regards Henrik

On Thu, 3 Aug 2023 17:12:56 +0200
Henrik Carlqvist <hc981@poolhem.se> wrote:

> From a6dfb322a88965281e3bba00a92f8d5e437bfa95 Mon Sep 17 00:00:00 2001
> From: Henrik Carlqvist <hc1245@poolhem.se>
> Date: Thu, 3 Aug 2023 16:52:25 +0200
> Subject: [PATCH] Allowing setting and overriding parameters in smb.conf,
>  moving some parameters from the [qemu] section to the [global] section to
>  allow them to get overridden by custom user settings.
> 
> Signed-off-by: Henrik Carlqvist <hc1245@poolhem.se>
> ---
> 
> In this second version of the patch I have moved also the "force user" 
> parameter to the global section of smb.conf. Even though I do not self see
> the usefullness of altering that parameter we might just as well give the
> users the freedom to alter anything in smb.conf. Maybe someone else will see
> the need to alter that parameter.
> 
> Best regards Henrik
> 
>  net/slirp.c     | 50 ++++++++++++++++++++++++++++++++++++++++---------
>  qapi/net.json   |  3 +++
>  qemu-options.hx | 15 ++++++++++++---
>  3 files changed, 56 insertions(+), 12 deletions(-)
> 
> diff --git a/net/slirp.c b/net/slirp.c
> index c33b3e02e7..e27d115bc4 100644
> --- a/net/slirp.c
> +++ b/net/slirp.c
> @@ -106,7 +106,8 @@ static int slirp_guestfwd(SlirpState *s, const char
> *config_str, Error **errp);
>  
>  #if defined(CONFIG_SMBD_COMMAND)
>  static int slirp_smb(SlirpState *s, const char *exported_dir,
> -                     struct in_addr vserver_addr, Error **errp);
> +                     struct in_addr vserver_addr, const char *smbparams,
> +                     Error **errp);
>  static void slirp_smb_cleanup(SlirpState *s);
>  #else
>  static inline void slirp_smb_cleanup(SlirpState *s) { }
> @@ -424,6 +425,7 @@ static int net_slirp_init(NetClientState *peer, const
> char *model,
>                            const char *bootfile, const char *vdhcp_start,
>                            const char *vnameserver, const char
>                            *vnameserver6, const char *smb_export, const char
>                            *vsmbserver,
> +                          const char *smbparams,
>                            const char **dnssearch, const char *vdomainname,
>                            const char *tftp_server_name,
>                            Error **errp)
> @@ -678,7 +680,7 @@ static int net_slirp_init(NetClientState *peer, const
> char *model,
>      }
>  #if defined(CONFIG_SMBD_COMMAND)
>      if (smb_export) {
> -        if (slirp_smb(s, smb_export, smbsrv, errp) < 0) {
> +        if (slirp_smb(s, smb_export, smbsrv, smbparams, errp) < 0) {
>              goto error;
>          }
>      }
> @@ -891,7 +893,8 @@ static void slirp_smb_cleanup(SlirpState *s)
>  }
>  
>  static int slirp_smb(SlirpState* s, const char *exported_dir,
> -                     struct in_addr vserver_addr, Error **errp)
> +                     struct in_addr vserver_addr, const char *smbparams,
> +                     Error **errp)
>  {
>      char *smb_conf;
>      char *smb_cmdline;
> @@ -950,11 +953,12 @@ static int slirp_smb(SlirpState* s, const char
> *exported_dir,
>              "printing = bsd\n"
>              "disable spoolss = yes\n"
>              "usershare max shares = 0\n"
> -            "[qemu]\n"
> -            "path=%s\n"
>              "read only=no\n"
>              "guest ok=yes\n"
> -            "force user=%s\n",
> +            "force user=%s\n"
> +	    "%s"
> +            "[qemu]\n"
> +            "path=%s\n",
>              s->smb_dir,
>              s->smb_dir,
>              s->smb_dir,
> @@ -963,8 +967,9 @@ static int slirp_smb(SlirpState* s, const char
> *exported_dir,
>              s->smb_dir,
>              s->smb_dir,
>              s->smb_dir,
> -            exported_dir,
> -            passwd->pw_name
> +            passwd->pw_name,
> +            smbparams,
> +            exported_dir
>              );
>      fclose(f);
>  
> @@ -1143,6 +1148,29 @@ static const char **slirp_dnssearch(const StringList
> *dnsname)
>      return ret;
>  }
>  
> +static char *slirp_smbparams(const StringList *smbparam)
> +{
> +    const StringList *c = smbparam;
> +    size_t i = 1; /* for string terminating 0 */
> +    char *ret;
> +
> +    while (c) {
> +        i += strlen(c->value->str);
> +        i++; /* for \n */
> +        c = c->next;
> +    }
> +    ret = g_malloc(i * sizeof(*ret));
> +    ret[0]=0; /* Start with empty string */
> +
> +    c = smbparam;
> +    while (c) {
> +        pstrcat(ret, i * sizeof(*ret), c->value->str);
> +        pstrcat(ret, i * sizeof(*ret), "\n");
> +        c = c->next;
> +    }
> +    return ret;
> +}
> +
>  int net_init_slirp(const Netdev *netdev, const char *name,
>                     NetClientState *peer, Error **errp)
>  {
> @@ -1151,6 +1179,7 @@ int net_init_slirp(const Netdev *netdev, const char
> *name,
>      int ret;
>      const NetdevUserOptions *user;
>      const char **dnssearch;
> +    char *smbparams;
>      bool ipv4 = true, ipv6 = true;
>  
>      assert(netdev->type == NET_CLIENT_DRIVER_USER);
> @@ -1170,6 +1199,7 @@ int net_init_slirp(const Netdev *netdev, const char
> *name,
>             NULL;
>  
>      dnssearch = slirp_dnssearch(user->dnssearch);
> +    smbparams = slirp_smbparams(user->smbparam);
>  
>      /* all optional fields are initialized to "all bits zero" */
>  
> @@ -1182,7 +1212,8 @@ int net_init_slirp(const Netdev *netdev, const char
> *name,
>                           user->ipv6_host, user->hostname, user->tftp,
>                           user->bootfile, user->dhcpstart,
>                           user->dns, user->ipv6_dns, user->smb,
> -                         user->smbserver, dnssearch, user->domainname,
> +                         user->smbserver, smbparams,
> +                         dnssearch, user->domainname,
>                           user->tftp_server_name, errp);
>  
>      while (slirp_configs) {
> @@ -1193,6 +1224,7 @@ int net_init_slirp(const Netdev *netdev, const char
> *name,
>  
>      g_free(vnet);
>      g_free(dnssearch);
> +    g_free(smbparams);
>  
>      return ret;
>  }
> diff --git a/qapi/net.json b/qapi/net.json
> index 313c8a606e..163091719c 100644
> --- a/qapi/net.json
> +++ b/qapi/net.json
> @@ -156,6 +156,8 @@
>  #
>  # @smbserver: IP address of the built-in SMB server
>  #
> +# @smbparam: list of parameters with values for smb.conf
> +#
>  # @hostfwd: redirect incoming TCP or UDP host connections to guest
>  #     endpoints
>  #
> @@ -186,6 +188,7 @@
>      '*ipv6-dns':         'str',
>      '*smb':       'str',
>      '*smbserver': 'str',
> +    '*smbparam': ['String'],
>      '*hostfwd':   ['String'],
>      '*guestfwd':  ['String'],
>      '*tftp-server-name': 'str' } }
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 29b98c3d4c..7b92d08c3e 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -2758,9 +2758,9 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
>      "         [,ipv6=on|off][,ipv6-net=addr[/int]][,ipv6-host=addr]\n"
>      "         [,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
>      "        
>      [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,domainname=domain]\n"
> -    "        
> [,tftp=dir][,tftp-server-name=name][,bootfile=f][,hostfwd=rule][,guestfwd=r
> ule]"+    "        
> [,tftp=dir][,tftp-server-name=name][,bootfile=f][,hostfwd=rule][,guestfwd=r
> ule]\n"
>  #ifndef _WIN32
> -                                            
> "[,smb=dir[,smbserver=addr]]\n"+    "        
> [,smb=dir[,smbserver=addr][,smbparam=parameter=value]]\n"
>  #endif
>      "                configure a user mode network backend with ID
>      'str',\n""                its DHCP server and optional services\n"
> @@ -3062,7 +3062,7 @@ SRST
>              |qemu_system| -hda linux.img -boot n -device e1000,netdev=n1 \\
>                  -netdev
>                  user,id=n1,tftp=/path/to/tftp/files,bootfile=/pxelinux.0
>  
> -    ``smb=dir[,smbserver=addr]``
> +    ``smb=dir[,smbserver=addr][,smbparam=parameter=value]``
>          When using the user mode network stack, activate a built-in SMB
>          server so that Windows OSes can access to the host files in
>          ``dir`` transparently. The IP address of the SMB server can be
> @@ -3081,6 +3081,15 @@ SRST
>  
>          Then ``dir`` can be accessed in ``\\smbserver\qemu``.
>  
> +        It is possible to set samba parameters in the generated smb.conf
> +        with one or more ``smbparam=parameter=value``. Example:
> +
> +        .. parsed-literal::
> +
> +            |qemu_system| -nic user,smb=/tmp,smbparam="read
> only"=yes,smbparam="server min protocol"=NT1+
> +        See the man page of smb.conf for a complete listing of parameters.
> +
>          Note that a SAMBA server must be installed on the host OS.
>  
>      ``hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport``
> -- 
> 2.35.1
>
Ping 2: [PATCH v2] Allowing setting and overriding parameters in smb.conf
Posted by Henrik Carlqvist 2 months, 1 week ago
Still wondering if there are any plans to apply my patch or if you would like
to change anything in the patch?

Being able to set parameters in smb.conf would be really useful these days for
people running old versions of Windows like Windows XP in a qemu guest. Today,
the default settings of Samba has disabled SMBv1 making old versions of
Windows unable to connect to Samba shares.

regards Henrik

On Sun, 10 Sep 2023 13:48:12 +0200
Henrik Carlqvist <hc94@poolhem.se> wrote:

> I'm just wondering if there are any plans to apply my patch in this version
> or if you would like me to change anything more in the patch? I am aware
> that during this time of the year many have been away on vacation and it has
> also been a new release 8.1 which has blocked any submitted patches but bug
> fixes. However, now might be a good time to push this patch towards master?
> 
> Best regards Henrik
> 
> On Thu, 3 Aug 2023 17:12:56 +0200
> Henrik Carlqvist <hc981@poolhem.se> wrote:
> 
> > From a6dfb322a88965281e3bba00a92f8d5e437bfa95 Mon Sep 17 00:00:00 2001
> > From: Henrik Carlqvist <hc1245@poolhem.se>
> > Date: Thu, 3 Aug 2023 16:52:25 +0200
> > Subject: [PATCH] Allowing setting and overriding parameters in smb.conf,
> >  moving some parameters from the [qemu] section to the [global] section to
> >  allow them to get overridden by custom user settings.
> > 
> > Signed-off-by: Henrik Carlqvist <hc1245@poolhem.se>
> > ---
> > 
> > In this second version of the patch I have moved also the "force user" 
> > parameter to the global section of smb.conf. Even though I do not self see
> > the usefullness of altering that parameter we might just as well give the
> > users the freedom to alter anything in smb.conf. Maybe someone else will
> > see the need to alter that parameter.
> > 
> > Best regards Henrik
> > 
> >  net/slirp.c     | 50 ++++++++++++++++++++++++++++++++++++++++---------
> >  qapi/net.json   |  3 +++
> >  qemu-options.hx | 15 ++++++++++++---
> >  3 files changed, 56 insertions(+), 12 deletions(-)
> > 
> > diff --git a/net/slirp.c b/net/slirp.c
> > index c33b3e02e7..e27d115bc4 100644
> > --- a/net/slirp.c
> > +++ b/net/slirp.c
> > @@ -106,7 +106,8 @@ static int slirp_guestfwd(SlirpState *s, const char
> > *config_str, Error **errp);
> >  
> >  #if defined(CONFIG_SMBD_COMMAND)
> >  static int slirp_smb(SlirpState *s, const char *exported_dir,
> > -                     struct in_addr vserver_addr, Error **errp);
> > +                     struct in_addr vserver_addr, const char *smbparams,
> > +                     Error **errp);
> >  static void slirp_smb_cleanup(SlirpState *s);
> >  #else
> >  static inline void slirp_smb_cleanup(SlirpState *s) { }
> > @@ -424,6 +425,7 @@ static int net_slirp_init(NetClientState *peer, const
> > char *model,
> >                            const char *bootfile, const char *vdhcp_start,
> >                            const char *vnameserver, const char
> >                            *vnameserver6, const char *smb_export, const
> >                            char*vsmbserver,
> > +                          const char *smbparams,
> >                            const char **dnssearch, const char
> >                            *vdomainname, const char *tftp_server_name,
> >                            Error **errp)
> > @@ -678,7 +680,7 @@ static int net_slirp_init(NetClientState *peer, const
> > char *model,
> >      }
> >  #if defined(CONFIG_SMBD_COMMAND)
> >      if (smb_export) {
> > -        if (slirp_smb(s, smb_export, smbsrv, errp) < 0) {
> > +        if (slirp_smb(s, smb_export, smbsrv, smbparams, errp) < 0) {
> >              goto error;
> >          }
> >      }
> > @@ -891,7 +893,8 @@ static void slirp_smb_cleanup(SlirpState *s)
> >  }
> >  
> >  static int slirp_smb(SlirpState* s, const char *exported_dir,
> > -                     struct in_addr vserver_addr, Error **errp)
> > +                     struct in_addr vserver_addr, const char *smbparams,
> > +                     Error **errp)
> >  {
> >      char *smb_conf;
> >      char *smb_cmdline;
> > @@ -950,11 +953,12 @@ static int slirp_smb(SlirpState* s, const char
> > *exported_dir,
> >              "printing = bsd\n"
> >              "disable spoolss = yes\n"
> >              "usershare max shares = 0\n"
> > -            "[qemu]\n"
> > -            "path=%s\n"
> >              "read only=no\n"
> >              "guest ok=yes\n"
> > -            "force user=%s\n",
> > +            "force user=%s\n"
> > +	    "%s"
> > +            "[qemu]\n"
> > +            "path=%s\n",
> >              s->smb_dir,
> >              s->smb_dir,
> >              s->smb_dir,
> > @@ -963,8 +967,9 @@ static int slirp_smb(SlirpState* s, const char
> > *exported_dir,
> >              s->smb_dir,
> >              s->smb_dir,
> >              s->smb_dir,
> > -            exported_dir,
> > -            passwd->pw_name
> > +            passwd->pw_name,
> > +            smbparams,
> > +            exported_dir
> >              );
> >      fclose(f);
> >  
> > @@ -1143,6 +1148,29 @@ static const char **slirp_dnssearch(const
> > StringList*dnsname)
> >      return ret;
> >  }
> >  
> > +static char *slirp_smbparams(const StringList *smbparam)
> > +{
> > +    const StringList *c = smbparam;
> > +    size_t i = 1; /* for string terminating 0 */
> > +    char *ret;
> > +
> > +    while (c) {
> > +        i += strlen(c->value->str);
> > +        i++; /* for \n */
> > +        c = c->next;
> > +    }
> > +    ret = g_malloc(i * sizeof(*ret));
> > +    ret[0]=0; /* Start with empty string */
> > +
> > +    c = smbparam;
> > +    while (c) {
> > +        pstrcat(ret, i * sizeof(*ret), c->value->str);
> > +        pstrcat(ret, i * sizeof(*ret), "\n");
> > +        c = c->next;
> > +    }
> > +    return ret;
> > +}
> > +
> >  int net_init_slirp(const Netdev *netdev, const char *name,
> >                     NetClientState *peer, Error **errp)
> >  {
> > @@ -1151,6 +1179,7 @@ int net_init_slirp(const Netdev *netdev, const char
> > *name,
> >      int ret;
> >      const NetdevUserOptions *user;
> >      const char **dnssearch;
> > +    char *smbparams;
> >      bool ipv4 = true, ipv6 = true;
> >  
> >      assert(netdev->type == NET_CLIENT_DRIVER_USER);
> > @@ -1170,6 +1199,7 @@ int net_init_slirp(const Netdev *netdev, const char
> > *name,
> >             NULL;
> >  
> >      dnssearch = slirp_dnssearch(user->dnssearch);
> > +    smbparams = slirp_smbparams(user->smbparam);
> >  
> >      /* all optional fields are initialized to "all bits zero" */
> >  
> > @@ -1182,7 +1212,8 @@ int net_init_slirp(const Netdev *netdev, const char
> > *name,
> >                           user->ipv6_host, user->hostname, user->tftp,
> >                           user->bootfile, user->dhcpstart,
> >                           user->dns, user->ipv6_dns, user->smb,
> > -                         user->smbserver, dnssearch, user->domainname,
> > +                         user->smbserver, smbparams,
> > +                         dnssearch, user->domainname,
> >                           user->tftp_server_name, errp);
> >  
> >      while (slirp_configs) {
> > @@ -1193,6 +1224,7 @@ int net_init_slirp(const Netdev *netdev, const char
> > *name,
> >  
> >      g_free(vnet);
> >      g_free(dnssearch);
> > +    g_free(smbparams);
> >  
> >      return ret;
> >  }
> > diff --git a/qapi/net.json b/qapi/net.json
> > index 313c8a606e..163091719c 100644
> > --- a/qapi/net.json
> > +++ b/qapi/net.json
> > @@ -156,6 +156,8 @@
> >  #
> >  # @smbserver: IP address of the built-in SMB server
> >  #
> > +# @smbparam: list of parameters with values for smb.conf
> > +#
> >  # @hostfwd: redirect incoming TCP or UDP host connections to guest
> >  #     endpoints
> >  #
> > @@ -186,6 +188,7 @@
> >      '*ipv6-dns':         'str',
> >      '*smb':       'str',
> >      '*smbserver': 'str',
> > +    '*smbparam': ['String'],
> >      '*hostfwd':   ['String'],
> >      '*guestfwd':  ['String'],
> >      '*tftp-server-name': 'str' } }
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index 29b98c3d4c..7b92d08c3e 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -2758,9 +2758,9 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
> >      "         [,ipv6=on|off][,ipv6-net=addr[/int]][,ipv6-host=addr]\n"
> >      "         [,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
> >      "        
> >      [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,domainname=domain]\n"
> > -    "        
> > [,tftp=dir][,tftp-server-name=name][,bootfile=f][,hostfwd=rule][,guestfwd
> > =r ule]"+    "        
> > [,tftp=dir][,tftp-server-name=name][,bootfile=f][,hostfwd=rule][,guestfwd
> > =r ule]\n"
> >  #ifndef _WIN32
> > -                                            
> > "[,smb=dir[,smbserver=addr]]\n"+    "        
> > [,smb=dir[,smbserver=addr][,smbparam=parameter=value]]\n"
> >  #endif
> >      "                configure a user mode network backend with ID
> >      'str',\n""                its DHCP server and optional services\n"
> > @@ -3062,7 +3062,7 @@ SRST
> >              |qemu_system| -hda linux.img -boot n -device e1000,netdev=n1
> >              |\\
> >                  -netdev
> >                  user,id=n1,tftp=/path/to/tftp/files,bootfile=/pxelinux.0
> >  
> > -    ``smb=dir[,smbserver=addr]``
> > +    ``smb=dir[,smbserver=addr][,smbparam=parameter=value]``
> >          When using the user mode network stack, activate a built-in SMB
> >          server so that Windows OSes can access to the host files in
> >          ``dir`` transparently. The IP address of the SMB server can be
> > @@ -3081,6 +3081,15 @@ SRST
> >  
> >          Then ``dir`` can be accessed in ``\\smbserver\qemu``.
> >  
> > +        It is possible to set samba parameters in the generated smb.conf
> > +        with one or more ``smbparam=parameter=value``. Example:
> > +
> > +        .. parsed-literal::
> > +
> > +            |qemu_system| -nic user,smb=/tmp,smbparam="read
> > only"=yes,smbparam="server min protocol"=NT1+
> > +        See the man page of smb.conf for a complete listing of
> > parameters.+
> >          Note that a SAMBA server must be installed on the host OS.
> >  
> >      ``hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport``
> > -- 
> > 2.35.1
> >
Re: Ping 2: [PATCH v2] Allowing setting and overriding parameters in smb.conf
Posted by Michael Tokarev 2 months, 1 week ago
18.02.2024 01:28, Henrik Carlqvist :
> Still wondering if there are any plans to apply my patch or if you would like
> to change anything in the patch?
> 
> Being able to set parameters in smb.conf would be really useful these days for
> people running old versions of Windows like Windows XP in a qemu guest. Today,
> the default settings of Samba has disabled SMBv1 making old versions of
> Windows unable to connect to Samba shares.

I don't maintain this code, so my email is just a random comment.
But I did have an issue with smbd not working right due to one
missing/wrong parameter or another, more than once.  Also, samba
is evolving too, so it might need more parameters or less.

My suggestion is still the same as 10+ years ago: to ship a shell script
which run smbd, instead of running smbd directly.  This script will set
up smb.conf (whole thing, exactly as it is done now in the C code), and
exec /usr/sbin/smbd with the necessary args.

This way, it's a) trivial to modify parameters on the qemu side (easy to
edit just this script), b) possible to see which samba version is in use
and adopt some parameters, c) use alternative smbd, and especially d)
allow the end-user to override smbd or config in use.

The best, I'd say, is to allow to specify the script on qemu command line
(like samba=/etc/qemu/run-smbd.sh), and have default value for that, like
/usr/share/qemu/run-smbd.sh, which is the default script shipped with
qemu.  Or maybe let qemu choose to use either the one specified on the
command line, /etc/qemu/run-smbd.sh if it exists, or /usr/share/qemu/run-smbd.sh.

/mjt
Re: Ping 2: [PATCH v2] Allowing setting and overriding parameters in smb.conf
Posted by Henrik Carlqvist 2 months, 1 week ago
On Sun, 18 Feb 2024 12:30:01 +0300
Michael Tokarev <mjt@tls.msk.ru> wrote:
> I don't maintain this code, so my email is just a random comment.

Thanks for your comment anyway!

> But I did have an issue with smbd not working right due to one
> missing/wrong parameter or another, more than once.  Also, samba
> is evolving too, so it might need more parameters or less.

During the years, my brute force approach to solve issues like this has been
to locally patch qemu source code to build custom qemu binaries with the
smb.conf parameters that I want. 

> My suggestion is still the same as 10+ years ago: to ship a shell script
> which run smbd, instead of running smbd directly.  This script will set
> up smb.conf (whole thing, exactly as it is done now in the C code), and
> exec /usr/sbin/smbd with the necessary args.

Such a script would be easier to modify than changing the C sources.

> This way, it's a) trivial to modify parameters on the qemu side (easy to
> edit just this script), b) possible to see which samba version is in use
> and adopt some parameters, c) use alternative smbd, and especially d)
> allow the end-user to override smbd or config in use.

During the years, I have also seen the need to use alternative smbd. I have
then solved it by having the old smbd that I prefered for qemu in /usr/sbin
and moved the "original" smbd provided by the Linux distribution to
/usr/local/sbin where it has been started by any real Samba servers in the
network.

> The best, I'd say, is to allow to specify the script on qemu command line
> (like samba=/etc/qemu/run-smbd.sh), and have default value for that, like
> /usr/share/qemu/run-smbd.sh, which is the default script shipped with
> qemu.  Or maybe let qemu choose to use either the one specified on the
> command line, /etc/qemu/run-smbd.sh if it exists, or
> /usr/share/qemu/run-smbd.sh.

Yes, by specifying such a script on the command line it would be possible to
have different parameters for different qemu sessions.  However, I think that
also my solution allowing settings of samba parameters fixes most of the
problems in a way which most of the times will be easier to use. 

Usually, there is no need to modify more than a handfull of parameters so
those extra arguments to the qemu command line will be less to write than a
separate script starting samba. In my experience qemu is mostly started from a
script with a rather long qemu command line anyway.

The remaining problem is when Samba comes with a new version which requires
new settings of parameters. Regardless of solution some script will need to be
modified to solve that problem.

Again, thanks for your comment! I hope that someone will consider my patch or
your suggestion. The next thing to look into would be the possibility to start
some userspace NFS daemon as an alternative to Samba as Unix-guests works
better with NFS than CIFS. However, that would be a much bigger project and I
won't dig into such a thing until I have gotten any response on this small
patch.

regards Henrik