~ubuntu-branches/ubuntu/raring/libvirt/raring

« back to all changes in this revision

Viewing changes to src/util/virnetlink.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-11-19 10:41:02 UTC
  • mfrom: (1.2.15) (223.1.2 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20121119104102-l6ewdppikysbzztu
Tags: 1.0.0-0ubuntu2
debian/patches/add-armhf-sysinfo-infomration.patch: Disable
to fix FTBFS on arm.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
 * Lesser General Public License for more details.
14
14
 *
15
15
 * You should have received a copy of the GNU Lesser General Public
16
 
 * License along with this library; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 
16
 * License along with this library.  If not, see
 
17
 * <http://www.gnu.org/licenses/>.
18
18
 *
19
19
 * Authors:
20
20
 *     Stefan Berger <stefanb@us.ibm.com>
33
33
#include <errno.h>
34
34
#include <unistd.h>
35
35
#include <sys/types.h>
 
36
#include <sys/socket.h>
36
37
 
37
38
#include "virnetlink.h"
38
39
#include "logging.h"
41
42
#include "virmacaddr.h"
42
43
#include "virterror_internal.h"
43
44
 
 
45
#ifndef SOL_NETLINK
 
46
# define SOL_NETLINK 270
 
47
#endif
 
48
 
44
49
#define VIR_FROM_THIS VIR_FROM_NET
45
50
 
46
 
#define netlinkError(code, ...)                                           \
47
 
        virReportErrorHelper(VIR_FROM_NET, code, __FILE__,                 \
48
 
                             __FUNCTION__, __LINE__, __VA_ARGS__)
49
 
 
50
51
#define NETLINK_ACK_TIMEOUT_S  2
51
52
 
52
53
#if defined(__linux__) && defined(HAVE_LIBNL)
56
57
    virNetlinkEventHandleCallback handleCB;
57
58
    virNetlinkEventRemoveCallback removeCB;
58
59
    void *opaque;
59
 
    unsigned char macaddr[VIR_MAC_BUFLEN];
 
60
    virMacAddr macaddr;
60
61
    int deleted;
61
62
};
62
63
 
97
98
 records in this multiple */
98
99
# define NETLINK_EVENT_ALLOC_EXTENT 10
99
100
 
100
 
static virNetlinkEventSrvPrivatePtr server = NULL;
 
101
/* Linux kernel supports up to MAX_LINKS (32 at the time) individual
 
102
 * netlink protocols. */
 
103
static virNetlinkEventSrvPrivatePtr server[MAX_LINKS] = {NULL};
101
104
static virNetlinkHandle *placeholder_nlhandle = NULL;
102
105
 
103
106
/* Function definitions */
161
164
 * @respbuf: pointer to pointer where response buffer will be allocated
162
165
 * @respbuflen: pointer to integer holding the size of the response buffer
163
166
 *      on return of the function.
164
 
 * @nl_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
 
167
 * @src_pid: the pid of the process to send a message
 
168
 * @dst_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
 
169
 * @protocol: netlink protocol
 
170
 * @groups: the group identifier
165
171
 *
166
172
 * Send the given message to the netlink layer and receive response.
167
173
 * Returns 0 on success, -1 on error. In case of error, no response
169
175
 */
170
176
int virNetlinkCommand(struct nl_msg *nl_msg,
171
177
                      unsigned char **respbuf, unsigned int *respbuflen,
172
 
                      uint32_t src_pid, uint32_t dst_pid)
 
178
                      uint32_t src_pid, uint32_t dst_pid,
 
179
                      unsigned int protocol, unsigned int groups)
