From c6e663d1fd672e6c832061a6067ebaea5a95f24d Mon Sep 17 00:00:00 2001 From: chenglch Date: Mon, 25 Jan 2016 01:53:54 -0500 Subject: [PATCH] Use fifo pipe to enhance getadapter Currently the getadapter implementation store the nics information in multiple files. This implementaion will store the records in the database and add the following changes: 1. Add taskstate table to record the getadapter request. 2. Add route_request hook in xcatd to avoid of too much process. 3. Add adapterinfo column to keep the adapter information. 4. Use fifo pipe to send/recv the adapter message and wake up the waiting process. 5. Use alarm signal to handle the timeout event. --- docs/source/advanced/networks/getadapter.rst | 51 + docs/source/advanced/networks/getadapters.rst | 53 -- .../references/man1/getadapter.1.rst | 118 +++ .../admin-guides/references/man5/nics.5.rst | 15 +- .../references/man5/taskstate.5.rst | 76 ++ .../admin-guides/references/man5/xcatdb.5.rst | 10 + .../admin-guides/references/man7/group.7.rst | 46 +- .../admin-guides/references/man7/node.7.rst | 46 +- .../references/man7/taskstate.7.rst | 85 ++ perl-xCAT/xCAT/Schema.pm | 56 +- xCAT-client/debian/xcat-client.links | 1 + xCAT-client/pods/man1/getadapter.1.pod | 84 ++ xCAT-client/pods/man1/getadapters.1.pod | 85 -- xCAT-client/xCAT-client.spec | 1 + xCAT-genesis-scripts/bin/getadapter | 19 +- xCAT-server/lib/perl/xCAT/FifoPipe.pm | 219 +++++ xCAT-server/lib/perl/xCAT/State.pm | 15 + xCAT-server/lib/xcat/plugins/getadapter.pm | 894 ++++++++++++------ xCAT-server/sbin/xcatd | 25 +- 19 files changed, 1425 insertions(+), 474 deletions(-) create mode 100644 docs/source/advanced/networks/getadapter.rst delete mode 100755 docs/source/advanced/networks/getadapters.rst create mode 100644 docs/source/guides/admin-guides/references/man1/getadapter.1.rst create mode 100644 docs/source/guides/admin-guides/references/man5/taskstate.5.rst create mode 100644 docs/source/guides/admin-guides/references/man7/taskstate.7.rst create mode 100644 xCAT-client/pods/man1/getadapter.1.pod delete mode 100644 xCAT-client/pods/man1/getadapters.1.pod create mode 100644 xCAT-server/lib/perl/xCAT/FifoPipe.pm create mode 100644 xCAT-server/lib/perl/xCAT/State.pm diff --git a/docs/source/advanced/networks/getadapter.rst b/docs/source/advanced/networks/getadapter.rst new file mode 100644 index 000000000..c1ce39e48 --- /dev/null +++ b/docs/source/advanced/networks/getadapter.rst @@ -0,0 +1,51 @@ +Predict network adapter name before deployment +============================================== + + + +Traditionally, network interfaces in Linux are enumerated as eth[0123…], but these names do not necessarily correspond to actual labels on the chassis. customer need a methods to get consistent and predictable network device name before provision or network configuration. xCAT provide a tool ``getadapter`` to help customer to resolve this problem. + + +**[Note]** : This feature needs to restart your target sever which you want to obtain network adapter from. + +How to use get adapters +----------------------- + + +Using below command to obtain the network adapters information :: + + getadapter + +Then will get output like below :: + + + The whole scan result: + -------------------------------------- + [node2] scan successfully, below are the latest data + node2:[1]->eno1!mac=34:40:b5:be:6a:80|pci=/pci0000:00/0000:00:01.0/0000:0c:00.0|candidatename=eno1/enp12s0f0/enx3440b5be6a80 + node2:[2]->enp0s29u1u1u5!mac=36:40:b5:bf:44:33|pci=/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1.5/2-1.1.5:1.0|candidatename=enp0s29u1u1u5/enx3640b5bf4433 + -------------------------------------- + [node1] scan successfully, below are the latest data + node1:[1]->eno1!mac=34:40:b5:be:6a:80|pci=/pci0000:00/0000:00:01.0/0000:0c:00.0|candidatename=eno1/enp12s0f0/enx3440b5be6a80 + node1:[2]->enp0s29u1u1u5!mac=36:40:b5:bf:44:33|pci=/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1.5/2-1.1.5:1.0|candidatename=enp0s29u1u1u5/enx3640b5bf4433 + + +Every node gets a separate section to display its all network adapters information, every network adapter owns single line which start as node name and followed by index and other information. + +xCAT try its best to collect more information for each network adapter, but can’t guarantee collect same much information for every one. If a network adapter can be derived by xcat genesis, this adapter will have a predictable name, if it can’t be, it only has the information xcat can obtain. + +below are the possible information: + +* **name**: the consistent name which can be used by confignic directly in operating system which follow the same naming scheme with rhels7 + +* **pci**: the pci location + +* **mac**: the MAC address + +* **candidatename**: All the names which satisfy predictable network device naming scheme, if customer needs to customize their network adapter name, they can choose one of them. (``confignic`` needs to do more work to support this. if customer want to use their own name, xcat should offer a interface to get customer’s input and change this column) + +* **vendor**: the vender of network device + +* **modle**: the modle of network device + +* **linkstate**: The link state of network device diff --git a/docs/source/advanced/networks/getadapters.rst b/docs/source/advanced/networks/getadapters.rst deleted file mode 100755 index 16cb6a06b..000000000 --- a/docs/source/advanced/networks/getadapters.rst +++ /dev/null @@ -1,53 +0,0 @@ -Predict network adapter name before deployment -============================================== - - - -Traditionally, network interfaces in Linux are enumerated as eth[0123…], but these names do not necessarily correspond to actual labels on the chassis. customer need a methods to get consistent and predictable network device name before provision or network configuration. xCAT provide a tool ``getadapters`` to help customer to resolve this problem. - - -**[Note]** : This feature needs to restart your target sever which you want to obtain network adapter from. - -How to use get adapters ------------------------ - - -Using below command to obtain the network adapters information :: - - getadapters - -Then will get output like below :: - - - The whole scan result: - -------------------------------------- - node1:1:hitname=enP3p3s0f0|pci=/pci0003:00/0003:00:00.0/0003:01:00.0/0003:02:01.0/0003:03:00.0|mac=98be9459ea24|candidatename=enP3p3s0f0,enx98be9459ea24|vendor=Broadcom Corporation|modle=NetXtreme II BCM57800 1/10 Gigabit Ethernet - node1:2:hitname=enP3p3s0f1|pci=/pci0003:00/0003:00:00.0/0003:01:00.0/0003:02:01.0/0003:03:00.1|mac=98be9459ea25|candidatename=enP3p3s0f1,enx98be9459ea25|vendor=Broadcom Corporation|modle=NetXtreme II BCM57800 1/10 Gigabit Ethernet - node1:3:hitname=enP3p3s0f2|pci=/pci0003:00/0003:00:00.0/0003:01:00.0/0003:02:01.0/0003:03:00.2|mac=98be9459ea26|candidatename=enP3p3s0f2,enx98be9459ea26|vendor=Broadcom Corporation|modle=NetXtreme II BCM57800 1/10 Gigabit Ethernet - node1:4:hitname=enP3p3s0f3|pci=/pci0003:00/0003:00:00.0/0003:01:00.0/0003:02:01.0/0003:03:00.3|mac=98be9459ea27|candidatename=enP3p3s0f3,enx98be9459ea27|vendor=Broadcom Corporation|modle=NetXtreme II BCM57800 1/10 Gigabit Ethernet - node1:5:pci=0001:01:00.0|modle=Mellanox Technologies MT27600 [Connect-IB] - -------------------------------------- - node2:1:hitname=enP3p3s0f0|pci=/pci0003:00/0003:00:00.0/0003:01:00.0/0003:02:01.0/0003:03:00.0|mac=98be9459ea24|candidatename=enP3p3s0f0,enx98be9459ea24|vendor=Broadcom Corporation|modle=NetXtreme II BCM57800 1/10 Gigabit Ethernet - node2:2:hitname=enP3p3s0f1|pci=/pci0003:00/0003:00:00.0/0003:01:00.0/0003:02:01.0/0003:03:00.1|mac=98be9459ea25|candidatename=enP3p3s0f1,enx98be9459ea25|vendor=Broadcom Corporation|modle=NetXtreme II BCM57800 1/10 Gigabit Ethernet - - -Every node gets a separate section to display its all network adapters information, every network adapter owns single line which start as node name and followed by index and other information. - -xCAT try its best to collect more information for each network adapter, but can’t guarantee collect same much information for every one. If a network adapter can be derived by xcat genesis, this adapter will have a predictable name, if it can’t be, it only has the information xcat can obtain. - -below are the possible information: - -* **hitname**: the consistent name which can be used in ``confignic`` derectly in operating system which follow the same naming scheme with rhels7. (``confignic`` doesn’t need to do more work) - -* **pci**: the pci location - -* **mac**: the MAC address - -* **candidatename**: All the names which satisfy predictable network device naming scheme, if customer needs to customize their network adapter name, they can choose one of them. (``confignic`` needs to do more work to support this. if customer want to use their own name, xcat should offer a interface to get customer’s input and change this column) - -* **vendor**: the vender of network device - -* **modle**: the modle of network device - - - diff --git a/docs/source/guides/admin-guides/references/man1/getadapter.1.rst b/docs/source/guides/admin-guides/references/man1/getadapter.1.rst new file mode 100644 index 000000000..c687fca17 --- /dev/null +++ b/docs/source/guides/admin-guides/references/man1/getadapter.1.rst @@ -0,0 +1,118 @@ + +############ +getadapter.1 +############ + +.. highlight:: perl + + +**** +NAME +**** + + +\ **getadapter**\ - Obtain all network adapters's predictable name and some other information before provision or network configuration. + + +******** +SYNOPSIS +******** + + +\ **getadapter**\ \ *noderange*\ [\ **-f**\ ] + +\ **getadapter**\ [\ **-h**\ |\ **--help**\ |\ **-v**\ |\ **--version**\ |\ **-V**\ ] + + +*********** +DESCRIPTION +*********** + + +Traditionally, network interfaces in Linux are enumerated as eth[0123…], but these names do not necessarily correspond to actual labels on the chassis. \ **getadapter**\ help customer to get predictable network device name and some other network adapter information before provision or network configuration. + +\ **getadapter**\ use genesis to collect network adapters information, so that mean it need to restart the target node. + +\ **getadapter**\ follows below scheme: + +If the target node is scaned for the first time, \ **getadapter**\ will trigger genesis to collect information then save the information at local. +If the target node has ever been scaned, i.e. this node has network device information in local, \ **getadapter**\ use the local information first. +If user doesn't want to use local information, can use \ **-f**\ option to force to trigger new round scan process. +if part nodes of \ *noderange*\ don't have network device information in local and the rest have, \ **getadapter**\ only trigger real scan process for these nodes which don't have local information, the nodes have network device information in local, \ **getadapter**\ still use the local information first. + +\ **getadapter**\ tries to collect more information for the target network device, but doesn't guarantee collect same much information for every network device. + +Below are the possible information can be collect up to now: +\ **name**\ : the consistent name which can be used by confignic directly in operating system which follow the same naming scheme with rhels7 +\ **pci**\ : the pci location +\ **mac**\ : the MAC address +\ **candidatename**\ : All the names which satisfy predictable network device naming scheme. \ *(if xcat enhance confignic command later, user can use these names to configure their network adapter, even customize their name)*\ +\ **vender**\ : the vender of network device +\ **model**\ : the model of network device +\ **linkstate**\ : the link state of network device + + +******* +OPTIONS +******* + + +\ **-h**\ + +Display usage message. + +\ **-v**\ + +Command Version. + +\ **-V**\ + +Display verbose message. + +\ **-f**\ + +Force to trigger new round scan. ignore the data collected before. + + +******** +EXAMPLES +******** + + +1. To collect node[1-3]'s network device information, enter: + + +.. code-block:: perl + + getadapter node[1-2] + + +Output is similar to: + +-->Starting scan for: node1,node2 +The whole scan result: +-------------------------------------- +[node1]: Adapter information exists, no need to scan. +-------------------------------------- +[node2] scan successfully, below are the latest data +node2:[1]->eno1!mac=34:40:b5:be:6a:80|pci=/pci0000:00/0000:00:01.0/0000:0c:00.0|candidatename=eno1/enp12s0f0/enx3440b5be6a80 +node2:[2]->enp0s29u1u1u5!mac=36:40:b5:bf:44:33|pci=/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1.5/2-1.1.5:1.0|candidatename=enp0s29u1u1u5/enx3640b5bf4433 + +Every node gets a separate section to display its all network adapters information, every network adapter owns single line which start as node name and followed by index and other information. + +2. Force to trigger new round scan + + +.. code-block:: perl + + getadatper node -f + + + +******** +SEE ALSO +******** + + +noderange(3)|noderange.3 + diff --git a/docs/source/guides/admin-guides/references/man5/nics.5.rst b/docs/source/guides/admin-guides/references/man5/nics.5.rst index 2166fd42f..4855c0a56 100644 --- a/docs/source/guides/admin-guides/references/man5/nics.5.rst +++ b/docs/source/guides/admin-guides/references/man5/nics.5.rst @@ -19,7 +19,7 @@ SYNOPSIS ******** -\ **nics Attributes:**\ \ *node*\ , \ *nicips*\ , \ *nichostnamesuffixes*\ , \ *nichostnameprefixes*\ , \ *nictypes*\ , \ *niccustomscripts*\ , \ *nicnetworks*\ , \ *nicaliases*\ , \ *nicextraparams*\ , \ *comments*\ , \ *disable*\ +\ **nics Attributes:**\ \ *node*\ , \ *nicips*\ , \ *nichostnamesuffixes*\ , \ *nichostnameprefixes*\ , \ *nictypes*\ , \ *niccustomscripts*\ , \ *nicnetworks*\ , \ *nicaliases*\ , \ *nicextraparams*\ , \ *nicdevices*\ , \ *nicsadapter*\ , \ *comments*\ , \ *disable*\ *********** @@ -119,6 +119,19 @@ nics Attributes: +\ **nicdevices**\ + + Comma-separated list of NIC device per NIC, multiple ethernet devices can be bonded as bond device, these ethernet devices are separated by |. !|,!, e.g. bond0!eth0|eth2,br0!bond0. The xCAT object definition commands support to use nicdevices. as the sub attributes. + + + +\ **nicsadapter**\ + + Comma-separated list of extra parameters that will be used for each NIC configuration. + !|,!|, for example, eth0!MTU=1500|MTU=1460,ib0!MTU=65520 CONNECTED_MODE=yes. + + + \ **comments**\ Any user-written notes. diff --git a/docs/source/guides/admin-guides/references/man5/taskstate.5.rst b/docs/source/guides/admin-guides/references/man5/taskstate.5.rst new file mode 100644 index 000000000..44fb0ee01 --- /dev/null +++ b/docs/source/guides/admin-guides/references/man5/taskstate.5.rst @@ -0,0 +1,76 @@ + +########### +taskstate.5 +########### + +.. highlight:: perl + + +**** +NAME +**** + + +\ **taskstate**\ - a table in the xCAT database. + + +******** +SYNOPSIS +******** + + +\ **taskstate Attributes:**\ \ *node*\ , \ *command*\ , \ *state*\ , \ *pid*\ , \ *reserve*\ + + +*********** +DESCRIPTION +*********** + + +The task state for the node. + + +********************* +taskstate Attributes: +********************* + + + +\ **node**\ + + The node name. + + + +\ **command**\ + + Current command is running + + + +\ **state**\ + + The task state(callback, running) for the node. + + + +\ **pid**\ + + The process id of the request process. + + + +\ **reserve**\ + + used to lock the node + + + + +******** +SEE ALSO +******** + + +\ **nodels(1)**\ , \ **chtab(8)**\ , \ **tabdump(8)**\ , \ **tabedit(8)**\ + diff --git a/docs/source/guides/admin-guides/references/man5/xcatdb.5.rst b/docs/source/guides/admin-guides/references/man5/xcatdb.5.rst index 785c909e0..86806e6ae 100644 --- a/docs/source/guides/admin-guides/references/man5/xcatdb.5.rst +++ b/docs/source/guides/admin-guides/references/man5/xcatdb.5.rst @@ -304,6 +304,10 @@ site(7)|site.7 +taskstate(7)|taskstate.7 + + + zone(7)|zone.7 @@ -682,6 +686,12 @@ switches(5)|switches.5 +taskstate(5)|taskstate.5 + + The task state for the node. + + + token(5)|token.5 The token of users for authentication. diff --git a/docs/source/guides/admin-guides/references/man7/group.7.rst b/docs/source/guides/admin-guides/references/man7/group.7.rst index 550d7084e..618e8b15e 100644 --- a/docs/source/guides/admin-guides/references/man7/group.7.rst +++ b/docs/source/guides/admin-guides/references/man7/group.7.rst @@ -19,7 +19,7 @@ SYNOPSIS ******** -\ **group Attributes:**\ \ *addkcmdline*\ , \ *arch*\ , \ *authdomain*\ , \ *bmc*\ , \ *bmcpassword*\ , \ *bmcport*\ , \ *bmcusername*\ , \ *cfgmgr*\ , \ *cfgmgtroles*\ , \ *cfgserver*\ , \ *chain*\ , \ *chassis*\ , \ *cmdmapping*\ , \ *cons*\ , \ *conserver*\ , \ *consoleondemand*\ , \ *cpucount*\ , \ *cputype*\ , \ *currchain*\ , \ *currstate*\ , \ *dhcpinterfaces*\ , \ *disksize*\ , \ *displayname*\ , \ *domainadminpassword*\ , \ *domainadminuser*\ , \ *domaintype*\ , \ *getmac*\ , \ *groupname*\ , \ *grouptype*\ , \ *hcp*\ , \ *height*\ , \ *hostcluster*\ , \ *hostinterface*\ , \ *hostmanager*\ , \ *hostnames*\ , \ *hosttype*\ , \ *hwtype*\ , \ *id*\ , \ *initrd*\ , \ *installnic*\ , \ *interface*\ , \ *ip*\ , \ *iscsipassword*\ , \ *iscsiserver*\ , \ *iscsitarget*\ , \ *iscsiuserid*\ , \ *kcmdline*\ , \ *kernel*\ , \ *linkports*\ , \ *mac*\ , \ *membergroups*\ , \ *members*\ , \ *memory*\ , \ *mgt*\ , \ *micbridge*\ , \ *michost*\ , \ *micid*\ , \ *miconboot*\ , \ *micpowermgt*\ , \ *micvlog*\ , \ *migrationdest*\ , \ *monserver*\ , \ *mpa*\ , \ *mtm*\ , \ *nameservers*\ , \ *netboot*\ , \ *nfsdir*\ , \ *nfsserver*\ , \ *nicaliases*\ , \ *niccustomscripts*\ , \ *nicextraparams*\ , \ *nichostnameprefixes*\ , \ *nichostnamesuffixes*\ , \ *nicips*\ , \ *nicnetworks*\ , \ *nictypes*\ , \ *nimserver*\ , \ *nodetype*\ , \ *ondiscover*\ , \ *os*\ , \ *osvolume*\ , \ *otherinterfaces*\ , \ *ou*\ , \ *parent*\ , \ *passwd.HMC*\ , \ *passwd.admin*\ , \ *passwd.celogin*\ , \ *passwd.general*\ , \ *passwd.hscroot*\ , \ *password*\ , \ *postbootscripts*\ , \ *postscripts*\ , \ *power*\ , \ *pprofile*\ , \ *prescripts-begin*\ , \ *prescripts-end*\ , \ *primarynic*\ , \ *productkey*\ , \ *profile*\ , \ *protocol*\ , \ *provmethod*\ , \ *rack*\ , \ *room*\ , \ *routenames*\ , \ *serial*\ , \ *serialflow*\ , \ *serialport*\ , \ *serialspeed*\ , \ *servicenode*\ , \ *setupconserver*\ , \ *setupdhcp*\ , \ *setupftp*\ , \ *setupipforward*\ , \ *setupldap*\ , \ *setupnameserver*\ , \ *setupnfs*\ , \ *setupnim*\ , \ *setupntp*\ , \ *setupproxydhcp*\ , \ *setuptftp*\ , \ *sfp*\ , \ *side*\ , \ *slot*\ , \ *slotid*\ , \ *slots*\ , \ *snmpauth*\ , \ *snmppassword*\ , \ *snmpprivacy*\ , \ *snmpusername*\ , \ *snmpversion*\ , \ *storagcontroller*\ , \ *storagetype*\ , \ *supernode*\ , \ *supportedarchs*\ , \ *supportproxydhcp*\ , \ *switch*\ , \ *switchinterface*\ , \ *switchport*\ , \ *switchtype*\ , \ *switchvlan*\ , \ *termport*\ , \ *termserver*\ , \ *tftpdir*\ , \ *tftpserver*\ , \ *unit*\ , \ *urlpath*\ , \ *usercomment*\ , \ *userid*\ , \ *username*\ , \ *vmbeacon*\ , \ *vmbootorder*\ , \ *vmcfgstore*\ , \ *vmcluster*\ , \ *vmcpus*\ , \ *vmhost*\ , \ *vmmanager*\ , \ *vmmaster*\ , \ *vmmemory*\ , \ *vmnicnicmodel*\ , \ *vmnics*\ , \ *vmothersetting*\ , \ *vmphyslots*\ , \ *vmstorage*\ , \ *vmstoragecache*\ , \ *vmstorageformat*\ , \ *vmstoragemodel*\ , \ *vmtextconsole*\ , \ *vmvirtflags*\ , \ *vmvncport*\ , \ *webport*\ , \ *wherevals*\ , \ *xcatmaster*\ +\ **group Attributes:**\ \ *addkcmdline*\ , \ *arch*\ , \ *authdomain*\ , \ *bmc*\ , \ *bmcpassword*\ , \ *bmcport*\ , \ *bmcusername*\ , \ *cfgmgr*\ , \ *cfgmgtroles*\ , \ *cfgserver*\ , \ *chain*\ , \ *chassis*\ , \ *cmdmapping*\ , \ *cons*\ , \ *conserver*\ , \ *consoleondemand*\ , \ *cpucount*\ , \ *cputype*\ , \ *currchain*\ , \ *currstate*\ , \ *dhcpinterfaces*\ , \ *disksize*\ , \ *displayname*\ , \ *dockercpus*\ , \ *dockerflag*\ , \ *dockerhost*\ , \ *dockermemory*\ , \ *domainadminpassword*\ , \ *domainadminuser*\ , \ *domaintype*\ , \ *getmac*\ , \ *groupname*\ , \ *grouptype*\ , \ *hcp*\ , \ *height*\ , \ *hostcluster*\ , \ *hostinterface*\ , \ *hostmanager*\ , \ *hostnames*\ , \ *hosttype*\ , \ *hwtype*\ , \ *id*\ , \ *initrd*\ , \ *installnic*\ , \ *interface*\ , \ *ip*\ , \ *iscsipassword*\ , \ *iscsiserver*\ , \ *iscsitarget*\ , \ *iscsiuserid*\ , \ *kcmdline*\ , \ *kernel*\ , \ *linkports*\ , \ *mac*\ , \ *membergroups*\ , \ *members*\ , \ *memory*\ , \ *mgt*\ , \ *micbridge*\ , \ *michost*\ , \ *micid*\ , \ *miconboot*\ , \ *micpowermgt*\ , \ *micvlog*\ , \ *migrationdest*\ , \ *monserver*\ , \ *mpa*\ , \ *mtm*\ , \ *nameservers*\ , \ *netboot*\ , \ *nfsdir*\ , \ *nfsserver*\ , \ *nicaliases*\ , \ *niccustomscripts*\ , \ *nicdevices*\ , \ *nicextraparams*\ , \ *nichostnameprefixes*\ , \ *nichostnamesuffixes*\ , \ *nicips*\ , \ *nicnetworks*\ , \ *nicsadapter*\ , \ *nictypes*\ , \ *nimserver*\ , \ *nodetype*\ , \ *ondiscover*\ , \ *os*\ , \ *osvolume*\ , \ *otherinterfaces*\ , \ *ou*\ , \ *parent*\ , \ *passwd.HMC*\ , \ *passwd.admin*\ , \ *passwd.celogin*\ , \ *passwd.general*\ , \ *passwd.hscroot*\ , \ *password*\ , \ *postbootscripts*\ , \ *postscripts*\ , \ *power*\ , \ *pprofile*\ , \ *prescripts-begin*\ , \ *prescripts-end*\ , \ *primarynic*\ , \ *productkey*\ , \ *profile*\ , \ *protocol*\ , \ *provmethod*\ , \ *rack*\ , \ *room*\ , \ *routenames*\ , \ *serial*\ , \ *serialflow*\ , \ *serialport*\ , \ *serialspeed*\ , \ *servicenode*\ , \ *setupconserver*\ , \ *setupdhcp*\ , \ *setupftp*\ , \ *setupipforward*\ , \ *setupldap*\ , \ *setupnameserver*\ , \ *setupnfs*\ , \ *setupnim*\ , \ *setupntp*\ , \ *setupproxydhcp*\ , \ *setuptftp*\ , \ *sfp*\ , \ *side*\ , \ *slot*\ , \ *slotid*\ , \ *slots*\ , \ *snmpauth*\ , \ *snmppassword*\ , \ *snmpprivacy*\ , \ *snmpusername*\ , \ *snmpversion*\ , \ *storagcontroller*\ , \ *storagetype*\ , \ *supernode*\ , \ *supportedarchs*\ , \ *supportproxydhcp*\ , \ *switch*\ , \ *switchinterface*\ , \ *switchport*\ , \ *switchtype*\ , \ *switchvlan*\ , \ *termport*\ , \ *termserver*\ , \ *tftpdir*\ , \ *tftpserver*\ , \ *unit*\ , \ *urlpath*\ , \ *usercomment*\ , \ *userid*\ , \ *username*\ , \ *vmbeacon*\ , \ *vmbootorder*\ , \ *vmcfgstore*\ , \ *vmcluster*\ , \ *vmcpus*\ , \ *vmhost*\ , \ *vmmanager*\ , \ *vmmaster*\ , \ *vmmemory*\ , \ *vmnicnicmodel*\ , \ *vmnics*\ , \ *vmothersetting*\ , \ *vmphyslots*\ , \ *vmstorage*\ , \ *vmstoragecache*\ , \ *vmstorageformat*\ , \ *vmstoragemodel*\ , \ *vmtextconsole*\ , \ *vmvirtflags*\ , \ *vmvncport*\ , \ *webport*\ , \ *wherevals*\ , \ *xcatmaster*\ *********** @@ -259,6 +259,30 @@ group Attributes: +\ **dockercpus**\ (vm.cpus) + + Number of CPUs the node should see. + + + +\ **dockerflag**\ (vm.othersettings) + + This allows specifying a semicolon delimited list of key->value pairs to include in a vmx file of VMware or KVM. For partitioning on normal power machines, this option is used to specify the hugepage and/or bsr information, the value is like:'hugepage:1,bsr=2'. For KVM cpu pinning, this option is used to specify the physical cpu set on the host, the value is like:"vcpupin:'0-15,^8'",Its syntax is a comma separated list and a special markup using '-' and '^' (ex. '0-4', '0-3,^2') can also be allowed, the '-' denotes the range and the '^' denotes exclusive. For KVM memory binding, the value is like:'membind:0', restrict a guest to allocate memory from the specified set of NUMA nodes. For PCI passthrough, the value is like:'devpassthrough:pci_0001_01_00_0,pci_0000_03_00_0',the PCI devices are assigned to a virtual machine, and the virtual machine can use this I/O exclusively,the devices list are a list of PCI device names delimited with comma, the PCI device names can be obtained by running \ **virsh nodedev-list**\ on the host. + + + +\ **dockerhost**\ (vm.host) + + The system that currently hosts the VM + + + +\ **dockermemory**\ (vm.memory) + + Megabytes of memory the VM currently should be set to. + + + \ **domainadminpassword**\ (domain.adminpassword) Allow a node specific indication of Administrative user password for the domain. Most will want to ignore this in favor of passwd table. @@ -589,6 +613,12 @@ group Attributes: +\ **nicdevices**\ (nics.nicdevices) + + Comma-separated list of NIC device per NIC, multiple ethernet devices can be bonded as bond device, these ethernet devices are separated by |. !|,!, e.g. bond0!eth0|eth2,br0!bond0. The xCAT object definition commands support to use nicdevices. as the sub attributes. + + + \ **nicextraparams**\ (nics.nicextraparams) Comma-separated list of extra parameters that will be used for each NIC configuration. @@ -689,6 +719,18 @@ group Attributes: +\ **nicsadapter**\ (nics.nicsadapter) + + Comma-separated list of extra parameters that will be used for each NIC configuration. + + + .. code-block:: perl + + !|,!|, for example, eth0!MTU=1500|MTU=1460,ib0!MTU=65520 CONNECTED_MODE=yes. + + + + \ **nictypes**\ (nics.nictypes) Comma-separated list of NIC types per NIC. !,!, e.g. eth0!Ethernet,ib0!Infiniband. The xCAT object definition commands support to use nictypes. as the sub attributes. @@ -1313,7 +1355,7 @@ group Attributes: \ **vmothersetting**\ (vm.othersettings) - This allows specifying a semicolon delimited list of key->value pairs to include in a vmx file of VMware or KVM. For partitioning on normal power machines, this option is used to specify the hugepage and/or bsr information, the value is like:'hugepage:1,bsr=2'. For KVM cpu pinning, this option is used to specify the physical cpu set on the host, the value is like:'vcpupin:'0-15,^8' ',Its syntax is a comma separated list and a special markup using '-' and '^' (ex. '0-4', '0-3,^2') can also be allowed, the '-' denotes the range and the '^' denotes exclusive. For KVM memory binding, the value is like:'membind:0', restrict a guest to allocate memory from the specified set of NUMA nodes. For PCI passthrough, the value is like:'devpassthrough:pci_0001_01_00_0,pci_0000_03_00_0',the PCI devices are assigned to a virtual machine, and the virtual machine can use this I/O exclusively,the devices list are a list of PCI device names delimited with comma, the PCI device names can be obtained by running \ **virsh nodedev-list**\ on the host. + This allows specifying a semicolon delimited list of key->value pairs to include in a vmx file of VMware or KVM. For partitioning on normal power machines, this option is used to specify the hugepage and/or bsr information, the value is like:'hugepage:1,bsr=2'. For KVM cpu pinning, this option is used to specify the physical cpu set on the host, the value is like:"vcpupin:'0-15,^8'",Its syntax is a comma separated list and a special markup using '-' and '^' (ex. '0-4', '0-3,^2') can also be allowed, the '-' denotes the range and the '^' denotes exclusive. For KVM memory binding, the value is like:'membind:0', restrict a guest to allocate memory from the specified set of NUMA nodes. For PCI passthrough, the value is like:'devpassthrough:pci_0001_01_00_0,pci_0000_03_00_0',the PCI devices are assigned to a virtual machine, and the virtual machine can use this I/O exclusively,the devices list are a list of PCI device names delimited with comma, the PCI device names can be obtained by running \ **virsh nodedev-list**\ on the host. diff --git a/docs/source/guides/admin-guides/references/man7/node.7.rst b/docs/source/guides/admin-guides/references/man7/node.7.rst index 4cf0ea65b..9af9380f1 100644 --- a/docs/source/guides/admin-guides/references/man7/node.7.rst +++ b/docs/source/guides/admin-guides/references/man7/node.7.rst @@ -19,7 +19,7 @@ SYNOPSIS ******** -\ **node Attributes:**\ \ *addkcmdline*\ , \ *appstatus*\ , \ *appstatustime*\ , \ *arch*\ , \ *authdomain*\ , \ *bmc*\ , \ *bmcpassword*\ , \ *bmcport*\ , \ *bmcusername*\ , \ *cfgmgr*\ , \ *cfgmgtroles*\ , \ *cfgserver*\ , \ *chain*\ , \ *chassis*\ , \ *cmdmapping*\ , \ *cons*\ , \ *conserver*\ , \ *consoleondemand*\ , \ *cpucount*\ , \ *cputype*\ , \ *currchain*\ , \ *currstate*\ , \ *dhcpinterfaces*\ , \ *disksize*\ , \ *displayname*\ , \ *domainadminpassword*\ , \ *domainadminuser*\ , \ *domaintype*\ , \ *getmac*\ , \ *groups*\ , \ *hcp*\ , \ *height*\ , \ *hidden*\ , \ *hostcluster*\ , \ *hostinterface*\ , \ *hostmanager*\ , \ *hostnames*\ , \ *hosttype*\ , \ *hwtype*\ , \ *id*\ , \ *initrd*\ , \ *installnic*\ , \ *interface*\ , \ *ip*\ , \ *iscsipassword*\ , \ *iscsiserver*\ , \ *iscsitarget*\ , \ *iscsiuserid*\ , \ *kcmdline*\ , \ *kernel*\ , \ *linkports*\ , \ *mac*\ , \ *memory*\ , \ *mgt*\ , \ *micbridge*\ , \ *michost*\ , \ *micid*\ , \ *miconboot*\ , \ *micpowermgt*\ , \ *micvlog*\ , \ *migrationdest*\ , \ *monserver*\ , \ *mpa*\ , \ *mtm*\ , \ *nameservers*\ , \ *netboot*\ , \ *nfsdir*\ , \ *nfsserver*\ , \ *nicaliases*\ , \ *niccustomscripts*\ , \ *nicextraparams*\ , \ *nichostnameprefixes*\ , \ *nichostnamesuffixes*\ , \ *nicips*\ , \ *nicnetworks*\ , \ *nictypes*\ , \ *nimserver*\ , \ *node*\ , \ *nodetype*\ , \ *ondiscover*\ , \ *os*\ , \ *osvolume*\ , \ *otherinterfaces*\ , \ *ou*\ , \ *parent*\ , \ *passwd.HMC*\ , \ *passwd.admin*\ , \ *passwd.celogin*\ , \ *passwd.general*\ , \ *passwd.hscroot*\ , \ *password*\ , \ *postbootscripts*\ , \ *postscripts*\ , \ *power*\ , \ *pprofile*\ , \ *prescripts-begin*\ , \ *prescripts-end*\ , \ *primarynic*\ , \ *primarysn*\ , \ *productkey*\ , \ *profile*\ , \ *protocol*\ , \ *provmethod*\ , \ *rack*\ , \ *room*\ , \ *routenames*\ , \ *serial*\ , \ *serialflow*\ , \ *serialport*\ , \ *serialspeed*\ , \ *servicenode*\ , \ *setupconserver*\ , \ *setupdhcp*\ , \ *setupftp*\ , \ *setupipforward*\ , \ *setupldap*\ , \ *setupnameserver*\ , \ *setupnfs*\ , \ *setupnim*\ , \ *setupntp*\ , \ *setupproxydhcp*\ , \ *setuptftp*\ , \ *sfp*\ , \ *side*\ , \ *slot*\ , \ *slotid*\ , \ *slots*\ , \ *snmpauth*\ , \ *snmppassword*\ , \ *snmpprivacy*\ , \ *snmpusername*\ , \ *snmpversion*\ , \ *status*\ , \ *statustime*\ , \ *storagcontroller*\ , \ *storagetype*\ , \ *supernode*\ , \ *supportedarchs*\ , \ *supportproxydhcp*\ , \ *switch*\ , \ *switchinterface*\ , \ *switchport*\ , \ *switchtype*\ , \ *switchvlan*\ , \ *termport*\ , \ *termserver*\ , \ *tftpdir*\ , \ *tftpserver*\ , \ *unit*\ , \ *updatestatus*\ , \ *updatestatustime*\ , \ *urlpath*\ , \ *usercomment*\ , \ *userid*\ , \ *username*\ , \ *vmbeacon*\ , \ *vmbootorder*\ , \ *vmcfgstore*\ , \ *vmcluster*\ , \ *vmcpus*\ , \ *vmhost*\ , \ *vmmanager*\ , \ *vmmaster*\ , \ *vmmemory*\ , \ *vmnicnicmodel*\ , \ *vmnics*\ , \ *vmothersetting*\ , \ *vmphyslots*\ , \ *vmstorage*\ , \ *vmstoragecache*\ , \ *vmstorageformat*\ , \ *vmstoragemodel*\ , \ *vmtextconsole*\ , \ *vmvirtflags*\ , \ *vmvncport*\ , \ *webport*\ , \ *xcatmaster*\ , \ *zonename*\ +\ **node Attributes:**\ \ *addkcmdline*\ , \ *appstatus*\ , \ *appstatustime*\ , \ *arch*\ , \ *authdomain*\ , \ *bmc*\ , \ *bmcpassword*\ , \ *bmcport*\ , \ *bmcusername*\ , \ *cfgmgr*\ , \ *cfgmgtroles*\ , \ *cfgserver*\ , \ *chain*\ , \ *chassis*\ , \ *cmdmapping*\ , \ *cons*\ , \ *conserver*\ , \ *consoleondemand*\ , \ *cpucount*\ , \ *cputype*\ , \ *currchain*\ , \ *currstate*\ , \ *dhcpinterfaces*\ , \ *disksize*\ , \ *displayname*\ , \ *dockercpus*\ , \ *dockerflag*\ , \ *dockerhost*\ , \ *dockermemory*\ , \ *domainadminpassword*\ , \ *domainadminuser*\ , \ *domaintype*\ , \ *getmac*\ , \ *groups*\ , \ *hcp*\ , \ *height*\ , \ *hidden*\ , \ *hostcluster*\ , \ *hostinterface*\ , \ *hostmanager*\ , \ *hostnames*\ , \ *hosttype*\ , \ *hwtype*\ , \ *id*\ , \ *initrd*\ , \ *installnic*\ , \ *interface*\ , \ *ip*\ , \ *iscsipassword*\ , \ *iscsiserver*\ , \ *iscsitarget*\ , \ *iscsiuserid*\ , \ *kcmdline*\ , \ *kernel*\ , \ *linkports*\ , \ *mac*\ , \ *memory*\ , \ *mgt*\ , \ *micbridge*\ , \ *michost*\ , \ *micid*\ , \ *miconboot*\ , \ *micpowermgt*\ , \ *micvlog*\ , \ *migrationdest*\ , \ *monserver*\ , \ *mpa*\ , \ *mtm*\ , \ *nameservers*\ , \ *netboot*\ , \ *nfsdir*\ , \ *nfsserver*\ , \ *nicaliases*\ , \ *niccustomscripts*\ , \ *nicdevices*\ , \ *nicextraparams*\ , \ *nichostnameprefixes*\ , \ *nichostnamesuffixes*\ , \ *nicips*\ , \ *nicnetworks*\ , \ *nicsadapter*\ , \ *nictypes*\ , \ *nimserver*\ , \ *node*\ , \ *nodetype*\ , \ *ondiscover*\ , \ *os*\ , \ *osvolume*\ , \ *otherinterfaces*\ , \ *ou*\ , \ *parent*\ , \ *passwd.HMC*\ , \ *passwd.admin*\ , \ *passwd.celogin*\ , \ *passwd.general*\ , \ *passwd.hscroot*\ , \ *password*\ , \ *postbootscripts*\ , \ *postscripts*\ , \ *power*\ , \ *pprofile*\ , \ *prescripts-begin*\ , \ *prescripts-end*\ , \ *primarynic*\ , \ *primarysn*\ , \ *productkey*\ , \ *profile*\ , \ *protocol*\ , \ *provmethod*\ , \ *rack*\ , \ *room*\ , \ *routenames*\ , \ *serial*\ , \ *serialflow*\ , \ *serialport*\ , \ *serialspeed*\ , \ *servicenode*\ , \ *setupconserver*\ , \ *setupdhcp*\ , \ *setupftp*\ , \ *setupipforward*\ , \ *setupldap*\ , \ *setupnameserver*\ , \ *setupnfs*\ , \ *setupnim*\ , \ *setupntp*\ , \ *setupproxydhcp*\ , \ *setuptftp*\ , \ *sfp*\ , \ *side*\ , \ *slot*\ , \ *slotid*\ , \ *slots*\ , \ *snmpauth*\ , \ *snmppassword*\ , \ *snmpprivacy*\ , \ *snmpusername*\ , \ *snmpversion*\ , \ *status*\ , \ *statustime*\ , \ *storagcontroller*\ , \ *storagetype*\ , \ *supernode*\ , \ *supportedarchs*\ , \ *supportproxydhcp*\ , \ *switch*\ , \ *switchinterface*\ , \ *switchport*\ , \ *switchtype*\ , \ *switchvlan*\ , \ *termport*\ , \ *termserver*\ , \ *tftpdir*\ , \ *tftpserver*\ , \ *unit*\ , \ *updatestatus*\ , \ *updatestatustime*\ , \ *urlpath*\ , \ *usercomment*\ , \ *userid*\ , \ *username*\ , \ *vmbeacon*\ , \ *vmbootorder*\ , \ *vmcfgstore*\ , \ *vmcluster*\ , \ *vmcpus*\ , \ *vmhost*\ , \ *vmmanager*\ , \ *vmmaster*\ , \ *vmmemory*\ , \ *vmnicnicmodel*\ , \ *vmnics*\ , \ *vmothersetting*\ , \ *vmphyslots*\ , \ *vmstorage*\ , \ *vmstoragecache*\ , \ *vmstorageformat*\ , \ *vmstoragemodel*\ , \ *vmtextconsole*\ , \ *vmvirtflags*\ , \ *vmvncport*\ , \ *webport*\ , \ *xcatmaster*\ , \ *zonename*\ *********** @@ -271,6 +271,30 @@ node Attributes: +\ **dockercpus**\ (vm.cpus) + + Number of CPUs the node should see. + + + +\ **dockerflag**\ (vm.othersettings) + + This allows specifying a semicolon delimited list of key->value pairs to include in a vmx file of VMware or KVM. For partitioning on normal power machines, this option is used to specify the hugepage and/or bsr information, the value is like:'hugepage:1,bsr=2'. For KVM cpu pinning, this option is used to specify the physical cpu set on the host, the value is like:"vcpupin:'0-15,^8'",Its syntax is a comma separated list and a special markup using '-' and '^' (ex. '0-4', '0-3,^2') can also be allowed, the '-' denotes the range and the '^' denotes exclusive. For KVM memory binding, the value is like:'membind:0', restrict a guest to allocate memory from the specified set of NUMA nodes. For PCI passthrough, the value is like:'devpassthrough:pci_0001_01_00_0,pci_0000_03_00_0',the PCI devices are assigned to a virtual machine, and the virtual machine can use this I/O exclusively,the devices list are a list of PCI device names delimited with comma, the PCI device names can be obtained by running \ **virsh nodedev-list**\ on the host. + + + +\ **dockerhost**\ (vm.host) + + The system that currently hosts the VM + + + +\ **dockermemory**\ (vm.memory) + + Megabytes of memory the VM currently should be set to. + + + \ **domainadminpassword**\ (domain.adminpassword) Allow a node specific indication of Administrative user password for the domain. Most will want to ignore this in favor of passwd table. @@ -589,6 +613,12 @@ node Attributes: +\ **nicdevices**\ (nics.nicdevices) + + Comma-separated list of NIC device per NIC, multiple ethernet devices can be bonded as bond device, these ethernet devices are separated by |. !|,!, e.g. bond0!eth0|eth2,br0!bond0. The xCAT object definition commands support to use nicdevices. as the sub attributes. + + + \ **nicextraparams**\ (nics.nicextraparams) Comma-separated list of extra parameters that will be used for each NIC configuration. @@ -689,6 +719,18 @@ node Attributes: +\ **nicsadapter**\ (nics.nicsadapter) + + Comma-separated list of extra parameters that will be used for each NIC configuration. + + + .. code-block:: perl + + !|,!|, for example, eth0!MTU=1500|MTU=1460,ib0!MTU=65520 CONNECTED_MODE=yes. + + + + \ **nictypes**\ (nics.nictypes) Comma-separated list of NIC types per NIC. !,!, e.g. eth0!Ethernet,ib0!Infiniband. The xCAT object definition commands support to use nictypes. as the sub attributes. @@ -1349,7 +1391,7 @@ node Attributes: \ **vmothersetting**\ (vm.othersettings) - This allows specifying a semicolon delimited list of key->value pairs to include in a vmx file of VMware or KVM. For partitioning on normal power machines, this option is used to specify the hugepage and/or bsr information, the value is like:'hugepage:1,bsr=2'. For KVM cpu pinning, this option is used to specify the physical cpu set on the host, the value is like:'vcpupin:'0-15,^8' ',Its syntax is a comma separated list and a special markup using '-' and '^' (ex. '0-4', '0-3,^2') can also be allowed, the '-' denotes the range and the '^' denotes exclusive. For KVM memory binding, the value is like:'membind:0', restrict a guest to allocate memory from the specified set of NUMA nodes. For PCI passthrough, the value is like:'devpassthrough:pci_0001_01_00_0,pci_0000_03_00_0',the PCI devices are assigned to a virtual machine, and the virtual machine can use this I/O exclusively,the devices list are a list of PCI device names delimited with comma, the PCI device names can be obtained by running \ **virsh nodedev-list**\ on the host. + This allows specifying a semicolon delimited list of key->value pairs to include in a vmx file of VMware or KVM. For partitioning on normal power machines, this option is used to specify the hugepage and/or bsr information, the value is like:'hugepage:1,bsr=2'. For KVM cpu pinning, this option is used to specify the physical cpu set on the host, the value is like:"vcpupin:'0-15,^8'",Its syntax is a comma separated list and a special markup using '-' and '^' (ex. '0-4', '0-3,^2') can also be allowed, the '-' denotes the range and the '^' denotes exclusive. For KVM memory binding, the value is like:'membind:0', restrict a guest to allocate memory from the specified set of NUMA nodes. For PCI passthrough, the value is like:'devpassthrough:pci_0001_01_00_0,pci_0000_03_00_0',the PCI devices are assigned to a virtual machine, and the virtual machine can use this I/O exclusively,the devices list are a list of PCI device names delimited with comma, the PCI device names can be obtained by running \ **virsh nodedev-list**\ on the host. diff --git a/docs/source/guides/admin-guides/references/man7/taskstate.7.rst b/docs/source/guides/admin-guides/references/man7/taskstate.7.rst new file mode 100644 index 000000000..464a2206d --- /dev/null +++ b/docs/source/guides/admin-guides/references/man7/taskstate.7.rst @@ -0,0 +1,85 @@ + +########### +taskstate.7 +########### + +.. highlight:: perl + + +**** +NAME +**** + + +\ **taskstate**\ - a logical object definition in the xCAT database. + + +******** +SYNOPSIS +******** + + +\ **taskstate Attributes:**\ \ *command*\ , \ *disable*\ , \ *node*\ , \ *pid*\ , \ *reserve*\ , \ *state*\ + + +*********** +DESCRIPTION +*********** + + +Logical objects of this type are stored in the xCAT database in one or more tables. Use the following commands +to manipulate the objects: \ **mkdef**\ , \ **chdef**\ , \ **lsdef**\ , and \ **rmdef**\ . These commands will take care of +knowing which tables the object attributes should be stored in. The attribute list below shows, in +parentheses, what tables each attribute is stored in. + + +********************* +taskstate Attributes: +********************* + + + +\ **command**\ (taskstate.command) + + Current command is running + + + +\ **disable**\ (taskstate.disable) + + Set to 'yes' or '1' to comment out this row. + + + +\ **node**\ (taskstate.node) + + The node name. + + + +\ **pid**\ (taskstate.pid) + + The process id of the request process. + + + +\ **reserve**\ (taskstate.reserve) + + used to lock the node + + + +\ **state**\ (taskstate.state) + + The task state(callback, running) for the node. + + + + +******** +SEE ALSO +******** + + +\ **mkdef(1)**\ , \ **chdef(1)**\ , \ **lsdef(1)**\ , \ **rmdef(1)**\ + diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index 5af9867f9..045ab6d84 100755 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -1442,7 +1442,7 @@ firmware => { }, nics => { - cols => [qw(node nicips nichostnamesuffixes nichostnameprefixes nictypes niccustomscripts nicnetworks nicaliases nicextraparams nicdevices comments disable)], + cols => [qw(node nicips nichostnamesuffixes nichostnameprefixes nictypes niccustomscripts nicnetworks nicaliases nicextraparams nicdevices nicsadapter comments disable)], keys => [qw(node)], tablespace =>'XCATTBS16K', table_desc => 'Stores NIC details.', @@ -1486,6 +1486,8 @@ nics => { !|,!|, for example, eth0!MTU=1500|MTU=1460,ib0!MTU=65520 CONNECTED_MODE=yes. The xCAT object definition commands support to use nicextraparams. as the sub attributes.', nicdevices => 'Comma-separated list of NIC device per NIC, multiple ethernet devices can be bonded as bond device, these ethernet devices are separated by |. !|,!, e.g. bond0!eth0|eth2,br0!bond0. The xCAT object definition commands support to use nicdevices. as the sub attributes.', + nicsadapter => 'Comma-separated list of extra parameters that will be used for each NIC configuration. + !|,!|, for example, eth0!MTU=1500|MTU=1460,ib0!MTU=65520 CONNECTED_MODE=yes.', comments => 'Any user-written notes.', disable => "Set to 'yes' or '1' to comment out this row.", }, @@ -1684,6 +1686,19 @@ token => { disable => "Set to 'yes' or '1' to comment out this row.", }, }, +taskstate => { + cols => [qw(node command state pid reserve)], + keys => [qw(node)], + table_desc => 'The task state for the node.', + descriptions => { + node => 'The node name.', + command => 'Current command is running', + state => 'The task state(callback, running) for the node.', + pid => 'The process id of the request process.', + reserve => 'used to lock the node', + disable => "Set to 'yes' or '1' to comment out this row.", + }, +}, ); # end of tabspec definition @@ -2416,10 +2431,14 @@ my @nodeattrs = ( tabentry => 'nics.nicextraparams', access_tabentry => 'nics.node=attr:node', }, - {attr_name => 'nicdevices', + {attr_name => 'nicdevices', tabentry => 'nics.nicdevices', access_tabentry => 'nics.node=attr:node', - }, + }, + {attr_name => 'nicsadapter', + tabentry => 'nics.nicsadapter', + access_tabentry => 'nics.node=attr:node', + }, ####################### # prodkey table # ###################### @@ -3580,6 +3599,37 @@ push(@{$defspec{group}->{'attrs'}}, @nodeattrs); }, ); +########################### +# taskstate data object # +########################### +# taskstate table # +########################### +@{$defspec{taskstate}->{'attrs'}} = ( + {attr_name => 'node', + tabentry => 'taskstate.node', + access_tabentry => 'taskstate.node=attr:node', + }, + {attr_name => 'command', + tabentry => 'taskstate.command', + access_tabentry => 'taskstate.node=attr:node', + }, + {attr_name => 'state', + tabentry => 'taskstate.state', + access_tabentry => 'taskstate.node=attr:node', + }, + {attr_name => 'pid', + tabentry => 'taskstate.pid', + access_tabentry => 'taskstate.node=attr:node', + }, + {attr_name => 'reserve', + tabentry => 'taskstate.reserve', + access_tabentry => 'taskstate.node=attr:node', + }, + {attr_name => 'disable', + tabentry => 'taskstate.disable', + access_tabentry => 'taskstate.node=attr:node', + }, +); ############################# # auditlog object # diff --git a/xCAT-client/debian/xcat-client.links b/xCAT-client/debian/xcat-client.links index c9c0dc1b3..d1e323960 100644 --- a/xCAT-client/debian/xcat-client.links +++ b/xCAT-client/debian/xcat-client.links @@ -37,6 +37,7 @@ opt/xcat/bin/xcatclient opt/xcat/bin/lstree opt/xcat/bin/xcatclient opt/xcat/bin/lsflexnode opt/xcat/bin/xcatclient opt/xcat/bin/rmflexnode opt/xcat/bin/xcatclient opt/xcat/bin/mkflexnode +opt/xcat/bin/xcatclient opt/xcat/bin/getadapter opt/xcat/bin/xcatclientnnr opt/xcat/bin/lsslp opt/xcat/bin/xcatclient opt/xcat/bin/imgcapture opt/xcat/bin/xcatclientnnr opt/xcat/bin/swapnodes diff --git a/xCAT-client/pods/man1/getadapter.1.pod b/xCAT-client/pods/man1/getadapter.1.pod new file mode 100644 index 000000000..a9d0b2875 --- /dev/null +++ b/xCAT-client/pods/man1/getadapter.1.pod @@ -0,0 +1,84 @@ +=head1 NAME + +B - Obtain all network adapters's predictable name and some other information before provision or network configuration. + +=head1 SYNOPSIS + +B I [B<-f>] + +B [B<-h>|B<--help>|B<-v>|B<--version>|B<-V>] + +=head1 DESCRIPTION + +Traditionally, network interfaces in Linux are enumerated as eth[0123…], but these names do not necessarily correspond to actual labels on the chassis. B help customer to get predictable network device name and some other network adapter information before provision or network configuration. + +B use genesis to collect network adapters information, so that mean it need to restart the target node. + +B follows below scheme: + +If the target node is scaned for the first time, B will trigger genesis to collect information then save the information at local. +If the target node has ever been scaned, i.e. this node has network device information in local, B use the local information first. +If user doesn't want to use local information, can use B<-f> option to force to trigger new round scan process. +if part nodes of I don't have network device information in local and the rest have, B only trigger real scan process for these nodes which don't have local information, the nodes have network device information in local, B still use the local information first. + +B tries to collect more information for the target network device, but doesn't guarantee collect same much information for every network device. + +Below are the possible information can be collect up to now: +B: the consistent name which can be used by confignic directly in operating system which follow the same naming scheme with rhels7 +B: the pci location +B: the MAC address +B: All the names which satisfy predictable network device naming scheme. I<(if xcat enhance confignic command later, user can use these names to configure their network adapter, even customize their name)> +B: the vender of network device +B: the model of network device +B: the link state of network device + +=head1 OPTIONS + +B<-h> + +Display usage message. + +B<-v> + +Command Version. + +B<-V> + +Display verbose message. + +B<-f> + +Force to trigger new round scan. ignore the data collected before. + + +=head1 EXAMPLES + +1. To collect node[1-3]'s network device information, enter: + + getadapter node[1-2] + +Output is similar to: + +-->Starting scan for: node1,node2 +The whole scan result: +-------------------------------------- +[node1]: Adapter information exists, no need to scan. +-------------------------------------- +[node2] scan successfully, below are the latest data +node2:[1]->eno1!mac=34:40:b5:be:6a:80|pci=/pci0000:00/0000:00:01.0/0000:0c:00.0|candidatename=eno1/enp12s0f0/enx3440b5be6a80 +node2:[2]->enp0s29u1u1u5!mac=36:40:b5:bf:44:33|pci=/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1.5/2-1.1.5:1.0|candidatename=enp0s29u1u1u5/enx3640b5bf4433 + +Every node gets a separate section to display its all network adapters information, every network adapter owns single line which start as node name and followed by index and other information. + + +2. Force to trigger new round scan + + getadatper node -f + + + +=head1 SEE ALSO + +L + + diff --git a/xCAT-client/pods/man1/getadapters.1.pod b/xCAT-client/pods/man1/getadapters.1.pod deleted file mode 100644 index 99b4ad479..000000000 --- a/xCAT-client/pods/man1/getadapters.1.pod +++ /dev/null @@ -1,85 +0,0 @@ -=head1 NAME - -B - Obtain all network adapters's predictable name and some other information before provision or network configuration. - -=head1 SYNOPSIS - -B I [B<-f>] - -B [B<-h>|B<--help>|B<-v>|B<--version>|B<-V>] - -=head1 DESCRIPTION - -Traditionally, network interfaces in Linux are enumerated as eth[0123…], but these names do not necessarily correspond to actual labels on the chassis. B help customer to get predictable network device name and some other network adapter information before provision or network configuration. - -B use genesis to collect network adapters information, so that mean it need to restart the target node. - -B follows below scheme: - -If the target node is scaned for the first time, B will trigger genesis to collect information then save the information at local. -If the target node has ever been scaned, i.e. this node has network device information in local, B use the local information first. -If user doesn't want to use local information, can use B<-f> option to force to trigger new round scan process. -if part nodes of I don't have network device information in local and the rest have, B only trigger real scan process for these nodes which don't have local information, the nodes have network device information in local, B still use the local information first. - -B tries to collect more information for the target network device, but doesn't guarantee collect same much information for every network device. - -Below are the possible information can be collect up to now: -B: the consistent name which can be used by confignic directly in operating system which follow the same naming scheme with rhels7 -B: the pci location -B: the MAC address -B: All the names which satisfy predictable network device naming scheme. I<(if xcat enhance confignic command later, user can use these names to configure their network adapter, even customize their name)> -B: the vender of network device -B: the model of network device - -=head1 OPTIONS - -B<-h> - -Display usage message. - -B<-v> - -Command Version. - -B<-V> - -Display verbose message. - -B<-f> - -Force to trigger new round scan. ignore the data collected before. - - -=head1 EXAMPLES - -1. To collect node[1-3]'s network device information, enter: - - getadapters node[1-2] - -Output is similar to: - --->Starting scan for: node1,node2 -The whole scan result: --------------------------------------- -[node1] with no need for scan due to old data exist, using the old data: -node1:1:mac=98be9459ea24|pci=/0003:03:00.0|candidatename=enx98be9459ea24|vender=Broadcom Corporation -node1:2:mac=98be9459ea25|pci=/0003:03:00.1|candidatename=enx98be9459ea25|vender=Broadcom Corporation --------------------------------------- -[node2] scan successfully, below are the latest data -node2:1:mac=98be9459ea34|pci=/0003:03:00.0|candidatename=enx98be9459ea34|vender=Broadcom Corporation -node2:2:mac=98be9459ea35|pci=/0003:03:00.1|candidatename=enx98be9459ea35|vender=Broadcom Corporation - -Every node gets a separate section to display its all network adapters information, every network adapter owns single line which start as node name and followed by index and other information. - - -2. Force to trigger new round scan - - getadatpers node -f - - - -=head1 SEE ALSO - -L - - diff --git a/xCAT-client/xCAT-client.spec b/xCAT-client/xCAT-client.spec index efa11d55a..d8741b739 100644 --- a/xCAT-client/xCAT-client.spec +++ b/xCAT-client/xCAT-client.spec @@ -165,6 +165,7 @@ ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/bin/lstree ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/bin/lsflexnode ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/bin/rmflexnode ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/bin/mkflexnode +ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/bin/getadapter ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/lsslp ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/switchdiscover ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/bmcdiscover diff --git a/xCAT-genesis-scripts/bin/getadapter b/xCAT-genesis-scripts/bin/getadapter index 1f907230e..25b11afaf 100755 --- a/xCAT-genesis-scripts/bin/getadapter +++ b/xCAT-genesis-scripts/bin/getadapter @@ -16,9 +16,10 @@ if [ -f "$ADAPTERFILE" ]; then fi echo " -findadapter +getadapter cli -$HOSTNAME" >> "$ADAPTERFILE" +$HOSTNAME +update" >> "$ADAPTERFILE" #scan adapters have recognized by operating system for n in /sys/class/net/*; do @@ -31,7 +32,7 @@ for n in /sys/class/net/*; do if [ -n "$tmp" ]; then echo "$tmp" >> "$ADAPTERFILE" fi - tmp=`udevadm info /sys/class/net/"$nic" | grep ID_NET_NAME | awk -F '=' '{print $2}'|sort -u| tr -s "\n" "," | sed "s/,$//g"` + tmp=`udevadm info /sys/class/net/"$nic" | grep ID_NET_NAME | awk -F '=' '{print $2}'|sort -u| tr -s "\n" "/" | sed "s/\/$//g"` if [ -n "$tmp" ]; then echo "$tmp" >> "$ADAPTERFILE" fi @@ -39,11 +40,8 @@ for n in /sys/class/net/*; do if [ -n "$tmp" ]; then echo "${tmp%/net*}" >> "$ADAPTERFILE" fi - tmp=`udevadm info /sys/class/net/"$nic" | grep ID_NET_NAME_MAC | awk -F '=' '{print $2}'` - if [ -n "$tmp" ]; then - echo "${tmp##*enx}" >> "$ADAPTERFILE" - fi - tmp=`udevadm info /sys/class/net/"$nic" | grep ID_VENDOR_FROM_DATABASE | awk -F '=' '{print $2}' | tr -s "\n" "," | sed "s/,$//g"` + echo "`cat /sys/class/net/$nic/address`" >> "$ADAPTERFILE" + tmp=`udevadm info /sys/class/net/"$nic" | grep ID_VENDOR_FROM_DATABASE | awk -F '=' '{print $2}' | tr -s "\n" "/" | sed "s/\/$//g"` if [ -n "$tmp" ]; then echo "$tmp" >> "$ADAPTERFILE" fi @@ -51,6 +49,11 @@ for n in /sys/class/net/*; do if [ -n "$tmp" ]; then echo "$tmp" >> "$ADAPTERFILE" fi + tmp=`ip link show $nic` + if [ -n "$tmp" ]; then + tmp=${tmp#*state } + echo "${tmp% mode*}" >> "$ADAPTERFILE" + fi echo '' >> "$ADAPTERFILE" fi done diff --git a/xCAT-server/lib/perl/xCAT/FifoPipe.pm b/xCAT-server/lib/perl/xCAT/FifoPipe.pm new file mode 100644 index 000000000..b3fdca641 --- /dev/null +++ b/xCAT-server/lib/perl/xCAT/FifoPipe.pm @@ -0,0 +1,219 @@ +#!/usr/bin/env perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html +package xCAT::FifoPipe; + +BEGIN { + $::XCATROOT = + $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} + : -d '/opt/xcat' ? '/opt/xcat' + : '/usr'; +} + +use lib "$::XCATROOT/lib/perl"; + +use strict; +use xCAT::Table; +use xCAT::MsgUtils; +use Data::Dumper; +use POSIX; + + +use constant PIPE_SIZE => 4096; # use ulimit -a to check + +#------------------------------------------------------- + +=head3 _create_pipe + Create the pipe file if not exists. This function is a + private method in FifoPipe. + Input: + $pipe_file: the file path of the pipe file + Return: + -1: Unexpected error + 0: Create success + Usage example: + my $fifo_path = '/tmp/fifopipe/pipe1; + _create_pipe($pipe_file); +=cut + +#------------------------------------------------------- +sub _create_pipe { + my $pipe_file = shift; + unless (-p $pipe_file) { + if (-e _) { + xCAT::MsgUtils->message("S", "$pipe_file is not a pipe file."); + return -1; + } else { + unless (POSIX::mkfifo($pipe_file, 0660)) { + xCAT::MsgUtils->message("S", "Can not create fifo pipe: $pipe_file"); + return -1; + } + xCAT::MsgUtils->message("I", "Create $pipe_file as a pipe file."); + } + } + return 0; +} + +#------------------------------------------------------- + +=head3 recv_message + Use fifo pipe to receive the message + Input: + $class: FifoPipe class + $pipe_file: the file path of the pipe file + $buf_ptr: A pointer to the message buffer array + Return: + -1: Unexpected error + count: Number of message getting from fifo pipe + Usage example: + my $fifo_path = '/tmp/fifopipe/pipe1; + my @buf = (); + xCAT::FifoPipe->recv_message($fifo_path, \@buf); +=cut + +#------------------------------------------------------- +sub recv_message { + my $class = shift; + my $pipe_file = shift; + my $buf_array_ptr = shift; + my ($len, $pipe, $tmp); + my $count = 0; + my $rt = -1; + + my $read_pipe_func = sub { + my $pipe = shift; + my $buf_ptr = shift; + my $len = shift; + my $read_len = $len; + my ($rt, $tmp); + + + while (($rt = read($pipe, $tmp, $read_len)) > 0) { + $read_len -= $rt; + ${$buf_ptr} .= $tmp; + if ($read_len == 0) { + return $len; + } + } + if (!defined($rt)) { + xCAT::MsgUtils->message("S", "Read pipe $pipe_file error return code=$rt."); + return -1; + } + return 0; + }; # end of read_pipe_func + + if (_create_pipe($pipe_file)) { + return -1; + } + + # NOTE(chenglch) if multiple process are writing the fifo pipe + # at the same time, the open call of reader will be blocked only + # once, but multiple messages should be retrived. + $rt = open($pipe, '<', $pipe_file); + unless ($rt) { + xCAT::MsgUtils->message("S", "open $pipe_file error"); + return -1; + } + + while (&$read_pipe_func($pipe, \$len, 8) > 0) { + $len = unpack("A8", $len); + if (($rt = &$read_pipe_func($pipe, \$tmp, $len)) < 0) { + return -1; + } + if ($rt != $len) { + xCAT::MsgUtils->message("S", "Read pipe $pipe_file error, uncomplete."); + return -1; + } + ${$buf_array_ptr}[$count] = $tmp; + $count++; + } + close($pipe); + return $count; +} + +#------------------------------------------------------- + +=head3 send_message + Send message to fifo pipe + Input: + $class: FifoPipe class + $pipe_file: the file path of the pipe file + $buf: A buf string + Return: + -1: Unexpected error + 0: send success + Usage example: + my $fifo_path = '/tmp/fifopipe/pipe1; + my $buf = "hellow fifo pipe"; + xCAT::FifoPipe->send_message($fifo_path, $buf); +=cut + +#------------------------------------------------------- +sub send_message { + my $class = shift; + my $pipe_file = shift; + my $buf = shift; + my $pipe; + + # WARNING: the lenth of the buf should not be larger than PIPE_BUF, + # otherwise the write opration for fifo pipe can not be + # looked as a atomic opration. + my $len = length($buf); + if ($len > PIPE_SIZE - 8) { + xCAT::MsgUtils->message("W", "The size of message is larger than 4088 bytes."); + } + my $tmp = pack("A8", $len); + $buf = $tmp . $buf; + $len += 8; + if (_create_pipe($pipe_file)) { + return -1; + } + my $rt = sysopen(PIPEHANDLE, $pipe_file, O_WRONLY); + unless ($rt) { + xCAT::MsgUtils->message("S", "open $pipe_file error"); + return -1; + } + while (($rt = syswrite(PIPEHANDLE, $buf, $len)) > 0) { + $len -= $rt; + if ($len == 0) { + last; + } + } + if (!defined($rt)) { + xCAT::MsgUtils->message("S", "Write $pipe_file error"); + return -1; + } + if ($len != 0) { + xCAT::MsgUtils->message("S", "Write $pipe_file error"); + return -1; + } + + #print {$pipe} $buf; + close(PIPEHANDLE); + return 0; +} + +#------------------------------------------------------- + +=head3 remove_pipe + Remove the fifo pipe file if pipe file exists. + Input: + $class: FifoPipe class + $pipe_file: the file path of the pipe file + + Usage example: + my $fifo_path = '/tmp/fifopipe/pipe1; + xCAT::FifoPipe->remove_pipe($fifo_path); +=cut + +#------------------------------------------------------- +sub remove_pipe { + my $class = shift; + my $pipe_file = shift; + xCAT::MsgUtils->message("I", "Remove fifo pipe file $pipe_file"); + if (-p $pipe_file) { + unlink($pipe_file); + } +} + + +1; diff --git a/xCAT-server/lib/perl/xCAT/State.pm b/xCAT-server/lib/perl/xCAT/State.pm new file mode 100644 index 000000000..b757f4c4b --- /dev/null +++ b/xCAT-server/lib/perl/xCAT/State.pm @@ -0,0 +1,15 @@ +#!/usr/bin/env perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html +package xCAT::State; + +use constant REQUEST_ERROR => 0; +use constant REQUEST_WAIT => 1; +use constant REQUEST_UPDATE => 2; + +use constant WAIT_STATE => 'waiting'; +use constant UPDATE_STATE => 'updating'; + +use constant INSPECT_ACTION => 'inspect'; +use constant UPDATE_ACTION => 'update'; + +1; diff --git a/xCAT-server/lib/xcat/plugins/getadapter.pm b/xCAT-server/lib/xcat/plugins/getadapter.pm index 6d028405b..b9a0122a9 100644 --- a/xCAT-server/lib/xcat/plugins/getadapter.pm +++ b/xCAT-server/lib/xcat/plugins/getadapter.pm @@ -2,38 +2,54 @@ #------------------------------------------------------- =head1 - xCAT plugin package to handle getadapters management + xCAT plugin package to handle getadapter management Supported command: - getadapters->getadapters - findadapter->getadapters + getadapter->getadapter =cut #------------------------------------------------------- package xCAT_plugin::getadapter; -BEGIN{ - $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; +BEGIN { + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; } use lib "$::XCATROOT/lib/perl"; use xCAT::Table; use xCAT::Utils; +use xCAT::FifoPipe; use xCAT::MsgUtils; +use xCAT::State; use Data::Dumper; use Getopt::Long; use File::Path; -use IO::Select; use Term::ANSIColor; use Time::Local; +use strict; +use Class::Struct; +use XML::Simple; +use Storable qw(dclone); my %usage = ( - "getadapters" => "Usage:\n\tgetadapters [-h|--help|-v|--version|V]\n\tgetadapters [-f]", +"getadapter" => "Usage:\n\tgetadapter [-h|--help|-v|--version|V]\n\tgetadapter [-f]", ); -my $inforootdir = "/var/lib/xcat/adapters/"; -my $VERBOSE=0; +my $VERBOSE = 0; +use constant OPT_FORCE => 0; +use constant OPT_UPDATE => 1; + +use constant GET_ADPATER_DIR => "/var/run/getadapter"; +use constant ALARM_TIMEOUT => 1800; + +unless (-d GET_ADPATER_DIR) { + mkpath(GET_ADPATER_DIR); +} + +my %child_pids; +my $timeout_event = 0; + #------------------------------------------------------- =head3 handled_commands @@ -47,8 +63,7 @@ Return list of commands handled by this plugin sub handled_commands { return { - getadapters => "getadapter", - findadapter => "getadapter", + getadapter => "getadapter", }; } @@ -56,7 +71,7 @@ sub handled_commands =head3 process_request - Process the command + Process the command. =cut @@ -68,45 +83,131 @@ sub process_request my $subreq = shift; my $command = $request->{command}->[0]; - $SIG{CHLD}='DEFAULT'; + $SIG{INT} = $SIG{TERM} = sub { + xCAT::MsgUtils->message("W", "getadapter: int or term signal received, clean up task state"); + exit(clean_up()); + }; - if ($command eq "getadapters"){ - &handle_getadapters($request, $callback, $subreq); + if ($command eq "getadapter") { + &handle_getadapter($request, $callback, $subreq); } - - if ($command eq "findadapter"){ - &handle_findadapter($request, $callback); - } - return; } -sub handle_getadapters{ +#------------------------------------------------------------------ + +=head3 route_request + + Route the request, this funciton is called in the reqeust process. + + return REQUEST_UPDATE if update request arrived. Now just send + message to the waiting process with fifo pipe. + + (TODO) If getadapter is used in chain table to complete + the discovery process, the adapter information can be + updated directly in immediate plugin and there is no need + to fork plugin process. + + return REQUEST_WAIT if inspect request arrived. Tell xcatd fork + plugin process to handle this request. + return REQUEST_ERROR if error happened. + + Usage example: + This is a hook function in xcatd, do not use it directly. +=cut + +#----------------------------------------------------------------- +sub route_request { + my ($request, $callback, $subreq) = @_; + my $command = $request->{command}->[0]; + my $ret = xCAT::State->REQUEST_ERROR; + + if (scalar(@{ $request->{node} }) == 0) { + return $ret; + } + + my $build_request_message_func = sub { + my $req = shift; + my $xs = new XML::Simple(); + my $nic_info; + $nic_info->{'nic'} = $req->{'nic'}; + $nic_info->{'node'} = $req->{node}->[0]; + return $xs->XMLout($nic_info); + }; + + if (defined($request->{'action'}) and $request->{action}->[0] eq xCAT::State->UPDATE_ACTION) { + + # may be a callback request, just check the state then send message + # no need to fork a plugin process. + my $node = ${ $request->{'node'} }[0]; + my $taskstate_table = xCAT::Table->new('taskstate'); + unless ($taskstate_table) { + xCAT::MsgUtils->message("S", "Unable to open taskstate table, denying"); + return $ret; + } + my $node_obj = $taskstate_table->getAttribs({ 'node' => $node, 'command' => $command }, 'state', 'pid'); + + if (defined($node_obj) and $node_obj->{'state'} eq xCAT::State->WAIT_STATE) { + my $msg_queue = xCAT::FifoPipe->send_message( + xCAT::Utils->full_path($node_obj->{'pid'}, GET_ADPATER_DIR), + &$build_request_message_func($request)); + $ret = xCAT::State->REQUEST_UPDATE; + } + else { + xCAT::MsgUtils->message("S", "Error to find the node in waiting state"); + } + $taskstate_table->close(); + } elsif (!defined($request->{'action'}) or $request->{action}->[0] eq xCAT::State->INSPECT_ACTION) { + + # new request, fork a plugin child process to handle this request. + $ret = xCAT::State->REQUEST_WAIT; + } + return $ret; +} + +#------------------------------------------------------- + +=head3 handle_getadapter + + This function check the command option, then call the + function to complete the request. + + Usage example: + This function is called from process_request, + do not call it directly. +=cut + +#------------------------------------------------------- + +sub handle_getadapter { my $request = shift; my $callback = shift; my $subreq = shift; my $command = $request->{command}->[0]; + my @opts; - my @args=(); + my @args = (); my $HELP; my $VERSION; my $FORCE; + my $UPDATE; if (ref($request->{arg})) { - @args=@{$request->{arg}}; - } else { - @args=($request->{arg}); + @args = @{ $request->{arg} }; + } else { + @args = ($request->{arg}); } @ARGV = @args; - Getopt::Long::Configure("bundling"); + Getopt::Long::Configure("bundling"); Getopt::Long::Configure("no_pass_through"); - if (!GetOptions("h|help" => \$HELP, - "v|version" => \$VERSION, - "f" => \$FORCE, - "V" => \$VERBOSE - ) ) { - if($usage{$command}) { + if (!GetOptions("h|help" => \$HELP, + "v|version" => \$VERSION, + "f" => \$FORCE, + "u" => \$UPDATE, + "V" => \$VERBOSE + )) { + if ($usage{$command}) { my $rsp = {}; - $rsp->{error}->[0] = $usage{$command}; + $rsp->{error}->[0] = $usage{$command}; $rsp->{errorcode}->[0] = 1; $callback->($rsp); } @@ -114,9 +215,9 @@ sub handle_getadapters{ } if ($HELP) { - if($usage{$command}) { + if ($usage{$command}) { my %rsp; - $rsp{data}->[0]=$usage{$command}; + $rsp{data}->[0] = $usage{$command}; $callback->(\%rsp); } return; @@ -125,328 +226,491 @@ sub handle_getadapters{ if ($VERSION) { my $ver = xCAT::Utils->Version(); my %rsp; - $rsp{data}->[0]="$ver"; + $rsp{data}->[0] = "$ver"; $callback->(\%rsp); - return; + return; } + @opts = ($FORCE, $UPDATE); - my $tmpnodes = join(",", @{$request->{node}}); - my $tmpargs = join(",", @args); - xCAT::MsgUtils->trace($VERBOSE,"d","getadapters: handling command <$command $tmpnodes $tmpargs>"); - - if($FORCE || ! -d $inforootdir) { - my @tmpnodes = @{$request->{node}}; - $request->{missnode} = \@tmpnodes; - &scan_adapters($request, $callback, $subreq); - }else{ - my @nodes = @{$request->{node}}; - my $node; - my @missnodes = (); - foreach $node (@nodes){ - if ( ! -e "$inforootdir/$node.info" || -z "$inforootdir/$node.info"){ - push @missnodes,$node; - } - } - - if(scalar(@missnodes) != 0){ - $request->{missnode} = \@missnodes; - &scan_adapters($request, $callback, $subreq); - } - } - - &get_info_from_local($request, $callback); - return; - -} - -sub handle_findadapter{ - - my $request = shift; - my $callback = shift; - my $hostname = $request->{hostname}->[0]; - - xCAT::MsgUtils->trace($VERBOSE,"d","getadapters: receiving a findadapter response from $hostname"); - - my $nicnum = scalar @{$request->{nic}}; - my $content = ""; - #print "-----------nicnum = $nicnum----------------\n"; - for (my $i = 0; $i < $nicnum; $i++) { - $content .= "$i:"; - if(exists($request->{nic}->[$i]->{interface})){ - $content .= "hitname=".$request->{nic}->[$i]->{interface}->[0]."|"; - } - if(exists($request->{nic}->[$i]->{pcilocation})){ - $content .= "pci=".$request->{nic}->[$i]->{pcilocation}->[0]."|"; - } - if(exists($request->{nic}->[$i]->{mac})){ - $content .= "mac=".$request->{nic}->[$i]->{mac}->[0]."|"; - } - if(exists($request->{nic}->[$i]->{predictablename})){ - $content .= "candidatename=".$request->{nic}->[$i]->{predictablename}->[0]."|"; - } - if(exists($request->{nic}->[$i]->{vendor})){ - $content .= "vendor=".$request->{nic}->[$i]->{vendor}->[0]."|"; - } - if(exists($request->{nic}->[$i]->{model})){ - $content .= "model=".$request->{nic}->[$i]->{model}->[0]; - } - $content .= "\n"; - } - $content =~ s/\n$//; - - my $fd; - if(!open($fd,">$inforootdir/$hostname.info")) { - xCAT::MsgUtils->trace($VERBOSE,"d","findadapter: can't open $inforootdir/$hostname.info to record adapter info"); - }else{ - print $fd "$content"; - close($fd); + if (!defined($request->{'action'}) or $request->{action}->[0] eq xCAT::State->INSPECT_ACTION) { + return inspect_adapter($request, $callback, $subreq, \@opts); } return; } -sub scan_adapters{ - my $request = shift; - my $callback = shift; - my $subreq = shift; - my @targetscannodes = @{$request->{missnode}}; +#------------------------------------------------------------------ - if (scalar(@{$request->{node}}) == 0){ - return 1; +=head3 clean_up + + Clean up the getadapter running environment + + return 1 if clean up failed + + Usage example: + clean_up() +=cut + +#----------------------------------------------------------------- +sub clean_up { + my $ret = 0; + foreach (keys %child_pids) { + kill 2, $_; } + xCAT::MsgUtils->message("S", "Getadapter: clean up task state in database"); - my $tmptargetnodes = join(",", @targetscannodes); - xCAT::MsgUtils->trace($VERBOSE,"d","getadapters: issue new scaning for $tmptargetnodes"); + # NOTE(chenglch): Currently xcatd listener process has bug in signal handler, + # just comment out these code. + my $taskstate_table = xCAT::Table->new('taskstate'); - my %autorsp; - $autorsp{data}->[0]="-->Starting scan for: $tmptargetnodes"; - $callback->(\%autorsp); - - if ( ! -d $inforootdir){ - mkpath("$inforootdir"); + if ($taskstate_table) { + $taskstate_table->delEntries({ 'pid' => getppid() }); + $taskstate_table->close(); } - - my $node; - foreach $node (@targetscannodes){ - if ( -e "$inforootdir/$node.info"){ - rename("$inforootdir/$node.info", "$inforootdir/$node.info.bak"); - xCAT::MsgUtils->trace($VERBOSE,"d","getadapters: move $inforootdir/$node.info to $inforootdir/$node.info.bak"); - }else{ - open OUT,">$inforootdir/$node.first" - } + else { + xCAT::MsgUtils->message("S", "Clean up taskstate error"); + $ret = 1; } + xCAT::FifoPipe->remove_pipe(xCAT::Utils->full_path(getppid(), GET_ADPATER_DIR)); + return $ret; +} - #do scan stuff + +#------------------------------------------------------------------ + +=head3 deploy_genesis + + Fork processes to boot the target node into genesis + + return array of nodes which are booting geneses. + + Usage example: + my @nodes= ('node1', 'node2', 'node3'); + my $nodes_desc_ptr, a hash pointer to the description of nodes array. + @nodes = deploy_genesis(\@nodes, $nodes_desc_ptr, $callback, $subreq); + +=cut + +#----------------------------------------------------------------- +sub deploy_genesis { + my $nodes_ptr = shift; + my $nodes_desc_ptr = shift; + my $callback = shift; + my $subreq = shift; + my @nodes = @{$nodes_ptr}; my $pid; - my $forkcount = 0; - my %pidrecord; - foreach $node (@targetscannodes){ - $pid = xCAT::Utils->xfork(); - if (!defined($pid)){ - $autorsp{info}->[0]="failed to fork process to restart $node"; - $callback->(\%autorsp); - deletenode($request->{missnode}, "$node"); - last; - }elsif ($pid == 0){ - # Child process - xCAT::MsgUtils->trace($VERBOSE,"d","getadapters: fork new process $$ to start scaning $node"); - - my $outref = xCAT::Utils->runxcmd( - { - command => ['nodeset'], - node => ["$node"], - arg => ['runcmd=getadapter'], - }, - ,$subreq, 0, 1); - if($::RUNCMD_RC != 0){ - my $tmp = join(" ", @$outref); - $autorsp{data}->[0]="$tmp"; - $callback->(\%autorsp); - exit(1); - } - - my $tab = xCAT::Table->new("nodehm"); - my $hmhash = $tab->getNodeAttribs(["$node"], ['mgt']); - $tab->close(); - - if ($hmhash->{mgt} eq "ipmi"){ - $outref = xCAT::Utils->runxcmd( - { - command => ["rsetboot"], - node => ["$node"], - arg => ['net'], - }, - ,$subreq, 0, 1); - if($::RUNCMD_RC != 0){ - my $tmp = join(" ", @$outref); - $autorsp{data}->[0]="$tmp"; - $callback->(\%autorsp); - exit(1); - } - - $outref = xCAT::Utils->runxcmd( - { - command => ['rpower'], - node => ["$node"], - arg => ['reset'], - }, - ,$subreq, 0, 1); - if($::RUNCMD_RC != 0){ - my $tmp = join(" ", @$outref); - $autorsp{data}->[0]="$tmp"; - $callback->(\%autorsp); - exit(1); - } - }else{ - $outref = xCAT::Utils->runxcmd( - { - command => ["rnetboot"], - node => ["$node"], - }, - ,$subreq, 0, 1); - if($::RUNCMD_RC != 0){ - my $tmp = join(" ", @$outref); - $autorsp{data}->[0]="$tmp"; - $callback->(\%autorsp); - exit(1); - } - } - # Exit process - exit(0); + my $child_process_func = sub { + my ($node, $node_desc_ptr, $callback, $subreq) = @_; + my $outref = xCAT::Utils->runxcmd( + { + command => ['nodeset'], + node => ["$node"], + arg => ['runcmd=getadapter'], + }, + $subreq, 0, 1); + if ($::RUNCMD_RC != 0) { + $callback->({ error => "failed to run command: nodeset $node rumcmd=getadapter", errorcode => 1 }); + return 1; + } + if ($node_desc_ptr->{mgt} eq "ipmi") { + $outref = xCAT::Utils->runxcmd( + { + command => ["rsetboot"], + node => ["$node"], + arg => ['net'], + }, + $subreq, 0, 1); + if ($::RUNCMD_RC != 0) { + $callback->({ error => "failed to run command: rsetboot $node net", errorcode => 1 }); + return 1; + } + + $outref = xCAT::Utils->runxcmd( + { + command => ['rpower'], + node => ["$node"], + arg => ['reset'], + }, + $subreq, 0, 1); + if ($::RUNCMD_RC != 0) { + $callback->({ error => "failed to run command: rpower $node reset", errorcode => 1 }); + return 1; + } + } else { + $outref = xCAT::Utils->runxcmd( + { + command => ["rnetboot"], + node => ["$node"], + }, + $subreq, 0, 1); + if ($::RUNCMD_RC != 0) { + $callback->({ error => "failed to run command: rnetboot $node", errorcode => 1 }); + return 1; + } + } + return 0; + }; # end of child_process_func + + $SIG{CHLD} = 'DEFAULT'; + foreach my $node (@nodes) { + $pid = xCAT::Utils->xfork(); + if (!defined($pid)) { + $callback->({ error => "failed to fork process to restart $node", errorcode => 1 }); + $node = undef; + last; + } elsif ($pid == 0) { + + # child process + $SIG{INT} = $SIG{TERM} = 'DEFAULT'; + my $node_desc_ptr = $nodes_desc_ptr->{$node}; + xCAT::MsgUtils->trace($VERBOSE, "d", "getadapter: fork new process $$ to start scaning $node"); + my $ret = &$child_process_func($node, $node_desc_ptr, $callback, $subreq); + exit($ret); + } else { + + # Parent process + $child_pids{$pid} = $node; } - # Parent process - $forkcount++; - $pidrecord{$pid} = $node; } # Wait for all processes to end - if($forkcount == 0){ - deletenode($request->{missnode}, "all"); - return 1; - }else{ - while($forkcount){ - my $cpid; - while (($cpid=waitpid(-1,WNOHANG)) > 0) { - my $cpr=$?; - if($cpr>0){ - deletenode($request->{missnode}, "$pidreord{$cpid}"); - } - $forkcount--; + my $cpid = 0; + while (keys %child_pids) { + if (($cpid = wait()) > 0) { + my $status = $?; + if ($status != 0) { + my $node = $child_pids{$cpid}; + + #delete nodes if child process error. + map { $_ = undef if $_ eq $node } @nodes; } - sleep 0.1; + delete $child_pids{$cpid}; } } - - check_scan_result($request, $callback); + + # delete undef + @nodes = grep /./, @nodes; + return @nodes; +} + +#------------------------------------------------------------------ + +=head3 update_adapter_result + + Update the adapter information in the nics table. + Print the adapter information to STDOUT. + + Input: + $msg: A hash pointer parsed from message from fifopipe + $nodes_desc_ptr: Nodes description pointer + $opts_ptr: A pointer to the nodes option + $callback: callback object + + return -1 if unexpectd error. + return 0 success + + Usage example: + my $msg; + my $nodes_desc_ptr; + my $opts_ptr; + my $callback + update_adapter_result($msg, $nodes_desc_ptr, $opts_ptr, $callback)); + +=cut + +#----------------------------------------------------------------- +sub update_adapter_result { + my $msg = shift; + my $nodes_desc_ptr = shift; + my $opts_ptr = shift; + my $callback = shift; + my $node = $msg->{'node'}; + my $nicnum = scalar @{ $msg->{nic} }; + my ($output, $data, $interface_exists, $has_nic, %updates); + + $data = ""; + $output = "[$node] scan successfully below is result:\n"; + for (my $i = 0 ; $i < $nicnum ; $i++) { + $output.= "$node:[$i]->"; + $interface_exists = 0; + + if (exists($msg->{nic}->[$i]->{interface})) { + $output .= $msg->{nic}->[$i]->{interface}; + if ($has_nic) { + $data .= "," . $msg->{nic}->[$i]->{interface} . "!"; + } + else { + $data .= $msg->{nic}->[$i]->{interface} . "!"; + } + $interface_exists = 1; + $has_nic = 1; + } + if (exists($msg->{nic}->[$i]->{mac})) { + $output .= "!mac=" . $msg->{nic}->[$i]->{mac}; + if ($interface_exists) { + $data .= " mac=" . $msg->{nic}->[$i]->{mac}; + } + } + if (exists($msg->{nic}->[$i]->{pcilocation})) { + $output .= "|pci=" . $msg->{nic}->[$i]->{pcilocation}; + if ($interface_exists) { + $data .= "pci=" . $msg->{nic}->[$i]->{pcilocation}; + } + } + if (exists($msg->{nic}->[$i]->{predictablename})) { + $output .= "|candidatename=" . $msg->{nic}->[$i]->{predictablename}; + } + if (exists($msg->{nic}->[$i]->{vendor})) { + $output .= "|vendor=" . $msg->{nic}->[$i]->{vendor}; + } + if (exists($msg->{nic}->[$i]->{model})) { + $output .= "|model=" . $msg->{nic}->[$i]->{model}; + } + if (exists($msg->{nic}->[$i]->{linkstate})) { + $output .= "|linkstate=" . $msg->{nic}->[$i]->{linkstate}; + if ($interface_exists) { + $data .= " linkstate=" . $msg->{nic}->[$i]->{linkstate}; + } + } + $output .= "\n"; + } + $callback->({ data => "$output" }); + my $nics_table = xCAT::Table->new('nics'); + unless ($nics_table) { + xCAT::MsgUtils->message("S", "Unable to open nics table, denying"); + $callback->({ error => "Error to connect to nics table.", + errorcode => 1 }); + return -1; + } + $updates{'nicsadapter'} = $data; + if ($nics_table->setAttribs({ 'node' => $node }, \%updates) != 0) { + xCAT::MsgUtils->message("S", "Error to update nics table."); + $callback->({ error => "Error to update nics table.", + errorcode => 1 }); + return -1; + } return 0; } -sub check_scan_result{ - my $request = shift; - my $callback = shift; - my $retry =60; - my $rsp = {}; - my $nodenum = scalar @{$request->{missnode}}; - my $backnum = 0; - - if (exists($request->{missnode}) && (scalar(@{$request->{missnode}}) > 0)){ - while($retry && $backnum != $nodenum){ - sleep 10; - $retry--; - foreach $backnode (@{$request->{missnode}}){ - if( -e "$inforootdir/$backnode.info" ){ - $backnum++; - deletenode($request->{missnode}, "$backnode"); - } +#------------------------------------------------------------------ + +=head3 do_inspect + + The main function to run the getadapter process + + + Input: + $nodesptr: The nodes pointer + $nodes_desc_ptr: Nodes description pointer + $opts_ptr: Option pointer + $callback: callback object + $subreq: xcat sub request + + return -1 if unexpectd error. + return 0 success + +=cut + +#----------------------------------------------------------------- + +sub do_inspect { + my $nodesptr = shift; + my $nodes_desc_ptr = shift; + my $opts_ptr = shift; + my $callback = shift; + my $subreq = shift; + my @nodes = @{$nodesptr}; + my %updates; + my $msg; # parse from xml + + my $parse_request_message_func = sub { + my $xml = shift; + my $xs = new XML::Simple(); + return $xs->XMLin($xml); + }; + + my $timeout_output_func = sub { + my $nodes_ptr = shift; + my $callback = shift; + foreach my $node (@{$nodes_ptr}) { + if ($node) { + $callback->({ error => "$node: Timeout to get the adapter information", + errorcode => 1 }); } } + }; + + my $taskstate_table = xCAT::Table->new('taskstate'); + unless ($taskstate_table) { + xCAT::MsgUtils->message("S", "Unable to open taskstate table, denying"); + $callback->({ error => "Error to connect to taskstate table.", + errorcode => 1 }); + return -1; } - if($retry == 0 && $backnum != $nodenum){ - my $tmpnode = join(",", @{$request->{missnode}}); - push @{$rsp->{data}}, "waiting scan result for $tmpnode time out"; - $callback->($rsp); - } + # TODO(chenglch) Currently xcat db access is a single process model, this is + # safe. In the future: + # 1. If database is refactored, we need to protect the task + # state with Optimistic Lock of database. + # 2. If we leverage the memcache or other cache database, we can make use of + # the feature of the CAS to provide the atomic operation. + foreach my $node (@nodes) { + $updates{'command'} = "getadapter"; + $updates{'state'} = xCAT::State->WAIT_STATE; + $updates{'pid'} = getppid(); + if ($taskstate_table->setAttribs({ 'node' => $node }, \%updates) != 0) { + $callback->({ error => "Error to update taskstate table.", + errorcode => 1 }); + return -1; + } + } + $taskstate_table->close(); + @nodes = deploy_genesis(\@nodes, $nodes_desc_ptr, $callback, $subreq); + my $total = scalar(@nodes); + my $count = 0; + my @node_buf; + + $SIG{ALRM} = sub { + xCAT::MsgUtils->message("W", "getadapter: alarm signal received"); + $timeout_event = 1; + + # pipe broken, wake up the wait fifo pipe + xCAT::FifoPipe->remove_pipe(xCAT::Utils->full_path(getppid(), GET_ADPATER_DIR)); + }; + alarm(ALARM_TIMEOUT); + + while ($count < $total) { + my $c = xCAT::FifoPipe->recv_message( + xCAT::Utils->full_path(getppid(), GET_ADPATER_DIR), + \@node_buf); + if ($c <= 0) { + if ($timeout_event == 1) { + &$timeout_output_func(\@nodes, $callback); + clean_up(); + return -1; + } + xCAT::MsgUtils->message("S", "Unexpected pipe error, abort."); + return -1; + } + + my $nics_table = xCAT::Table->new('nics'); + unless ($nics_table) { + xCAT::MsgUtils->message("S", "Unable to open nics table, denying"); + return -1; + } + + my $taskstate_table = xCAT::Table->new('taskstate'); + unless ($taskstate_table) { + xCAT::MsgUtils->message("S", "Unable to open taskstate table, denying"); + return -1; + } + + for (my $i = 0 ; $i < $c ; $i++) { + $msg = &$parse_request_message_func($node_buf[$i]); + + # delete the node + map { $_ = undef if $_ eq $msg->{'node'} } @nodes; + if (update_adapter_result($msg, $nodes_desc_ptr, $opts_ptr, $callback)) { + return -1; + } + $taskstate_table->delEntries({ 'node' => $msg->{'node'} }); + } + $count += $c; + $taskstate_table->close(); + $nics_table->close(); + } + xCAT::MsgUtils->trace($VERBOSE, "d", "getadapter: remove pipe " . xCAT::Utils->full_path(getppid(), GET_ADPATER_DIR)); + xCAT::FifoPipe->remove_pipe(xCAT::Utils->full_path(getppid(), GET_ADPATER_DIR)); + return 0; } +#------------------------------------------------------------------ -sub get_info_from_local{ +=head3 inspect_adapter + + Process the getadapter command option. + + return -1 if unexpectd error. + return 0 success. + +=cut + +#----------------------------------------------------------------- +sub inspect_adapter { my $request = shift; my $callback = shift; - my $retry = 60; - my $rsp = {}; + my $subreq = shift; + my $opts_ptr = shift; + my @nodes; + my @entries; + my %nodes_desc; - push @{$rsp->{data}}, "\nThe whole scan result:"; - - if (scalar(@{$request->{node}}) == 0){ - $callback->({ - error=>[qq{Please indicate the nodes which are needed to scan}], - errorcode=>[1]}); - return 1; - } - - my $node; - foreach $node (@{$request->{node}}){ - my $readfile=1; - push @{$rsp->{data}}, "--------------------------------------"; - if ( ! -e "$inforootdir/$node.info" && ! -e "$inforootdir/$node.info.bak" ){ - push @{$rsp->{data}}, "[$node] Scan failed and without old data. there isn't data to show"; - $readfile=0; - }elsif( ! -e "$inforootdir/$node.info" && -e "$inforootdir/$node.info.bak" ){ - rename("$inforootdir/$node.info.bak","$inforootdir/$node.info"); - push @{$rsp->{data}}, "[$node] Scan failed but old data exist, using the old data:"; - }elsif( -e "$inforootdir/$node.info" && ! -e "$inforootdir/$node.info.bak" && ! -e "$inforootdir/$node.first"){ - push @{$rsp->{data}}, "[$node] with no need for scan due to old data exist, using the old data:"; - }elsif(-e "$inforootdir/$node.info" && ! -e "$inforootdir/$node.info.bak" && -e "$inforootdir/$node.first"){ - unlink "$inforootdir/$node.first"; - push @{$rsp->{data}}, "[$node] scan successfully, below are the latest data:"; - }else{ - unlink "$inforootdir/$node.info.bak"; - push @{$rsp->{data}}, "[$node] scan successfully, below are the latest data:"; + my $init_desc_func = sub { + my $nodes_ptr = shift; + my $callback = shift; + my $nodes_desc_ptr = shift; + my @nodes = @{$nodes_ptr}; + my @tmp = @{ dclone(\@nodes) }; + @tmp = map { $_ = '"' . $_ . '"'; } @tmp; + my $clause = "node in (" . join(",", @tmp) . ")"; + my $nodehm_table = xCAT::Table->new('nodehm'); + unless ($nodehm_table) { + xCAT::MsgUtils->message("S", "Unable to open nodehm table, denying"); + return -1; } - if($readfile){ - if( -z "$inforootdir/$node.info"){ - push @{$rsp->{data}}, "[$node] the file is empty, nothing to show"; - }else{ - if (open($myfile, "$inforootdir/$node.info")) { - while ($line = <$myfile>) { - push @{$rsp->{data}}, "$node:$line"; - } - close($myfile); - }else{ - push @{$rsp->{data}}, "[$node] Can't open $inforootdir/$node.info"; - } + my @entries = $nodehm_table->getAllAttribsWhere($clause, 'node', 'mgt'); + unless (@entries) { + xCAT::MsgUtils->message("S", "No records about " . join(",", @tmp) . " in nodehm table"); + return -1; + } + foreach my $i (@entries) { + my %attr; + $attr{'mgt'} = $i->{mgt}; + $nodes_desc_ptr->{ $i->{node} } = \%attr; + } + $nodehm_table->close(); + return 0; + }; # end of init_desc_func + + # Get the nodes should be inspect. + if ($opts_ptr->[OPT_FORCE]) { + @nodes = @{ $request->{node} }; + } else { + my $nics_table = xCAT::Table->new('nics'); + unless ($nics_table) { + xCAT::MsgUtils->message("S", "Unable to open nics table, denying"); + return -1; + } + my @tmp = @{ dclone(\@{ $request->{node} }) }; + @tmp = map { $_ = '"' . $_ . '"'; } @tmp; + my $clause = "node in (" . join(",", @tmp) . ") and nicsadapter != \'\'"; + + my @entries = $nics_table->getAllAttribsWhere($clause, 'node'); + my @checked_nodes; + foreach my $checked (@entries) { + push(@checked_nodes, $checked->{'node'}); + } + + foreach my $node (@{ $request->{node} }) { + if (!grep (/^$node$/, @checked_nodes)) { + push(@nodes, $node); + } + else { + $callback->({ data => "$node: Adapter information exists, no need to inspect." }); } } } - $callback->($rsp); - - return; -} - -sub deletenode{ - my $arrref = shift; - my $targetnode = shift; - my $arrcount = scalar @$arrref; - my $targetindex=0; - - if( "$targetnode" ne "all" ){ - for (my $i = 0; $i < $arrcount; $i++){ - if ("$arrref->[$i]" eq "$targetnode"){ - $targetindex = $i; - last; - } - } - for (my $i = $targetindex; $i < $arrcount-1; $i++){ - $arrref->[$i] = $arrref->[$i+1] ; - } - pop @$arrref; - }else{ - for (my $i = 0; $i < $arrcount; $i++){ - pop @$arrref; - } + if (scalar(@nodes) == 0) { + $callback->({ data => "No adapter information need to inspect." }); + return -1; } + xCAT::MsgUtils->trace($VERBOSE, "d", "getadapter: scaning start for " . join(",", @nodes)); + if (&$init_desc_func(\@nodes, $callback, \%nodes_desc)) { + return -1; + } + + return do_inspect(\@nodes, \%nodes_desc, $opts_ptr, $callback, $subreq); } 1; diff --git a/xCAT-server/sbin/xcatd b/xCAT-server/sbin/xcatd index 4ba8377b4..74da551d6 100644 --- a/xCAT-server/sbin/xcatd +++ b/xCAT-server/sbin/xcatd @@ -44,6 +44,7 @@ use xCAT::TableUtils; use xCAT::NetworkUtils; use xCAT::MsgUtils; use xCAT::xcatd; +use xCAT::State; my $os = xCAT::Utils->osver(); my $arch = `uname -p`; # These do not have the IO::Uncompress rpm available @@ -73,6 +74,9 @@ my %dispatched_children=(); my $plugin_numchildren=0; my %plugin_children; my $inet6support; + +my @CALLBACK_COMMAND =('getadapter'); + if ($^O =~ /^aix/i) { # disable AIX IPV6 TODO $inet6support = 0; } else { @@ -111,7 +115,7 @@ use xCAT::ExtTab; use Data::Dumper; use Getopt::Long; use Sys::Syslog qw(:DEFAULT setlogsock); -openlog("xcat",,"local4"); +openlog("xcat","local4"); # turn off warnings for call to setlogsock. puts out warning message if # syslog tcp port not defined in /etc/services. this can safely be ignored. no warnings; @@ -1472,10 +1476,6 @@ xCAT_monitoring::monitorctrl::stop($$); my $parent_fd; my %resps; - - - - sub plugin_command { my $req = shift; my $sock = shift; @@ -1744,6 +1744,7 @@ sub plugin_command { $parent_fd = $old_parent_fd; } else { my $req_back = undef; + my $command = $req->{'command'}->[0]; # executing plugins parallel foreach (keys %handler_hash) { my $modname = $_; @@ -1751,6 +1752,20 @@ sub plugin_command { if (-r $plugins_dir."/".$modname.".pm") { require $plugins_dir."/".$modname.".pm"; $plugin_numchildren++; + # build the request queue for the callback command + if (grep (/^$command$/, @CALLBACK_COMMAND)) { + no strict "refs"; + if (defined(${"xCAT_plugin::".$modname."::"}{route_request})) { + my $ret = ${"xCAT_plugin::".$modname."::"}{route_request} + ($req,$callback,\&do_request); + if ($ret == xCAT::State->REQUEST_ERROR) { + xCAT::MsgUtils->message("S", "Request failed: $!"); + next; + } elsif ($ret == xCAT::State->REQUEST_UPDATE) { + next; + } + } + } my $pfd; # will be referenced for inter-process messaging. my $parfd; # not causing a problem that I discern yet, but theoretically my $child;