X-Git-Url: http://git.openwrt.org/?p=project%2Fprocd.git;a=blobdiff_plain;f=plug%2Fhotplug.c;h=6df79717bd36cfffcb8dff90899869dd3db30eb5;hp=ca1e823b65c5fdeac1c5d30f2633669abb2e5a56;hb=47d5be7160e33966f5ded484232d10dcc220f172;hpb=916f95cb58604038695347ee41a430d8ca1f0556 diff --git a/plug/hotplug.c b/plug/hotplug.c index ca1e823..6df7971 100644 --- a/plug/hotplug.c +++ b/plug/hotplug.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -161,10 +162,10 @@ static void handle_firmware(struct blob_attr *msg, struct blob_attr *data) char *dir = blobmsg_get_string(blobmsg_data(data)); char *file = hotplug_msg_find_var(msg, "FIRMWARE"); char *dev = hotplug_msg_find_var(msg, "DEVPATH"); - void *fw_data; - struct stat s; + struct stat s = { 0 }; char *path, loadpath[256], syspath[256]; - int fw, load, sys, len; + int fw, src, load, len; + static char buf[4096]; DEBUG(2, "Firmware request for %s/%s\n", dir, file); @@ -173,35 +174,24 @@ static void handle_firmware(struct blob_attr *msg, struct blob_attr *data) exit(-1); } - path = malloc(strlen(dir) + strlen(file) + 2); - if (!path) { - ERROR("Failed to allocate memory\n"); - exit(-1); - } + path = alloca(strlen(dir) + strlen(file) + 2); sprintf(path, "%s/%s", dir, file); if (stat(path, &s)) { ERROR("Could not find firmware %s\n", path); - exit(-1); + src = -1; + s.st_size = 0; + goto send_to_kernel; } - fw_data = malloc(s.st_size); - if (!fw_data) { - ERROR("Failed to allocate firmware data memory\n"); - exit(-1); - } - - fw = open(path, O_RDONLY); - if (!fw) { + src = open(path, O_RDONLY); + if (src < 0) { ERROR("Failed to open %s\n", path); - exit(-1); + s.st_size = 0; + goto send_to_kernel; } - if (read(fw, fw_data, s.st_size) != s.st_size) { - ERROR("Failed to read firmware data\n"); - exit(-1); - } - close(fw); +send_to_kernel: snprintf(loadpath, sizeof(loadpath), "/sys/%s/loading", dev); load = open(loadpath, O_WRONLY); if (!load) { @@ -212,19 +202,23 @@ static void handle_firmware(struct blob_attr *msg, struct blob_attr *data) close(load); snprintf(syspath, sizeof(syspath), "/sys/%s/data", dev); - sys = open(syspath, O_WRONLY); - if (!sys) { + fw = open(syspath, O_WRONLY); + if (fw < 0) { ERROR("Failed to open %s\n", syspath); exit(-1); } len = s.st_size; - while (len > 4096) { - write(fw, fw_data, 4096); - len -= 4096; + while (len) { + len = read(src, buf, sizeof(buf)); + if (len <= 0) + break; + + write(fw, buf, len); } - if (len) - write(fw, fw_data, len); + + if (src >= 0) + close(src); close(fw); load = open(loadpath, O_WRONLY); @@ -342,7 +336,7 @@ rule_handle_file(struct json_script_ctx *ctx, const char *name) json_object *obj; obj = json_object_from_file((char*)name); - if (is_error(obj)) + if (!obj) return NULL; blob_buf_init(&script, 0); @@ -399,6 +393,18 @@ static struct json_script_ctx jctx = { .handle_file = rule_handle_file, }; +static void hotplug_handler_debug(struct blob_attr *data) +{ + char *str; + + if (debug < 3) + return; + + str = blobmsg_format_json(data, true); + DEBUG(3, "%s\n", str); + free(str); +} + static void hotplug_handler(struct uloop_fd *u, unsigned int ev) { int i = 0; @@ -421,7 +427,7 @@ static void hotplug_handler(struct uloop_fd *u, unsigned int ev) i += l; } blobmsg_close_table(&b, index); - DEBUG(3, "%s\n", blobmsg_format_json(b.head, true)); + hotplug_handler_debug(b.head); json_script_run(&jctx, rule_file, blob_data(b.head)); } @@ -441,6 +447,7 @@ void hotplug_last_event(uloop_timeout_handler handler) void hotplug(char *rules) { struct sockaddr_nl nls; + int nlbufsize = 512 * 1024; rule_file = strdup(rules); memset(&nls,0,sizeof(struct sockaddr_nl)); @@ -457,6 +464,9 @@ void hotplug(char *rules) exit(1); } + if (setsockopt(hotplug_fd.fd, SOL_SOCKET, SO_RCVBUFFORCE, &nlbufsize, sizeof(nlbufsize))) + ERROR("Failed to resize receive buffer: %s\n", strerror(errno)); + json_script_init(&jctx); queue_proc.cb = queue_proc_cb; uloop_fd_add(&hotplug_fd, ULOOP_READ);