Hi Jack,

?2009?12?19??04:41?Jack Schwartz???
> Hi Zhongyuan.
> 
> On 12/17/09 22:20, zhongyuan sun - Sun Microsystems - Beijing China
> wrote: 
> > Looks good! a little clarification,
> > 
> > ?2009?12?18??08:17?Jack Schwartz???
> >   
> > > Hi Zhongyuan.
> > > 
> > > Thanks for your feedback.
> > > 
> > > On 12/16/09 22:45, zhongyuan sun - Sun Microsystems - Beijing China
> > > wrote: 
> > >     
> > > > Hi Jack,
> > > > 
> > > > Thanks your quick response. my comments:
> > > > 
> > > > (1)I'm not very clear about class devscan_data, what its main function?
> > > > so far I think it's no more different with a list type. The main
> > > > scanning function was implemented by ddu_devscan(). If devscan_data only
> > > > provide like append function, I suggest just use a list but not this
> > > > additional class.
> > > >   
> > > >       
> > > The devscan_data class bundles the data with search functionality.  (I
> > > assume this search functionality is something you need, since you had
> > > originally suggested using a dictionary.) 
> > > get_list_by_devtype(devtype) is the search method.
> > > A list by itself could be used, but then you would need to add
> > > external search methods to filter the data, (like all devices of type
> > > "Audio").  It is convenient to put those methods into the same class
> > > as the data.
> > >     
> > ddu_devscan function will be used in GUI/AI/Text-mode parts. 
> > While in GUI part, ddu_devscan will be called separately for each
> > components(audio,network,storage....), the source code would be
> > like:ddu_devcan(return_missing_only=All, device_type="audio") and then
> > ddu_devcan(return_missing_only=All, device_type="network") and on. In
> > this way, ddu_devscan will do the search method, its return value(will
> > be stored in class devscan_data) do not need to search again. 
> > For AI/Text-mode parts, ddu_devscan will be called only once and return
> > all missing driver components. But since AI/Text-mode do not care about
> > which type(audio,network...) the devices belongs to, so in this way even
> > class devscan_data provide get_list_by_devtype method, it will never be
> > called. 
> > In a summary, I do not know when this method get_list_by_devtype in
> > class devscan_data will be called.
> >   
> Thanks for your clarification.  So get_list_by_devtype() is not
> needed, and we can just use a list at the top level.
> 
> ddu_devscan() will now return a list of dev_data objects.
It's OK, Thanks.