173
180
{
174
181
    int rc = 0;
175
182
    struct sockaddr_nl nladdr = {
185
192
    int fd;
186
193
    int n;
187
194
    struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
188
 
    virNetlinkHandle *nlhandle = virNetlinkAlloc();
189
 
 
 
195
    virNetlinkHandle *nlhandle = NULL;
 
196
 
 
197
    if (protocol >= MAX_LINKS) {
 
198
        virReportSystemError(EINVAL,
 
199
                             _("invalid protocol argument: %d"), protocol);
 
200
        return -EINVAL;
 
201
    }
 
202
 
 
203
    nlhandle = virNetlinkAlloc();
190
204
    if (!nlhandle) {
191
205
        virReportSystemError(errno,
192
206
                             "%s", _("cannot allocate nlhandle for netlink"));
193
207
        return -1;
194
208
    }
195
209
 
196
 
    if (nl_connect(nlhandle, NETLINK_ROUTE) < 0) {
197
 
        virReportSystemError(errno,
198
 
                             "%s", _("cannot connect to netlink socket"));
 
210
    if (nl_connect(nlhandle, protocol) < 0) {
 
211
        virReportSystemError(errno,
 
212
                        _("cannot connect to netlink socket with protocol %d"),
 
213
                             protocol);
 
214
        rc = -1;
 
215
        goto error;
 
216
    }
 
217
 
 
218
    fd = nl_socket_get_fd(nlhandle);
 
219
    if (fd < 0) {
 
220
        virReportSystemError(errno,
 
221
                             "%s", _("cannot get netlink socket fd"));
 
222
        rc = -1;
 
223
        goto error;
 
224
    }
 
225
 
 
226
    if (groups && nl_socket_add_membership(nlhandle, groups) < 0) {
 
227
        virReportSystemError(errno,
 
228
                             "%s", _("cannot add netlink membership"));
199
229
        rc = -1;
200
230
        goto error;
201
231
    }
212
242
        goto error;
213
243
    }
214
244
 
215
 
    fd = nl_socket_get_fd(nlhandle);
216
 
 
217
245
    FD_ZERO(&readfds);
218
246
    FD_SET(fd, &readfds);
219
247
 
262
290
 * virNetlinkEventRemoveClientPrimitive:
263
291
 *
264
292
 * @i: index of the client to remove from the table
 
293
 * @protocol: netlink protocol
265
294
 *
266
295
 * This static function does the low level removal of a client from
267
296
 * the table once its index is known, including calling the remove
271
300
 *
272
301
 * assumes success, returns nothing.
273
302
 */
274
 
static void
275
 
virNetlinkEventRemoveClientPrimitive(size_t i)
 
303
static int
 
304
virNetlinkEventRemoveClientPrimitive(size_t i, unsigned int protocol)
276
305
{
277
 
    virNetlinkEventRemoveCallback removeCB = server->handles[i].removeCB;
 
306
    if (protocol >= MAX_LINKS)
 
307
        return -EINVAL;
 
308
 
 
309
    virNetlinkEventRemoveCallback removeCB = server[protocol]->handles[i].removeCB;
278
310
 
279
311
    if (removeCB) {
280
 
        (removeCB)(server->handles[i].watch,
281
 
                   server->handles[i].macaddr,
282
 
                   server->handles[i].opaque);
 
312
        (removeCB)(server[protocol]->handles[i].watch,
 
313
                   &server[protocol]->handles[i].macaddr,
 
314
                   server[protocol]->handles[i].opaque);
283
315
    }
284
 
    server->handles[i].deleted = VIR_NETLINK_HANDLE_DELETED;
 
316
    server[protocol]->handles[i].deleted = VIR_NETLINK_HANDLE_DELETED;
 
317
    return 0;
285
318
}
286
319
 
287
320
static void
334
367
 * stop the monitor to receive netlink messages for libvirtd.
335
368
 * This removes the netlink socket fd from the event handler.
336
369
 *
 
370
 * @protocol: netlink protocol
 
371
 *
337
372
 * Returns -1 if the monitor cannot be unregistered, 0 upon success
338
373
 */
339
374
int
340
 
virNetlinkEventServiceStop(void)
 
375
virNetlinkEventServiceStop(unsigned int protocol)
341
376
{
342
 
    virNetlinkEventSrvPrivatePtr srv = server;
 
377
    if (protocol >= MAX_LINKS)
 
378
        return -EINVAL;
 
379
 
 
380
    virNetlinkEventSrvPrivatePtr srv = server[protocol];
343
381
    int i;
344
382
 
345
383
    VIR_INFO("stopping netlink event service");
346
384
 
347
 
    if (!server)
 
385
    if (!server[protocol])
348
386
        return 0;
349
387
 
350
388
    virNetlinkEventServerLock(srv);
355
393
    /* free any remaining clients on the list */
356
394
    for (i = 0; i < srv->handlesCount; i++) {
357
395
        if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_VALID)
358
 
            virNetlinkEventRemoveClientPrimitive(i);
 
396
            virNetlinkEventRemoveClientPrimitive(i, protocol);
359
397
    }
360
398
 
361
 
    server = 0;
 
399
    server[protocol] = NULL;
362
400
    virNetlinkEventServerUnlock(srv);
363
401
 
364
402
    virMutexDestroy(&srv->lock);
367
405
}
368
406
 
369
407
/**
 
408
 * virNetlinkEventServiceStopAll:
 
409
 *
 
410
 * Stop all the monitors to receive netlink messages for libvirtd.
 
411
 *
 
412
 * Returns -1 if any monitor cannot be unregistered, 0 upon success
 
413
 */
 
414
int
 
415
virNetlinkEventServiceStopAll(void)
 
416
{
 
417
    unsigned int i, j;
 
418
    virNetlinkEventSrvPrivatePtr srv = NULL;
 
419
 
 
420
    VIR_INFO("stopping all netlink event services");
 
421
 
 
422
    for (i = 0; i < MAX_LINKS; i++) {
 
423
        srv = server[i];
 
424
        if (!srv)
 
425
            continue;
 
426
 
 
427
        virNetlinkEventServerLock(srv);
 
428
        nl_close(srv->netlinknh);
 
429
        virNetlinkFree(srv->netlinknh);
 
430
        virEventRemoveHandle(srv->eventwatch);
 
431
 
 
432
        for (j = 0; j < srv->handlesCount; j++) {
 
433
            if (srv->handles[j].deleted == VIR_NETLINK_HANDLE_VALID)
 
434
                virNetlinkEventRemoveClientPrimitive(j, i);
 
435
        }
 
436
 
 
437
        server[i] = NULL;
 
438
        virNetlinkEventServerUnlock(srv);
 
439
 
 
440
        virMutexDestroy(&srv->lock);
 
441
        VIR_FREE(srv);
 
442
    }
 
443
 
 
444
    return 0;
 
445
}
 
446
 
 
447
/**
370
448
 * virNetlinkEventServiceIsRunning:
371
449
 *
372
450
 * Returns if the netlink event service is running.
373
451
 *
 
452
 * @protocol: netlink protocol
 
453
 *
374
454
 * Returns 'true' if the service is running, 'false' if stopped.
375
455
 */
376
456
bool
377
 
virNetlinkEventServiceIsRunning(void)
 
457
virNetlinkEventServiceIsRunning(unsigned int protocol)
378
458
{
379
 
    return server != NULL;
 
459
    if (protocol >= MAX_LINKS) {
 
460
        virReportSystemError(EINVAL,
 
461
                             _("invalid protocol argument: %d"), protocol);
 
462
        return false;
 
463
    }
 
464
 
 
465
    return server[protocol] != NULL;
380
466
}
381
467
 
382
468
/**
383
469
 * virNetlinkEventServiceLocalPid:
384
470
 *
 
471
 * @protocol: netlink protocol
 
472
 *
385
473
 * Returns the nl_pid value that was used to bind() the netlink socket
386
474
 * used by the netlink event service, or -1 on error (netlink
387
475
 * guarantees that this value will always be > 0).
388
476
 */
389
 
int virNetlinkEventServiceLocalPid(void)
 
477
int virNetlinkEventServiceLocalPid(unsigned int protocol)
390
478
{
391
 
    if (!(server && server->netlinknh)) {
392
 
        netlinkError(VIR_ERR_INTERNAL_ERROR, "%s",
393
 
                     _("netlink event service not running"));
 
479
    if (protocol >= MAX_LINKS)
 
480
        return -EINVAL;
 
481
 
 
482
    if (!(server[protocol] && server[protocol]->netlinknh)) {
 
483
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
484
                       _("netlink event service not running"));
394
485
        return -1;
395
486
    }
396
 
    return (int)nl_socket_get_local_port(server->netlinknh);
 
487
    return (int)nl_socket_get_local_port(server[protocol]->netlinknh);
397
488
}
398
489
 
399
490
 
403
494
 * start a monitor to receive netlink messages for libvirtd.
404
495
 * This registers a netlink socket with the event interface.
405
496
 *
 
497
 * @protocol: netlink protocol
 
498
 * @groups: broadcast groups to join in
406
499
 * Returns -1 if the monitor cannot be registered, 0 upon success
407
500
 */
408
501
int
409
 
virNetlinkEventServiceStart(void)
 
502
virNetlinkEventServiceStart(unsigned int protocol, unsigned int groups)
410
503
{
411
504
    virNetlinkEventSrvPrivatePtr srv;
412
505
    int fd;
413
506
    int ret = -1;
414
507
 
415
 
    if (server)
 
508
    if (protocol >= MAX_LINKS) {
 
509
        virReportSystemError(EINVAL,
 
510
                             _("invalid protocol argument: %d"), protocol);
 
511
        return -EINVAL;
 
512
    }
 
513
 
 
514
    if (server[protocol])
416
515
        return 0;
417
516
 
418
 
    VIR_INFO("starting netlink event service");
 
517
    VIR_INFO("starting netlink event service with protocol %d", protocol);
419
518
 
420
519
    if (VIR_ALLOC(srv) < 0) {
421
520
        virReportOOMError();
438
537
        goto error_locked;
439
538
    }
440
539
 
441
 
    if (nl_connect(srv->netlinknh, NETLINK_ROUTE) < 0) {
 
540
    if (nl_connect(srv->netlinknh, protocol) < 0) {
442
541
        virReportSystemError(errno,
443
 
                             "%s", _("cannot connect to netlink socket"));
 
542
                             _("cannot connect to netlink socket with protocol %d"), protocol);
444
543
        goto error_server;
445
544
    }
446
545
 
447
546
    fd = nl_socket_get_fd(srv->netlinknh);
448
 
 
449
547
    if (fd < 0) {
450
548
        virReportSystemError(errno,
451
549
                             "%s", _("cannot get netlink socket fd"));
452
550
        goto error_server;
453
551
    }
454
552
 
 
553
    if (groups && nl_socket_add_membership(srv->netlinknh, groups) < 0) {
 
554
        virReportSystemError(errno,
 
555
                             "%s", _("cannot add netlink membership"));
 
556
        goto error_server;
 
557
    }
 
558
 
455
559
    if (nl_socket_set_nonblocking(srv->netlinknh)) {
456
560
        virReportSystemError(errno, "%s",
457
561
                             _("cannot set netlink socket nonblocking"));
462
566
                                             VIR_EVENT_HANDLE_READABLE,
463
567
                                             virNetlinkEventCallback,
464
568
                                             srv, NULL)) < 0) {
465
 
        netlinkError(VIR_ERR_INTERNAL_ERROR, "%s",
466
 
                     _("Failed to add netlink event handle watch"));
 
569
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
570
                       _("Failed to add netlink event handle watch"));
