When making a peer of unknown type framework tries to load module
using linker_load_module(). This works OK if NGM_MKPEER message came from userland and we have process associated with thread. But when NGM_MKPEER was queued because target node was busy, linker_load_module() is called from netisr thread leading to panic. To workaround that we do not load modules by framework, instead ng_socket loads module (if this is required) before sending NGM_MKPEER. However, the race condition between return from NgSendMsg() and actual creation of node still exist and needs to be solved. PR: kern/62789 Approved by: julian
This commit is contained in:
parent
bad960b11b
commit
7610f57454
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=132705
@ -1059,6 +1059,7 @@ int ng_address_hook(node_p here, item_p item, hook_p hook, ng_ID_t retaddr);
|
||||
int ng_address_path(node_p here, item_p item, char *address, ng_ID_t raddr);
|
||||
int ng_bypass(hook_p hook1, hook_p hook2);
|
||||
hook_p ng_findhook(node_p node, const char *name);
|
||||
struct ng_type *ng_findtype(const char *type);
|
||||
int ng_make_node_common(struct ng_type *typep, node_p *nodep);
|
||||
int ng_name_node(node_p node, const char *name);
|
||||
int ng_newtype(struct ng_type *tp);
|
||||
|
@ -53,7 +53,6 @@
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/ctype.h>
|
||||
@ -205,7 +204,6 @@ void ng_destroy_hook(hook_p hook);
|
||||
node_p ng_name2noderef(node_p node, const char *name);
|
||||
int ng_path2noderef(node_p here, const char *path,
|
||||
node_p *dest, hook_p *lasthook);
|
||||
struct ng_type *ng_findtype(const char *type);
|
||||
int ng_make_node(const char *type, node_p *nodepp);
|
||||
int ng_path_parse(char *addr, char **node, char **path, char **hook);
|
||||
void ng_rmnode(node_p node, hook_p dummy1, void *dummy2, int dummy3);
|
||||
@ -547,23 +545,11 @@ ng_make_node(const char *typename, node_p *nodepp)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/* Locate the node type */
|
||||
if ((type = ng_findtype(typename)) == NULL) {
|
||||
char filename[NG_TYPESIZ + 3];
|
||||
linker_file_t lf;
|
||||
int error;
|
||||
|
||||
/* Not found, try to load it as a loadable module */
|
||||
snprintf(filename, sizeof(filename), "ng_%s", typename);
|
||||
error = linker_load_module(NULL, filename, NULL, NULL, &lf);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
lf->userrefs++; /* pretend loaded by the syscall */
|
||||
|
||||
/* Try again, as now the type should have linked itself in */
|
||||
if ((type = ng_findtype(typename)) == NULL)
|
||||
return (ENXIO);
|
||||
}
|
||||
/* Locate the node type. If we fail we return. Do not try to load
|
||||
* module.
|
||||
*/
|
||||
if ((type = ng_findtype(typename)) == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
/*
|
||||
* If we have a constructor, then make the node and
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include <sys/errno.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
@ -281,6 +282,39 @@ printf("errx=%d\n",error);
|
||||
} while (0);
|
||||
|
||||
#else
|
||||
/*
|
||||
* Hack alert!
|
||||
* We look into the message and if it mkpeers a node of unknown type, we
|
||||
* try to load it. We need to do this now, in syscall thread, because if
|
||||
* message gets queued and applied later we will get panic.
|
||||
*/
|
||||
if (msg->header.cmd == NGM_MKPEER) {
|
||||
struct ngm_mkpeer *const mkp = (struct ngm_mkpeer *) msg->data;
|
||||
struct ng_type *type;
|
||||
|
||||
if ((type = ng_findtype(mkp->type)) == NULL) {
|
||||
char filename[NG_TYPESIZ + 3];
|
||||
linker_file_t lf;
|
||||
int error;
|
||||
|
||||
/* Not found, try to load it as a loadable module */
|
||||
snprintf(filename, sizeof(filename), "ng_%s", mkp->type);
|
||||
error = linker_load_module(NULL, filename, NULL, NULL, &lf);
|
||||
if (error != 0) {
|
||||
FREE(msg, M_NETGRAPH_MSG);
|
||||
goto release;
|
||||
}
|
||||
lf->userrefs++;
|
||||
|
||||
/* Try again, as now the type should have linked itself in */
|
||||
if ((type = ng_findtype(mkp->type)) == NULL) {
|
||||
FREE(msg, M_NETGRAPH_MSG);
|
||||
error = ENXIO;
|
||||
goto release;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The callee will free the msg when done. The path is our business. */
|
||||
NG_SEND_MSG_PATH(error, pcbp->sockdata->node, msg, path, 0);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user