2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-05 08:45:23 +00:00

dpif-linux: Fail earlier if OVS kernel module isn't loaded

When the kernel module isn't loaded, the bridge tries to open all the
possible minor devices, regardless.  This change first checks that there
is a major device number for Open vSwitch and only then tries to open the
minor devices.

This change also removes the assumption that there's a default Open vSwitch
major device number, since the kernel module always attempts to get a
dynamic one.  Maybe one day we'll have one...

Bug #1179
This commit is contained in:
Justin Pettit
2009-10-02 15:20:12 -07:00
parent 0b8870d4a5
commit 57aaff8a99

View File

@@ -61,6 +61,7 @@ static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(9999, 5);
static int do_ioctl(const struct dpif *, int cmd, const void *arg);
static int lookup_minor(const char *name, int *minor);
static int finish_open(struct dpif *, const char *local_ifname);
static int get_openvswitch_major(void);
static int create_minor(const char *name, int minor, struct dpif **dpifp);
static int open_minor(int minor, struct dpif **dpifp);
static int make_openvswitch_device(int minor, char **fnp);
@@ -77,9 +78,16 @@ dpif_linux_cast(const struct dpif *dpif)
static int
dpif_linux_enumerate(struct svec *all_dps)
{
int major;
int error;
int i;
/* Check that the Open vSwitch module is loaded. */
major = get_openvswitch_major();
if (major < 0) {
return -major;
}
error = 0;
for (i = 0; i < ODP_MAX; i++) {
struct dpif *dpif;
@@ -472,7 +480,7 @@ const struct dpif_class dpif_linux_class = {
};
static int get_openvswitch_major(void);
static int get_major(const char *target, int default_major);
static int get_major(const char *target);
static int
do_ioctl(const struct dpif *dpif_, int cmd, const void *arg)
@@ -541,11 +549,18 @@ error:
static int
make_openvswitch_device(int minor, char **fnp)
{
dev_t dev = makedev(get_openvswitch_major(), minor);
const char dirname[] = "/dev/net";
int major;
dev_t dev;
struct stat s;
char fn[128];
major = get_openvswitch_major();
if (major < 0) {
return -major;
}
dev = makedev(major, minor);
*fnp = NULL;
sprintf(fn, "%s/dp%d", dirname, minor);
if (!stat(fn, &s)) {
@@ -597,20 +612,20 @@ success:
return 0;
}
/* Return the major device number of the Open vSwitch device. If it
* cannot be determined, a negative errno is returned. */
static int
get_openvswitch_major(void)
{
static unsigned int openvswitch_major;
if (!openvswitch_major) {
enum { DEFAULT_MAJOR = 248 };
openvswitch_major = get_major("openvswitch", DEFAULT_MAJOR);
static int openvswitch_major = -1;
if (openvswitch_major < 0) {
openvswitch_major = get_major("openvswitch");
}
return openvswitch_major;
}
static int
get_major(const char *target, int default_major)
get_major(const char *target)
{
const char fn[] = "/proc/devices";
char line[128];
@@ -620,7 +635,7 @@ get_major(const char *target, int default_major)
file = fopen(fn, "r");
if (!file) {
VLOG_ERR("opening %s failed (%s)", fn, strerror(errno));
goto error;
return -errno;
}
for (ln = 1; fgets(line, sizeof line, file); ln++) {
@@ -646,11 +661,8 @@ get_major(const char *target, int default_major)
}
}
VLOG_ERR("%s: %s major not found (is the module loaded?), using "
"default major %d", fn, target, default_major);
error:
VLOG_INFO("using default major %d for %s", default_major, target);
return default_major;
VLOG_ERR("%s: %s major not found (is the module loaded?)", fn, target);
return -ENODEV;
}
static int