~serge-hallyn/ubuntu/oneiric/libvirt/fix-shutdown

« back to all changes in this revision

Viewing changes to src/lxc/veth.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2010-11-02 16:26:51 UTC
  • mfrom: (1.2.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20101102162651-aq8tnbz58mdf01bf
Tags: 0.8.5-0ubuntu1
* New upstream release.
* Removed a slew of patches which have been
  applied upstream since 0.8.3.
  - 9012-apparmor-extra-tests.patch
  - 9013-apparmor-chardev.patch
  - 9015-Add-ubd-to-the-list-of-disk-prefixes.patch
  - 9016-Close-fd-s-of-persistent-tap-devices.patch
  - 9017-Make-sure-all-command-line-arguments-get-passed-to-U.patch
  - 9018-Make-umlConnectTapDevice-ask-brAddTap-for-a-persiste.patch
  - 9019-uml-fix-logic-bug-in-checking-reply-length.patch
  - 9021-Allow-chardev-of-type-file-for-UML-domains.patch
  - 9022-Rename-qemudShrinkDisks-to-virDomainDiskRemove-and-m.patch
  - 9023-Support-virDomainAttachDevice-and-virDomainDetachDev.patch
  - 9024-Explicitly-pass-uml_dir-argument-to-user-mode-linux.patch
  - 9025-Add-nwfilter-support-to-UML-driver.patch
  - 9026-Rebuild-network-filter-for-UML-guests-on-updates.patch
  - 9027-Make-newfilter-xml-transformations-endian-safe.patch
  - 9028-lp628055.patch
* Updated 9002-better_default_uri_virsh.patch to use vshStrdup,
  as now required in that file.  (use of strdup now causes compilation
  to fail)
* Removed 9008-run-as-root-by-default.patch, which has not been
  applied for awhile now, with no ill effects.
* Simple refresh of:
  - 0001-remove-RHism.diff.patch
  - 0003-allow-libvirt-group-to-access-the-socket.patch
  - 0004-fix-Debian-specific-path-to-hvm-loader.patch
  - 0006-patch-qemuMonitorTextGetMigrationStatus-to-intercept.patch
  - 9000-delayed_iff_up_bridge.patch
  - 9001-dont_clobber_existing_bridges.patch
  - 9003-better-default-arch.patch
  - 9004-libvirtd-group-name.patch
  - 9005-increase-unix-socket-timeout.patch
  - 9006-default-config-test-case.patch
  - 9009-autodetect-nc-params.patch
  - 9010-dont-disable-ipv6.patch
  - 9011-move-ebtables-script.patch
  - 9014-skip-nodeinfotest.patch
  - 9020-lp545795.patch
* Create a patch to include stdint.h so lxc_container.h, which
  #includes linux/fs.h, doesn't trip up on undefined uint64_t.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
#include <config.h>
14
14
 
15
15
#include <string.h>
 
16
#include <stdbool.h>
16
17
#include <stdio.h>
17
18
#include <sys/types.h>
18
19
#include <sys/wait.h>
33
34
/* Functions */
34
35
/**
35
36
 * getFreeVethName:
36
 
 * @veth: name for veth device (NULL to find first open)
37
 
 * @maxLen: max length of veth name
 
37
 * @veth: pointer to store returned name for veth device
38
38
 * @startDev: device number to start at (x in vethx)
39
39
 *
40
40
 * Looks in /sys/class/net/ to find the first available veth device
41
41
 * name.
42
42
 *
43
 
 * Returns 0 on success or -1 in case of error
 
43
 * Returns non-negative device number on success or -1 in case of error
44
44
 */
45
 
static int getFreeVethName(char *veth, int maxLen, int startDev)
 
45
static int getFreeVethName(char **veth, int startDev)
46
46
{
47
 
    int rc = -1;
48
47
    int devNum = startDev-1;
49
 
    char path[PATH_MAX];
 
48
    char *path = NULL;
50
49
 
51
50
    do {
 
51
        VIR_FREE(path);
52
52
        ++devNum;
53
 
        snprintf(path, PATH_MAX, "/sys/class/net/veth%d/", devNum);
 
53
        if (virAsprintf(&path, "/sys/class/net/veth%d/", devNum) < 0) {
 
54
            virReportOOMError();
 
55
            return -1;
 
56
        }
54
57
    } while (virFileExists(path));
55
 
 
56
 
    snprintf(veth, maxLen, "veth%d", devNum);
57
 
 
58
 
    rc = devNum;
59
 
 
60
 
    return rc;
 
58
    VIR_FREE(path);
 
59
 
 
60
    if (virAsprintf(veth, "veth%d", devNum) < 0) {
 
61
        virReportOOMError();
 
62
        return -1;
 
63
    }
 
64
    return devNum;
61
65
}
62
66
 
63
67
/**
64
68
 * vethCreate:
65
 
 * @veth1: name for one end of veth pair
66
 
 * @veth1MaxLen: max length of veth1 name
67
 
 * @veth2: name for one end of veth pair
68
 
 * @veth2MaxLen: max length of veth1 name
 
69
 * @veth1: pointer to name for parent end of veth pair
 
70
 * @veth2: pointer to return name for container end of veth pair
69
71
 *
70
72
 * Creates a veth device pair using the ip command:
71
73
 * ip link add veth1 type veth peer name veth2
 
74
 * If veth1 points to NULL on entry, it will be a valid interface on
 
75
 * return.  veth2 should point to NULL on entry.
 
76
 *
72
77
 * NOTE: If veth1 and veth2 names are not specified, ip will auto assign
73
78
 *       names.  There seems to be two problems here -
74
79
 *       1) There doesn't seem to be a way to determine the names of the
78
83
 *       2) Once one of the veth devices is moved to another namespace, it
79
84
 *          is no longer visible in the parent namespace.  This seems to
80
85
 *          confuse the name assignment causing it to fail with File exists.
81
 
 *       Because of these issues, this function currently forces the caller
82
 
 *       to fully specify the veth device names.
 
86
 *       Because of these issues, this function currently allocates names
 
87
 *       prior to using the ip command, and returns any allocated names
 
88
 *       to the caller.
83
89
 *
84
90
 * Returns 0 on success or -1 in case of error
85
91
 */
86
 
int vethCreate(char* veth1, int veth1MaxLen,
87
 
               char* veth2, int veth2MaxLen)
 
92
int vethCreate(char** veth1, char** veth2)
88
93
{
89
94
    int rc;
90
95
    const char *argv[] = {
91
 
        "ip", "link", "add", veth1, "type", "veth", "peer", "name", veth2, NULL
 
96
        "ip", "link", "add", NULL, "type", "veth", "peer", "name", NULL, NULL
92
97
    };
93
98
    int cmdResult = 0;
94
99
    int vethDev = 0;
95
 
 
96
 
    DEBUG("veth1: %s veth2: %s", veth1, veth2);
97
 
 
98
 
    while ((1 > strlen(veth1)) || STREQ(veth1, veth2)) {
99
 
        vethDev = getFreeVethName(veth1, veth1MaxLen, 0);
100
 
        ++vethDev;
101
 
        DEBUG("Assigned veth1: %s", veth1);
102
 
    }
103
 
 
104
 
    while ((1 > strlen(veth2)) || STREQ(veth1, veth2)) {
105
 
        vethDev = getFreeVethName(veth2, veth2MaxLen, vethDev);
106
 
        ++vethDev;
107
 
        DEBUG("Assigned veth2: %s", veth2);
108
 
    }
109
 
 
110
 
    DEBUG("veth1: %s veth2: %s", veth1, veth2);
 
100
    bool veth1_alloc = false;
 
101
 
 
102
    DEBUG("veth1: %s veth2: %s", NULLSTR(*veth1), NULLSTR(*veth2));
 
103
 
 
104
    if (*veth1 == NULL) {
 
105
        vethDev = getFreeVethName(veth1, vethDev);
 
106
        if (vethDev < 0)
 
107
            return vethDev;
 
108
        DEBUG("Assigned veth1: %s", *veth1);
 
109
        veth1_alloc = true;
 
110
    }
 
111
    argv[3] = *veth1;
 
112
 
 
113
    while (*veth2 == NULL || STREQ(*veth1, *veth2)) {
 
114
        VIR_FREE(*veth2);
 
115
        vethDev = getFreeVethName(veth2, vethDev + 1);
 
116
        if (vethDev < 0) {
 
117
            if (veth1_alloc)
 
118
                VIR_FREE(*veth1);
 
119
            return vethDev;
 
120
        }
 
121
        DEBUG("Assigned veth2: %s", *veth2);
 
122
    }
 
123
    argv[8] = *veth2;
 
124
 
 
125
    DEBUG("veth1: %s veth2: %s", *veth1, *veth2);
111
126
    rc = virRun(argv, &cmdResult);
112
127
 
113
128
    if (rc != 0 ||
114
129
        (WIFEXITED(cmdResult) && WEXITSTATUS(cmdResult) != 0)) {
115
130
        vethError(VIR_ERR_INTERNAL_ERROR,
116
131
                  _("Failed to create veth device pair '%s', '%s': %d"),
117
 
                  veth1, veth2, WEXITSTATUS(cmdResult));
 
132
                  *veth1, *veth2, WEXITSTATUS(cmdResult));
 
133
        if (veth1_alloc)
 
134
            VIR_FREE(*veth1);
 
135
        VIR_FREE(*veth2);
118
136
        rc = -1;
119
137
    }
120
138