467
571
        goto error_server;
468
572
    }
469
573
 
471
575
    VIR_DEBUG("netlink event listener on fd: %i running", fd);
472
576
 
473
577
    ret = 0;
474
 
    server = srv;
 
578
    server[protocol] = srv;
475
579
 
476
580
error_server:
477
581
    if (ret < 0) {
495
599
 * @opaque: user data to pass to callback
496
600
 * @macaddr: macaddr to store with the data. Used to identify callers.
497
601
 *           May be null.
 
602
 * @protocol: netlink protocol
498
603
 *
499
604
 * register a callback for handling of netlink messages. The
500
605
 * registered function receives the entire netlink message and
506
611
int
507
612
virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB,
508
613
                         virNetlinkEventRemoveCallback removeCB,
509
 
                         void *opaque, const unsigned char *macaddr)
 
614
                         void *opaque, const virMacAddrPtr macaddr,
 
615
                         unsigned int protocol)
510
616
{
511
617
    int i, r, ret = -1;
512
 
    virNetlinkEventSrvPrivatePtr srv = server;
 
618
    virNetlinkEventSrvPrivatePtr srv = NULL;
 
619
 
 
620
    if (protocol >= MAX_LINKS)
 
621
        return -EINVAL;
 
622
 
 
623
    srv = server[protocol];
513
624
 
514
625
    if (handleCB == NULL) {
515
 
        netlinkError(VIR_ERR_INTERNAL_ERROR, "%s",
516
 
                     _("Invalid NULL callback provided"));
 
626
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
627
                       _("Invalid NULL callback provided"));
517
628
        return -1;
518
629
    }
519
630
 
548
659
    srv->handles[r].opaque   = opaque;
549
660
    srv->handles[r].deleted  = VIR_NETLINK_HANDLE_VALID;
550
661
    if (macaddr)
551
 
        memcpy(srv->handles[r].macaddr, macaddr, VIR_MAC_BUFLEN);
 
662
        virMacAddrSet(&srv->handles[r].macaddr, macaddr);
552
663
    else
553
 
        memset(srv->handles[r].macaddr, 0, VIR_MAC_BUFLEN);
 
664
        virMacAddrSetRaw(&srv->handles[r].macaddr,
 
665
                         (unsigned char[VIR_MAC_BUFLEN]){0,0,0,0,0,0});
554
666
 
555
667
    VIR_DEBUG("added client to loop slot: %d. with macaddr ptr=%p", r, macaddr);
556
668
 
565
677
 *
566
678
 * @watch: watch whose handle to remove
567
679
 * @macaddr: macaddr whose handle to remove
 
680
 * @protocol: netlink protocol
568
681
 *
569
682
 * Unregister a callback from a netlink monitor.
570
683
 * The handler function referenced will no longer receive netlink messages.
573
686
 * Returns -1 if the file handle was not registered, 0 upon success
574
687
 */
575
688
int
576
 
virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr)
 
