Skip to content

Commit

Permalink
Add documentation for command plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
bignaux committed Oct 1, 2023
1 parent 4ef3ae9 commit 9406962
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 33 deletions.
9 changes: 6 additions & 3 deletions examples/local-shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

#define _GNU_SOURCE
#include <errno.h>
#include <libgen.h>
#include <lwnbd.h>
#include <stdlib.h>
Expand Down Expand Up @@ -38,7 +39,7 @@ int main(int argc, char **argv)
{
lwnbd_plugin_h cmdplg, memplg;
lwnbd_context_t *ctx;
char *p, *buf, memtest[512];
char *p, *buf, *memtest;
int errno, r = 0;
uint64_t size = 0;

Expand All @@ -62,6 +63,7 @@ int main(int argc, char **argv)
*/

memplg = lwnbd_plugin_init(memory_plugin_init);
memtest = calloc(1, 512);

struct memory_config memh = {
.base = (uint64_t)memtest,
Expand All @@ -72,13 +74,13 @@ int main(int argc, char **argv)
lwnbd_plugin_new(memplg, &memh);

/*
* let's use query mechanism to set it
* let's use query mechanism to set it, just because we can !
*/

if (-1 == asprintf(&buf, "test?memcpy=Example of shared memory.\n")) /* create the request */
exit(EXIT_FAILURE);

ctx = lwnbd_get_context(buf); /* GET */
lwnbd_get_context(buf); /* GET */

/*
* create a command to change export, to be able to switch to it
Expand Down Expand Up @@ -135,5 +137,6 @@ int main(int argc, char **argv)
free(exportname);
free(prompt);
free(base);
free(memtest);
exit(EXIT_SUCCESS);
}
45 changes: 23 additions & 22 deletions examples/lwnbd-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,15 @@ int greeter(int argc, char **argv, void *result, int64_t *size)
return 0;
}

int server_shutdown(int argc, char **argv, void *result, int64_t *size)
/* man 7 signal */
int signal_cb(int argc, char **argv, void *result, int64_t *size)
{
uv_kill(uv_os_getpid(), SIGINT);
int signum = SIGINT;
if (argc > 1) {
signum = atoi(argv[1]);
}
*size = sprintf(result, "%s with signal %s\n", argv[0], strsignal(signum));
uv_kill(uv_os_getpid(), signum);
return 0;
}

Expand Down Expand Up @@ -138,25 +144,15 @@ int main(int argc, const char **argv)
lwnbd_server_t nbdsrv;
lwnbd_plugin_h fileplg, memplg, cmdplg;

// int i = atexit(coucou);
// if (i != 0) {
// fprintf(stderr, "cannot set exit function\n");
// exit(EXIT_FAILURE);
// }

// if (argc < 2) {
// fprintf(stderr, "Usage: %s <files>\n", argv[0]);
// exit(EXIT_FAILURE);
// }

/*
/*******************************************************************************
* Register and configure some content plugins ...
* Plugins can be shared between different servers so they live autonomously.
*
*/
*******************************************************************************/

/* NBD has no standard to get remote information about the server ?
* let's use memory plugin to create an export 'motd' with some useful infos.
/*
* NBD has no standard to get remote information about the server ?
* Let's use memory plugin to create an export 'motd' with some useful infos.
*/

memplg = lwnbd_plugin_init(memory_plugin_init);
Expand All @@ -172,19 +168,25 @@ int main(int argc, const char **argv)


/*
* Register few useful callback to control the server over the network
*
*/

cmdplg = lwnbd_plugin_init(command_plugin_init);
struct lwnbd_command mycmd[] = {
{.name = "le", .desc = "list export", .cmd = greeter},
{.name = "shutdown", .desc = "turn off the application", .cmd = server_shutdown},
{.name = "shutdown", .desc = "turn off the application", .cmd = signal_cb},
NULL,
};

lwnbd_plugin_new(cmdplg, &mycmd[0]);
lwnbd_plugin_new(cmdplg, &mycmd[1]);


/*
* Export all files passed from command line
*/

fileplg = lwnbd_plugin_init(file_plugin_init);
/* assuming no user input error */
/* todo : lwnbd_plugin_news() */
Expand All @@ -193,7 +195,7 @@ int main(int argc, const char **argv)
}

/*
* create a NBD server, and eventually configure it.
* Create a NBD server, and eventually configure it.
*
*/

Expand All @@ -217,8 +219,9 @@ int main(int argc, const char **argv)

uv_loop_t *loop = uv_default_loop();
struct sockaddr_in addr;

memset(client_states, CLIENT_FREE, sizeof(client_states));
uv_tcp_t server;

uv_tcp_init(loop, &server);

uv_ip4_addr("0.0.0.0", mynbd.port, &addr);
Expand All @@ -236,7 +239,5 @@ int main(int argc, const char **argv)
uv_signal_init(loop, &sig);
uv_signal_start(&sig, signal_handler, SIGINT);

memset(client_states, CLIENT_FREE, sizeof(client_states));

return uv_run(loop, UV_RUN_DEFAULT);
}
15 changes: 10 additions & 5 deletions plugins/command/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#define PLUGIN_NAME command
#define CMD_DRIVER_MAX 100

