X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-rtnl%2Fsd-rtnl.c;h=767c583735211dcf35b8533348a7b504ab7b4503;hp=a45ca5e9f57370528836a1fc8aa6be862e8cc124;hb=a9944163fe5600bce85898dae78cd68442a6ff7c;hpb=6d0b55c272ea31d025e8b3c311cea8cda0bfefd7 diff --git a/src/libsystemd/sd-rtnl/sd-rtnl.c b/src/libsystemd/sd-rtnl/sd-rtnl.c index a45ca5e9f..767c58373 100644 --- a/src/libsystemd/sd-rtnl/sd-rtnl.c +++ b/src/libsystemd/sd-rtnl/sd-rtnl.c @@ -67,6 +67,31 @@ static int sd_rtnl_new(sd_rtnl **ret) { return 0; } +int sd_rtnl_new_from_netlink(sd_rtnl **ret, int fd) { + _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL; + socklen_t addrlen; + int r; + + assert_return(ret, -EINVAL); + + r = sd_rtnl_new(ret); + if (r < 0) + return r; + + addrlen = sizeof(rtnl->sockaddr); + + r = getsockname(fd, &rtnl->sockaddr.sa, &addrlen); + if (r < 0) + return -errno; + + rtnl->fd = fd; + + *ret = rtnl; + rtnl = NULL; + + return 0; +} + static bool rtnl_pid_changed(sd_rtnl *rtnl) { assert(rtnl); @@ -126,7 +151,7 @@ static int rtnl_open_fd_ap(sd_rtnl **ret, int fd, unsigned n_groups, va_list ap) r = getsockname(fd, &rtnl->sockaddr.sa, &addrlen); if (r < 0) - return r; + return -errno; rtnl->fd = fd; @@ -187,7 +212,7 @@ sd_rtnl *sd_rtnl_unref(sd_rtnl *rtnl) { assert_return(!rtnl_pid_changed(rtnl), NULL); - if (REFCNT_DEC(rtnl->n_ref) <= 0) { + if (REFCNT_DEC(rtnl->n_ref) == 0) { struct match_callback *f; unsigned i; @@ -379,9 +404,12 @@ static int process_timeout(sd_rtnl *rtnl) { hashmap_remove(rtnl->reply_callbacks, &c->serial); r = c->callback(rtnl, m, c->userdata); + if (r < 0) + log_debug_errno(r, "sd-rtnl: timedout callback failed: %m"); + free(c); - return r < 0 ? r : 1; + return 1; } static int process_reply(sd_rtnl *rtnl, sd_rtnl_message *m) { @@ -404,9 +432,12 @@ static int process_reply(sd_rtnl *rtnl, sd_rtnl_message *m) { prioq_remove(rtnl->reply_callbacks_prioq, c, &c->prioq_idx); r = c->callback(rtnl, m, c->userdata); + if (r < 0) + log_debug_errno(r, "sd-rtnl: callback failed: %m"); + free(c); - return r; + return 1; } static int process_match(sd_rtnl *rtnl, sd_rtnl_message *m) { @@ -424,12 +455,16 @@ static int process_match(sd_rtnl *rtnl, sd_rtnl_message *m) { LIST_FOREACH(match_callbacks, c, rtnl->match_callbacks) { if (type == c->type) { r = c->callback(rtnl, m, c->userdata); - if (r != 0) - return r; + if (r != 0) { + if (r < 0) + log_debug_errno(r, "sd-rtnl: match callback failed: %m"); + + break; + } } } - return 0; + return 1; } static int process_running(sd_rtnl *rtnl, sd_rtnl_message **ret) {