689
virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr,
 
690
                            unsigned int protocol)
577
691
{
578
692
    int i;
579
693
    int ret = -1;
580
 
    virNetlinkEventSrvPrivatePtr srv = server;
 
694
    virNetlinkEventSrvPrivatePtr srv = NULL;
 
695
 
 
696
    if (protocol >= MAX_LINKS)
 
697
        return -EINVAL;
 
698
 
 
699
    srv = server[protocol];
581
700
 
582
701
    VIR_DEBUG("removing client watch=%d, mac=%p.", watch, macaddr);
583
702
 
594
713
 
595
714
        if ((watch && srv->handles[i].watch == watch) ||
596
715
            (!watch &&
597
 
             memcmp(macaddr, srv->handles[i].macaddr, VIR_MAC_BUFLEN) == 0)) {
 
716
             virMacAddrCmp(macaddr, &srv->handles[i].macaddr) == 0)) {
598
717
 
599
718
            VIR_DEBUG("removed client: %d by %s.",
600
719
                      srv->handles[i].watch, watch ? "index" : "mac");
601
 
            virNetlinkEventRemoveClientPrimitive(i);
 
720
            virNetlinkEventRemoveClientPrimitive(i, protocol);
602
721
            ret = 0;
603
722
            goto cleanup;
604
723
        }