#define CMD_BUFFER_SZ 512
/*
* Here we don't want an export by command,
* but one export to be reachable by lwnbd_get_context()
Expand All @@ -14,7 +14,7 @@ static int commands_cnt = 0;

struct result_h
{
char result[512];
char result[CMD_BUFFER_SZ];
int64_t size;
};

Expand Down Expand Up @@ -77,16 +77,21 @@ static int command_query(void *handle, struct query_t *params, int nb_params)
cnt++;
}

memset(pr.result, '\0', 512);
/* nbd client doesn't like 0 size export :
* -> nbd.Error: nbd_pread: count cannot be 0: Invalid argument (EINVAL)
* workaround for cmd that doesn't have result...
*/
pr.size = 1;
memset(pr.result, '\0', CMD_BUFFER_SZ);

/* 404 */
if (pvhandle == NULL) {
DEBUGLOG("%s: command not found\n", commands[cnt].name);
pr.size = sprintf(pr.result, "%s: command not found\n", params[0].key);
return 0;
}

/* TODO: format argv from params */
pvhandle->cmd(1, &params[0].val, pr.result, &pr.size);
pvhandle->cmd(nb_params + 1, (char **)&params[0], pr.result, &pr.size);

return 0;
}
Expand Down
48 changes: 48 additions & 0 deletions plugins/command/lwnbd-command-plugin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# command plugin

## Usage : A RPC handler

TARGETS : all

STATUS : Experimental

```c
struct lwnbd_command
{
char *name;
char *desc;
int (*cmd)(int argc, char **argv, void *result, int64_t *size);
};
```

As traditionnal (int argc, char **argv) scheme, you need to manually do the Command-line argument parsing ...
for now argv contains only the first query of the request, so the all the parameters should go in first value string (space allowed).

see example in [examples/local-shell.c](./examples/local-shell.c)

You can test the mecanism over NBD with [lwnbd-server server](./examples/lwnbd-server.c) and [remoteshell.py](./examples/remoteshell.py)

Start lwnbd-server then remoteshell client, typic session :

```
/app/lwNBD/examples # ./remoteshell.py -iv
Welcome! Type ? to list commands
lwnbd> lc
Clear URI: nbd://192.168.1.5/shell?lc=
Request: nbd://192.168.1.5/shell%3Flc=
Response: 153 bytes
lc : list commands
le : list export
shutdown : turn off the application
lwnbd> shutdown=2
Clear URI: nbd://192.168.1.5/shell?shutdown=2
Request: nbd://192.168.1.5/shell%3Fshutdown=2
Response: 31 bytes
shutdown with signal Interrupt
lwnbd> exit
Bye
```

Then lwnbd-server finished his job and terminate using signal interruption.
Thanks to the verbose switch, you can see we got kinda HTTP GET equivalent on NBD transport.
4 changes: 2 additions & 2 deletions plugins/memory/lwnbd-memory-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

TARGETS : all

STATUS : WIP
STATUS : Experimental

You just need to declare a memory slice:

Expand All @@ -23,7 +23,7 @@ Then add it to the memory plugin:
lwnbd_plugin_new(memplg, &iopram);
```
see full example in ports/playstation2/lwnbd_irx.c
see full example in [examples/local-shell.c](./examples/local-shell.c)
a current limitation of some nbd client is their minimal read is 512 bytes (minimal blocksize) despite the protocol allow 1 byte blocksize.
It's not an issue to dump an entire device, but for now, you need to put a minimal .size of 512 in your structure (and multiple of 512) or you'll get truncated data.
Expand Down
2 changes: 1 addition & 1 deletion ports/playstation2/lwnbd-playstation2-port.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ could add echo "https://dl-cdn.alpinelinux.org/alpine/edge/testing/" >> /etc/apk
rm -fr Open-PS2-Loader/modules/network/lwNBD/
ln -rs lwNBD Open-PS2-Loader/modules/network/lwNBD

docker pull ghcr.io/ps2homebrew/ps2homebrew:main
docker pull ghcr.io/ps2homebrew/ps2homebrew:main
docker run -it -w /app -v "$(pwd)":/app ghcr.io/ps2homebrew/ps2homebrew:main

export PS2_WORKSPACE=/app (should be in a docker script)
Expand Down

0 comments on commit 9406962

Please sign in to comment.