On Thursday, September 15, 2011 11:03:09 AM Michael Mol wrote: > On Thu, Sep 15, 2011 at 10:48 AM, Joost Roeleveld <jo...@antarean.org> wrote: > > On Thursday, September 15, 2011 10:32:50 AM Michael Mol wrote: > >> On Thu, Sep 15, 2011 at 10:11 AM, Joost Roeleveld <jo...@antarean.org> > > > > wrote: > >> >> I'm not entirely convinced this is the case, because it feels > >> >> like > >> >> some situations like network devices (nbd, iSCSI) or loopback > >> >> would > >> >> require userland tools to bring up once networking is up. > >> > > >> > Yes, but the kernel-events referencing those devices won't appear > >> > untill after the networking is brought up. > >> > The scripts that "udev" starts are run *after* a device-event is > >> > created. If the device itself has not been spotted by the kernel > >> > (for > >> > instance, the networking doesn't exist yet), the event won't be > >> > triggered yet. > >> > > >> > This situation does not require udev to start all these tools when > >> > network- devices appear. > >> > > >> > I hope the following would make my thoughts a bit clearer: > >> > > >> > 1) kernel boots > >> > > >> > 2) kernel detects network device and places "network-device-event" > >> > in > >> > the > >> > queue > >> > > >> > 3) further things happen and kernel places relevant events in the > >> > queue (some other events may also already be in the queue before > >> > step 2) > >> > > >> > 4) udev starts and starts processing the queue > >> > > >> > 5) For each event, udev creates the corresponding device-entry and > >> > places > >> > action-entries in a queue > >> > > >> > 6) system-init-scripts mount all local filesystems > >> > > >> > 7) udev-actions starts (I made up this name) > >> > > >> > 8) udev-actions processes all the entries in the action-queue > >> > > >> > From step 4, udev will keep processing further events it gets, > >> > which > >> > means that if any action taken by "udev-actions" causes further > >> > devices to become available, "udev" will create the > >> > device-entries and place the action in the action-queue. > >> > >> So, if I read this correctly, there are two classes of processing > >> events. kernel events and scripted actions. Here's rough pseudocode > >> describing what I think you're saying. (Or perhaps what I'm hoping > >> you're saying) > >> > >> while(wait_for_event()) > >> { > >> kevent* pkEvent = NULL; > >> if(get_waiting_kernel_event(pkEvent)) // returns true if an event > >> was > >> waiting { > >> process_kernel_event(pkEvent); > >> } > >> else > >> { > >> aevent* pAction = NULL; > >> if(get_waiting_action(pAction)) // Returns true if there's an > >> action waiting. > >> { > >> process_action(pAction); > >> } > >> } > >> } > > > > This is, sort-of, what I feel should happen. But currently, in > > pseudo-code, the following seems to happen: > > while(wait_for_event()) > > { > > kevent* pkEvent = NULL; > > if(get_waiting_kernel_event(pkEvent)) // returns true if an event was > > waiting { > > process_kernel_event(pkEvent); > > } > > } > > > > I would prefer to see 2 seperate processes: > > > > --- process 1 --- > > while(wait_for_event()) > > { > > kevent* pkEvent = NULL; > > if(get_waiting_kernel_event(pkEvent)) // returns true if an event was > > waiting > > { > > action_event = process_kernel_event(pkEvent); > > if (action_event != NULL) > > { > > put_action_event(pkEvent); > > } > > } > > } > > > > ------ > > > > --- process 2 --- > > while(wait_for_event()) > > { > > aevent* paEvent = NULL; > > if(get_waiting_action_event(paEvent)) // returns true if an event was > > waiting > > { > > process_action_event(paEvent); > > } > > } > > ------- > > > >> So, udev processes one event at a time, and always processes kernel > >> events with a higher priority than resulting scripts. This makes a > >> certain amount of sense; an action could launch, e.g. nbdclient, which > >> would cause a new kernel event to get queued. > > > > Yes, except that udev ONLY handles kernel-events and doesn't process any > > "actions" itself. > > These are placed on a seperate queue for a seperate process. > > The problem with this is that you now need to manage synchronization > between the kernel event processor and the action processor, which is > actually more complicated than keeping them together in a > single-threaded, single-process scenario.
I don't agree. Why does this need to be synchronized? The kernel puts events in the new-dev-event-queue that process 1 picks up. process 1 creates the /dev-entrie(s) and, if there is an action to be taken, puts the action in the new-action-event-queue. Process 2 will then pick up this action from the new-action-event-queue and will process this. If, as a side-effect, of the action processed by process 2, a new device appears for the kernel, the kernel will simply put a corresponding event in the new-dev-event-queue. At which state does this need to be synchronized? We can simply use a pipe-device as, for instance, used for syslog? -- Joost