634
753
                      unsigned char **respbuf ATTRIBUTE_UNUSED,
635
754
                      unsigned int *respbuflen ATTRIBUTE_UNUSED,
636
755
                      uint32_t src_pid ATTRIBUTE_UNUSED,
637
 
                      uint32_t dst_pid ATTRIBUTE_UNUSED)
 
756
                      uint32_t dst_pid ATTRIBUTE_UNUSED,
 
757
                      unsigned int protocol ATTRIBUTE_UNUSED,
 
758
                      unsigned int groups ATTRIBUTE_UNUSED)
638
759
{
639
 
    netlinkError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
 
760
    virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
640
761
    return -1;
641
762
}
642
763
 
644
765
 * stopNetlinkEventServer: stop the monitor to receive netlink
645
766
 * messages for libvirtd
646
767
 */
647
 
int virNetlinkEventServiceStop(void)
 
768
int virNetlinkEventServiceStop(unsigned int protocol ATTRIBUTE_UNUSED)
 
769
{
 
770
    VIR_DEBUG("%s", _(unsupported));
 
771
    return 0;
 
772
}
 
773
 
 
774
/**
 
775
 * stopNetlinkEventServerAll: stop all the monitors to receive netlink
 
776
 * messages for libvirtd
 
777
 */
 
778
int virNetlinkEventServiceStopAll(void)
648
779
{
649
780
    VIR_DEBUG("%s", _(unsupported));
650
781
    return 0;
654
785
 * startNetlinkEventServer: start a monitor to receive netlink
655
786
 * messages for libvirtd
656
787
 */
657
 
int virNetlinkEventServiceStart(void)
 
788
int virNetlinkEventServiceStart(unsigned int protocol ATTRIBUTE_UNUSED,
 
789
                                unsigned int groups ATTRIBUTE_UNUSED)
658
790
{
659
791
    VIR_DEBUG("%s", _(unsupported));
660
792
    return 0;
664
796
 * virNetlinkEventServiceIsRunning: returns if the netlink event
665
797
 * service is running.
666
798
 */
667
 
bool virNetlinkEventServiceIsRunning(void)
 
799
bool virNetlinkEventServiceIsRunning(unsigned int protocol ATTRIBUTE_UNUSED)
668
800
{
669
 
    netlinkError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
 
801
    virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
670
802
    return 0;
671
803
}
672
804
 
673
 
int virNetlinkEventServiceLocalPid(void)
 
805
int virNetlinkEventServiceLocalPid(unsigned int protocol ATTRIBUTE_UNUSED)
674
806
{
675
 
    netlinkError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
 
807
    virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
676
808
    return -1;
677
809
}
678
810
 
683
815
int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB ATTRIBUTE_UNUSED,
684
816
                             virNetlinkEventRemoveCallback removeCB ATTRIBUTE_UNUSED,
685
817
                             void *opaque ATTRIBUTE_UNUSED,
686
 
                             const unsigned char *macaddr ATTRIBUTE_UNUSED)
 
818
                             const virMacAddrPtr macaddr ATTRIBUTE_UNUSED,
 
819
                             unsigned int protocol ATTRIBUTE_UNUSED)
687
820
{
688
 
    netlinkError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
 
821
    virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
689
822
    return -1;
690
823
}
691
824
 
693
826
 * virNetlinkEventRemoveClient: unregister a callback from a netlink monitor
694
827
 */
695
828
int virNetlinkEventRemoveClient(int watch ATTRIBUTE_UNUSED,
696
 
                                const unsigned char *macaddr ATTRIBUTE_UNUSED)
 
829
                                const virMacAddrPtr macaddr ATTRIBUTE_UNUSED,
 
830
                                unsigned int protocol ATTRIBUTE_UNUSED)
697
831
{
698
 
    netlinkError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
 
832
    virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
699
833
    return -1;
700
834
}
701
835