> >   
> > > Why my class instead of a dictionary?  Because it is simpler and more
> > > flexible than a dictionary.  This class is flexible as you can add
> > > additional search methods in the future if needed.)  If a dictionary
> > > is used instead then this additional flexibility becomes harder to
> > > implement.  I would think (but haven't verified this) that 
> > > dictionaries are more heavyweight than the dev_data class.
> > >     
> > > > (2)Which class will in charge of store "Device compatible name" string
> > > > used by ddu_package_lookup()? I did not put it in class dev_data because
> > > > I think this class only store general device information, while "Device
> > > > compatible name" is not a general information especially for that device
> > > > which already has a working driver. "Device compatible name" will be
> > > > only useful for fetching driver information. Shall we add a new function
> > > > to generate "Device compatible name"? This function's argument can be
> > > > pci path and output is "Device compatible name".
> > > >   
> > > >       
> > > From what I see, dev_data stores data specific to a device.  (For
> > > example, attach_status and instance_ID are very specific to a
> > > device.)  The compatible name string is another piece of device
> > > specific data, and so I think we should include it in dev_data. 
> > > (Note: it is currently missing from dev_data;  that is an oversight
> > > and will be corrected.)
> > > 
> > >     
> > Yes, compatible name string could be a property of class dev_data. While
> > from the implementation point of view, all the current dev_data 11
> > properties(description,driver_name,instance_ID...) are get from one
> > session(they are output from a DDU tool). We do not include compatible
> > name string as a default output because its only useful for missing
> > driver components. For that non-missing driver component DDU does not
> > use it. So for most devices the compatible name string is not a very
> > critical property for DDU, DDU only fetch it when needed that is a
> > missing driver device want to look for its driver.
> > Of course DDU can get compatible name string very easy, but it need some
> > more codes in another block. That why i suggest to create another method
> > in dev_data. 
> > Again the dev_data 11
> > properties(description,driver_name,instance_ID...)are get from one
> > session and compatible name string will be fetched from another session
> > even if the method is very easy.
> > If compatible name string is a property of class dev_data, From
> > performance point of view, the non-missing driver device will set it to
> > None and missing driver device will set to its real value?
> >   
> A specification assumes (and therefore limits) the use of a field when
> it specifies that field is to be set only under certain conditions. 
> This is not always a bad thing, but a more versatile solution is to
> always set the field if it is going to be present.  So I suggest to
> either always set the compatible name or else to not include it in the
> structure.
> 
> Let's take the suggestion you made yesterday, and have a separate
> function to return the compatible name string, when given a dev_data
> object argument.  This way, the DDU can get the compatible name when
> it needs it (and so performance around this will be optimized), and
> dev_data fields will be consistent.
Or you can put this function as a method of dev_data, while either
solution is OK, thanks.


> 
> How about this:
> 
> def get_compatible_name(dev_data):
>   # Returns compatible name string
> 
> > > If the compatible name string is in dev_data, do you still need the
> > > vendor_id, device_id and class_code?  (I think you do, as you can use
> > > these items to locate a specific kind of device if necessary, but
> > > please confirm.)
> > >     
> > Yes
> >   
> OK.
> >   
> > > You can already retrieve a device's compatible name string from the
> > > kernel via prtconf (and probably other ways too).  Since the device
> > > compatible name string is already generated elsewhere, let's not
> > > create another function to generate it again.  Duplication of existing
> > > functionality makes the code more difficult to maintain.
> > >     
> > > > (3)function ddu_devscan() and ddu_package_lookup() will take a little
> > > > long time when it running, also during this time these two functions
> > > > will fork some child processes. Should we provide a mechanism to stop
> > > > these functions during it running then they can kill all their child
> > > > processes? This situation usually happens in GUI environment.
> > > >   
> > > >       
> > > I think providing a way for the parent to kill its child processes is
> > > a good idea.  However, I would try to make it automatic via a signal
> > > handler.  When the parent receives a signal to die, have it catch that
> > > catch and process its signal by signaling each of its children to die
> > > gracefully before terminating itself.
> > >     
> > This is exactly what i want, all the child process will be killed via
> > signal. I just want a way for these two functions ddu_devscan() and
> > ddu_package_lookup() can send kill signals to their child processes. For
> > example, can we set a argument for these functions? If the function
> > found this argument has been set to True, then they can have a chance to
> > send kill signals to child processes.
> >   
> I think what you are suggesting is that ddu_devscan and
> ddu_package_lookup will spawn subprocesses when called with an
> argument "termination=False" and to kill the subprocesses they spawned
> when called with "termination=True".  Do I understand correctly?
> 
> Assuming I understand correctly, I don't think the additional arg is
> necessary.  Just have their parent (whoever calls ddu_devcscan and
> ddu_package_lookup) send a signal to the process group at termination
> time.  This will terminate those subprocesses plus all of their
> children.  If you don't want to terminate the parent at that time, set
> it up to ignore the signal before sending it.
> 
Thanks, this way make things simple.


> I wrote and attached a sample shell and python program to show how
> this can be done.  You may need to do a hybrid approach of the two
> programs depending on how your library is set up.
> 
> Since we seem to be converging, I'm going to update the spec again. 
> If you have more issues or if I didn't understand you correctly,
> please reply ASAP.
> 
>     Thanks,
>     Jack
> 
> P.S. Don't use these sample programs as examples of final form. 
> Though they are reasonably clean, I haven't checked them for PEP8
> compliance or style conformity, etc.
> > Thanks,
> > Zhongyuan
> >   
> > >     Thanks,
> > >     Jack
> > >     
> > > > Also thanks Keith's review, I agree with his comments.
> > > > 
> > > > Thank,
> > > > Zhongyuan
> > > > 
> > > > ?2009?12?17??07:02?Jack Schwartz???
> > > >   
> > > >       
> > > > > Hi Zhongyuan.
> > > > > 
> > > > > Thanks for your feedback.  Here's my assessment of requirements, based
> > > > > on both of our emails, and a new proposal which I believe addresses
> > > > > both
> > > > > of our needs and concerns.  Hopefully it is not too long...
> > > > > 
> > > > > A) You need a way to easily restrict the output to a given device
> > > > > type.
> > > > > I assume this why you proposed a dictionary keyed to the device type,
> > > > > at the top level.  I didn't account for that in my original proposal.
> > > > > 
> > > > > B) My proposal placed more of an emphasis on readability and clarity.
> > > > > This is why I originally proposed to store a device's attributes in a
> > > > > dictionary: attributes could be extracted by name.
> > > > > 
> > > > > Additional requirements, as I see things:
> > > > > 
> > > > > C) We don't want to make the data structures too complicated from a
> > > > > data
> > > > > access perspective.  For example a dictionary of lists of dictionaries
> > > > > makes the code hard to follow.
> > > > > 
> > > > > D) We don't want to introduce unnecessary overhead.  If we can use
> > > > > something more lightweight than a dictionary and still have the
> > > > > functionality we need, then I would favor not using the dictionary.
> > > > > 
> > > > > 
> > > > > ddu_devscan() will be returning a group of items corresponding to
> > > > > devices, so it is appropriate to use a collection of some kind for the
> > > > > top level data structure it returns.  At first I agreed with you that
> > > > > a
> > > > > dictionary would be best at the top level:
> > > > > - its items are named (via a key),
> > > > > - it can filter out unwanted items,
> > > > > - it doesn't have to keep a place for items it doesn't need.
> > > > > However, after thinking more, this could prove restrictive in the
> > > > > future.  We return lots of information for each device, any of which
> > > > > could potentially be used as a filter for returning data.  If the
> > > > > dictionary is keyed on device type and later we decide we need to
> > > > > filter on something else (or perhaps multiple items), say vendor ID
> > > > > and/or device ID, we're not set up for that.
> > > > > 
> > > > > Instead, I propose a new class, call it devscan_data, which stores the
> > > > > full list of items returned by ddu_devscan() and has a method for
> > > > > searching and returning only items of a particular device type.  Then
> > > > > in the future we could add other methods to support returning items
> > > > > based on some other filter criteria.  It is also lightweight and
> > > > > provides only the functionality needed.
> > > > > 
> > > > > What are the devscan_data list items?  They would store the different
> > > > > fields of data per device.  The list could point to dictionaries as I
> > > > > had originally proposed, to tuples as you have proposed, or to
> > > > > something
> > > > > else.  I have changed my mind about dictionaries, and think they are
> > > > > the
> > > > > wrong tool; the number and type of fields will not change from one
> > > > > device to the next.  I also still don't like tuples as the fields are
> > > > > hard to keep track of.  Named tuples are better, but more heavyweight
> > > > > than if we defined a new class to hold the data.  So I propose a new
> > > > > class, which would have attributes and get() methods for each field we
> > > > > want to return.  Let's call it dev_data for now.
> > > > > 
> > > > > To summarize:
> > > > > 
> > > > > ddu_devscan() would return a devscan_data object defined like this:
> > > > > 
> > > > > class devscan_data():
> > > > > 
> > > > >     def __init__()
> > > > >         # Holds objects of dev_data.
> > > > >         self.dev_data_list = []
> > > > > 
> > > > >     def add_dev_data_object(dev_data):
> > > > >        self.dev_data_list.append(dev_data)
> > > > >     
> > > > >     def get_list_by_devtype(device_type):
> > > > >         # loop through instance list data to find and return matches
> > > > > on
> > > > >         # device_type
> > > > > 
> > > > > Lists returned by get_list_by_devtype() point to objects of type
> > > > > dev_data.
> > > > > There is one of these objects per device returned.
> > > > > 
> > > > > class dev_data:
> > > > > 
> > > > >     def __init__(...):
> > > > >         self.device_type = ...
> > > > >         self.description = ...
> > > > >         self.driver_name
> > > > >         self.instance_ID
> > > > >         self.item_ID
> > > > >         self.parent_item_ID
> > > > >         self.attach_status
> > > > >         self.vendor_id
> > > > >         self.device_id
> > > > >         self.class_code
> > > > >         self.pci_path
> > > > > 
> > > > >     def get_device_type():
> > > > >         return self.device_type
> > > > > 
> > > > >     def get_description():
> > > > >         return self.description
> > > > > 
> > > > >     ...
> > > > >     ...
> > > > > 
> > > > >     def get_pci_path:
> > > > >         return self.pci_path
> > > > > 
> > > > > Does this work for you?
> > > > > 
> > > > >         Thanks,
> > > > >         Jack
> > > > > 
> > > > > On 12/15/09 21:56, zhongyuan sun - Sun Microsystems - Beijing China
> > > > > wrote: 
> > > > >     
> > > > >         
> > > > > > Hi Jack,
> > > > > > 
> > > > > > It's OK ddu_devscan return dictionary type instead of a list of 
> > > > > > tuples.
> > > > > > I suggest use device type as this dictionary's key and the 
> > > > > > dictionary's
> > > > > > value would be a list of tuples.
> > > > > > 
> > > > > > ddu_devscan description would be as following:
> > > > > > 
> > > > > > Arguments:
> > > > > > - return_missing_only: Boolean; default value is True
> > > > > >   - When True, ddu_devscan returns only the devices which are 
> > > > > > missing
> > > > > >     drivers.
> > > > > >   - When False, all devices found are returned.
> > > > > > - device_type: Type of devices to scan for.  "All" to check all.
> > > > > >   - Possible types
> > > > > > are:"audio"/"battery"/"cpu"/"cd_dvd"/"memory"/"network"/"storage"/"usb"/"video"/"others"
> > > > > > 
> > > > > > 
> > > > > > In each tuple of the list:
> > > > > > - ItemID:
> > > > > > - Parent Item ID:
> > > > > >     /*these two fields(ItemID and Parent Item ID) used for device 
> > > > > > tree to
> > > > > > identify a device and the controller it             attached to. Of 
> > > > > > course for a
> > > > > > controller we do not need to set its parent Item ID.
> > > > > >     */
> > > > > > - Device description:Device name
> > > > > > - Device ID:
> > > > > > - Classcode:
> > > > > > - PCI physical path:This field used to get its detail information.
> > > > > > - Driver name:
> > > > > > - Instance ID:
> > > > > > - Attachment status:
> > > > > >     /*These two fields(Instance ID and Attachment status) used for
> > > > > > determine whether a driver
> > > > > >      has been attached abnormally.
> > > > > >     */
> > > > > > - Vendor ID
> > > > > > 
> > > > > > 
> > > > > > Here is a short example of ddu_devscan return value:
> > > > > >   
> > > > > >       
> > > > > >           
> > > > > > > > > {'Audio': [(200,"","nVidia Corporation MCP55 High Definition
> > > > > > > > >         
> > > > > > > > >             
> > > > > > > > >                 
> > > > > > Audio","0x0371","00040300","[0,6,1]","unknown",-1,"Detached","0x10de")],'Network':[(0,"","nVidia
> > > > > >  Corporation MCP55 
> > > > > > Ethernet","0x0373","00068000","[80,8,0]","nge",0,"Attached","0x10de"),(1,"","nVidia
> > > > > >  Corporation MCP55 
> > > > > > Ethernet","0x0373","00068000","[80,9,0]","nge",1,"Attached","0x10de")],'DVD':[(400,"","nVidia
> > > > > >  Corporation MCP55 
> > > > > > IDE","0x036e","0001018a","[0,4,0]","pci-ide",0,"Attached","0x10de"),(401,400,"MATSHITA
> > > > > >  DVD-RAM UJ-85JS","","","/pci at 0,0/pci-ide at 4/ide at 0/sd at 
> > > > > > 0,0","sd",0,"Attached","")]}
> > > > > > 
> > > > > > 
> > > > > > I also would like to discuss with you a issue during scan process. 
> > > > > > When
> > > > > > user kill GUI during scan process, some backround scripts will 
> > > > > > still be
> > > > > > running even GUI thread has been killed, these scripts was created 
> > > > > > when
> > > > > > performing scanning. Our solution was send a SIGUSR2 signal when GUI
> > > > > > want to kill its child processes. While if we wrapped our scripts 
> > > > > > into
> > > > > > ddu_devscan, how can this function send a signal to its child 
> > > > > > processes?
> > > > > > can we add a argument for this?
> > > > > > 
> > > > > > 
> > > > > > Thanks,
> > > > > > Zhongyuan
> > > > > > 
> > > > > > ?2009?12?15??06:43?Jack Schwartz???
> > > > > >   
> > > > > >       
> > > > > >           
> > > > > > > Hi Zhongyuan.
> > > > > > > 
> > > > > > > Thanks for reviewing the interface spec.  Moving to public forum.
> > > > > > > 
> > > > > > >  > I've some comments on DDU library API--ddu_devscan() function.
> > > > > > >  > You've expanded this function to involve all devices found, 
> > > > > > > it's
> > > > > > >  > good! While for the Return value, currently it only includes
> > > > > > >  > "compatible name" and "device descriptor" strings, It's not
> > > > > > >  > sufficient especially for GUI part:
> > > > > > >  >
> > > > > > >  > *For non-mission items
> > > > > > >  > (1)If the driver works fine,we need a "driver name" field.
> > > > > > >  >
> > > > > > > OK
> > > > > > > 
> > > > > > >  > (2)If the driver dos not works fine, wee need the driver 
> > > > > > > instance
> > > > > > >  > ID and attachment status for this driver.
> > > > > > >  >
> > > > > > >  > Instance ID is a number get from system when driver attached. 
> > > > > > > If
> > > > > > >  > you have 2 e1000g nic cards and they all have been attached
> > > > > > >  > properly, then they will get instance 0 and 1, while if the 
> > > > > > > driver
> > > > > > >  > have not been attached properly or device have been installed
> > > > > > >  > properly, the instance ID will be <0 and attachment status 
> > > > > > > will be
> > > > > > >  > "detached".
> > > > > > >  >
> > > > > > >  > DDU GUI version used "instance ID" and attachment status to 
> > > > > > > give
> > > > > > >  > user a notification "driver missconfigured".
> > > > > > > 
> > > > > > > OK
> > > > > > > 
> > > > > > >  >
> > > > > > >  > BTW, for both non-missing and missing device, I hope we can add
> > > > > > >  > "device category" argument to ddu_devscan function to indicate 
> > > > > > > what
> > > > > > >  > type of category will be looked for(like "Audio"/"Network" 
> > > > > > > etc). By
> > > > > > >  > default this argument can be set to "All" to look for all 
> > > > > > > types of > 
> > > > > > > device.
> > > > > > > 
> > > > > > > OK.
> > > > > > > 
> > > > > > >  > For both missing and non-missing items, we also need these 
> > > > > > > fields
> > > > > > >  > at least:
> > > > > > >  > (1)"Vendor id"/"device id"/"classcode" to identify which 
> > > > > > > category
> > > > > > >  > this device belongs to.
> > > > > > > 
> > > > > > > OK.
> > > > > > > 
> > > > > > >  > (2)pci path to indicate this device's detail information. 
> > > > > > >  > Hopefully this can be involved into ddu_devscan function.
> > > > > > > 
> > > > > > > OK.
> > > > > > > 
> > > > > > > These are a lot of changes for ddu_devscan() for the GUI.  I 
> > > > > > > propose 
> > > > > > > that ddu_devscan returns a list of dictionaries rather than a 
> > > > > > > list of 
> > > > > > > tuples (as before).  Dictionaries because there are a lot of 
> > > > > > > items 
> > > > > > > returned.  Also, not all fields will be used for all devices.  
> > > > > > > (For 
> > > > > > > example, the driver_name field won't be used when a device is 
> > > > > > > missing).
> > > > > > > 
> > > > > > > So this would translate into adding a signature of ddu_devscan() 
> > > > > > > as follows:
> > > > > > > 
> > > > > > > Arguments:
> > > > > > > - return_missing_only: Boolean; default value is True
> > > > > > >   - When True, ddu_devscan returns only the devices which are 
> > > > > > > missing
> > > > > > >     drivers.
> > > > > > >   - When False, all devices found are returned.
> > > > > > > - device_type: Type of devices to scan for.  "All" to check all.
> > > > > > > 
> > > > > > > ===> Please send the list of device types which are valid.  
> > > > > > > "Audio" and 
> > > > > > > "Network" were mentioned earlier.
> > > > > > > 
> > > > > > > Returns:
> > > > > > > A list of dictionaries, each dictionary representing a device.  
> > > > > > > List can 
> > > > > > > be empty (possible only when Return_missing_only is True) to 
> > > > > > > represent a 
> > > > > > > system with no missing drivers.
> > > > > > > 
> > > > > > > Items in each dictionary are:
> > > > > > > 
> > > > > > > - compatible: device compatible name string, a space-separated 
> > > > > > > string of 
> > > > > > > all compatible names for a device.  Compatible names in the 
> > > > > > > string are 
> > > > > > > ordered from the most specific name to the most general name 
> > > > > > > (i.e. the 
> > > > > > > "pciclass" definitions are listed last).
> > > > > > >     - It is OK if two list items have one or more compatible
> > > > > > >       names in common, but each list item should be unique.
> > > > > > > 
> > > > > > > - description: Device description.  can be used for error 
> > > > > > > messages and 
> > > > > > > status reporting.
> > > > > > > 
> > > > > > > - device_type: Type of device (e.g. "Audio", "Network")
> > > > > > > 
> > > > > > > - driver_name: Name of the driver operating the device.  (Can be 
> > > > > > > omitted 
> > > > > > > if driver is missing.)
> > > > > > > 
> > > > > > > - instance_ID: Instance ID assigned to the device.  (Always 
> > > > > > > present.  
> > > > > > > Will be <0 if no driver is attached to the device.)
> > > > > > > 
> > > > > > > - attach_status: Status of whether or not a driver is attached to 
> > > > > > > the 
> > > > > > > device.  (Always present.  Will be "detached" if driver is not 
> > > > > > > attached, 
> > > > > > > "attached" if driver is attached.
> > > > > > > 
> > > > > > > ===> Any other statuses possible?
> > > > > > > 
> > > > > > > - vendor_id: Device's vendor ID.  (Always present.)
> > > > > > > 
> > > > > > > - device_id: Device's device ID  (Always present.)
> > > > > > > 
> > > > > > > - class_code: Device's class code  (Always present.)
> > > > > > > 
> > > > > > > - pci_path: Device path  (Always present.)
> > > > > > > 
> > > > > > > Please let me know by today COB (PRC time) the device types and 
> > > > > > > if any 
> > > > > > > corrections are needed.
> > > > > > > 
> > > > > > >     Thanks,
> > > > > > >     Jack
> > > > > > > 
> > > > > > > On 12/04/09 09:20, Jack Schwartz wrote:
> > > > > > >     
> > > > > > >         
> > > > > > >             
> > > > > > > > Hi everyone.
> > > > > > > > 
> > > > > > > > FYI: Driver Update functional and programming interface specs 
> > > > > > > > have had 
> > > > > > > > a minor update.  The items addressed deal either with 
> > > > > > > > subtleties 
> > > > > > > > missed during the main review but which came up during 
> > > > > > > > development, or 
> > > > > > > > other things we discovered were needed during development.
> > > > > > > > 
> > > > > > > > Functional spec:
> > > > > > > > - Clarify that any repo can be specified, not only repos which 
> > > > > > > > a 
> > > > > > > > system already
> > > > > > > >  knows about.
> > > > > > > > - Clarify that it is an error if a publisher name is already 
> > > > > > > > mapped to 
> > > > > > > > a repo,
> > > > > > > >  and another repo with the same publisher name is requested.
> > > > > > > > - Add publisher to AI searchall capability
> > > > > > > > 
> > > > > > > > Interface spec:
> > > > > > > > - Add arg to ddu_devscan() so that the function can return 
> > > > > > > > either all 
> > > > > > > > devices
> > > > > > > >  on a system, or only devices which are missing their driver.
> > > > > > > > 
> > > > > > > > Links on the Driver Update page have been updated.  Previous 
> > > > > > > > spec 
> > > > > > > > versions have been retained on that page for comparison 
> > > > > > > > purposes.
> > > > > > > > 
> > > > > > > > Driver update page is at:
> > > > > > > > http://hub.opensolaris.org/bin/view/Project+caiman/Driver_Update
> > > > > > > > 
> > > > > > > > If there are any questions or comments please send them my way.
> > > > > > > > 
> > > > > > > >    Thanks,
> > > > > > > >    Jack
> > > > > > > > 
> > > > > > > > 
> > > > > > > >       
> > > > > > > >           
> > > > > > > >               
> > > > > >                   
> > > >         
> >   
> 
> 
> 
> ______________________________________________________________________
> #!/bin/ksh
> 
> #
> # Child part
> #
> if [ "$1" == "child" ] ; then
> $0 grandchild &
> $0 grandchild &
>   echo "Hi from child with pid $$"
>   sleep 1000
>   echo "Bye from child with pid $$"
>   exit 0
> fi
> 
> #
> # Grandchild part
> #
> if [ "$1" == "grandchild" ] ; then
>   echo "Hi from grandchild with pid $$"
>   sleep 1000
>   echo "Bye from grandchild with pid $$"
>   exit 0
> fi
> 
> #
> # Parent part
> #
> 
> #---------------
> function handler
> #---------------
> {
> echo "Terminating all child processes in this group ($$)..."
> 
> # Catch the signal we're about to send out, so that I don't terminate by it.
> # Needed to prevent recursion if this handler is called when TERM received
> #     (see "trap handler" line in main below)
> trap "" TERM
> 
> # Send out the signal.
> pkill -TERM -g $$
> 
> # Now perform any other cleanup I have to do.
> echo "Check for un-killed children..."
> echo "There should be only this process with PID $$ showing..."
> ps -efjl | head -1
> ps -efjl | grep $$ | grep -v grep | grep -v efjl
> echo "Handler Bye from parent"
> exit 0
> }
> 
> #-----
> # Main
> #-----
> 
> # Catch ^C, ^\ and regular "kill"
> trap handler INT QUIT TERM
> 
> # Call this script with "child" as first arg to spawn child processes
> $0 child &
> $0 child &
> sleep 1000
> echo "Normal Bye from parent" # This won't execute if handler terminates me.
> exit 0
> 
> ______________________________________________________________________
> #!/bin/python2.6
> 
> import sys
> import subprocess
> import os
> import signal
> import time
> 
> from subprocess import PIPE as PIPE
> 
> #--------------------------
> def handler(signum, frame):
> #--------------------------
>     print ("Terminating all child processes in this group (" +
>            str(os.getpid()) + ") ...")
> 
>     # Catch the signal we're about to send out, so that I don't terminate by 
> it.
>     # Needed to prevent recursion if this handler is called when TERM received
>     # (see "trap handler" line in main below)
>     signal.signal(signal.SIGTERM, signal.SIG_IGN)
> 
>     # Send out the signal.
>     subprocess.Popen(["/bin/pkill", "-TERM", "-g", str(os.getpid())])
> 
>     # Now perform any other cleanup I have to do.
>     print "Check for un-killed children..."
>     print ("There should be only this process with PID " +
>            str(os.getpid()) + " showing...")
>     # subprocess.Popen(["/bin/ps", "-efjl", "|", "head", "-1", ";",
>     #                   "/bin/ps", "-efjl", "|", "grep", str(os.getpid()), 
> "|",
>     #                   "grep", "-v", "grep", "|", "grep", "-v", "efjl"],
>     #                   shell=True)
>     p1 = subprocess.Popen(["/bin/ps", "-efjl"], stdout=PIPE)
>     p2 = subprocess.Popen(["head", "-1"], stdin=p1.stdout)
>     p2.wait()
>     p1 = subprocess.Popen(["/bin/ps", "-efjl"], stdout=PIPE)
>     p2 = subprocess.Popen(["grep", str(os.getpid())], stdin=p1.stdout,
>                           stdout=PIPE)
>     p3 = subprocess.Popen(["grep", "-v", "grep"], stdin=p2.stdout, 
> stdout=PIPE)
>     p4 = subprocess.Popen(["grep", "-v", "efjl"], stdin=p3.stdout)
>     p4.wait()
>     print "Handler Bye from parent"
>     sys.exit(0)
> 
> 
> #--------------
> def main(argv):
> #--------------
>     full_pathname = os.getcwd() + "/" + argv[0].rsplit("/",1)[1]
> 
>     #
>     # Child part
>     #
>     if ((len(argv) > 1) and (argv[1] == "child")):
>         subprocess.Popen([full_pathname, "grandchild"])
>         subprocess.Popen([full_pathname, "grandchild"])
>         print "Hi from child with pid " + str(os.getpid())
>         time.sleep(1000)
>         print "Bye from child with pid " + str(os.getpid())
>         sys.exit(0)
> 
>     #
>     # Grandchild part
>     #
>     if ((len(argv) > 1) and (argv[1] == "grandchild")):
>         print "Hi from grandchild with pid " + str(os.getpid())
>         time.sleep(1000)
>         print "Bye from grandchild with pid " + str(os.getpid())
>         sys.exit(0)
> 
>     #
>     # Parent part
>     #
> 
>     # Catch ^C, ^\ and regular "kill"
>     signal.signal(signal.SIGINT, handler)
>     signal.signal(signal.SIGQUIT, handler)
>     signal.signal(signal.SIGTERM, handler)
> 
>     # Call this script with "child" as first arg to spawn child processes
>     subprocess.Popen([full_pathname, "child"])
>     subprocess.Popen([full_pathname, "child"])
>     time.sleep(1000)
>     print "Normal Bye from parent" # This won't execute if handler terminates 
> me
>     sys.exit(0)
> 
> if __name__ == "__main__":
> 
>     try:
>         main(sys.argv)
>     except (SystemExit, KeyboardInterrupt):
>         pass
> 


Reply via email to