+ switch (type)
+ {
+ case NSCTL_REQ_LOAD:
+ if (request.argc != 1)
+ {
+ response.type = NSCTL_RES_ERR;
+ response.argc = 1;
+ response.argv[0] = "name of plugin required";
+ }
+ else if ((r = add_plugin(request.argv[0])) < 1)
+ {
+ response.type = NSCTL_RES_ERR;
+ response.argc = 1;
+ response.argv[0] = !r
+ ? "plugin already loaded"
+ : "error loading plugin";
+ }
+ else
+ {
+ response.type = NSCTL_RES_OK;
+ response.argc = 0;
+ }
+
+ break;
+
+ case NSCTL_REQ_UNLOAD:
+ if (request.argc != 1)
+ {
+ response.type = NSCTL_RES_ERR;
+ response.argc = 1;
+ response.argv[0] = "name of plugin required";
+ }
+ else if ((r = remove_plugin(request.argv[0])) < 1)
+ {
+ response.type = NSCTL_RES_ERR;
+ response.argc = 1;
+ response.argv[0] = !r
+ ? "plugin not loaded"
+ : "plugin not found";
+ }
+ else
+ {
+ response.type = NSCTL_RES_OK;
+ response.argc = 0;
+ }
+
+ break;
+
+ case NSCTL_REQ_HELP:
+ response.type = NSCTL_RES_OK;
+ response.argc = 0;
+
+ ll_reset(loaded_plugins);
+ while ((p = ll_next(loaded_plugins)))
+ {
+ char **help = dlsym(p, "plugin_control_help");
+ while (response.argc < 0xff && help && *help)
+ response.argv[response.argc++] = *help++;
+ }
+
+ break;
+
+ case NSCTL_REQ_CONTROL:
+ {
+ struct param_control param = {
+ config->cluster_iam_master,
+ request.argc,
+ request.argv,
+ 0,
+ NULL,
+ };
+
+ int r = run_plugins(PLUGIN_CONTROL, ¶m);
+
+ if (r == PLUGIN_RET_ERROR)
+ {
+ response.type = NSCTL_RES_ERR;
+ response.argc = 1;
+ response.argv[0] = param.additional
+ ? param.additional
+ : "error returned by plugin";
+ }
+ else if (r == PLUGIN_RET_NOTMASTER)
+ {
+ static char msg[] = "must be run on master: 000.000.000.000";
+
+ response.type = NSCTL_RES_ERR;
+ response.argc = 1;
+ if (config->cluster_master_address)
+ {
+ strcpy(msg + 23, fmtaddr(config->cluster_master_address, 0));
+ response.argv[0] = msg;
+ }
+ else
+ {
+ response.argv[0] = "must be run on master: none elected";
+ }
+ }
+ else if (!(param.response & NSCTL_RESPONSE))
+ {
+ response.type = NSCTL_RES_ERR;
+ response.argc = 1;
+ response.argv[0] = param.response
+ ? "unrecognised response value from plugin"
+ : "unhandled action";
+ }
+ else
+ {
+ response.type = param.response;
+ response.argc = 0;
+ if (param.additional)
+ {
+ response.argc = 1;
+ response.argv[0] = param.additional;
+ }
+ }
+ }
+
+ break;