Skip to content

Instantly share code, notes, and snippets.

@rwmjones
Created May 10, 2026 15:54
Show Gist options
  • Select an option

  • Save rwmjones/1e5221ab392f24a2edf0476892ad4e27 to your computer and use it in GitHub Desktop.

Select an option

Save rwmjones/1e5221ab392f24a2edf0476892ad4e27 to your computer and use it in GitHub Desktop.
Let's see how bad QWEN3 is at a coding task ...
> please write me an nbdkit plugin in C which will serve the poem "the 12 days of christmas" in a disk image
Here is a complete C plugin for `nbdkit` that serves "The 12 Days of Christmas" as a disk image.
### Overview
* **Disk Size:** The plugin presents a virtual 1 MB block device.
* **Content:** The poem is embedded at the beginning of the disk image.
* **Padding:** Any data requested beyond the length of the poem is returned as null bytes (simulating a sparse disk).
* **Read-Only:** The device is read-only, as per the nature of a disk image.
### Source Code (`nbdkit-christmas.c`)
```c
/* nbdkit-christmas.c
*
* An nbdkit plugin that serves "The 12 Days of Christmas" poem.
* It presents the poem as a 1 MB read-only disk image.
*
* Compile with:
* gcc -shared -o nbdkit-christmas.so -fPIC nbdkit-christmas.c $(pkg-config --cflags --libs nbdkit)
*
* Usage:
* nbdkit --plugin ./nbdkit-christmas.so -p 10809
*/
#include <nbdkit-plugin.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* The full text of "The 12 Days of Christmas" */
static const char *poem_text =
"1. On the first day of Christmas,\n"
" my true love sent to me:\n"
" A partridge in a pear tree.\n\n"
"2. On the second day of Christmas,\n"
" my true love sent to me:\n"
" Two turtle doves,\n"
" And a partridge in a pear tree.\n\n"
"3. On the third day of Christmas,\n"
" my true love sent to me:\n"
" Three French hens,\n"
" Two turtle doves,\n"
" And a partridge in a pear tree.\n\n"
"4. On the fourth day of Christmas,\n"
" my true love sent to me:\n"
" Four calling birds,\n"
" Three French hens,\n"
" Two turtle doves,\n"
" And a partridge in a pear tree.\n\n"
"5. On the fifth day of Christmas,\n"
" my true love sent to me:\n"
" Five golden rings,\n"
" Four calling birds,\n"
" Three French hens,\n"
" Two turtle doves,\n"
" And a partridge in a pear tree.\n\n"
"6. On the sixth day of Christmas,\n"
" my true love sent to me:\n"
" Six geese a-laying,\n"
" Five golden rings,\n"
" Four calling birds,\n"
" Three French hens,\n"
" Two turtle doves,\n"
" And a partridge in a pear tree.\n\n"
"7. On the seventh day of Christmas,\n"
" my true love sent to me:\n"
" Seven swans a-swimming,\n"
" Six geese a-laying,\n"
" Five golden rings,\n"
" Four calling birds,\n"
" Three French hens,\n"
" Two turtle doves,\n"
" And a partridge in a pear tree.\n\n"
"8. On the eighth day of Christmas,\n"
" my true love sent to me:\n"
" Eight maids a-milking,\n"
" Seven swans a-swimming,\n"
" Six geese a-laying,\n"
" Five golden rings,\n"
" Four calling birds,\n"
" Three French hens,\n"
" Two turtle doves,\n"
" And a partridge in a pear tree.\n\n"
"9. On the ninth day of Christmas,\n"
" my true love sent to me:\n"
" Nine ladies dancing,\n"
" Eight maids a-milking,\n"
" Seven swans a-swimming,\n"
" Six geese a-laying,\n"
" Five golden rings,\n"
" Four calling birds,\n"
" Three French hens,\n"
" Two turtle doves,\n"
" And a partridge in a pear tree.\n\n"
"10. On the tenth day of Christmas,\n"
" my true love sent to me:\n"
" Ten lords a-leaping,\n"
" Nine ladies dancing,\n"
" Eight maids a-milking,\n"
" Seven swans a-swimming,\n"
" Six geese a-laying,\n"
" Five golden rings,\n"
" Four calling birds,\n"
" Three French hens,\n"
" Two turtle doves,\n"
" And a partridge in a pear tree.\n\n"
"11. On the eleventh day of Christmas,\n"
" my true love sent to me:\n"
" Eleven pipers piping,\n"
" Ten lords a-leaping,\n"
" Nine ladies dancing,\n"
" Eight maids a-milking,\n"
" Seven swans a-swimming,\n"
" Six geese a-laying,\n"
" Five golden rings,\n"
" Four calling birds,\n"
" Three French hens,\n"
" Two turtle doves,\n"
" And a partridge in a pear tree.\n\n"
"12. On the twelfth day of Christmas,\n"
" my true love sent to me:\n"
" Twelve drummers drumming,\n"
" Eleven pipers piping,\n"
" Ten lords a-leaping,\n"
" Nine ladies dancing,\n"
" Eight maids a-milking,\n"
" Seven swans a-swimming,\n"
" Six geese a-laying,\n"
" Five golden rings,\n"
" Four calling birds,\n"
" Three French hens,\n"
" Two turtle doves,\n"
" And a partridge in a pear tree.";
/* Calculate size at compile time (strlen of the string) */
static const uint64_t poem_len = sizeof(poem_text) - 1; /* -1 to exclude null terminator */
static const uint64_t disk_size = 1024 * 1024; /* 1 MB disk image */
/* Initialize the plugin */
static int init(void)
{
printf("Christmas plugin initialized.\n");
printf("Poem size: %" PRIu64 " bytes\n", poem_len);
printf("Disk image size: %" PRIu64 " bytes\n", disk_size);
return 0;
}
/* Called when a connection is opened */
static int open(nbd_context *ctx)
{
printf("Connection opened.\n");
return 0;
}
/* Called when a connection is closed */
static int close(nbd_context *ctx)
{
printf("Connection closed.\n");
return 0;
}
/* Return the size of the disk */
static uint64_t get_size(nbd_context *ctx)
{
return disk_size;
}
/* Read data from the disk */
static int read_data(nbd_context *ctx, off_t offset, uint32_t count, void *buf,
uint32_t *flags, int *error)
{
/* Sanity check */
if (offset < 0) {
*error = errno;
return -1;
}
/* Calculate remaining bytes available in the poem */
uint64_t remaining = poem_len - offset;
/* Determine how much data we actually copy */
uint32_t copy_count = count;
if (remaining > 0) {
if ((uint64_t)count > remaining) {
copy_count = (uint32_t)remaining;
}
} else {
/* Offset is beyond the poem, we will just pad with zeros */
copy_count = count;
}
/* Copy poem data if within bounds */
if (copy_count > 0 && offset < poem_len) {
memcpy(buf, poem_text + offset, copy_count);
}
/* Pad the rest with zeros if needed */
if (copy_count < count) {
memset((char *)buf + copy_count, 0, count - copy_count);
}
/* Set return values for the plugin framework */
*flags = 0;
*error = 0;
return 0;
}
/* Export flags (read-only) */
static uint32_t flags(void)
{
return 0; /* Default flags (read-write), we enforce read-only by not implementing write() */
}
/* The main plugin structure exported for nbdkit to load */
struct nbdkit_plugin nbdkit_plugin = {
.name = "christmas",
.init = init,
.get_size = get_size,
.open = open,
.close = close,
.read = read_data,
/* We do not implement write, flush, or preallocate, making it read-only */
};
```
### Compilation
To compile this plugin, you need `nbdkit` development files installed.
```bash
gcc -shared -o nbdkit-christmas.so -fPIC nbdkit-christmas.c $(pkg-config --cflags --libs nbdkit)
```
*Note: If `pkg-config` cannot find nbdkit, you may need to specify the library path manually, e.g., `-lnbdkit -L/usr/lib/nbdkit`.*
### Usage
Run the `nbdkit` server with your new plugin:
```bash
nbdkit --plugin ./nbdkit-christmas.so -U -p 10809
```
* `--plugin`: Loads your custom `.so` file.
* `-U`: Disables the UDS (Unix Domain Socket) listener for simplicity in this example.
* `-p 10809`: Listens on TCP port 10809.
### Connecting to the Server
You can test this disk image using `libnbd` (the client library) or standard block tools.
**Using `nbd-client` (if available):**
```bash
nbd-client -p 10809 <host> /dev/nbd0
```
**Using `dd` to read the poem:**
Once connected (e.g., to `/dev/nbd0`):
```bash
# Read the first 1000 bytes (should be the start of the poem)
dd if=/dev/nbd0 bs=1000 count=1
```
**Using a hex dump:**
```bash
hexdump -C /dev/nbd0
```
If you access the data correctly, the first part of the disk will contain the ASCII text of the poem, followed by null bytes until the 1 MB mark.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment