Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
DISCONTINUED:openSUSE:11.2:Update
lvm2
device-mapper-wait_udev.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File device-mapper-wait_udev.diff of Package lvm2
Index: LVM2.2.02.45/libdm/ioctl/libdm-iface.c =================================================================== --- LVM2.2.02.45.orig/libdm/ioctl/libdm-iface.c 2009-04-27 17:53:30.000000000 +0800 +++ LVM2.2.02.45/libdm/ioctl/libdm-iface.c 2009-04-27 17:57:54.000000000 +0800 @@ -129,6 +129,67 @@ # define DM_EXISTS_FLAG 0x00000004 #endif +static unsigned long long get_seq() +{ + struct stat s; + int r; + unsigned long long seq = 0; + FILE* fp; + r = stat("/sys/kernel/uevent_seqnum", &s); + if (r) { return seq; } + if (!S_ISREG(s.st_mode)) { return seq; } + fp = fopen("/sys/kernel/uevent_seqnum", "r"); + if (fp == NULL) { return seq; } + fscanf(fp, "%llu\n", &seq); + fclose(fp); + return seq; +} + +static int wait_4_udev(unsigned long long start_seq, unsigned long long end_seq) +{ + FILE* fp; + struct stat s; + int r; + int ite=30; /* Iterate 30 times. Otherwise, it's considered timed out */ + unsigned long long seq; + /* + * len("/dev/.udev/queue/") + len(str(0xffffffffffffffff)) = 38 + */ + #define PATH_SIZE 40 + char filename[PATH_SIZE]; + #undef PATH_SIZE + + if (start_seq > end_seq || end_seq == 0) return 1; + + /* Wait until end_seq is enqueued into udev */ + r = stat("/dev/.udev/uevent_seqnum", &s); + if (r) { return 1; } + if (!S_ISREG(s.st_mode)) { return 1; } + while (ite-- > 0) { + fp = fopen("/dev/.udev/uevent_seqnum", "r"); + if (fp == NULL) { return 1; } + fscanf(fp, "%llu\n", &seq); + fclose(fp); + if (seq >= end_seq) { break; } + usleep(200000); + } + if (ite <=0 ) return 1; + + /* Loop to make sure all $seq are unlinked in /dev/.udev/queue then */ + for (seq = start_seq; seq <= end_seq; seq++) { + ite = 30; + while (ite-- > 0) { + snprintf(filename, sizeof(filename), "/dev/.udev/queue/%llu", seq); + r = open(filename, O_RDONLY); + if (r == -1 && errno == ENOENT) break; + if (r >= 0) close(r); + usleep(200000); + } + if (ite <=0 ) return 1; + } + return 0; +} + static void *_align(void *ptr, unsigned int a) { register unsigned long agn = --a; @@ -679,6 +740,7 @@ { struct dm_ioctl_v1 *dmi; unsigned int command; + unsigned long long before_seq, after_seq; dmi = _flatten_v1(dmt); if (!dmi) { @@ -705,6 +767,8 @@ dmi->name, dmi->uuid, dmt->newname ? " " : "", dmt->newname ? dmt->newname : "", dmi->data_size); + + before_seq = get_seq(); if (dmt->type == DM_DEVICE_LIST) { if (!_dm_names_v1(dmi)) goto bad; @@ -724,10 +788,13 @@ #else /* Userspace alternative for testing */ #endif + after_seq = get_seq(); if (dmi->flags & DM_BUFFER_FULL_FLAG) /* FIXME Increase buffer size and retry operation (if query) */ log_error("WARNING: libdevmapper buffer too small for data"); + wait_4_udev(before_seq, after_seq); + switch (dmt->type) { case DM_DEVICE_CREATE: add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev), @@ -1706,6 +1773,7 @@ { struct dm_ioctl *dmi; unsigned command; + unsigned long long before_seq, after_seq; #ifdef DM_COMPAT if (_dm_version == 1) @@ -1736,9 +1804,11 @@ return 0; repeat_ioctl: + before_seq = get_seq(); if (!(dmi = _do_dm_ioctl(dmt, command, _ioctl_buffer_double_factor))) return 0; + after_seq = get_seq(); if (dmi->flags & DM_BUFFER_FULL_FLAG) { switch (dmt->type) { case DM_DEVICE_LIST_VERSIONS: @@ -1755,6 +1825,8 @@ } } + wait_4_udev(before_seq, after_seq); + switch (dmt->type) { case DM_DEVICE_CREATE: if (dmt->dev_name && *dmt->dev_name)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor