mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
95 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44598496c5 | ||
|
|
2a6a28023b | ||
|
|
e581fa3fea | ||
|
|
0382659f4f | ||
|
|
e767a2b99d | ||
|
|
869f629746 | ||
|
|
7b8d09e62e | ||
|
|
5a8eee163b | ||
|
|
75a45158ad | ||
|
|
16c4074e47 | ||
|
|
2b92bc4c08 | ||
|
|
d0e2caf0ff | ||
|
|
d542138868 | ||
|
|
df133846b5 | ||
|
|
283e0bd5ea | ||
|
|
5ae3ec72b2 | ||
|
|
d9e9f7185f | ||
|
|
532d87d281 | ||
|
|
8600296030 | ||
|
|
3908725d3b | ||
|
|
780133f825 | ||
|
|
82c8148983 | ||
|
|
c12c4af760 | ||
|
|
f595bce3c0 | ||
|
|
0768fbbb20 | ||
|
|
523d833eb3 | ||
|
|
3fc01e7520 | ||
|
|
9259370891 | ||
|
|
7b84e30471 | ||
|
|
9c2a0649f2 | ||
|
|
778292e771 | ||
|
|
c21e464856 | ||
|
|
a060dc22db | ||
|
|
66f0090989 | ||
|
|
5d10b925c8 | ||
|
|
7076d19c7f | ||
|
|
69199219bc | ||
|
|
f0116ee79c | ||
|
|
4ad5e29f2f | ||
|
|
a0d3e3a1a8 | ||
|
|
1261105fe2 | ||
|
|
31866fbfa4 | ||
|
|
e179b7a9ac | ||
|
|
5e4577d76b | ||
|
|
496c257bf2 | ||
|
|
0028f166aa | ||
|
|
97047896ab | ||
|
|
94fcd8dc18 | ||
|
|
afdecb4a57 | ||
|
|
e5f9279295 | ||
|
|
55f0b001d1 | ||
|
|
5f768dd52d | ||
|
|
0daa7ba0b5 | ||
|
|
e748fff347 | ||
|
|
d81c423429 | ||
|
|
c993ad89c5 | ||
|
|
398f9ceac8 | ||
|
|
f0d8bc02a7 | ||
|
|
aba46da2d0 | ||
|
|
ddfe2bf59b | ||
|
|
364b4c0686 | ||
|
|
8818e229cc | ||
|
|
ed18044925 | ||
|
|
3c80f7e025 | ||
|
|
70243b8135 | ||
|
|
2f461f673e | ||
|
|
c0dc514af8 | ||
|
|
e831269e74 | ||
|
|
063425d515 | ||
|
|
61b60baf57 | ||
|
|
cd085dc721 | ||
|
|
c2cb410b8f | ||
|
|
0b4686dd76 | ||
|
|
ca50924acb | ||
|
|
8ff6af3a4b | ||
|
|
221e74c27c | ||
|
|
6c3c721275 | ||
|
|
93d91679c3 | ||
|
|
6b8b336cf0 | ||
|
|
616d379c60 | ||
|
|
f3f16a7ca4 | ||
|
|
d029030308 | ||
|
|
097c498340 | ||
|
|
73d5e17026 | ||
|
|
f3e552d67c | ||
|
|
5ba519973f | ||
|
|
18f1730b92 | ||
|
|
f1a5ab20b7 | ||
|
|
39382ec5fd | ||
|
|
2e8ad91d3d | ||
|
|
7548b470c2 | ||
|
|
b4714e6113 | ||
|
|
fe0b2d96f7 | ||
|
|
b53793d1b6 | ||
|
|
9b5568d2ef |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,7 +3,7 @@
|
||||
#
|
||||
*.o
|
||||
*.a
|
||||
*.d
|
||||
*.o.d
|
||||
|
||||
#
|
||||
# Ignore generated executables and other generated files
|
||||
|
||||
12
AUTHORS.md
12
AUTHORS.md
@@ -10,15 +10,19 @@ List of all individuals having contributed content to s390-tools
|
||||
- Benjamin Block
|
||||
- Carsten Otte
|
||||
- Christian Borntraeger
|
||||
- Christian Ehrhardt
|
||||
- Christof Schmitt
|
||||
- Claudio Imbrenda
|
||||
- Clemens von Mann
|
||||
- Dan Horak
|
||||
- Despina Papadopoulou
|
||||
- Eberhard Pasch
|
||||
- Einar Lueck
|
||||
- Erwin Vicari
|
||||
- Eugene Dvurechenski
|
||||
- Eugene Crosser
|
||||
- Eugene Dvurechenski
|
||||
- Farhan Ali
|
||||
- Fedor Loshakov
|
||||
- Felix Beck
|
||||
- Frank Blaschka
|
||||
- Frank Munzert
|
||||
@@ -26,8 +30,9 @@ List of all individuals having contributed content to s390-tools
|
||||
- Fritz Elfert
|
||||
- Gerald Schaefer
|
||||
- Gerhard Tonn
|
||||
- Hans Wippel
|
||||
- Hannes Reinecke
|
||||
- Hans-Joachim Picht
|
||||
- Hans Wippel
|
||||
- Harald Freudenberger
|
||||
- Heiko Carstens
|
||||
- Hendrik Brueckner
|
||||
@@ -62,6 +67,9 @@ List of all individuals having contributed content to s390-tools
|
||||
- Mikhail Zaslonko
|
||||
- Peter Oberparleiter
|
||||
- Peter Tiedemann
|
||||
- Philipp Kern
|
||||
- Philipp Rudo
|
||||
- Rafael Fonseca
|
||||
- Raimund Schroeder
|
||||
- Ralph Wuerthner
|
||||
- Rene Trumpp
|
||||
|
||||
54
CHANGELOG.md
54
CHANGELOG.md
@@ -1,11 +1,63 @@
|
||||
Release history for s390-tools (MIT version)
|
||||
--------------------------------------------
|
||||
|
||||
* __v2.2.0 (2017-12-07)__
|
||||
|
||||
For Linux kernel version: 4.14
|
||||
|
||||
Removed tools:
|
||||
- lsmem/chmem: Moved to util-linux >= 2.30
|
||||
|
||||
Changes of existing tools:
|
||||
- lszcrypt: Add CEX6S support
|
||||
- cpuplugd/mon_tools: Improve systemctl start error handling
|
||||
- systemd: Install also the unit configuration files
|
||||
|
||||
Bug Fixes:
|
||||
- build process: Fix parallel build for libutil
|
||||
- cpi: Add missing Install section to service unit
|
||||
- lsluns: Do not scan (all) if filters match nothing
|
||||
- lsluns: Enhance usage statement and man page
|
||||
- zdev: Use correct path to vmcp binary
|
||||
- ziomon: Re-add missing line in ziomon_fcpconf
|
||||
- ziomon: Fix non-zero return code in ziomon_util
|
||||
- zipl: Remove invalid dasdview command line option
|
||||
|
||||
* __v2.1.0 (2017-09-25)__
|
||||
|
||||
For Linux kernel version: 4.13
|
||||
|
||||
Added new tools:
|
||||
- netboot: Scripts for building a PXE-style netboot image for KVM
|
||||
- 90-cpi.rules/cpictl: New udev rule to update CPI when KVM is used
|
||||
|
||||
Changes of existing tools:
|
||||
- lsqeth/zdev: Add VNIC Characteristics support
|
||||
|
||||
Bug Fixes:
|
||||
- chzcrypt: Corrected handling of insufficient permissions
|
||||
- cpacfstats: Add size setting to perf event
|
||||
- fdasd: Skip partition check with the force option
|
||||
- ttyrun: Fix deprecated BindTo usage in ttyrun-getty@.service.in
|
||||
- lszcrypt: Fix core dump caused by stack overwrite
|
||||
- lszcrypt: Fix random domain printout when no config available
|
||||
- zdev: Fix segfault with unknown qeth attribute
|
||||
- zdev: Fix IPv6 NDP proxy description
|
||||
- zdev: Fix zdev dracut module temp file location
|
||||
- zkey: Correctly detect abbreviated commands
|
||||
- zkey: Validate XTS key: ignore domain and card
|
||||
- zkey: Use octal values instead of S_IRWX* constants
|
||||
- zkey: Properly set umask to prohibit permissions to group and others
|
||||
- zkey: Add -ldl to LDLIBS (not LDFLAGS)
|
||||
- znetconf: Re-add missing line in lsznet.raw
|
||||
- Fix several gcc 7 warnings
|
||||
|
||||
* __v2.0.0 (2017-08-21)__
|
||||
|
||||
- Publish package under the MIT license with the same contents as
|
||||
the already available s390-tools-1.39.0
|
||||
|
||||
Previous releases of s390-tools can be found on the IBM Developer Works web pages:
|
||||
Previous releases of s390-tools can be found on the IBM Developer Works
|
||||
web pages:
|
||||
|
||||
- https://www.ibm.com/developerworks/linux/linux390/s390-tools.html
|
||||
|
||||
47
CODINGSTYLE.md
Normal file
47
CODINGSTYLE.md
Normal file
@@ -0,0 +1,47 @@
|
||||
Coding guidelines for s390-tools
|
||||
================================
|
||||
|
||||
For s390-tools the preferred language is C. We provide libraries, e.g.
|
||||
[`libutil`](libutil) that should be used by all tools if possible.
|
||||
|
||||
The coding style is based on the Linux [kernel guidelines]. Therefore, use
|
||||
the [checkpatch] tool for verification before you submit a patch.
|
||||
|
||||
[kernel guidelines]: https://www.kernel.org/doc/html/latest/process/coding-style.html
|
||||
[checkpatch]: https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl
|
||||
|
||||
Below we describe some additional things that we want you to consider when
|
||||
writing new code for s390-tools.
|
||||
|
||||
This package started in 2001 and has a long "tradition" - therefore, older tools
|
||||
might not follow all recommendations. Note that when changing existing code,
|
||||
consistency could have priority over applying rules.
|
||||
|
||||
Standard abbreviations
|
||||
----------------------
|
||||
|
||||
The abbreviations below are recommended to be used in the source code.
|
||||
|
||||
| __Short Name__ | __Long Name__ |
|
||||
|:----------------|:--------------------------------------------------|
|
||||
| attr | Attribute |
|
||||
| blk | Block |
|
||||
| buf | Buffer |
|
||||
| col | Column |
|
||||
| count | Count |
|
||||
| desc | Description |
|
||||
| dir | Directory |
|
||||
| fd | File descriptor (open) |
|
||||
| fp | File pointer (fopen) |
|
||||
| len | Length |
|
||||
| lib | Library |
|
||||
| mod | Module |
|
||||
| nr | Number |
|
||||
| parm | Parameter |
|
||||
| path | File path |
|
||||
| ptr | Pointer |
|
||||
| rc | Return code |
|
||||
| size | Size |
|
||||
| src | Source |
|
||||
| str | String |
|
||||
| sym | Symbol |
|
||||
218
CONTRIBUTING.md
218
CONTRIBUTING.md
@@ -42,24 +42,222 @@ Developer's Certificate of Origin 1.1
|
||||
this project or the open source license(s) involved.
|
||||
```
|
||||
|
||||
If you can certify the above, just add a line saying:
|
||||
If you can certify the above, just add a line stating the following at the
|
||||
bottom of each of your commit messages:
|
||||
|
||||
```
|
||||
Signed-off-by: Random Developer <random@developer.example.org>
|
||||
```
|
||||
|
||||
Please use your real name (no pseudonyms or anonymous contributions).
|
||||
Please use your real name and a valid e-mail address (no pseudonyms or anonymous
|
||||
contributions).
|
||||
|
||||
Submitting code
|
||||
---------------
|
||||
The preferred way is to create a github pull request for your code.
|
||||
The preferred way is to create GitHub pull requests for your code contributions.
|
||||
Please create separate pull requests for each logical enhancement, new feature,
|
||||
or fix.
|
||||
|
||||
Coding guidelines
|
||||
-----------------
|
||||
For s390-tools the preferred language is C. We provide libraries, e.g. libutil
|
||||
that should be used by all tools if possible.
|
||||
Before you submit your code please consider our recommendations in the
|
||||
[CODINGSTYLE](CODINGSTYLE.md) document.
|
||||
|
||||
The coding style is based on the Linux kernel guidelines. Therefore, use
|
||||
the checkpatch tool [1] for verification before you submit a patch.
|
||||
GitHub workflow for contributions
|
||||
---------------------------------
|
||||
In the examples below we use this fictive identity:
|
||||
|
||||
[1] https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl
|
||||
- Name: Random Developer
|
||||
- E-mail: random@developer.example.org
|
||||
- GitHub ID: random-developer
|
||||
|
||||
### Setup GitHub and local git
|
||||
|
||||
1. Create a fork of this repository by clicking the `Fork` button on the top
|
||||
right of the [s390-tools](https://github.com/ibm-s390-tools/s390-tools)
|
||||
main page
|
||||
|
||||
2. Clone your forked repository to your local development system
|
||||
```
|
||||
$ git clone https://github.com/random-developer/s390-tools.git
|
||||
```
|
||||
|
||||
3. Configure a remote called "upstream" pointing to the official
|
||||
s390-tools repository on GitHub
|
||||
```
|
||||
$ cd s390-tools
|
||||
~/s390-tools $ git remote add upstream https://github.com/ibm-s390-tools/s390-tools.git
|
||||
```
|
||||
|
||||
4. Verify your remotes
|
||||
```
|
||||
~/s390-tools $ git remote -v
|
||||
origin https://github.com/random-developer/s390-tools.git (fetch)
|
||||
origin https://github.com/random-developer/s390-tools.git (push)
|
||||
upstream https://github.com/ibm-s390-tools/s390-tools.git (fetch)
|
||||
upstream https://github.com/ibm-s390-tools/s390-tools.git (push)
|
||||
```
|
||||
You now have two remotes: The "origin" remote points to your fork
|
||||
and the "upstream" remote to the official s390-tools repository.
|
||||
|
||||
5. Configure your git user name and e-mail
|
||||
```
|
||||
~/s390-tools $ git config user.name "Random Developer"
|
||||
~/s390-tools $ git config user.email "random@developer.example.com"
|
||||
```
|
||||
|
||||
### Create a pull request
|
||||
|
||||
1. Create and checkout a new branch for your contribution
|
||||
```
|
||||
~/s390-tools $ git checkout -b contrib-doc-pr
|
||||
```
|
||||
|
||||
2. Make your changes to the code
|
||||
```
|
||||
~/s390-tools $ vim CONTRIBUTING.md
|
||||
```
|
||||
|
||||
3. Build and test your contribution
|
||||
```
|
||||
~/s390-tools $ make clean all
|
||||
~/s390-tools $ # Whatever you have to do for testing
|
||||
```
|
||||
|
||||
4. Commit your changes
|
||||
```
|
||||
~/s390-tools $ git add CONTRIBUTING.md
|
||||
~/s390-tools $ git commit -s
|
||||
```
|
||||
|
||||
Provide a meaningful commit message including your "Signed-off-by" line to
|
||||
each commit:
|
||||
```
|
||||
CONTRIBUTING: Outline steps to submit code
|
||||
|
||||
Explain in more detail how to submit s390-tools contributions as GitHub
|
||||
pull requests.
|
||||
|
||||
Signed-off-by: Random Developer <random@developer.example.com>
|
||||
```
|
||||
|
||||
5. Use the [checkpatch] tool to validate your commits
|
||||
```
|
||||
~/s390-tools $ checkpatch.pl --no-tree --git master..HEAD
|
||||
```
|
||||
|
||||
Interpret the checkpatch messages wisely - e.g. the 80 character rule can be
|
||||
ignored for printf format strings.
|
||||
|
||||
[checkpatch]: https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl
|
||||
|
||||
6. Push the changes to your fork of the repository
|
||||
```
|
||||
~/s390-tools $ git push origin contrib-doc-pr
|
||||
```
|
||||
|
||||
7. Go to the GitHub website of your s390-tools fork and create a pull request
|
||||
for your branch "contrib-doc-pr"
|
||||
|
||||
### Update a pull request during review
|
||||
|
||||
If there are changes requested during the review process, you have to update
|
||||
your code in the pull request.
|
||||
|
||||
To retain the existing review comments, add commits on top of your pull request
|
||||
branch. Depending on the size and number of changes, a rebase of the pull
|
||||
request might be required. This will be communicated during the review.
|
||||
|
||||
1. Update your code with new commits
|
||||
```
|
||||
~/s390-tools $ vi CONTRIBUTING.md
|
||||
~/s390-tools $ git add CONTRIBUTING.md
|
||||
~/s390-tools $ git commit -s -m "CONTRIBUTING: Add update PR info"
|
||||
```
|
||||
|
||||
2. Update your pull request by pushing changes
|
||||
```
|
||||
~/s390-tools $ git push origin contrib-doc-pr
|
||||
```
|
||||
|
||||
### Finalize a pull request
|
||||
|
||||
After the review process is finished or if you are explicitly asked for it,
|
||||
you have to create a clean commit series.
|
||||
|
||||
1. Save branch to "contrib-doc-pr.v1"
|
||||
```
|
||||
$ cd s390-tools
|
||||
~/s390-tools $ git branch contrib-doc-pr.v1
|
||||
```
|
||||
|
||||
2. Use interactive git rebase to merge commits, adjust commit messages,
|
||||
and rebase onto your local master branch
|
||||
```
|
||||
~/s390-tools $ git rebase -i master
|
||||
```
|
||||
|
||||
An editor is started and shows the following:
|
||||
```
|
||||
pick 2c73b9fc CONTRIBUTING: Outline steps to submit code
|
||||
pick fcfb0412 CONTRIBUTING: Add update PR info
|
||||
```
|
||||
|
||||
To merge the update into the original commit, replace "pick fcfb0412"
|
||||
with "squash fcfb0412".
|
||||
|
||||
```
|
||||
pick 2c73b9fc CONTRIBUTING: Outline steps to submit code
|
||||
squash fcfb0412 CONTRIBUTING: Add update PR info
|
||||
```
|
||||
|
||||
Save the document and exit the editor to finish the merge. Another editor
|
||||
window is presented to modify the commit message.
|
||||
|
||||
You now could change the commit message as follows:
|
||||
|
||||
```
|
||||
CONTRIBUTING: Outline steps to submit code
|
||||
|
||||
Explain in more detail how to submit s390-tools contributions as GitHub
|
||||
pull requests and how to update already submitted pull requests.
|
||||
|
||||
Signed-off-by: Random Developer <random@developer.example.com>
|
||||
```
|
||||
|
||||
With interactive rebasing you can also change the order of commits and
|
||||
modify commit messages with "reword".
|
||||
|
||||
3. Use `git push` with the force option to replace the existing pull request
|
||||
with your locally modified commits
|
||||
```
|
||||
~/s390-tools $ git push --force origin contrib-doc-pr
|
||||
```
|
||||
|
||||
### Rebase a pull request
|
||||
|
||||
If changes are made to the master branch in the official s390-tools
|
||||
repository you may be asked to rebase your branch with your contribution
|
||||
onto it. This can be required to prevent any merge conflicts that might
|
||||
arise when integrating your contribution.
|
||||
|
||||
1. Fetch all upstream changes from the official s390-tools repository,
|
||||
rebase your local master branch and update the master branch
|
||||
on your fork
|
||||
```
|
||||
~/s390-tools $ git fetch upstream
|
||||
~/s390-tools $ git checkout master
|
||||
~/s390-tools $ git rebase upstream/master
|
||||
~/s390-tools $ git push origin master
|
||||
```
|
||||
|
||||
2. Rebase your branch with your contribution onto the master branch of
|
||||
the official s390-tools repository
|
||||
```
|
||||
~/s390-tools $ git checkout contrib-doc-pr
|
||||
~/s390-tools $ git rebase master
|
||||
```
|
||||
|
||||
3. Use `git push` with the force option to replace the existing pull
|
||||
request with your locally modified commits
|
||||
```
|
||||
~/s390-tools $ git push --force origin contrib-doc-pr
|
||||
```
|
||||
|
||||
2
Makefile
2
Makefile
@@ -8,7 +8,7 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
||||
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
|
||||
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
||||
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
||||
systemd hmcdrvfs cpacfstats zdev dump2tar zkey
|
||||
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc
|
||||
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
|
||||
|
||||
all: $(TOOL_DIRS)
|
||||
|
||||
33
README.md
33
README.md
@@ -11,6 +11,7 @@ The package also contains the following files:
|
||||
* [LICENSE](LICENSE): The MIT license that applies to this package
|
||||
* [CHANGELOG](CHANGELOG.md): The history of s390-tools versions
|
||||
* [AUTHORS](AUTHORS.md): A list of all authors of the s390-tools package
|
||||
* [CODINGSTYLE](CODINGSTYLE.md): Recommendations for writing s390-tools code
|
||||
|
||||
Package contents
|
||||
----------------
|
||||
@@ -35,6 +36,8 @@ Package contents
|
||||
- 57-osasnmpd.rules: udev rules for osasnmpd.
|
||||
- 60-readahead.rules: udev rules to set increased "default max readahead".
|
||||
- 40-z90crypt.rules: udev rules for z90crypt driver
|
||||
- 90-cpi.rules: udev rule to update Control-Program-Information when KVM is
|
||||
used.
|
||||
|
||||
* systemd units:
|
||||
- cpi.service: Unit to apply CPI settings
|
||||
@@ -122,14 +125,13 @@ Package contents
|
||||
- lsscm: List information about available Storage Class Memory
|
||||
Increments.
|
||||
- chchp: Modify channel-path state.
|
||||
- lsluns: List available SCSI LUNs depending on adapter or port.
|
||||
- lsluns: List LUNs discovered in the FC SAN,
|
||||
or show encryption state of attached LUNs.
|
||||
- lszcrypt: Show Information about zcrypt devices and configuration.
|
||||
- chzcrypt: Modify the zcrypt configuration.
|
||||
- znetconf: List and configure network devices for s390 network adapters.
|
||||
- cio_ignore: Query and modify the contents of the CIO device driver
|
||||
blacklist.
|
||||
- lsmem: Display the online status of the available memory.
|
||||
- chmem: Set hotplug memory online or offline.
|
||||
- dasdstat: Configure and format the debugfs based DASD statistics data.
|
||||
|
||||
* zkey:
|
||||
@@ -234,6 +236,10 @@ Package contents
|
||||
arbitrary files. It works even when the size of the actual file content
|
||||
is not known beforehand (e.g. FIFOs, sysfs files).
|
||||
|
||||
* netboot:
|
||||
Provides simple tools to create a binary that can be used to implement
|
||||
simple network boot setups following the PXELINUX conventions.
|
||||
|
||||
For more information refer to the following publications:
|
||||
|
||||
* "Device Drivers, Features, and Commands" chapter "Useful Linux commands"
|
||||
@@ -250,13 +256,14 @@ HAVE_FUSE=0`".
|
||||
The following table provides an overview of the used libraries and
|
||||
build options:
|
||||
|
||||
| __LIBRARY__|__BUILD OPTION__| __TOOLS__ |
|
||||
|------------|:--------------:|:-------------------------------------:|
|
||||
| fuse | `HAVE_FUSE` | cmsfs-fuse, zdsfs, hmcdrvfs, zgetdump |
|
||||
| zlib | `HAVE_ZLIB` | zgetdump, dump2tar |
|
||||
| ncurses | `HAVE_NCURSES` | hyptop |
|
||||
| pfm | `HAVE_PFM` | cpacfstats |
|
||||
| net-snmp | `HAVE_SNMP` | osasnmpd |
|
||||
| __LIBRARY__ | __BUILD OPTION__ | __TOOLS__ |
|
||||
|----------------|:------------------:|:-------------------------------------:|
|
||||
| fuse | `HAVE_FUSE` | cmsfs-fuse, zdsfs, hmcdrvfs, zgetdump |
|
||||
| zlib | `HAVE_ZLIB` | zgetdump, dump2tar |
|
||||
| ncurses | `HAVE_NCURSES` | hyptop |
|
||||
| pfm | `HAVE_PFM` | cpacfstats |
|
||||
| net-snmp | `HAVE_SNMP` | osasnmpd |
|
||||
| glibc-static | `HAVE_LIBC_STATIC` | zfcpdump |
|
||||
|
||||
This table lists additional build or install options:
|
||||
|
||||
@@ -280,9 +287,9 @@ the different tools are provided:
|
||||
http://net-snmp.sourceforge.net
|
||||
|
||||
* lsluns:
|
||||
For executing the lsluns script the sg_luns command must be available.
|
||||
The sg_luns executable is part of the SCSI generic device driver package
|
||||
(sg3 utils/sg utils).
|
||||
For executing the lsluns script the sg_luns and sg_inq commands must
|
||||
be available. The sg_luns and sg_inq executables are part of the
|
||||
SCSI generic device driver package (sg3 utils/sg utils).
|
||||
|
||||
* ziomon tools:
|
||||
For running the ziomon tools the following tools/packages are required:
|
||||
|
||||
135
bin/mk-authors
Executable file
135
bin/mk-authors
Executable file
@@ -0,0 +1,135 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# mk-authors - Update the s390-tools authors file (AUTHORS.md)
|
||||
#
|
||||
# Invocation examples:
|
||||
#
|
||||
# $ mk-authors
|
||||
# $ mk-authors -t v2.0.0
|
||||
#
|
||||
# Copyright IBM Corp. 2017
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
cmd=$(basename $0)
|
||||
authors_file="AUTHORS.md"
|
||||
|
||||
cleanup()
|
||||
{
|
||||
test -f $authors_file_tmp && rm -f $authors_file_tmp
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
#
|
||||
# Print usage information
|
||||
#
|
||||
print_usage()
|
||||
{
|
||||
cat <<EoUSAGE
|
||||
Usage: $cmd [-t LAST_GIT_TAG]
|
||||
|
||||
Add all new authors since last release to the $authors_file file. Without
|
||||
the -t option the tool uses the last available git tag as last release.
|
||||
|
||||
The tool should be called form the s390-tools master branch.
|
||||
|
||||
OPTIONS
|
||||
-t, --tag LAST_GIT_TAG Use git tag LAST_GIT_TAG as starting point
|
||||
-h, --help Print this help, then exit
|
||||
EoUSAGE
|
||||
}
|
||||
|
||||
#
|
||||
# Print help hint for option parsing error
|
||||
#
|
||||
print_parse_error_and_exit()
|
||||
{
|
||||
echo "Try '$cmd -h' for more information." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
#
|
||||
# Parse options
|
||||
#
|
||||
opts=$(getopt -o ht: -l help,tag: -n $cmd -- "$@")
|
||||
if [ $? != 0 ]; then
|
||||
print_parse_error_and_exit
|
||||
fi
|
||||
# Use eval to remove getopt quotes
|
||||
eval set -- $opts
|
||||
while [ -n $1 ]; do
|
||||
case $1 in
|
||||
-h | --help)
|
||||
print_usage
|
||||
exit 0
|
||||
;;
|
||||
-t | --tag)
|
||||
release_tag_last=$2
|
||||
shift 2
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $# != 0 ]; then
|
||||
echo "$cmd: Invalid argument $1" >&2
|
||||
print_parse_error_and_exit
|
||||
fi
|
||||
|
||||
#
|
||||
# Get git root and last release tag
|
||||
#
|
||||
git_root=$(git rev-parse --show-toplevel 2> /dev/null)
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "$cmd: Use tool within s390-tools git repository" >&2
|
||||
print_parse_error_and_exit
|
||||
fi
|
||||
authors_file_path=$git_root/$authors_file
|
||||
# Get last release tag if not specified via -t
|
||||
if [ -z $release_tag_last ]; then
|
||||
tag_commit=$(git rev-list --tags --max-count=1)
|
||||
release_tag_last=$(git describe --tags $tag_commit)
|
||||
fi
|
||||
# Verify release tag
|
||||
git show $release_tag_last &> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "$cmd: Cannot find tag '$release_tag_last'" >&2
|
||||
print_parse_error_and_exit
|
||||
fi
|
||||
|
||||
#
|
||||
# Update authors file
|
||||
#
|
||||
|
||||
# Create temporary file for new author list
|
||||
authors_file_tmp=$(mktemp /tmp/authors.XXXXXX)
|
||||
|
||||
echo "$cmd: Adding new authors since tag: $release_tag_last"
|
||||
{
|
||||
# Print authors list without header
|
||||
tail -n +4 $authors_file_path
|
||||
# Add the new authors
|
||||
git log --format="- %an" $release_tag_last..
|
||||
# Then sort everything and remove duplicates
|
||||
} | sort | uniq > $authors_file_tmp
|
||||
# Create new AUTHORS file with header ...
|
||||
cat <<EoHEADER > $authors_file_path
|
||||
List of all individuals having contributed content to s390-tools
|
||||
----------------------------------------------------------------
|
||||
|
||||
EoHEADER
|
||||
# ... and add new content
|
||||
cat $authors_file_tmp >> $authors_file_path
|
||||
|
||||
cat <<EoUPDATE_MSG
|
||||
- Updated file: $authors_file_path
|
||||
- Verify changes with: git diff $authors_file_path
|
||||
- Do a manual *cleanup* before commiting if necessary.
|
||||
EoUPDATE_MSG
|
||||
12
common.mak
12
common.mak
@@ -5,7 +5,7 @@ COMMON_INCLUDED = true
|
||||
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
||||
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
||||
VERSION = 2
|
||||
RELEASE = 0
|
||||
RELEASE = 2
|
||||
PATCHLEVEL = 0
|
||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||
@@ -113,9 +113,10 @@ DEFAULT_LDFLAGS = -rdynamic
|
||||
# $2: Name of include file to check
|
||||
# $3: Name of required devel package
|
||||
# $4: Option to skip build (e.g. HAVE_FUSE=0)
|
||||
# $5: Additional compiler & linker options (optional)
|
||||
#
|
||||
check_dep=\
|
||||
printf "\#include <%s>" $2 | ( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) -c -o /dev/null -xc - ) > /dev/null 2>&1; \
|
||||
printf "\#include <%s>\n int main(void) {return 0;}" $2 | ( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) $5 -o /dev/null -xc - ) > /dev/null 2>&1; \
|
||||
if [ $$? != 0 ]; \
|
||||
then \
|
||||
printf " REQCHK %s (%s)\n" $1 $2; \
|
||||
@@ -167,13 +168,14 @@ MANDIR = $(INSTALLDIR)/usr/share/man
|
||||
VARDIR = $(INSTALLDIR)/var
|
||||
TOOLS_DATADIR = $(INSTALLDIR)/usr/share/s390-tools
|
||||
TOOLS_LIBDIR = $(INSTALLDIR)/lib/s390-tools
|
||||
ZFCPDUMP_DIR = $(INSTALLDIR)/lib/s390-tools/zfcpdump
|
||||
ZFCPDUMP_DIR = $(TOOLS_LIBDIR)/zfcpdump
|
||||
# Systemd support files are installed only if a directory is specified
|
||||
# for SYSTEMDSYSTEMUNITDIR (e.g. /lib/systemd/system)
|
||||
SYSTEMDSYSTEMUNITDIR =
|
||||
|
||||
INSTDIRS = $(USRSBINDIR) $(USRBINDIR) $(BINDIR) $(LIBDIR) $(MANDIR) \
|
||||
$(SYSCONFDIR) $(TOOLS_LIBDIR) $(TOOLS_DATADIR) \
|
||||
$(SYSCONFDIR) $(SYSCONFDIR)/sysconfig \
|
||||
$(TOOLS_LIBDIR) $(TOOLS_DATADIR) \
|
||||
$(ZFCPDUMP_DIR) $(SYSTEMDSYSTEMUNITDIR)
|
||||
OWNER = $(shell id -un)
|
||||
GROUP = $(shell id -gn)
|
||||
@@ -193,12 +195,14 @@ ALL_CFLAGS = -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
||||
-DS390_TOOLS_LIBDIR=$(TOOLS_LIBDIR) \
|
||||
-DS390_TOOLS_DATADIR=$(TOOLS_DATADIR) \
|
||||
-DS390_TOOLS_SYSCONFDIR=$(SYSCONFDIR) \
|
||||
-DS390_TOOLS_BINDIR=$(BINDIR) \
|
||||
$(CFLAGS)
|
||||
CXXFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||
ALL_CXXFLAGS = -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
||||
-DS390_TOOLS_LIBDIR=$(TOOLS_LIBDIR) \
|
||||
-DS390_TOOLS_DATADIR=$(TOOLS_DATADIR) \
|
||||
-DS390_TOOLS_SYSCONFDIR=$(SYSCONFDIR) \
|
||||
-DS390_TOOLS_BINDIR=$(BINDIR) \
|
||||
$(CXXFLAGS)
|
||||
ALL_CPPFLAGS = -I $(rootdir)include $(CPPFLAGS)
|
||||
ALL_LDFLAGS = $(LDFLAGS)
|
||||
|
||||
@@ -97,6 +97,7 @@ int perf_init(void)
|
||||
memset(&pfm_event, 0, sizeof(pfm_event));
|
||||
pfm_arg.attr = &pfm_event;
|
||||
pfm_arg.size = sizeof(pfm_arg);
|
||||
pfm_event.size = sizeof(pfm_event);
|
||||
|
||||
/* search for the counter's corresponding pfm name */
|
||||
for (i = ALL_COUNTER-1; i >= 0; i--)
|
||||
|
||||
@@ -197,10 +197,10 @@ int is_online(int cpuid);
|
||||
long get_cmmpages_size();
|
||||
void parse_options(int argc, char **argv);
|
||||
void check_if_started_twice();
|
||||
void store_pid(void);
|
||||
void handle_signals(void);
|
||||
void handle_sighup(void);
|
||||
void reload_daemon(void);
|
||||
int daemonize(void);
|
||||
int check_cmmfiles(void);
|
||||
void check_config();
|
||||
void set_cmm_pages(long size);
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "cpuplugd.h"
|
||||
|
||||
const char *name = NAME;
|
||||
@@ -49,7 +53,7 @@ void print_version()
|
||||
/*
|
||||
* Store daemon's pid so it can be stopped
|
||||
*/
|
||||
void store_pid(void)
|
||||
static int store_pid(void)
|
||||
{
|
||||
FILE *filp;
|
||||
|
||||
@@ -57,10 +61,62 @@ void store_pid(void)
|
||||
if (!filp) {
|
||||
cpuplugd_error("cannot open pid file %s: %s\n", pid_file,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
fprintf(filp, "%d\n", getpid());
|
||||
fclose(filp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run daemon in background and write pid file
|
||||
*/
|
||||
int daemonize(void)
|
||||
{
|
||||
int fd, pipe_fds[2], startup_rc = 1;
|
||||
pid_t pid;
|
||||
|
||||
if (pipe(pipe_fds) == -1) {
|
||||
cpuplugd_error("cannot create pipe\n");
|
||||
return -1;
|
||||
}
|
||||
pid = fork();
|
||||
if (pid < 0)
|
||||
goto close_pipe;
|
||||
if (pid != 0) {
|
||||
/* Wait for startup return code from daemon */
|
||||
if (read(pipe_fds[0], &startup_rc, sizeof(startup_rc)) == -1)
|
||||
cpuplugd_error("cannot read from pipe\n");
|
||||
/* On success daemon has written pid file at this point */
|
||||
exit(startup_rc);
|
||||
}
|
||||
/* Create new session */
|
||||
if (setsid() < 0)
|
||||
goto notify_parent;
|
||||
/* Redirect stdin/out/err to /dev/null */
|
||||
fd = open("/dev/null", O_RDWR, 0);
|
||||
if (fd == -1)
|
||||
goto notify_parent;
|
||||
if (dup2(fd, STDIN_FILENO) < 0)
|
||||
goto notify_parent;
|
||||
if (dup2(fd, STDOUT_FILENO) < 0)
|
||||
goto notify_parent;
|
||||
if (dup2(fd, STDERR_FILENO) < 0)
|
||||
goto notify_parent;
|
||||
/* Create pid file */
|
||||
if (store_pid() < 0)
|
||||
goto notify_parent;
|
||||
startup_rc = 0;
|
||||
notify_parent:
|
||||
/* Inform waiting parent about startup return code */
|
||||
if (write(pipe_fds[1], &startup_rc, sizeof(startup_rc)) == -1) {
|
||||
cpuplugd_error("cannot write to pipe\n");
|
||||
startup_rc = 1;
|
||||
}
|
||||
close_pipe:
|
||||
close(pipe_fds[0]);
|
||||
close(pipe_fds[1]);
|
||||
return startup_rc ? -1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -418,13 +418,11 @@ int main(int argc, char *argv[])
|
||||
check_config();
|
||||
|
||||
if (!foreground) {
|
||||
rc = daemon(1, 0);
|
||||
rc = daemonize();
|
||||
if (rc < 0)
|
||||
cpuplugd_exit("Detach from terminal failed: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
/* Store daemon pid */
|
||||
store_pid();
|
||||
/* Unlock lock file */
|
||||
flock(fd, LOCK_UN);
|
||||
close(fd);
|
||||
|
||||
@@ -456,46 +456,34 @@ static void program_interrupt_signal(int sig)
|
||||
/*
|
||||
* check given device name for blanks and some special characters
|
||||
*/
|
||||
static void get_device_name(dasdfmt_info_t *info, char *name, int argc,
|
||||
char *argv[])
|
||||
static void get_device_name(char *devname,
|
||||
int optind, int argc, char *argv[])
|
||||
{
|
||||
struct util_proc_dev_entry dev_entry;
|
||||
struct stat dev_stat;
|
||||
|
||||
if (info->device_id + 1 < argc)
|
||||
if (optind + 1 < argc)
|
||||
ERRMSG_EXIT(EXIT_MISUSE,
|
||||
"%s: More than one device specified!\n", prog_name);
|
||||
|
||||
if (info->device_id >= argc)
|
||||
if (optind >= argc)
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n",
|
||||
prog_name);
|
||||
|
||||
if (info->device_id < argc) {
|
||||
strcpy(info->devname, argv[info->device_id]);
|
||||
} else {
|
||||
if ((strchr(name, ' ') != NULL) || (strchr(name, '#') != NULL) ||
|
||||
(strchr(name, '[') != NULL) || (strchr(name, ']') != NULL) ||
|
||||
(strchr(name, '!') != NULL) || (strchr(name, '>') != NULL) ||
|
||||
(strchr(name, '(') != NULL) || (strchr(name, '<') != NULL) ||
|
||||
(strchr(name, ')') != NULL) || (strchr(name, ':') != NULL) ||
|
||||
(strchr(name, '&') != NULL) || (strchr(name, ';') != NULL))
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: Your filename contains "
|
||||
"blanks or special characters!\n",
|
||||
prog_name);
|
||||
if (strlen(argv[optind]) >= PATH_MAX)
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: device name too long!\n",
|
||||
prog_name);
|
||||
strcpy(devname, argv[optind]);
|
||||
|
||||
strncpy(info->devname, name, PATH_MAX - 1);
|
||||
info->devname[PATH_MAX - 1] = '\0';
|
||||
}
|
||||
|
||||
if (stat(info->devname, &dev_stat) != 0)
|
||||
if (stat(devname, &dev_stat) != 0)
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: Could not get information for "
|
||||
"device node %s: %s\n", prog_name, info->devname,
|
||||
"device node %s: %s\n", prog_name, devname,
|
||||
strerror(errno));
|
||||
|
||||
if (minor(dev_stat.st_rdev) & PARTN_MASK) {
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: Unable to format partition %s. "
|
||||
"Please specify a device.\n", prog_name,
|
||||
info->devname);
|
||||
devname);
|
||||
}
|
||||
|
||||
if (util_proc_dev_get_entry(dev_stat.st_rdev, 1, &dev_entry) == 0) {
|
||||
@@ -505,7 +493,7 @@ static void get_device_name(dasdfmt_info_t *info, char *name, int argc,
|
||||
prog_name, dev_entry.name);
|
||||
} else {
|
||||
printf("%s WARNING: Unable to get driver name for device node %s",
|
||||
prog_name, info->devname);
|
||||
prog_name, devname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,7 +574,7 @@ static void check_layout(dasdfmt_info_t *info, unsigned int intensity)
|
||||
/*
|
||||
* check for disk type and set some variables (e.g. usage count)
|
||||
*/
|
||||
static void check_disk(dasdfmt_info_t *info)
|
||||
static void check_disk(dasdfmt_info_t *info, char *devname)
|
||||
{
|
||||
int ro, errno_save;
|
||||
|
||||
@@ -609,13 +597,13 @@ static void check_disk(dasdfmt_info_t *info)
|
||||
if (strncmp(info->dasd_info.type, "ECKD", 4) != 0) {
|
||||
ERRMSG_EXIT(EXIT_FAILURE,
|
||||
"%s: Unsupported disk type\n%s is not an "
|
||||
"ECKD disk!\n", prog_name, info->devname);
|
||||
"ECKD disk!\n", prog_name, devname);
|
||||
}
|
||||
|
||||
if (dasd_sys_raw_track_access(info->devname)) {
|
||||
if (dasd_sys_raw_track_access(devname)) {
|
||||
ERRMSG_EXIT(EXIT_FAILURE,
|
||||
"%s: Device '%s' is in raw-track access mode\n",
|
||||
prog_name, info->devname);
|
||||
prog_name, devname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -935,7 +923,8 @@ static format_data_t ask_user_for_blksize(format_data_t params)
|
||||
/*
|
||||
* print all information needed to format the device
|
||||
*/
|
||||
static void dasdfmt_print_info(dasdfmt_info_t *info, volume_label_t *vlabel,
|
||||
static void dasdfmt_print_info(dasdfmt_info_t *info, char *devname,
|
||||
volume_label_t *vlabel,
|
||||
unsigned int cylinders, unsigned int heads,
|
||||
format_data_t *p)
|
||||
{
|
||||
@@ -945,7 +934,7 @@ static void dasdfmt_print_info(dasdfmt_info_t *info, volume_label_t *vlabel,
|
||||
cylinders, heads, (cylinders * heads));
|
||||
|
||||
printf("\nI am going to format the device ");
|
||||
printf("%s in the following way:\n", info->devname);
|
||||
printf("%s in the following way:\n", devname);
|
||||
printf(" Device number of device : 0x%x\n", info->dasd_info.devno);
|
||||
printf(" Labelling device : %s\n",
|
||||
(info->writenolabel) ? "no" : "yes");
|
||||
@@ -970,28 +959,19 @@ static void dasdfmt_print_info(dasdfmt_info_t *info, volume_label_t *vlabel,
|
||||
/*
|
||||
* get volser
|
||||
*/
|
||||
static int dasdfmt_get_volser(dasdfmt_info_t *info, char *volser)
|
||||
static int dasdfmt_get_volser(char *devname, dasd_information2_t *dasd_info,
|
||||
char *volser)
|
||||
{
|
||||
unsigned int blksize;
|
||||
int f;
|
||||
volume_label_t vlabel;
|
||||
|
||||
f = open(info->devname, O_RDONLY);
|
||||
if (f == -1)
|
||||
ERRMSG_EXIT(EXIT_FAILURE, "%s: Unable to open device %s: %s\n",
|
||||
prog_name, info->devname, strerror(errno));
|
||||
|
||||
get_blocksize(&blksize);
|
||||
|
||||
if (close(f) != 0)
|
||||
ERRMSG("%s: error during close: %s\ncontinuing...\n",
|
||||
prog_name, strerror(errno));
|
||||
|
||||
if ((strncmp(info->dasd_info.type, "ECKD", 4) == 0) &&
|
||||
(!info->dasd_info.FBA_layout)) {
|
||||
if ((strncmp(dasd_info->type, "ECKD", 4) == 0) &&
|
||||
!dasd_info->FBA_layout) {
|
||||
/* OS/390 and zOS compatible disk layout */
|
||||
vtoc_read_volume_label(info->devname,
|
||||
info->dasd_info.label_block * blksize,
|
||||
vtoc_read_volume_label(devname,
|
||||
dasd_info->label_block * blksize,
|
||||
&vlabel);
|
||||
vtoc_volume_label_get_volser(&vlabel, volser);
|
||||
return 0;
|
||||
@@ -1385,7 +1365,8 @@ static void dasdfmt_quick_format(dasdfmt_info_t *info, unsigned int cylinders,
|
||||
disk_disabled = 0;
|
||||
}
|
||||
|
||||
static void do_format_dasd(dasdfmt_info_t *info, volume_label_t *vlabel,
|
||||
static void do_format_dasd(dasdfmt_info_t *info, char *devname,
|
||||
volume_label_t *vlabel,
|
||||
format_data_t *p, unsigned int cylinders,
|
||||
unsigned int heads)
|
||||
{
|
||||
@@ -1408,19 +1389,19 @@ static void do_format_dasd(dasdfmt_info_t *info, volume_label_t *vlabel,
|
||||
}
|
||||
|
||||
if ((info->verbosity > 0) || !info->withoutprompt || info->testmode)
|
||||
dasdfmt_print_info(info, vlabel, cylinders, heads, p);
|
||||
dasdfmt_print_info(info, devname, vlabel, cylinders, heads, p);
|
||||
|
||||
count = u2s_get_host_access_count(info->devname);
|
||||
count = u2s_get_host_access_count(devname);
|
||||
if (info->force_host) {
|
||||
if (count > 1) {
|
||||
ERRMSG_EXIT(EXIT_FAILURE,
|
||||
"\n%s: Disk %s is online on OS instances in %d different LPARs.\n"
|
||||
"Note: Your installation might include z/VM systems that are configured to\n"
|
||||
"automatically vary on disks, regardless of whether they are subsequently used.\n\n",
|
||||
prog_name, info->devname, count);
|
||||
prog_name, devname, count);
|
||||
} else if (count < 0) {
|
||||
ERRMSG("\nHosts access information not available for disk %s.\n\n",
|
||||
info->devname);
|
||||
devname);
|
||||
return;
|
||||
}
|
||||
} else if (count > 1)
|
||||
@@ -1429,7 +1410,7 @@ static void do_format_dasd(dasdfmt_info_t *info, volume_label_t *vlabel,
|
||||
"Ensure that the disk is not being used by a system outside your LPAR.\n"
|
||||
"Note: Your installation might include z/VM systems that are configured to\n"
|
||||
"automatically vary on disks, regardless of whether they are subsequently used.\n",
|
||||
info->devname, count);
|
||||
devname, count);
|
||||
|
||||
if (!info->testmode) {
|
||||
if (!info->withoutprompt) {
|
||||
@@ -1480,7 +1461,6 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
dasdfmt_info_t info = {
|
||||
.dasd_info = {0},
|
||||
{0}
|
||||
};
|
||||
volume_label_t vlabel;
|
||||
char old_volser[7];
|
||||
@@ -1624,7 +1604,6 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
case -1:
|
||||
/* End of options string - start of devices list */
|
||||
info.device_id = optind;
|
||||
break;
|
||||
default:
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "Try '%s --help' for more"
|
||||
@@ -1655,12 +1634,12 @@ int main(int argc, char *argv[])
|
||||
if (info.print_hashmarks)
|
||||
PARSE_PARAM_INTO(info.hashstep, hashstep_str, 10, "hashstep");
|
||||
|
||||
get_device_name(&info, dev_filename, argc, argv);
|
||||
get_device_name(dev_filename, optind, argc, argv);
|
||||
|
||||
filedes = open(info.devname, O_RDWR);
|
||||
filedes = open(dev_filename, O_RDWR);
|
||||
if (filedes == -1)
|
||||
ERRMSG_EXIT(EXIT_FAILURE, "%s: Unable to open device %s: %s\n",
|
||||
prog_name, info.devname, strerror(errno));
|
||||
prog_name, dev_filename, strerror(errno));
|
||||
|
||||
get_device_info(&info);
|
||||
|
||||
@@ -1684,15 +1663,16 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (dasdfmt_get_volser(&info, old_volser) == 0)
|
||||
if (dasdfmt_get_volser(dev_filename,
|
||||
&info.dasd_info, old_volser) == 0)
|
||||
vtoc_volume_label_set_volser(&vlabel, old_volser);
|
||||
else
|
||||
ERRMSG_EXIT(EXIT_FAILURE,
|
||||
"%s: VOLSER not found on device %s\n",
|
||||
prog_name, info.devname);
|
||||
prog_name, dev_filename);
|
||||
}
|
||||
|
||||
check_disk(&info);
|
||||
check_disk(&info, dev_filename);
|
||||
|
||||
if (check_param(str, ERR_LENGTH, &format_params) < 0)
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: %s\n", prog_name, str);
|
||||
@@ -1703,7 +1683,8 @@ int main(int argc, char *argv[])
|
||||
if (info.check)
|
||||
check_disk_format(&info, cylinders, heads, &format_params);
|
||||
else
|
||||
do_format_dasd(&info, &vlabel, &format_params, cylinders, heads);
|
||||
do_format_dasd(&info, dev_filename, &vlabel,
|
||||
&format_params, cylinders, heads);
|
||||
|
||||
if (close(filedes) != 0)
|
||||
ERRMSG("%s: error during close: %s\ncontinuing...\n",
|
||||
|
||||
@@ -291,7 +291,6 @@ typedef struct bootstrap2 {
|
||||
|
||||
typedef struct dasdfmt_info {
|
||||
dasd_information2_t dasd_info;
|
||||
char devname[PATH_MAX];
|
||||
int verbosity;
|
||||
int testmode;
|
||||
int withoutprompt;
|
||||
@@ -304,7 +303,6 @@ typedef struct dasdfmt_info {
|
||||
int cdl_format;
|
||||
int blksize_specified;
|
||||
int reqsize_specified;
|
||||
int device_id;
|
||||
int keep_volser;
|
||||
int force_host;
|
||||
int layout_specified;
|
||||
|
||||
@@ -23,11 +23,12 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_file.h"
|
||||
#include "lib/util_opt.h"
|
||||
#include "lib/util_prg.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#define READCHUNK 80
|
||||
#define RD_BUFFER_SIZE 80
|
||||
#define BLKSSZGET _IO(0x12,104)
|
||||
#define DASD_IOCTL_LETTER 'D'
|
||||
#define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,struct dasd_information)
|
||||
@@ -236,29 +237,9 @@ static char *dinfo_ebcdic_dec (char *source, char *target, int l)
|
||||
return target;
|
||||
}
|
||||
|
||||
static int dinfo_read_dasd_uid (char *uidfile, char *readbuf, int readbuflen)
|
||||
static int dinfo_read_dasd_uid(char *uidfile, char *readbuf)
|
||||
{
|
||||
FILE *dasduid;
|
||||
int offset = 0;
|
||||
|
||||
if ((dasduid = fopen(uidfile,"r")) == NULL)
|
||||
return -1;
|
||||
|
||||
while (fgets(readbuf + offset, READCHUNK, dasduid) &&
|
||||
readbuf[strlen(readbuf)-1] != '\n' ) {
|
||||
offset += READCHUNK-1;
|
||||
if ( offset+READCHUNK-1 >= readbuflen ) {
|
||||
readbuf = realloc(readbuf,
|
||||
readbuflen + READCHUNK-1);
|
||||
readbuflen += READCHUNK-1;
|
||||
}
|
||||
}
|
||||
fclose(dasduid);
|
||||
|
||||
if (strlen(readbuf) <= 1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
return util_file_read_line(readbuf, RD_BUFFER_SIZE, uidfile);
|
||||
}
|
||||
|
||||
static int dinfo_read_dasd_vlabel (char *device, struct volume_label *vlabel,
|
||||
@@ -411,14 +392,14 @@ static void dinfo_free_devnode(char *device)
|
||||
}
|
||||
}
|
||||
|
||||
static int dinfo_extract_dev(dev_t *dev, char *str, int readbuflen)
|
||||
static int dinfo_extract_dev(dev_t *dev, char *str)
|
||||
{
|
||||
char tmp[readbuflen];
|
||||
char tmp[RD_BUFFER_SIZE];
|
||||
char *p = NULL;
|
||||
int ma, mi;
|
||||
|
||||
bzero(tmp, readbuflen);
|
||||
strncpy(tmp, str, readbuflen);
|
||||
bzero(tmp, RD_BUFFER_SIZE);
|
||||
strncpy(tmp, str, RD_BUFFER_SIZE);
|
||||
if ((p = strchr(tmp, ':')) == NULL) {
|
||||
printf("Error: unable to extract major/minor\n");
|
||||
return -1;
|
||||
@@ -435,37 +416,17 @@ static int dinfo_extract_dev(dev_t *dev, char *str, int readbuflen)
|
||||
|
||||
static int dinfo_get_dev_from_blockdev(char *blockdev, dev_t *dev)
|
||||
{
|
||||
FILE *dasddev;
|
||||
int offset = 0;
|
||||
char *devfile = NULL;
|
||||
char *readbuf = NULL;
|
||||
int readbuflen = READCHUNK;
|
||||
|
||||
if ((devfile = dinfo_malloc(readbuflen)) == NULL)
|
||||
return -1;
|
||||
|
||||
sprintf(devfile,"/sys/block/%s/dev", blockdev);
|
||||
|
||||
if ((readbuf = dinfo_malloc(readbuflen)) == NULL) {
|
||||
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
|
||||
if (!readbuf) {
|
||||
printf("Error: Not enough memory to allocate readbuffer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((dasddev = fopen(devfile,"r")) == NULL)
|
||||
if (util_file_read_line(readbuf, RD_BUFFER_SIZE,
|
||||
"/sys/block/%s/dev", blockdev) < 0)
|
||||
return -1;
|
||||
|
||||
while (fgets(readbuf + offset, READCHUNK, dasddev) &&
|
||||
readbuf[strlen(readbuf)-1] != '\n' ) {
|
||||
offset += READCHUNK-1;
|
||||
if (offset+READCHUNK-1 >= readbuflen) {
|
||||
readbuf = realloc(readbuf,
|
||||
readbuflen + READCHUNK-1);
|
||||
readbuflen += READCHUNK-1;
|
||||
}
|
||||
}
|
||||
fclose(dasddev);
|
||||
|
||||
if (dinfo_extract_dev(dev, readbuf, readbuflen) != 0)
|
||||
if (dinfo_extract_dev(dev, readbuf) != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
@@ -580,14 +541,11 @@ out2:
|
||||
static int dinfo_get_uid_from_devnode(char **uidfile, char *devnode)
|
||||
{
|
||||
struct stat stat_buffer;
|
||||
char stat_dev[READCHUNK];
|
||||
char sys_dev_path[READCHUNK];
|
||||
char stat_dev[RD_BUFFER_SIZE];
|
||||
char *readbuf;
|
||||
DIR *directory = NULL;
|
||||
struct dirent *dir_entry = NULL;
|
||||
FILE *block_dev;
|
||||
int readbuflen = READCHUNK;
|
||||
int offset;
|
||||
int rc = 0;
|
||||
|
||||
if (stat(devnode, &stat_buffer) != 0) {
|
||||
printf("Error: could not stat %s\n", devnode);
|
||||
@@ -602,33 +560,29 @@ static int dinfo_get_uid_from_devnode(char **uidfile, char *devnode)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((readbuf = dinfo_malloc(readbuflen)) == NULL) {
|
||||
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
|
||||
if (!readbuf) {
|
||||
printf("Error: Not enough memory to allocate readbuffer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((dir_entry = readdir(directory)) != NULL) {
|
||||
sprintf(sys_dev_path, "/sys/block/%s/dev", dir_entry->d_name);
|
||||
|
||||
if ((block_dev = fopen(sys_dev_path,"r")) == NULL)
|
||||
if (util_file_read_line(readbuf, RD_BUFFER_SIZE,
|
||||
"/sys/block/%s/dev",
|
||||
dir_entry->d_name) < 0)
|
||||
continue;
|
||||
|
||||
offset = 0;
|
||||
while (fgets(readbuf + offset, READCHUNK, block_dev) &&
|
||||
readbuf[strlen(readbuf)-1] != '\n' ) {
|
||||
offset += READCHUNK-1;
|
||||
if ( offset+READCHUNK-1 >= readbuflen ) {
|
||||
readbuf = realloc(readbuf,
|
||||
readbuflen + READCHUNK-1);
|
||||
readbuflen += READCHUNK-1;
|
||||
}
|
||||
}
|
||||
fclose(block_dev);
|
||||
|
||||
if (strncmp(stat_dev, readbuf,
|
||||
MAX(strlen(stat_dev), strlen(readbuf)-1)) == 0) {
|
||||
sprintf(*uidfile,"/sys/block/%s/device/uid",
|
||||
dir_entry->d_name);
|
||||
rc = snprintf(*uidfile, RD_BUFFER_SIZE,
|
||||
"/sys/block/%s/device/uid",
|
||||
dir_entry->d_name);
|
||||
if (rc >= RD_BUFFER_SIZE) {
|
||||
fprintf(stderr,
|
||||
"Error: Device name was truncated\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -644,7 +598,6 @@ int main(int argc, char * argv[])
|
||||
char *uidfile = NULL;
|
||||
char *device = NULL;
|
||||
char *readbuf = NULL;
|
||||
int readbuflen = READCHUNK;
|
||||
dev_t dev;
|
||||
int export = 0;
|
||||
int c;
|
||||
@@ -733,8 +686,9 @@ int main(int argc, char * argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (((readbuf = dinfo_malloc(readbuflen)) == NULL) ||
|
||||
((uidfile = dinfo_malloc(readbuflen)) == NULL))
|
||||
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
|
||||
uidfile = dinfo_malloc(RD_BUFFER_SIZE);
|
||||
if (!(readbuf && uidfile))
|
||||
exit(1);
|
||||
|
||||
/* try to read the uid attribute */
|
||||
@@ -753,7 +707,7 @@ int main(int argc, char * argv[])
|
||||
}
|
||||
|
||||
if (print_uid) {
|
||||
if (dinfo_read_dasd_uid(uidfile, readbuf, readbuflen) == 0) {
|
||||
if (dinfo_read_dasd_uid(uidfile, readbuf) == 0) {
|
||||
/* look for the 4th '.' and cut there */
|
||||
srchuid = readbuf - 1;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
@@ -762,24 +716,23 @@ int main(int argc, char * argv[])
|
||||
break;
|
||||
}
|
||||
if (srchuid) {
|
||||
srchuid[0] = '\n';
|
||||
srchuid[1] = 0;
|
||||
srchuid[0] = '\0';
|
||||
}
|
||||
if (export) {
|
||||
printf("ID_UID=%s",readbuf);
|
||||
printf("ID_UID=%s\n", readbuf);
|
||||
} else
|
||||
printf("%s",readbuf);
|
||||
printf("%s\n", readbuf);
|
||||
if (!print_vlabel && !print_extended_uid)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (print_extended_uid) {
|
||||
if (dinfo_read_dasd_uid(uidfile, readbuf, readbuflen) == 0) {
|
||||
if (dinfo_read_dasd_uid(uidfile, readbuf) == 0) {
|
||||
if (export) {
|
||||
printf("ID_XUID=%s",readbuf);
|
||||
printf("ID_XUID=%s\n", readbuf);
|
||||
} else
|
||||
printf("%s",readbuf);
|
||||
printf("%s\n", readbuf);
|
||||
if (!print_vlabel)
|
||||
goto out;
|
||||
}
|
||||
@@ -808,7 +761,8 @@ int main(int argc, char * argv[])
|
||||
goto error;
|
||||
|
||||
} else if (devnode) {
|
||||
if ((device = dinfo_malloc(readbuflen)) == NULL)
|
||||
device = dinfo_malloc(RD_BUFFER_SIZE);
|
||||
if (!device)
|
||||
exit(1);
|
||||
strcpy(device, devnode);
|
||||
}
|
||||
|
||||
16
etc/Makefile
Normal file
16
etc/Makefile
Normal file
@@ -0,0 +1,16 @@
|
||||
include ../common.mak
|
||||
|
||||
CONFIG_FILES =
|
||||
|
||||
ifneq (${SYSTEMDSYSTEMUNITDIR},)
|
||||
CONFIG_FILES += cpuplugd.conf sysconfig/cpi sysconfig/dumpconf \
|
||||
sysconfig/mon_fsstatd sysconfig/mon_procd
|
||||
endif
|
||||
|
||||
install:
|
||||
for file in $(CONFIG_FILES); do \
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) \
|
||||
-m 644 $$file $(DESTDIR)$(SYSCONFDIR)/$$file ; \
|
||||
done
|
||||
|
||||
.PHONY: all install clean
|
||||
@@ -4,6 +4,11 @@
|
||||
# The system and sysplex names consist of up to eight characters of
|
||||
# the following set: A-Z, 0-9, $, @, #, and blank.
|
||||
|
||||
#
|
||||
# CPI system type
|
||||
#
|
||||
CPI_SYSTEM_TYPE="LINUX"
|
||||
|
||||
#
|
||||
# CPI system name
|
||||
#
|
||||
|
||||
6
etc/udev/rules.d/90-cpi.rules
Normal file
6
etc/udev/rules.d/90-cpi.rules
Normal file
@@ -0,0 +1,6 @@
|
||||
#
|
||||
# Rules to trigger cpictl when KVM is used
|
||||
# This file should be installed in /etc/udev/rules.d
|
||||
#
|
||||
|
||||
SUBSYSTEM=="misc", KERNEL=="kvm", ENV{CREATED}=="1", ENV{EVENT}=="create", RUN+="/lib/s390-tools/cpictl -b kvm"
|
||||
@@ -308,7 +308,7 @@ static void fdasd_cleanup(fdasd_anchor_t *anchor)
|
||||
/*
|
||||
* Exit fdasd.
|
||||
*/
|
||||
static void fdasd_exit(fdasd_anchor_t *anchor, int rc)
|
||||
static void __noreturn fdasd_exit(fdasd_anchor_t *anchor, int rc)
|
||||
{
|
||||
fdasd_cleanup(anchor);
|
||||
exit(rc);
|
||||
@@ -921,7 +921,7 @@ static void fdasd_verify_device(fdasd_anchor_t *anc, char *name)
|
||||
fdasd_error(anc, device_verification_failed, err_str);
|
||||
}
|
||||
|
||||
if (minor(dst.st_rdev) & PARTN_MASK) {
|
||||
if (!anc->force_virtual && minor(dst.st_rdev) & PARTN_MASK) {
|
||||
snprintf(err_str, ERROR_STRING_SIZE,
|
||||
"Partition '%s' (%d/%d) detected where device is "
|
||||
"required\n", name,
|
||||
|
||||
@@ -348,7 +348,7 @@ void hyptop_text_mode(void)
|
||||
/*
|
||||
* Exit hyptop
|
||||
*/
|
||||
void hyptop_exit(int rc)
|
||||
void __noreturn hyptop_exit(int rc)
|
||||
{
|
||||
hyptop_text_mode();
|
||||
exit(rc);
|
||||
|
||||
@@ -216,7 +216,7 @@ extern void win_cpu_types_init(void);
|
||||
* Misc functions
|
||||
*/
|
||||
extern void hyptop_update_term(void);
|
||||
extern void hyptop_exit(int rc);
|
||||
extern void __noreturn hyptop_exit(int rc);
|
||||
extern void hyptop_text_mode(void);
|
||||
|
||||
#endif /* HYPTOP_H */
|
||||
|
||||
@@ -20,5 +20,6 @@ bool util_path_is_readable(const char *fmt, ...);
|
||||
bool util_path_is_writable(const char *fmt, ...);
|
||||
bool util_path_is_dir(const char *fmt, ...);
|
||||
bool util_path_is_reg_file(const char *fmt, ...);
|
||||
bool util_path_exists(const char *fmt, ...);
|
||||
|
||||
#endif /** LIB_UTIL_PATH_H @} */
|
||||
|
||||
@@ -18,12 +18,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Copyright IBM Corp. 2016, 2017
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
struct util_prg_copyright {
|
||||
/** Name of the copyright owner, e.g. IBM */
|
||||
const char *owner;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define RELEASE_STRING STRINGIFY (S390_TOOLS_RELEASE)
|
||||
#define TOOLS_LIBDIR STRINGIFY (S390_TOOLS_LIBDIR)
|
||||
#define TOOLS_SYSCONFDIR STRINGIFY (S390_TOOLS_SYSCONFDIR)
|
||||
#define TOOLS_BINDIR STRINGIFY (S390_TOOLS_BINDIR)
|
||||
|
||||
#define __noreturn __attribute__((noreturn))
|
||||
#define __packed __attribute__((packed))
|
||||
|
||||
@@ -97,7 +97,7 @@ static struct locals {
|
||||
enum reipl_type reipl_type; /* CCW, FCP, NSS */
|
||||
} l;
|
||||
|
||||
static void print_usage_chreipl_exit(void)
|
||||
static void __noreturn print_usage_chreipl_exit(void)
|
||||
{
|
||||
printf(usage_chreipl, g.prog_name);
|
||||
exit(0);
|
||||
|
||||
@@ -34,7 +34,7 @@ static const char *const usage_chshut =
|
||||
" -h, --help Print this help, then exit\n"
|
||||
" -v, --version Print version information, then exit\n";
|
||||
|
||||
static void print_usage_chshut_exit(void)
|
||||
static void __noreturn print_usage_chshut_exit(void)
|
||||
{
|
||||
printf(usage_chshut, g.prog_name);
|
||||
exit(0);
|
||||
|
||||
@@ -25,7 +25,7 @@ static const char *const usage_lsreipl =
|
||||
" -h, --help Print this help, then exit\n"
|
||||
" -v, --version Print version information, then exit\n";
|
||||
|
||||
static void print_usage_lsreipl_exit(void)
|
||||
static void __noreturn print_usage_lsreipl_exit(void)
|
||||
{
|
||||
printf(usage_lsreipl, g.prog_name);
|
||||
exit(0);
|
||||
|
||||
@@ -20,7 +20,7 @@ static const char *const usage_lsshut =
|
||||
" -h, --help Print this help, then exit\n"
|
||||
" -v, --version Print version information, then exit\n";
|
||||
|
||||
static void print_usage_lsshut_exit(void)
|
||||
static __noreturn void print_usage_lsshut_exit(void)
|
||||
{
|
||||
printf(usage_lsshut, g.prog_name);
|
||||
exit(0);
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#define IPL_TYPE_LEN_MAX 100
|
||||
#define NSS_NAME_LEN_MAX 8
|
||||
|
||||
@@ -57,8 +59,8 @@ extern void read_str(char *string, const char *file, size_t len);
|
||||
extern void read_fw_str(char *string, const char *file, size_t len);
|
||||
extern void print_fw_str(const char *fmt, const char *dir, const char *file);
|
||||
|
||||
extern void print_version_exit(void);
|
||||
extern void print_help_hint_exit(void);
|
||||
extern void __noreturn print_version_exit(void);
|
||||
extern void __noreturn print_help_hint_exit(void);
|
||||
|
||||
/*
|
||||
* FCP
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
|
||||
struct globals g;
|
||||
|
||||
void print_help_hint_exit(void)
|
||||
void __noreturn print_help_hint_exit(void)
|
||||
{
|
||||
fprintf(stderr, "Try '%s' --help' for more information.\n",
|
||||
g.prog_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void print_version_exit(void)
|
||||
void __noreturn print_version_exit(void)
|
||||
{
|
||||
printf("%s: Linux on System z shutdown actions version %s\n",
|
||||
g.prog_name, RELEASE_STRING);
|
||||
|
||||
@@ -15,7 +15,7 @@ SYSTOOLS = ttyrun
|
||||
|
||||
all: $(PROGRAMS) $(SYSTOOLS)
|
||||
check:
|
||||
install:
|
||||
install: all
|
||||
for prg in $(PROGRAMS); do \
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 $$prg $(DESTDIR)$(USRBINDIR) ; \
|
||||
done
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -71,8 +72,8 @@ static const struct tool_info iucv_tool[2] = {
|
||||
};
|
||||
|
||||
|
||||
static void usage_exit(const struct tool_info *prg, int is_error,
|
||||
const char *msg)
|
||||
static void __noreturn usage_exit(const struct tool_info *prg, int is_error,
|
||||
const char *msg)
|
||||
{
|
||||
if (msg != NULL)
|
||||
fprintf(stderr, _("%s: %s\n"), prg->name, msg);
|
||||
@@ -80,7 +81,7 @@ static void usage_exit(const struct tool_info *prg, int is_error,
|
||||
exit(is_error ? 1 : 0); /* rc=1 .. invalid args */
|
||||
}
|
||||
|
||||
static void version_exit(const struct tool_info *prg)
|
||||
static void __noreturn version_exit(const struct tool_info *prg)
|
||||
{
|
||||
printf(_("%s: IUCV Terminal Applications, version %s\n"),
|
||||
prg->name, RELEASE_STRING);
|
||||
|
||||
@@ -62,13 +62,13 @@ static const char usage[] =
|
||||
"-h, --help Displays this help, then exits.\n"
|
||||
"-v, --version Displays version information, then exits.\n";
|
||||
|
||||
static void help_exit(const char *prg)
|
||||
static void __noreturn help_exit(const char *prg)
|
||||
{
|
||||
printf(usage, prg, prg);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void version_exit(const char *prg)
|
||||
static void __noreturn version_exit(const char *prg)
|
||||
{
|
||||
printf("%s: Start a program if a terminal device is available, "
|
||||
"version %s\n", prg, RELEASE_STRING);
|
||||
|
||||
@@ -28,17 +28,17 @@ objects = util_base.o \
|
||||
util_proc.o \
|
||||
util_rec.o
|
||||
|
||||
util_base_example: util_base_example.o $(rootdir)/libutil/libutil.a
|
||||
util_panic_example: util_panic_example.o $(rootdir)/libutil/libutil.a
|
||||
util_path_example: util_path_example.o $(rootdir)/libutil/libutil.a
|
||||
util_scandir_example: util_scandir_example.o $(rootdir)/libutil/libutil.a
|
||||
util_file_example: util_file_example.o $(rootdir)/libutil/libutil.a
|
||||
util_libc_example: util_libc_example.o $(rootdir)/libutil/libutil.a
|
||||
util_opt_example: util_opt_example.o $(rootdir)/libutil/libutil.a
|
||||
util_opt_command_example: util_opt_command_example.o $(rootdir)/libutil/libutil.a
|
||||
util_panic_example: util_panic_example.o $(rootdir)/libutil/libutil.a
|
||||
util_prg_example: util_prg_example.o $(rootdir)/libutil/libutil.a
|
||||
util_rec_example: util_rec_example.o $(rootdir)/libutil/libutil.a
|
||||
util_base_example: util_base_example.o $(lib)
|
||||
util_panic_example: util_panic_example.o $(lib)
|
||||
util_path_example: util_path_example.o $(lib)
|
||||
util_scandir_example: util_scandir_example.o $(lib)
|
||||
util_file_example: util_file_example.o $(lib)
|
||||
util_libc_example: util_libc_example.o $(lib)
|
||||
util_opt_example: util_opt_example.o $(lib)
|
||||
util_opt_command_example: util_opt_command_example.o $(lib)
|
||||
util_panic_example: util_panic_example.o $(lib)
|
||||
util_prg_example: util_prg_example.o $(lib)
|
||||
util_rec_example: util_rec_example.o $(lib)
|
||||
|
||||
$(lib): $(objects)
|
||||
|
||||
|
||||
@@ -194,3 +194,26 @@ free_str:
|
||||
free(path);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if path to directory or file exists
|
||||
*
|
||||
* This function has the same semantics as "-e path" in bash.
|
||||
*
|
||||
* @param[in] fmt Format string for path to test
|
||||
* @param[in] ... Variable arguments for format string
|
||||
*
|
||||
* @returns true Path exists
|
||||
* false Otherwise
|
||||
*/
|
||||
bool util_path_exists(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *path;
|
||||
bool rc;
|
||||
|
||||
UTIL_VASPRINTF(&path, fmt, ap);
|
||||
rc = access(path, F_OK) == 0 ? true : false;
|
||||
free(path);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -55,18 +55,22 @@ static void test_util_path_sysfs(void)
|
||||
static void test_path(const char *path)
|
||||
{
|
||||
printf("%-20s: ", path);
|
||||
if (util_path_exists(path))
|
||||
printf("exists=yes ");
|
||||
else
|
||||
printf("exists=no ");
|
||||
if (util_path_is_readable(path))
|
||||
printf("read=yes, ");
|
||||
printf("read=yes ");
|
||||
else
|
||||
printf("read=no , ");
|
||||
printf("read=no ");
|
||||
if (util_path_is_writable(path))
|
||||
printf("write=yes, ");
|
||||
printf("write=yes ");
|
||||
else
|
||||
printf("write=no , ");
|
||||
printf("write=no ");
|
||||
if (util_path_is_reg_file(path))
|
||||
printf("reg_file=yes");
|
||||
printf("reg_file=yes ");
|
||||
else
|
||||
printf("reg_file=no ");
|
||||
printf("reg_file=no ");
|
||||
if (util_path_is_dir(path))
|
||||
printf("dir=yes");
|
||||
else
|
||||
|
||||
@@ -90,17 +90,18 @@ static void fsstatd_open_monwriter(void)
|
||||
/*
|
||||
* Store daemon's pid so it can be stopped
|
||||
*/
|
||||
static void store_pid(void)
|
||||
static int store_pid(void)
|
||||
{
|
||||
FILE *f = fopen(pid_file, "w");
|
||||
|
||||
if (!f) {
|
||||
syslog(LOG_ERR, "cannot open pid file %s: %s", pid_file,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
fprintf(f, "%d\n", getpid());
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -244,41 +245,64 @@ static void fsstatd_write_ent(struct mntent *ent, time_t curr_time,
|
||||
*/
|
||||
static void fsstatd_daemonize(void)
|
||||
{
|
||||
int pipe_fds[2], startup_rc = 1;
|
||||
pid_t pid;
|
||||
|
||||
if (pipe(pipe_fds) == -1) {
|
||||
syslog(LOG_ERR, "pipe error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Fork off the parent process */
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
syslog(LOG_ERR, "fork error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (pid > 0)
|
||||
exit(0);
|
||||
if (pid > 0) {
|
||||
/* Wait for startup return code from daemon */
|
||||
if (read(pipe_fds[0], &startup_rc, sizeof(startup_rc)) == -1)
|
||||
syslog(LOG_ERR, "pipe read error: %s\n", strerror(errno));
|
||||
/* With startup_rc == 0, pid file was written at this point */
|
||||
exit(startup_rc);
|
||||
}
|
||||
|
||||
/* Change the file mode mask */
|
||||
umask(0);
|
||||
|
||||
/* Store daemon pid */
|
||||
store_pid();
|
||||
/* Catch SIGINT and SIGTERM to clean up pid file on exit */
|
||||
fsstatd_handle_signals();
|
||||
|
||||
/* Create a new SID for the child process */
|
||||
if (setsid() < 0) {
|
||||
syslog(LOG_ERR, "setsid error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
goto notify_parent;
|
||||
}
|
||||
|
||||
/* Change the current working directory */
|
||||
if (chdir("/") < 0) {
|
||||
syslog(LOG_ERR, "chdir error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
goto notify_parent;
|
||||
}
|
||||
|
||||
/* Close out the standard file descriptors */
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
|
||||
/* Store daemon pid */
|
||||
if (store_pid() < 0)
|
||||
goto notify_parent;
|
||||
startup_rc = 0;
|
||||
|
||||
notify_parent:
|
||||
/* Inform waiting parent about startup return code */
|
||||
if (write(pipe_fds[1], &startup_rc, sizeof(startup_rc)) == -1) {
|
||||
syslog(LOG_ERR, "pipe write error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (startup_rc != 0)
|
||||
exit(startup_rc);
|
||||
}
|
||||
|
||||
static int fsstatd_do_work(void)
|
||||
|
||||
@@ -109,17 +109,18 @@ static void procd_open_monwriter(void)
|
||||
/*
|
||||
* Store daemon's pid so it can be stopped
|
||||
*/
|
||||
static void store_pid(void)
|
||||
static int store_pid(void)
|
||||
{
|
||||
FILE *f = fopen(pid_file, "w");
|
||||
|
||||
if (!f) {
|
||||
syslog(LOG_ERR, "cannot open pid file %s: %s", pid_file,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
fprintf(f, "%d\n", getpid());
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -897,41 +898,64 @@ static void read_tasks(void)
|
||||
*/
|
||||
static void procd_daemonize(void)
|
||||
{
|
||||
int pipe_fds[2], startup_rc = 1;
|
||||
pid_t pid;
|
||||
|
||||
if (pipe(pipe_fds) == -1) {
|
||||
syslog(LOG_ERR, "pipe error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Fork off the parent process */
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
syslog(LOG_ERR, "fork error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (pid > 0)
|
||||
exit(0);
|
||||
if (pid > 0) {
|
||||
/* Wait for startup return code from daemon */
|
||||
if (read(pipe_fds[0], &startup_rc, sizeof(startup_rc)) == -1)
|
||||
syslog(LOG_ERR, "pipe read error: %s\n", strerror(errno));
|
||||
/* With startup_rc == 0, pid file was written at this point */
|
||||
exit(startup_rc);
|
||||
}
|
||||
|
||||
/* Change the file mode mask */
|
||||
umask(0);
|
||||
|
||||
/* Store daemon pid */
|
||||
store_pid();
|
||||
/* Catch SIGINT and SIGTERM to clean up pid file on exit */
|
||||
procd_handle_signals();
|
||||
|
||||
/* Create a new SID for the child process */
|
||||
if (setsid() < 0) {
|
||||
syslog(LOG_ERR, "setsid error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
goto notify_parent;
|
||||
}
|
||||
|
||||
/* Change the current working directory */
|
||||
if (chdir("/") < 0) {
|
||||
syslog(LOG_ERR, "chdir error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
goto notify_parent;
|
||||
}
|
||||
|
||||
/* Close out the standard file descriptors */
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
|
||||
/* Store daemon pid */
|
||||
if (store_pid() < 0)
|
||||
goto notify_parent;
|
||||
startup_rc = 0;
|
||||
|
||||
notify_parent:
|
||||
/* Inform waiting parent about startup return code */
|
||||
if (write(pipe_fds[1], &startup_rc, sizeof(startup_rc)) == -1) {
|
||||
syslog(LOG_ERR, "pipe write error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (startup_rc != 0)
|
||||
exit(startup_rc);
|
||||
}
|
||||
|
||||
static int procd_do_work(void)
|
||||
|
||||
21
netboot/Dockerfile
Normal file
21
netboot/Dockerfile
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# Sample Dockerfile to build PXE-style boot image for KVM on s390
|
||||
#
|
||||
|
||||
FROM s390x/ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
linux-image-4.4.0-78-generic \
|
||||
make \
|
||||
wget \
|
||||
bzip2 \
|
||||
linux-headers-4.4.0-78-generic \
|
||||
gcc \
|
||||
kexec-tools \
|
||||
file
|
||||
|
||||
RUN mkdir /netboot
|
||||
|
||||
COPY . /netboot
|
||||
|
||||
RUN cd /netboot && make -f Makefile.pxelinux.0 KERNEL_VERSION=4.4.0-78-generic
|
||||
16
netboot/Makefile
Normal file
16
netboot/Makefile
Normal file
@@ -0,0 +1,16 @@
|
||||
# Install the netboot image build scripts as samples
|
||||
|
||||
include ../common.mak
|
||||
|
||||
NETBOOT_SAMPLEDIR=$(TOOLS_DATADIR)/netboot
|
||||
|
||||
all:
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR)
|
||||
$(INSTALL) -m 755 mk-s390image mk-pxelinux-ramfs \
|
||||
$(DESTDIR)$(NETBOOT_SAMPLEDIR)
|
||||
$(INSTALL) -m 644 Dockerfile Makefile.pxelinux.0 README.md \
|
||||
$(DESTDIR)$(NETBOOT_SAMPLEDIR)
|
||||
|
||||
.PHONY: all install clean
|
||||
46
netboot/Makefile.pxelinux.0
Normal file
46
netboot/Makefile.pxelinux.0
Normal file
@@ -0,0 +1,46 @@
|
||||
# Sample Makefile to produce a pxe-style netboot image
|
||||
# matching the currently active kernel.
|
||||
# If the image is to be build for a different kernel version
|
||||
# the KERNEL_VERSION variable must be overridden
|
||||
# To use a local busybox installation, change BBINSTALL
|
||||
# to point to the local busybox install path
|
||||
|
||||
ifeq ("$(KERNEL_VERSION)","")
|
||||
KERNEL_VERSION=$(shell uname -r)
|
||||
endif
|
||||
export KERNEL_VERSION
|
||||
|
||||
filetype=$(shell file $1 | grep "Linux S390")
|
||||
s390_check=$(if $(call filetype,$1), $1)
|
||||
prefixes=image vmlinux vmlinuz
|
||||
kernel_images=$(foreach prefix, $(prefixes), \
|
||||
$(call s390_check,/boot/$(prefix)-$(KERNEL_VERSION)))
|
||||
KERNEL_IMAGE=$(firstword $(kernel_images))
|
||||
|
||||
ifeq ($(KERNEL_IMAGE),)
|
||||
$(error Could not find a kernel image under /boot)
|
||||
endif
|
||||
|
||||
BUSYBOX=busybox-1.27.1
|
||||
BBINSTALL=$(BUSYBOX)/_install
|
||||
|
||||
all: $(KERNEL_IMAGE) pxelinux.initramfs
|
||||
/bin/bash mk-s390image $(KERNEL_IMAGE) pxelinux.0 -r pxelinux.initramfs
|
||||
|
||||
pxelinux.initramfs: $(BBINSTALL)
|
||||
/bin/bash mk-pxelinux-ramfs -b $< -k $(KERNEL_VERSION) $@
|
||||
|
||||
$(BUSYBOX)/_install:
|
||||
wget https://busybox.net/downloads/$(BUSYBOX).tar.bz2
|
||||
tar xjf $(BUSYBOX).tar.bz2
|
||||
make -C $(BUSYBOX) defconfig
|
||||
make -C $(BUSYBOX) install
|
||||
|
||||
install:
|
||||
|
||||
clean:
|
||||
$(RM) pxelinux.0 pxelinux.initramfs $(BUSYBOX).tar.bz2
|
||||
$(RM) -r $(BUSYBOX)
|
||||
|
||||
.PHONY: all install clean
|
||||
|
||||
99
netboot/README.md
Normal file
99
netboot/README.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# How to build a PXELINUX-style network boot image for KVM
|
||||
|
||||
## Synopsis
|
||||
|
||||
To build a PXELINUX-style netboot image usable for KVM a s390 Linux system
|
||||
with access to the internet is required.
|
||||
|
||||
Running the following command will generate the netboot image pxlinux.0:
|
||||
|
||||
` $ make -f Makefile.pxelinux.0`
|
||||
|
||||
Alternatively you can use docker to build the image:
|
||||
|
||||
```
|
||||
$ docker build -t pxelinux0 .
|
||||
$ docker run --rm -v $(pwd):/out pxelinux0 cp /netboot/pxelinux.0 /out
|
||||
$ docker rmi pxelinux0
|
||||
```
|
||||
|
||||
The resulting file pxelinux.0 must be copied to the system acting as
|
||||
DHCP/BOOTP server for the KVM installation.
|
||||
|
||||
## Full Description
|
||||
|
||||
Starting with QEMU 2.10 it is possible to boot s390 virtual machines over a
|
||||
network interface using DHCP. As usual for DHCP/BOOTP a single bootable image
|
||||
is copied from the boot server, loaded into memory and booted. In order to
|
||||
boot a Linux Operating System, it is typically necessary to load a kernel
|
||||
together with an initial ramdisk (initramfs) and optionally specify some kernel
|
||||
command line parameters.
|
||||
|
||||
Alternatively, on s390 it is possible to load a single file consisting of
|
||||
the kernel image followed by an initial ramdisk. Such single boot images can
|
||||
be provided by a Linux distributor, e.g. on the installation media.
|
||||
|
||||
Single boot images can also easily be built from pre-existing kernel/initramfs
|
||||
pairs by concatenating these files. In order to allow the kernel to find the
|
||||
ramdisk, it is necessary to update the 8 bytes at location 0x10408 with the
|
||||
offset value of the ramdisk in the new binary, and the 8 bytes at location
|
||||
0x10410 with the size of the ramdisk. Both values need to be updated in binary,
|
||||
big endian format.
|
||||
|
||||
Since PXELINUX, the PXE boot implementation provided by the Syslinux project,
|
||||
has introduced a popular way to set up network boot servers for Linux, it
|
||||
is desirable that s390 network boot setups can be done in a similar way.
|
||||
A boot image simulating a PXELINUX-like boot for s390 can be easily
|
||||
constructed by combining a Linux kernel with a small fit-to-purpose initial
|
||||
ramdisk as described above. For practical purposes, using the host kernel is
|
||||
a reasonable way for this kind of approach. If possible, the initial ramdisk
|
||||
should be independent of the host, which is not always possible, as the kernel
|
||||
might require modules for e.g. virtio network and block devices.
|
||||
|
||||
### Example: Building a PXELINUX-style boot image
|
||||
|
||||
The approach described below consists of bundling some shell scripts, busybox
|
||||
and the kexec binary bundled into the initial ramdisk.
|
||||
|
||||
The init process can be a simple shell script that will mount a few essential
|
||||
file systems, like /dev, /proc, and /sys, start a DHCP client (e.g. busybox's
|
||||
udchpc) and then invoke another script to perform the network boot.
|
||||
udchpc will invoke the script /usr/share/udhcpc/default.script in response
|
||||
to DHCP server messages to perform configuration actions.
|
||||
The sample default.script delivered with busybox can be used for that purpose,
|
||||
but needs to be extended to evaluate the bootp specific DHCP options (most
|
||||
important the tftp server address) and store them for use by the boot script.
|
||||
|
||||
The boot script itself has to retrieve the PXELINUX configuration from the
|
||||
tftp server according to the rules described [here][1] then retrieve the
|
||||
remote kernel and initial ramdisk and finally use kexec to boot the network
|
||||
kernel.
|
||||
|
||||
In essence, the following steps are performed to produce the initial
|
||||
ramdisk:
|
||||
|
||||
1. Create a skeleton initramfs directory structure
|
||||
2. Create the init script, the boot script and the DHCP default script
|
||||
3. Copy kexec and it's dependencies from the host into the initramfs
|
||||
4. Copy virtio network and block modules of the host's active kernel into
|
||||
the initramfs
|
||||
5. Copy the busybox binaries into the initramfs.
|
||||
6. Copy the DHCP configuration and PXE boot scripts to the initramfs
|
||||
7. Build the ramdisk (in compressed CPIO format)
|
||||
8. Concatenate the kernel image and the initial ramdisk, and adjust the
|
||||
ramdisk offset as described above.
|
||||
|
||||
Steps 1 to 7 are performed by the sample script mk-pxelinux-ramfs, while step
|
||||
8 is done with the help of mk-s390image.
|
||||
|
||||
The binary resulting from the procedure described above can now be deployed
|
||||
to a DHCP/BOOTP server. This server should also act as a TFTP server for the
|
||||
PXELINUX configuration and binary files needed to complete the network boot.
|
||||
|
||||
Alternatively, it is possible to use programs like [petitboot][2] or
|
||||
[pxe-kexec][3] in the initial ramdisk, as these provide more sophisticated
|
||||
and robust processing of PXELINUX-style configurations.
|
||||
|
||||
[1]: http://www.syslinux.org/wiki/index.php?title=PXELINUX
|
||||
[2]: https://github.com/open-power/petitboot
|
||||
[3]: https://sourceforge.net/projects/pxe-kexec.berlios/
|
||||
410
netboot/mk-pxelinux-ramfs
Executable file
410
netboot/mk-pxelinux-ramfs
Executable file
@@ -0,0 +1,410 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# netboot - PXE-style boot for KVM on s390
|
||||
#
|
||||
# Sample script to build an initramfs image suitable for performing a
|
||||
# PXELINUX-style boot for KVM guests from a DHCP/BOOTP Server.
|
||||
# Has to be executed on the KVM host where it will be deployed and needs
|
||||
# to be re-run after kernel updates on the host, unless the virtio
|
||||
# drivers are statically built into the host kernel.
|
||||
#
|
||||
# The script requires a busybox install tree, e.g. resulting from a build
|
||||
# from source, after make defconfig && make install
|
||||
#
|
||||
# To keep things simple, we don't include udev but use devtmpfs
|
||||
# which means the host kernel must have been built with CONFIG_DEVTMPFS=y
|
||||
#
|
||||
# Sample invocation:
|
||||
#
|
||||
# ./mk-pxelinux-ramfs -b /downloads/busyboxdir pxelinux.initramfs
|
||||
#
|
||||
# Copyright IBM Corp. 2017
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
# Variables
|
||||
cmd=$(basename $0)
|
||||
busyboxdir=
|
||||
builddir=
|
||||
initramfs=
|
||||
success=no
|
||||
|
||||
# Cleanup on exit
|
||||
cleanup()
|
||||
{
|
||||
if [ -n $builddir ]
|
||||
then
|
||||
rm -rf $builddir
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Usage
|
||||
usage()
|
||||
{
|
||||
cat <<-EOF
|
||||
Usage: $cmd -b BUSYBOX_DIR [-k KERNEL_VERSION] INITRAMFS_FILE
|
||||
|
||||
Build a PXELINUX style boot initramfs INITRAMFS_FILE using a busybox installed
|
||||
in BUSYBOX_DIR and kernel modules from the currently running kernel or from
|
||||
the kernel version specified with the '-k KERNEL_VERSION' option.
|
||||
|
||||
OPTIONS
|
||||
-b Search installed busybox in directory BUSYBOX_DIR
|
||||
-k Use KERNEL_VERSION instead of currently running kernel
|
||||
-h Print this help, then exit
|
||||
EOF
|
||||
}
|
||||
|
||||
# Get shared objects for binary
|
||||
sharedobjs()
|
||||
{
|
||||
ldd $1 | sed -e 's?[^/]*??' -e 's/(.*)//'
|
||||
}
|
||||
|
||||
# Check args
|
||||
args=$(getopt b:k:h $*)
|
||||
if [ $? = 0 ]
|
||||
then
|
||||
set -- $args
|
||||
while [ -n $1 ]
|
||||
do
|
||||
case $1 in
|
||||
-b) busyboxdir=$2; shift 2;;
|
||||
-k) kernelversion=$2; shift 2;;
|
||||
-h) usage; exit 0;;
|
||||
--) shift; break;;
|
||||
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if [ $# != 1 -o "$busyboxdir" = "" ]
|
||||
then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Full output file path
|
||||
initramfs=$(readlink -m $(dirname $1))/$(basename $1)
|
||||
|
||||
# Exit on error
|
||||
set -e
|
||||
|
||||
# Module locations
|
||||
if [ -n $kernelversion ]; then
|
||||
moddir=/lib/modules/$kernelversion
|
||||
else
|
||||
moddir=/lib/modules/$(uname -r)
|
||||
fi
|
||||
netdir=$moddir/kernel/drivers/net
|
||||
blkdir=$moddir/kernel/drivers/block
|
||||
|
||||
# Setup build directory
|
||||
builddir=$(mktemp -d)
|
||||
echo "$cmd: Building in $builddir"
|
||||
|
||||
ramfsdirs="/bin /dev /etc /lib64 /lib /mnt /proc /run /sbin /sys /tmp /usr /var"
|
||||
for d in $ramfsdirs
|
||||
do
|
||||
mkdir -p $builddir/$d
|
||||
done
|
||||
|
||||
# Kexec
|
||||
echo "$cmd: Copying kexec"
|
||||
|
||||
# Install both binary and required shared libraries
|
||||
OLDPATH=$PATH
|
||||
PATH=$OLDPATH:/sbin:/usr/sbin
|
||||
kexec_bin=$(which kexec)
|
||||
kexec_sos=$(sharedobjs $kexec_bin)
|
||||
PATH=$OLDPATH
|
||||
|
||||
cp $kexec_bin $builddir/sbin
|
||||
for so in $kexec_sos
|
||||
do
|
||||
mkdir -p $builddir/$(dirname $so)
|
||||
cp $so $builddir/$(dirname $so)
|
||||
done
|
||||
|
||||
# virtio module(s), if present
|
||||
echo "$cmd: Copying virtio modules"
|
||||
|
||||
mkdir -p $builddir/$netdir
|
||||
mkdir -p $builddir/$blkdir
|
||||
set +e
|
||||
cp $netdir/virtio_net.ko $builddir/$netdir 2> /dev/null
|
||||
cp $blkdir/virtio_blk.ko $builddir/$blkdir 2> /dev/null
|
||||
set -e
|
||||
|
||||
# Busybox (+ dependencies)
|
||||
echo "$cmd: Copying busybox files"
|
||||
|
||||
cp -a $busyboxdir/* $builddir
|
||||
busybox_sos=$(sharedobjs $busyboxdir/bin/busybox)
|
||||
for so in $busybox_sos
|
||||
do
|
||||
mkdir -p $builddir/$(dirname $so)
|
||||
cp $so $builddir/$(dirname $so)
|
||||
done
|
||||
|
||||
# ad_packet module(s), if present
|
||||
echo "$cmd: Copying af_packet modules"
|
||||
|
||||
packetdir=$moddir/kernel/net/packet
|
||||
mkdir -p $builddir/$packetdir
|
||||
set +e
|
||||
cp $packetdir/* $builddir/$packetdir 2> /dev/null
|
||||
set -e
|
||||
|
||||
# Init script
|
||||
echo "$cmd: Making init script"
|
||||
|
||||
# --- begin init script
|
||||
cat <<'EOF' > $builddir/init
|
||||
#!/bin/sh
|
||||
/bin/mount -t devtmpfs none /dev
|
||||
/bin/mount -t proc none /proc
|
||||
/bin/mount -t sysfs none /sys
|
||||
/bin/mount -t tmpfs none /run
|
||||
|
||||
/sbin/modprobe virtio_net
|
||||
/sbin/udhcpc -O pxeconffile -O pxepathprefix &
|
||||
|
||||
/sbin/pxeboot.script
|
||||
EOF
|
||||
# --- end init script
|
||||
chmod +x $builddir/init
|
||||
|
||||
# udhcpc script
|
||||
echo "$cmd: Making DHCP script"
|
||||
|
||||
mkdir -p $builddir/usr/share/udhcpc
|
||||
# -- begin dhcp script
|
||||
cat <<'EOF' > $builddir/usr/share/udhcpc/default.script
|
||||
#!/bin/sh
|
||||
# Setup name resolution and PXE boot configuration
|
||||
# called by udhcpc
|
||||
|
||||
RESOLVCONF="/etc/resolv.conf"
|
||||
PXECONF="/etc/pxe.conf"
|
||||
|
||||
ccidr()
|
||||
{
|
||||
# clumsy netmask to cidr transformation
|
||||
# with minimal sanity checking
|
||||
OLDIFS=$IFS
|
||||
IFS=.
|
||||
c=0
|
||||
n=4
|
||||
for i in $1
|
||||
do
|
||||
n=$(/usr/bin/expr $n - 1)
|
||||
case $i in
|
||||
255) c=$(/usr/bin/expr $c + 8);;
|
||||
254) c=$(/usr/bin/expr $c + 7); break;;
|
||||
252) c=$(/usr/bin/expr $c + 6); break;;
|
||||
248) c=$(/usr/bin/expr $c + 5); break;;
|
||||
240) c=$(/usr/bin/expr $c + 4); break;;
|
||||
224) c=$(/usr/bin/expr $c + 3); break;;
|
||||
192) c=$(/usr/bin/expr $c + 2); break;;
|
||||
128) c=$(/usr/bin/expr $c + 1); break;;
|
||||
0) break;;
|
||||
*) c=0; break;;
|
||||
esac
|
||||
if [ $n = 0 ]
|
||||
then
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS=$OLDIFS
|
||||
echo $c
|
||||
}
|
||||
|
||||
echo "DHCP response $1: "
|
||||
case "$1" in
|
||||
deconfig)
|
||||
echo " interface: $interface"
|
||||
/sbin/ip route flush table all
|
||||
/sbin/ip addr flush $interface
|
||||
/sbin/ip link set $interface up
|
||||
/bin/rm -f $PXECONF $RESOLVCONF
|
||||
;;
|
||||
|
||||
renew|bound)
|
||||
echo " interface: $interface $ip $subnet"
|
||||
echo " router: $router"
|
||||
echo " domain: $domain $dns"
|
||||
echo " tftp: $siaddr"
|
||||
# flush routes
|
||||
/sbin/ip route flush table all
|
||||
# setup if link
|
||||
/sbin/ip addr flush $interface
|
||||
/sbin/ip link set $interface up
|
||||
# setup if addr
|
||||
if [ -n "$subnet" ]
|
||||
then
|
||||
maskedip="$ip"/$(ccidr $subnet)
|
||||
else
|
||||
maskedip="ip"
|
||||
fi
|
||||
/sbin/ip addr add $maskedip broadcast $broadcast dev $interface
|
||||
# setup default routes
|
||||
if [ -n "$router" ]
|
||||
then
|
||||
/sbin/ip route add default via $router
|
||||
fi
|
||||
|
||||
# setup resolv.conf
|
||||
if [ -n "$domain" ]
|
||||
then
|
||||
echo "search $domain" > $RESOLVCONF
|
||||
for i in $dns
|
||||
do
|
||||
echo " nameserver $i" >> $RESOLVCONF
|
||||
done
|
||||
fi
|
||||
|
||||
# pxe control
|
||||
if [ -n "$siaddr" ]
|
||||
then
|
||||
echo "siaddr=$siaddr" > $PXECONF
|
||||
echo "interface=$interface" >> $PXECONF
|
||||
echo "ip=$ip" >> $PXECONF
|
||||
fi
|
||||
;;
|
||||
|
||||
nak)
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
EOF
|
||||
# -- end dhcp script
|
||||
chmod +x $builddir/usr/share/udhcpc/default.script
|
||||
|
||||
# pxeboot script
|
||||
echo "$cmd: Making PXE boot script"
|
||||
|
||||
# -- begin pxeboot script
|
||||
cat <<'EOF' > $builddir/sbin/pxeboot.script
|
||||
#!/bin/sh
|
||||
# Perform a PXE style boot using kexec
|
||||
# Supports only super-simple config files
|
||||
|
||||
set -e
|
||||
|
||||
# Check if a valid pxe conf is available
|
||||
# so far a non configurable 600 sec timeout
|
||||
PXE_CONF=/etc/pxe.conf
|
||||
TIMEOUT=600
|
||||
WAITED=0
|
||||
echo "waiting for pxe config from DHCP (max $TIMEOUT sec)"
|
||||
while [ ! -f $PXE_CONF ]
|
||||
do
|
||||
sleep 1
|
||||
WAITED=$(($WAITED + 1))
|
||||
if [ $WAITED -gt $TIMEOUT ]
|
||||
then
|
||||
echo Error waiting for PXE configuration from DHCP
|
||||
exit
|
||||
fi
|
||||
done
|
||||
|
||||
# Source the DHCP-generated TFTP info
|
||||
# Currently we are just looking for siaddr
|
||||
. $PXE_CONF
|
||||
|
||||
# Retrieve the config (default only for now)
|
||||
CONFIGS=""
|
||||
if [ -n "$siaddr" ];
|
||||
then
|
||||
# Enable UUID based config on s390
|
||||
if [ $(/bin/uname -m) = "s390x" ]
|
||||
then
|
||||
set +e
|
||||
uuid=$(/bin/grep UUID /proc/sysinfo | tail -1 | tr -d ' ' | cut -d ':' -f 2) 2> /dev/null
|
||||
set -e
|
||||
else
|
||||
# not caring for other arches right now
|
||||
uuid=""
|
||||
fi
|
||||
CONFIGS="$CONFIGS $uuid"
|
||||
|
||||
# Enable MAC based config
|
||||
ifaddr=$(/bin/cat /sys/class/net/$interface/address | tr ':' '-')
|
||||
CONFIGS="$CONFIGS 01-$ifaddr"
|
||||
|
||||
# Enable IP based config
|
||||
iphex=$(printf %02X $(echo $ip | tr '.' ' '))
|
||||
for i in 8 7 6 5 4 3 2 1
|
||||
do
|
||||
CONFIGS="$CONFIGS $(echo $iphex | cut -c 1-$i)"
|
||||
done
|
||||
|
||||
# Finally enable default config
|
||||
CONFIGS="$CONFIGS default"
|
||||
|
||||
set +e
|
||||
for c in $CONFIGS
|
||||
do
|
||||
echo "fetching config pxelinux.cfg/$c from $siaddr"
|
||||
if /usr/bin/tftp -g -l /tmp/config -r pxelinux.cfg/$c $siaddr
|
||||
then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ ! -f /tmp/config ]
|
||||
then
|
||||
echo no config found
|
||||
exit
|
||||
fi
|
||||
|
||||
# Simple config file parsing, only one entry allowed
|
||||
kernel=$(/bin/grep -i "^[[:space:]]*kernel" /tmp/config | sed "s/^[[:space:]]*kernel[[:space:]]*//I")
|
||||
initrd=$(/bin/grep -i "^[[:space:]]*initrd" /tmp/config | sed "s/^[[:space:]]*initrd[[:space:]]*//I")
|
||||
append=$(/bin/grep -i "^[[:space:]]*append" /tmp/config | sed "s/^[[:space:]]*append[[:space:]]*//I")
|
||||
|
||||
if [ -z "$kernel" ]
|
||||
then
|
||||
echo no kernel statement found in config
|
||||
exit
|
||||
else
|
||||
echo fetch kernel $kernel from $siaddr
|
||||
/usr/bin/tftp -g -l /tmp/kernel -r $kernel $siaddr
|
||||
fi
|
||||
|
||||
if [ -n "$initrd" ]
|
||||
then
|
||||
echo fetch initrd $initrd from $siaddr
|
||||
/usr/bin/tftp -g -l /tmp/initrd -r $initrd $siaddr
|
||||
INITRD="--initrd=/tmp/initrd"
|
||||
else
|
||||
INITRD=""
|
||||
fi
|
||||
|
||||
if [ -z "$append" ]; then
|
||||
echo "Kexec load: kexec -l /tmp/kernel $INITRD"
|
||||
kexec -l /tmp/kernel $INITRD
|
||||
else
|
||||
echo "Kexec load: kexec -l /tmp/kernel $INITRD --append=\"$append\""
|
||||
kexec -l /tmp/kernel $INITRD --append="$append"
|
||||
fi
|
||||
kexec -e
|
||||
EOF
|
||||
# -- end pxeboot script
|
||||
chmod +x $builddir/sbin/pxeboot.script
|
||||
|
||||
# The final initramfs
|
||||
echo Building initramfs
|
||||
|
||||
cd $builddir
|
||||
find . | cpio -o -Hnewc | gzip - > $initramfs
|
||||
cd $OLDPWD
|
||||
171
netboot/mk-s390image
Executable file
171
netboot/mk-s390image
Executable file
@@ -0,0 +1,171 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# netboot - PXE-style boot for KVM on s390
|
||||
#
|
||||
# Sample script to build a single s390 boot image consisting of
|
||||
# kernel, an initial ramdisk and kernel parameters from
|
||||
# individual components. Note that bash is required to run this script!
|
||||
#
|
||||
# Sample invocation:
|
||||
#
|
||||
# ./mk-s390image /boot/image -r /boot/initrd image
|
||||
#
|
||||
# The resulting image can be used to build a bootable
|
||||
# ISO or as firmware image for KVM.
|
||||
#
|
||||
# Copyright IBM Corp. 2017
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
# Offsets
|
||||
OFFS_INITRD_START_BYTES=66568
|
||||
OFFS_INITRD_SIZE_BYTES=66576
|
||||
OFFS_COMMANDLINE_BYTES=66688
|
||||
MAX_PARMFILE_SIZE=896
|
||||
|
||||
# Variables
|
||||
cmd=$(basename $0)
|
||||
kernel=
|
||||
ramdisk=
|
||||
parmfile=
|
||||
image=
|
||||
binval=
|
||||
success=no
|
||||
|
||||
# Cleanup on exit
|
||||
cleanup()
|
||||
{
|
||||
if [ -n "$binval" ]
|
||||
then
|
||||
rm -f $binval
|
||||
fi
|
||||
if [ -n "$image" -a $success = no ]
|
||||
then
|
||||
rm $image
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Usage
|
||||
usage()
|
||||
{
|
||||
cat <<-EOF
|
||||
Usage: $cmd KERNEL BOOT_IMAGE [-r RAMDISK] [-p PARMFILE]
|
||||
|
||||
Build an s390 image BOOT_IMAGE suitable for CD/tape/network boot or as a
|
||||
KVM firmware image using a stripped Linux kernel file KERNEL.
|
||||
|
||||
OPTIONS
|
||||
-p Use PARMFILE with kernel parameters in the image
|
||||
-r Include RAMDISK in the image
|
||||
-h Print this help, then exit
|
||||
EOF
|
||||
}
|
||||
|
||||
# Convert decimal number to big endian doubleword
|
||||
dec2be64()
|
||||
{
|
||||
local num=$1
|
||||
local b
|
||||
local i
|
||||
for i in $(seq 1 8)
|
||||
do
|
||||
b="\\x$(printf '%x' $(expr $num % 256))$b"
|
||||
num=$(expr $num / 256) || true
|
||||
done
|
||||
printf $b
|
||||
}
|
||||
|
||||
# Do the image build
|
||||
dobuild()
|
||||
{
|
||||
local i
|
||||
local kernel_size
|
||||
local ramdisk_size
|
||||
local ramdisk_offset
|
||||
local parmfile_size
|
||||
# check whether all specified files exist
|
||||
for i in $kernel $ramdisk $parmfile
|
||||
do
|
||||
if [ ! -f $i ]
|
||||
then
|
||||
echo "$cmd: File $i not found" >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
if ! file -b $(readlink -f $kernel) | grep "Linux S390" > /dev/null
|
||||
then
|
||||
echo "$cmd: Unrecognized file format for $kernel" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# from now on we SHOULD only fail on disk shortage
|
||||
# or file permissions, let the shell handle that
|
||||
set -e
|
||||
|
||||
# copy over kernel padded with zeroes to page boundary
|
||||
dd if=$kernel of=$image bs=4096 conv=sync status=none
|
||||
|
||||
# append ramdisk if specified
|
||||
if [ "$ramdisk" != "" ]
|
||||
then
|
||||
ramdisk_size=$(du -b $ramdisk | cut -f1)
|
||||
kernel_size=$(du -b $kernel | cut -f1)
|
||||
ramdisk_offset=$(du -b $image | cut -f1)
|
||||
cat $ramdisk >> $image
|
||||
binval=$(mktemp)
|
||||
dec2be64 $ramdisk_offset > $binval
|
||||
dd seek=$OFFS_INITRD_START_BYTES if=$binval of=$image bs=1 \
|
||||
count=8 conv=notrunc status=none
|
||||
dec2be64 $ramdisk_size > $binval
|
||||
dd seek=$OFFS_INITRD_SIZE_BYTES if=$binval of=$image bs=1 \
|
||||
count=8 conv=notrunc status=none
|
||||
fi
|
||||
|
||||
# set cmdline
|
||||
if [ "$parmfile" != "" ]
|
||||
then
|
||||
parmfile_size=$(du -b $parmfile | cut -f1)
|
||||
if [ $parmfile_size -le $MAX_PARMFILE_SIZE ]
|
||||
then
|
||||
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 if=$parmfile \
|
||||
of=$image conv=notrunc status=none
|
||||
else
|
||||
echo "$cmd: Size $parmfile_size of $parmfile exceeds command line limit of $MAX_PARMFILE_SIZE" >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# we've done it
|
||||
success=yes
|
||||
}
|
||||
|
||||
# check args and build
|
||||
args=$(getopt "r:p:h" $*)
|
||||
if [ $? = 0 ]
|
||||
then
|
||||
set -- $args
|
||||
while [ $1 != "" ]
|
||||
do
|
||||
case $1 in
|
||||
-r) ramdisk=$2; shift 2;;
|
||||
-p) parmfile=$2; shift 2;;
|
||||
-h) usage; exit 0;;
|
||||
--) shift; break;;
|
||||
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if [ $# = 2 ]
|
||||
then
|
||||
kernel=$1
|
||||
image=$2
|
||||
dobuild
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# something wasn't right
|
||||
usage >&2
|
||||
exit 1
|
||||
@@ -1,6 +1,9 @@
|
||||
include ../common.mak
|
||||
LDLIBS = `net-snmp-config --agent-libs`
|
||||
CFLAGS += `net-snmp-config --cflags`
|
||||
# On some Linux systems `net-snmp-config --agent-libs` introduces -pie,
|
||||
# therefore add -fPIC to prevent link failures.
|
||||
ALL_CFLAGS += -fPIC
|
||||
ALL_CFLAGS += `net-snmp-config --cflags`
|
||||
|
||||
OBJS = ibmOSAMib.o ibmOSAMibUtil.o osasnmpd.o
|
||||
|
||||
|
||||
@@ -15,7 +15,12 @@ install:
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(BINDIR)/$$i; \
|
||||
chmod 755 $(DESTDIR)$(BINDIR)/$$i; \
|
||||
done
|
||||
|
||||
|
||||
sed -e 's+%S390_TOOLS_VERSION%+$(S390_TOOLS_RELEASE)+' cpictl > \
|
||||
$(DESTDIR)$(TOOLS_LIBDIR)/cpictl
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(TOOLS_LIBDIR)/cpictl
|
||||
chmod 775 $(DESTDIR)$(TOOLS_LIBDIR)/cpictl
|
||||
|
||||
@for i in $(MAN_PAGES); \
|
||||
do \
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 $$i \
|
||||
|
||||
275
scripts/cpictl
Executable file
275
scripts/cpictl
Executable file
@@ -0,0 +1,275 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# cpictl - Configure the Control-Program-Information (CPI) settings
|
||||
#
|
||||
# This is an internal helper script that is used by the "cpi.service"
|
||||
# systemd unit and the "90-cpi.rules" udev rule.
|
||||
#
|
||||
# The bash shell is really needed. Other shells have different ideas of how
|
||||
# bitwise operators work.
|
||||
#
|
||||
# Copyright 2017 IBM Corp.
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
#
|
||||
|
||||
readonly CPI_LOCK="/var/lock/cpictl.lock"
|
||||
|
||||
readonly PRG="${0##*/}"
|
||||
|
||||
readonly SYSTEM_LEVEL_PATH="/sys/firmware/cpi/system_level"
|
||||
readonly SYSTEM_TYPE_PATH="/sys/firmware/cpi/system_type"
|
||||
readonly SYSTEM_NAME_PATH="/sys/firmware/cpi/system_name"
|
||||
readonly SYSPLEX_NAME_PATH="/sys/firmware/cpi/sysplex_name"
|
||||
readonly CPI_SET="/sys/firmware/cpi/set"
|
||||
|
||||
declare LEVEL
|
||||
declare TYPE
|
||||
declare NAME
|
||||
declare SYSPLEX
|
||||
|
||||
declare -i DRYRUN=0
|
||||
|
||||
# Exit codes
|
||||
readonly EXIT_SUCCESS=0
|
||||
readonly EXIT_FAILURE=1
|
||||
readonly EXIT_ARG_TOO_LONG=3
|
||||
readonly EXIT_INVALID_CHARS=4
|
||||
|
||||
print_help_and_exit()
|
||||
{
|
||||
cat <<EndHelp
|
||||
Usage: $PRG [OPTIONS]
|
||||
|
||||
Configure the Control-Program-Information (CPI) settings.
|
||||
|
||||
-b, --set-bit BIT Set and commit the bit BIT in the flags
|
||||
-e, --environment Set and commit the system type, level, name and
|
||||
sysplex name with values taken from environment
|
||||
variables
|
||||
-h, --help Print this help, then exit
|
||||
-L, --level LEVEL Set and commit OS level to LEVEL (format xx.yy.zzABCD)
|
||||
-N, --name SYSTEM Set and commit the system name to SYSTEM
|
||||
-S, --sysplex SYSPLEX Set and commit the sysplex name to SYSPLEX
|
||||
-T, --type TYPE Set and commit OS type to TYPE
|
||||
-v, --version Print version information, then exit
|
||||
--commit Ignore all other options and commit any uncommitted
|
||||
values
|
||||
--dry-run Do not actually set or commit anything, but show what
|
||||
would be done
|
||||
--show Ignore all other options and show current (possibly
|
||||
uncommitted) values
|
||||
|
||||
Environment variables used for the --defaults option:
|
||||
CPI_SYSTEM_TYPE, CPI_SYSTEM_LEVEL, CPI_SYSTEM_NAME, CPI_SYSPLEX_NAME
|
||||
|
||||
Available bits for the --set-bit option:
|
||||
kvm: Indicate that system is a KVM host
|
||||
|
||||
The maximum length for system type, system name, and sysplex name is 8
|
||||
characters. The allowed characters are: [A-Z0-9 @#$]
|
||||
|
||||
This tool should be called as root.
|
||||
EndHelp
|
||||
exit $EXIT_SUCCESS
|
||||
}
|
||||
|
||||
print_version_and_exit()
|
||||
{
|
||||
cat <<EndVersion
|
||||
$PRG: Configure the CPI settings version %S390_TOOLS_VERSION%
|
||||
Copyright IBM Corp. 2017
|
||||
EndVersion
|
||||
exit $EXIT_SUCCESS
|
||||
}
|
||||
|
||||
cpi_show()
|
||||
{
|
||||
cat <<-EndShow
|
||||
System type: $(cat "$SYSTEM_TYPE_PATH")
|
||||
System level: $(cat "$SYSTEM_LEVEL_PATH")
|
||||
System name: $(cat "$SYSTEM_NAME_PATH")
|
||||
Sysplex name: $(cat "$SYSPLEX_NAME_PATH")
|
||||
EndShow
|
||||
}
|
||||
|
||||
print_parse_error_and_exit()
|
||||
{
|
||||
echo "Try '$PRG --help' for more information." >&2
|
||||
exit $EXIT_FAILURE
|
||||
}
|
||||
|
||||
fail_with()
|
||||
{
|
||||
echo "$1" >&2
|
||||
echo "Try '$PRG --help' for more information." >&2
|
||||
exit ${2:-$EXIT_FAILURE}
|
||||
}
|
||||
|
||||
cpi_commit()
|
||||
{
|
||||
echo 1 > "$CPI_SET"
|
||||
}
|
||||
|
||||
do_length_check()
|
||||
{
|
||||
[ ${#1} -gt 8 ] &&
|
||||
fail_with "$PRG: Specified $2 too long. The maximum length is 8 characters." $EXIT_ARG_TOO_LONG
|
||||
}
|
||||
|
||||
do_character_check()
|
||||
{
|
||||
echo "$1" | grep -q -E '^[a-zA-Z0-9@#$ ]*$' ||
|
||||
fail_with "$PRG: Invalid characters in $2. Valid characters are: A-Z0-9 @#$" $EXIT_INVALID_CHARS
|
||||
}
|
||||
|
||||
cpi_set_bit()
|
||||
{
|
||||
LEVEL=$(printf '0x%x' $((LEVEL | (1 << (63 - $1)) )) )
|
||||
}
|
||||
|
||||
cpi_set_oslevel()
|
||||
{
|
||||
local kver=$(echo "${1:-$(uname -r)}" | grep -E -o '^[0-9]+[.][0-9]+[.][0-9]+')
|
||||
local maj=$((${kver%%.*} % 256))
|
||||
local min=${kver#*.}
|
||||
min=$((${min%.*} % 256))
|
||||
local rev=$((${kver##*.} % 256))
|
||||
local hexlevel=$(printf '0x%02x%02x%02x' $maj $min $rev)
|
||||
LEVEL=$(printf '0x%016x' $(((LEVEL & 0xFFFFFFFFFF000000) | hexlevel)))
|
||||
}
|
||||
|
||||
cpi_set_type()
|
||||
{
|
||||
TYPE="$1"
|
||||
do_length_check "$TYPE" "system type"
|
||||
do_character_check "$TYPE" "system type"
|
||||
}
|
||||
|
||||
cpi_set_sysplex()
|
||||
{
|
||||
SYSPLEX="$1"
|
||||
do_length_check "$SYSPLEX" "sysplex name"
|
||||
do_character_check "$SYSPLEX" "sysplex name"
|
||||
}
|
||||
|
||||
cpi_set_name()
|
||||
{
|
||||
NAME="$1"
|
||||
do_length_check "$NAME" "system name"
|
||||
do_character_check "$NAME" "system name"
|
||||
}
|
||||
|
||||
# cpictl starts here
|
||||
|
||||
if [ $# -le 0 ]; then
|
||||
echo "$PRG: No parameters specified"
|
||||
print_parse_error_and_exit
|
||||
fi
|
||||
|
||||
opts=$(getopt -o b:ehL:N:S:T:v -l set-bit:,environment,help,level:,name:,sysplex:,type:,commit,dry-run,show,version -n $PRG -- "$@")
|
||||
if [ $? -ne 0 ]; then
|
||||
print_parse_error_and_exit
|
||||
fi
|
||||
|
||||
# This guarantees that only one instance will be running, and will serialize
|
||||
# the execution of multiple instances
|
||||
[ -e "$CPI_LOCK" -a ! -w "$CPI_LOCK" ] &&
|
||||
fail_with "$PRG: Cannot access lock file: $CPI_LOCK"
|
||||
[ ! -w "${CPI_LOCK%/*}" ] &&
|
||||
fail_with "$PRG: Cannot access lock file: $CPI_LOCK"
|
||||
|
||||
exec 9<> "$CPI_LOCK"
|
||||
flock -x 9
|
||||
|
||||
# Get current values from sys/firmware
|
||||
read LEVEL < "$SYSTEM_LEVEL_PATH"
|
||||
read TYPE < "$SYSTEM_TYPE_PATH"
|
||||
read NAME < "$SYSTEM_NAME_PATH"
|
||||
read SYSPLEX < "$SYSPLEX_NAME_PATH"
|
||||
|
||||
# Parse command line options: Use eval to remove getopt quotes
|
||||
eval set -- $opts
|
||||
while [ -n $1 ]; do
|
||||
case "$1" in
|
||||
--help|-h)
|
||||
print_help_and_exit
|
||||
;;
|
||||
--version|-v)
|
||||
print_version_and_exit
|
||||
;;
|
||||
-b|--set-bit)
|
||||
case "$2" in
|
||||
kvm)
|
||||
cpi_set_bit 0
|
||||
;;
|
||||
*)
|
||||
fail_with "$PRG: Unknown bit \"$2\" for the $1 option"
|
||||
;;
|
||||
esac
|
||||
shift 2
|
||||
;;
|
||||
-L|--level)
|
||||
cpi_set_oslevel "$2"
|
||||
shift 2
|
||||
;;
|
||||
-e|--environment)
|
||||
cpi_set_type "$CPI_SYSTEM_TYPE"
|
||||
cpi_set_name "$CPI_SYSTEM_NAME"
|
||||
cpi_set_oslevel "$CPI_SYSTEM_LEVEL"
|
||||
cpi_set_sysplex "$CPI_SYSPLEX_NAME"
|
||||
shift
|
||||
;;
|
||||
-T|--type)
|
||||
cpi_set_type "$2"
|
||||
shift 2
|
||||
;;
|
||||
-S|--sysplex)
|
||||
cpi_set_sysplex "$2"
|
||||
shift 2
|
||||
;;
|
||||
-N|--name)
|
||||
cpi_set_name "$2"
|
||||
shift 2
|
||||
;;
|
||||
--show)
|
||||
cpi_show
|
||||
exit $EXIT_SUCCESS
|
||||
;;
|
||||
--commit)
|
||||
cpi_commit
|
||||
exit $EXIT_SUCCESS
|
||||
;;
|
||||
--dry-run)
|
||||
DRYRUN=1
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
break;
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Print settings for --dry-run or commit them to sysfs otherwise
|
||||
|
||||
if [ $DRYRUN -eq 1 ]; then
|
||||
cat <<-EndDryrun
|
||||
System type: $TYPE
|
||||
System level: $LEVEL
|
||||
System name: $NAME
|
||||
Sysplex name: $SYSPLEX
|
||||
EndDryrun
|
||||
else
|
||||
echo "$LEVEL" > "$SYSTEM_LEVEL_PATH"
|
||||
echo "$TYPE" > "$SYSTEM_TYPE_PATH"
|
||||
echo "$NAME" > "$SYSTEM_NAME_PATH"
|
||||
echo "$SYSPLEX" > "$SYSPLEX_NAME_PATH"
|
||||
cpi_commit
|
||||
fi
|
||||
|
||||
exit $EXIT_SUCCESS
|
||||
@@ -375,7 +375,8 @@ CMDS="uname -a\
|
||||
:runlevel\
|
||||
:iptables -L\
|
||||
:ulimit -a\
|
||||
:ps -eo pid,tid,nlwp,policy,user,tname,ni,pri,psr,sgi_p,stat,wchan,start_time,time,pcpu,pmem,vsize,size,rss,share,command\
|
||||
:ps -emo pid,tid,nlwp,policy,user,tname,ni,pri,psr,sgi_p,stat,wchan,start_time,time,pcpu,pmem,vsize,size,rss,share,command\
|
||||
:ps -eHo pid,tid,nlwp,policy,user,tname,ni,pri,psr,sgi_p,stat,wchan,start_time,time,pcpu,pmem,vsize,size,rss,share,command\
|
||||
:ps axX\
|
||||
:dmesg -s 1048576\
|
||||
:last\
|
||||
|
||||
@@ -35,10 +35,12 @@ clean:
|
||||
real_usrbin_dir=$(USRBINDIR); \
|
||||
real_usrsbin_dir=$(USRSBINDIR); \
|
||||
real_toolslib_dir=$(TOOLS_LIBDIR); \
|
||||
real_sysconf_dir=$(SYSCONFDIR); \
|
||||
$(SED) -e "s#@bin_path@#$$real_bin_dir#g" \
|
||||
-e "s#@usrbin_path@#$$real_usrbin_dir#g" \
|
||||
-e "s#@usrsbin_path@#$$real_usrsbin_dir#g" \
|
||||
-e "s#@toolslib_path@#$$real_toolslib_dir#g" \
|
||||
-e "s#@sysconf_path@#$$real_sysconf_dir#g" \
|
||||
-e 's#@S390_TOOLS_RELEASE@#$(S390_TOOLS_RELEASE)#g' \
|
||||
< $< > $@
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ Type=oneshot
|
||||
# Specify a file with the environment variables using the EnvironmentFile=
|
||||
# service property.
|
||||
#
|
||||
EnvironmentFile=/etc/sysconfig/cpi
|
||||
EnvironmentFile=@sysconf_path@/sysconfig/cpi
|
||||
#
|
||||
# Alternatively, you can specify the environment variables directly,
|
||||
# using the Environment= service properties, which can be overridden by
|
||||
@@ -35,12 +35,9 @@ EnvironmentFile=/etc/sysconfig/cpi
|
||||
# Environment=CPI_SYSTEM_LEVEL=
|
||||
# Environment=CPI_SYSTEM_TYPE=LINUX
|
||||
|
||||
#
|
||||
# Apply settings
|
||||
ExecStartPre=/bin/sh -c 'if test -n "$CPI_SYSTEM_TYPE"; then echo $CPI_SYSTEM_TYPE |tr a-z A-Z > /sys/firmware/cpi/system_type; fi'
|
||||
ExecStartPre=/bin/sh -c 'if test -n "$CPI_SYSTEM_NAME"; then echo $CPI_SYSTEM_NAME |tr a-z A-Z > /sys/firmware/cpi/system_name; fi'
|
||||
ExecStartPre=/bin/sh -c 'if test -n "$CPI_SYSPLEX_NAME"; then echo $CPI_SYSPLEX_NAME |tr a-z A-Z > /sys/firmware/cpi/sysplex_name; fi'
|
||||
ExecStartPre=/bin/sh -c 'test -n "$CPI_SYSTEM_LEVEL" || CPI_SYSTEM_LEVEL="$(uname -r)" ; echo $CPI_SYSTEM_LEVEL |cut -d- -f1 | tr . " " |xargs printf "0x0000000000%02x%02x%02x\n" > /sys/firmware/cpi/system_level'
|
||||
#
|
||||
# Sending data to the HMC/SE
|
||||
ExecStart=/bin/sh -c 'echo 1 > /sys/firmware/cpi/set'
|
||||
ExecStart=@toolslib_path@/cpictl -e
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -13,10 +13,11 @@ Documentation=man:cpuplugd(8) man:cpuplugd.conf(5)
|
||||
After=remote-fs.target
|
||||
|
||||
[Service]
|
||||
ExecStart=@usrsbin_path@/cpuplugd -f -c /etc/cpuplugd.conf
|
||||
ExecStart=@usrsbin_path@/cpuplugd -c @sysconf_path@/cpuplugd.conf
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
Type=simple
|
||||
Type=forking
|
||||
PIDFile=/var/run/cpuplugd.pid
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -18,7 +18,7 @@ After=remote-fs.target
|
||||
# Specify a file with the environment variables using the EnvironmentFile=
|
||||
# service property.
|
||||
#
|
||||
EnvironmentFile=/etc/sysconfig/mon_fsstatd
|
||||
EnvironmentFile=@sysconf_path@/sysconfig/mon_fsstatd
|
||||
#
|
||||
# Alternatively, you can specify the environment variables directly,
|
||||
# using the Environment= service property, which can be overridden by
|
||||
@@ -30,10 +30,11 @@ EnvironmentFile=/etc/sysconfig/mon_fsstatd
|
||||
|
||||
ExecStartPre=-/sbin/modprobe monwriter
|
||||
ExecStartPre=/sbin/udevadm settle --timeout=10
|
||||
ExecStart=@usrsbin_path@/mon_fsstatd -a -i $FSSTAT_INTERVAL
|
||||
ExecStart=@usrsbin_path@/mon_fsstatd -i $FSSTAT_INTERVAL
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
Type=simple
|
||||
Type=forking
|
||||
PIDFile=/var/run/mon_fsstatd.pid
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -18,7 +18,7 @@ After=remote-fs.target
|
||||
# Specify a file with the environment variables using the EnvironmentFile=
|
||||
# service property.
|
||||
#
|
||||
EnvironmentFile=/etc/sysconfig/mon_procd
|
||||
EnvironmentFile=@sysconf_path@/sysconfig/mon_procd
|
||||
#
|
||||
# Alternatively, you can specify the environment variables directly,
|
||||
# using the Environment= service property, which can be overridden by
|
||||
@@ -30,10 +30,11 @@ EnvironmentFile=/etc/sysconfig/mon_procd
|
||||
|
||||
ExecStartPre=-/sbin/modprobe monwriter
|
||||
ExecStartPre=/sbin/udevadm settle --timeout=10
|
||||
ExecStart=@usrsbin_path@/mon_procd -a -i $PROC_INTERVAL
|
||||
ExecStart=@usrsbin_path@/mon_procd -i $PROC_INTERVAL
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
Type=simple
|
||||
Type=forking
|
||||
PIDFile=/var/run/mon_procd.pid
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
[Unit]
|
||||
Description=TTYRun on %I
|
||||
Documentation=man:ttyrun(8) man:agetty(8)
|
||||
BindTo=dev-%i.device
|
||||
BindsTo=dev-%i.device
|
||||
After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service
|
||||
After=rc-local.service
|
||||
Before=getty.target
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
include ../common.mak
|
||||
|
||||
SCRIPTS = lsdasd lstape chccwdev lszfcp cio_ignore znetconf dasdstat
|
||||
USRSBIN_SCRIPTS = lsmem chmem lsluns
|
||||
USRSBIN_SCRIPTS = lsluns
|
||||
MANPAGES= lsdasd.8 lstape.8 chccwdev.8 lszfcp.8 lsluns.8 \
|
||||
cio_ignore.8 znetconf.8 chmem.8 lsmem.8 dasdstat.8
|
||||
cio_ignore.8 znetconf.8 dasdstat.8
|
||||
|
||||
SUB_DIRS = zcrypt scm chp css qeth
|
||||
|
||||
|
||||
334
zconf/chmem
334
zconf/chmem
@@ -1,334 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# chmem - Tool to change memory hotplug status
|
||||
#
|
||||
# Copyright IBM Corp. 2010, 2017
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
#
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long qw(:config no_ignore_case no_auto_abbrev);
|
||||
use File::Basename;
|
||||
|
||||
my $script_name = fileparse($0);
|
||||
my $online = 0;
|
||||
my $offline = 0;
|
||||
my $memdir = "/sys/devices/system/memory";
|
||||
my $block_size = 0;
|
||||
my $max_block_nr = 0;
|
||||
my $devices = {};
|
||||
my $dev_size;
|
||||
my $blocks_per_dev = 0;
|
||||
my $devs_per_block = 0;
|
||||
my $ret = 0;
|
||||
my @entries;
|
||||
|
||||
sub chmem_usage()
|
||||
{
|
||||
print <<HERE;
|
||||
Usage: $script_name [OPTIONS] SIZE|RANGE
|
||||
|
||||
The $script_name command sets a particular size or range of memory online
|
||||
or offline.
|
||||
|
||||
Specify SIZE as <size>[m|M|g|G]. With m or M, <size> specifies the memory
|
||||
size in MB (1024 x 1024 bytes). With g or G, <size> specifies the memory size
|
||||
in GB (1024 x 1024 x 1024 bytes). The default unit is MB.
|
||||
|
||||
Specify RANGE in the form 0x<start>-0x<end> as shown in the output of the
|
||||
lsmem command. <start> is the hexadecimal address of the first byte and <end>
|
||||
is the hexadecimal address of the last byte in the memory range.
|
||||
|
||||
SIZE and RANGE must be aligned to the Linux memory block size, as shown in
|
||||
the output of the lsmem command.
|
||||
|
||||
OPTIONS
|
||||
-e, --enable
|
||||
Set the given RANGE or SIZE of memory online.
|
||||
|
||||
-d, --disable
|
||||
Set the given RANGE or SIZE of memory offline.
|
||||
|
||||
-h, --help
|
||||
Print a short help text, then exit.
|
||||
|
||||
-v, --version
|
||||
Print the version number, then exit.
|
||||
HERE
|
||||
}
|
||||
|
||||
sub chmem_version()
|
||||
{
|
||||
print "$script_name: version %S390_TOOLS_VERSION%\n";
|
||||
print "Copyright IBM Corp. 2010, 2017\n";
|
||||
}
|
||||
|
||||
sub chmem_get_dev_size()
|
||||
{
|
||||
my ($device, $old_device, $block, $old_block) = (0, 0, 0, 0);
|
||||
|
||||
foreach (@entries) {
|
||||
$_ =~ /memory(\d+)/;
|
||||
$block = $1;
|
||||
$device = `cat $_/phys_device`;
|
||||
chomp($device);
|
||||
if ($device > $old_device) {
|
||||
$dev_size = int((($block - $old_block) * $block_size) /
|
||||
($device - $old_device));
|
||||
last;
|
||||
}
|
||||
$dev_size += $block_size;
|
||||
$old_block = $block;
|
||||
}
|
||||
}
|
||||
|
||||
sub chmem_online($)
|
||||
{
|
||||
my $block = shift;
|
||||
|
||||
qx(echo online_movable > $memdir/memory$block/state 2>/dev/null);
|
||||
if ($? >> 8 != 0) {
|
||||
qx(echo online > $memdir/memory$block/state 2>/dev/null);
|
||||
}
|
||||
return $? >> 8;
|
||||
}
|
||||
|
||||
sub chmem_offline($)
|
||||
{
|
||||
my $block = shift;
|
||||
|
||||
qx(echo offline > $memdir/memory$block/state 2>/dev/null);
|
||||
return $? >> 8;;
|
||||
}
|
||||
|
||||
sub chmem_read_attr($$$)
|
||||
# parameters: state, device, block
|
||||
{
|
||||
my @attributes = qw(state phys_device);
|
||||
foreach (0..1) {
|
||||
$_[$_] = `cat $memdir/memory$_[2]/$attributes[$_]`;
|
||||
chomp($_[$_]);
|
||||
}
|
||||
}
|
||||
|
||||
sub chmem_read_devices()
|
||||
{
|
||||
my $block = 0;
|
||||
my $device = 0;
|
||||
my $old_device = 0;
|
||||
my $blocks = 0;
|
||||
my $state;
|
||||
|
||||
foreach (@entries) {
|
||||
$_ =~ /memory(\d+)/;
|
||||
$block = $1;
|
||||
chmem_read_attr($state, $device, $block);
|
||||
if ($device != $old_device) {
|
||||
$devices->{$old_device}->{'id'} = $old_device;
|
||||
$devices->{$old_device}->{'blocks'} = $blocks;
|
||||
$old_device = $device;
|
||||
$blocks = 0;
|
||||
}
|
||||
if ($state eq "online") {
|
||||
$blocks++;
|
||||
}
|
||||
}
|
||||
$devices->{$old_device}->{'blocks'} = $blocks;
|
||||
$devices->{$old_device}->{'id'} = $old_device;
|
||||
}
|
||||
|
||||
sub chmem_dev_action($$)
|
||||
{
|
||||
my ($dev_id, $blocks) = @_;
|
||||
my ($start_block, $end_block, $tmp_block, $max_blocks);
|
||||
my $state;
|
||||
my $i = 0;
|
||||
my $count = 0;
|
||||
|
||||
if ($blocks_per_dev > 0) {
|
||||
$start_block = $dev_id * $blocks_per_dev;
|
||||
$end_block = $start_block + $blocks_per_dev - 1;
|
||||
$max_blocks = $blocks_per_dev;
|
||||
} else {
|
||||
$start_block = int($dev_id / $devs_per_block);
|
||||
$end_block = $start_block;
|
||||
$max_blocks = 1;
|
||||
}
|
||||
if ($blocks > $max_blocks) {
|
||||
$blocks = $max_blocks;
|
||||
}
|
||||
while ($count < $blocks && $i < $max_blocks) {
|
||||
$tmp_block = $online ? $start_block + $i : $end_block - $i;
|
||||
$state = `cat $memdir/memory$tmp_block/state`;
|
||||
chomp($state);
|
||||
if ($offline && $state eq "online") {
|
||||
$count++ unless chmem_offline($tmp_block);
|
||||
}
|
||||
if ($online && $state eq "offline") {
|
||||
$count++ unless chmem_online($tmp_block);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
sub chmem_size($)
|
||||
{
|
||||
my $size = shift;
|
||||
my ($blocks, $dev_blocks, $dev_id);
|
||||
|
||||
$blocks = int($size / $block_size);
|
||||
if ($online) {
|
||||
foreach my $device (sort {$b->{'blocks'} <=> $a->{'blocks'} ||
|
||||
$a->{'id'} <=> $b->{'id'}}
|
||||
values %{$devices}) {
|
||||
$dev_blocks = $device->{'blocks'};
|
||||
$dev_id = $device->{'id'};
|
||||
if ($dev_blocks < $blocks_per_dev || $dev_blocks == 0) {
|
||||
$blocks -= chmem_dev_action($dev_id, $blocks);
|
||||
if ($blocks == 0) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($blocks > 0) {
|
||||
printf(STDERR "chmem: Could only set %lu MB of memory ".
|
||||
"online.\n", $size - $blocks * $block_size);
|
||||
$ret = 1;
|
||||
}
|
||||
} else {
|
||||
foreach my $device (sort {$a->{'blocks'} <=> $b->{'blocks'} ||
|
||||
$b->{'id'} <=> $a->{'id'}}
|
||||
values %{$devices}) {
|
||||
$dev_blocks = $device->{'blocks'};
|
||||
$dev_id = $device->{'id'};
|
||||
if ($dev_blocks > 0) {
|
||||
$blocks -= chmem_dev_action($dev_id, $blocks);
|
||||
if ($blocks == 0) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($blocks > 0) {
|
||||
printf(STDERR "chmem: Could only set %lu MB of memory ".
|
||||
"offline.\n", $size - $blocks * $block_size);
|
||||
$ret = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub chmem_range($$)
|
||||
{
|
||||
my ($start, $end) = @_;
|
||||
my $block = 0;
|
||||
my $state;
|
||||
|
||||
while ($start < $end && $block < $max_block_nr) {
|
||||
$block = int($start / ($block_size << 20));
|
||||
$state = `cat $memdir/memory$block/state`;
|
||||
chomp($state);
|
||||
if ($online && $state eq "offline") {
|
||||
if (chmem_online($block)) {
|
||||
printf(STDERR "chmem: Could not set ".
|
||||
"0x%016x-0x%016x online\n", $start,
|
||||
$start + ($block_size << 20) - 1);
|
||||
$ret = 1;
|
||||
}
|
||||
}
|
||||
if ($offline && $state eq "online") {
|
||||
if (chmem_offline($block)) {
|
||||
printf(STDERR "chmem: Could not set ".
|
||||
"0x%016x-0x%016x offline\n", $start,
|
||||
$start + ($block_size << 20) - 1);
|
||||
$ret = 1;
|
||||
}
|
||||
}
|
||||
$start += $block_size << 20;
|
||||
}
|
||||
}
|
||||
|
||||
sub chmem_check()
|
||||
{
|
||||
$block_size = `cat $memdir/block_size_bytes`;
|
||||
chomp($block_size);
|
||||
if ($block_size =~ /(?:0x)?([[:xdigit:]]+)/) {
|
||||
$block_size = unpack("Q", pack("H16",
|
||||
substr("0" x 16 . $1, -16)));
|
||||
$block_size = $block_size >> 20;
|
||||
} else {
|
||||
die "chmem: Unknown block size format in sysfs.\n";
|
||||
}
|
||||
if ($online == 0 && $offline == 0) {
|
||||
die "chmem: Please specify one of the options -e or -d.\n";
|
||||
}
|
||||
if ($online == 1 && $offline == 1) {
|
||||
die "chmem: You cannot specify both options -e and -d.\n";
|
||||
}
|
||||
|
||||
chmem_get_dev_size();
|
||||
if ($dev_size >= $block_size) {
|
||||
$blocks_per_dev = int($dev_size / $block_size);
|
||||
} else {
|
||||
$devs_per_block = int($block_size / $dev_size);
|
||||
}
|
||||
}
|
||||
|
||||
sub chmem_action()
|
||||
{
|
||||
my ($start, $end, $size, $unit);
|
||||
|
||||
if (!defined($ARGV[0])) {
|
||||
die "chmem: Missing size or range.\n";
|
||||
}
|
||||
if ($ARGV[0] =~ /^0x([[:xdigit:]]+)-0x([[:xdigit:]]+)$/) {
|
||||
$start = unpack("Q", pack("H16", substr("0" x 16 . $1, -16)));
|
||||
$end = unpack("Q", pack("H16", substr("0" x 16 . $2, -16)));
|
||||
if ($start % ($block_size << 20) ||
|
||||
($end + 1) % ($block_size << 20)) {
|
||||
die "chmem: Start address and (end address + 1) must ".
|
||||
"be aligned to memory block size ($block_size MB).\n";
|
||||
}
|
||||
chmem_range($start, $end);
|
||||
} else {
|
||||
if ($ARGV[0] =~ m/^(\d+)([mg]?)$/i) {
|
||||
$size = $1;
|
||||
$unit = $2 || "";
|
||||
if ($unit =~ /g/i) {
|
||||
$size = $size << 10;
|
||||
}
|
||||
if ($size % $block_size) {
|
||||
die "chmem: Size must be aligned to memory ".
|
||||
"block size ($block_size MB).\n";
|
||||
}
|
||||
chmem_size($size);
|
||||
} else {
|
||||
printf(STDERR "chmem: Invalid size or range: %s\n",
|
||||
$ARGV[0]);
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Main
|
||||
unless (GetOptions('v|version' => sub {chmem_version(); exit 0;},
|
||||
'h|help' => sub {chmem_usage(); exit 0;},
|
||||
'e|enable' => \$online,
|
||||
'd|disable' => \$offline)) {
|
||||
die "Try '$script_name --help' for more information.\n";
|
||||
};
|
||||
|
||||
@entries = (sort {length($a) <=> length($b) || $a cmp $b} <$memdir/memory*>);
|
||||
if (@entries == 0) {
|
||||
die "chmem: No memory hotplug interface in sysfs ($memdir).\n";
|
||||
}
|
||||
$entries[-1] =~ /memory(\d+)/;
|
||||
$max_block_nr = $1;
|
||||
|
||||
chmem_read_devices();
|
||||
chmem_check();
|
||||
chmem_action();
|
||||
exit $ret;
|
||||
@@ -1,75 +0,0 @@
|
||||
.\" Copyright 2017 IBM Corp.
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.TH CHMEM 8 "Apr 2010" "s390-tools"
|
||||
.
|
||||
.
|
||||
.SH NAME
|
||||
chmem \- set memory online or offline.
|
||||
.
|
||||
.SH SYNOPSIS
|
||||
.B chmem
|
||||
.RB OPTIONS
|
||||
.RB [SIZE|RANGE]
|
||||
.
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
The chmem command sets a particular size or range of memory online or offline.
|
||||
.
|
||||
.IP "\(hy" 2
|
||||
Specify SIZE as <size>[m|M|g|G]. With m or M, <size> specifies the memory
|
||||
size in MB (1024 x 1024 bytes). With g or G, <size> specifies the memory size
|
||||
in GB (1024 x 1024 x 1024 bytes). The default unit is MB.
|
||||
.
|
||||
.IP "\(hy" 2
|
||||
Specify RANGE in the form 0x<start>-0x<end> as shown in the output of the
|
||||
lsmem command. <start> is the hexadecimal address of the first byte and <end>
|
||||
is the hexadecimal address of the last byte in the memory range.
|
||||
.
|
||||
.PP
|
||||
SIZE and RANGE must be aligned to the Linux memory block size, as shown in
|
||||
the output of the lsmem command.
|
||||
|
||||
Setting memory online can fail if the hypervisor does not have enough memory
|
||||
left, for example because memory was overcommitted. Setting memory offline can
|
||||
fail if Linux cannot free the memory. If only part of the requested memory can
|
||||
be set online or offline, a message tells you how much memory was set online
|
||||
or offline instead of the requested amount.
|
||||
.
|
||||
.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Print a short help text, then exit.
|
||||
.
|
||||
.TP
|
||||
.BR \-v ", " \-\-version
|
||||
Print the version number, then exit.
|
||||
.
|
||||
.TP
|
||||
.BR \-e ", " \-\-enable
|
||||
Set the given RANGE or SIZE of memory online.
|
||||
.
|
||||
.TP
|
||||
.BR \-d ", " \-\-disable
|
||||
Set the given RANGE or SIZE of memory offline.
|
||||
.
|
||||
.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B chmem --enable 1024
|
||||
This command requests 1024 MB of memory to be set online.
|
||||
.
|
||||
.TP
|
||||
.B chmem -e 2g
|
||||
This command requests 2 GB of memory to be set online.
|
||||
.
|
||||
.TP
|
||||
.B chmem --disable 0x00000000e4000000-0x00000000f3ffffff
|
||||
This command requests the memory range starting with 0x00000000e4000000
|
||||
and ending with 0x00000000f3ffffff to be set offline.
|
||||
.
|
||||
.
|
||||
.SH SEE ALSO
|
||||
.BR lsmem (8)
|
||||
@@ -41,8 +41,7 @@
|
||||
#define UUID_FORMAT "^[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}$"
|
||||
|
||||
/* Misc constants */
|
||||
#define MAX_BUFFER_SIZE_FOR_SUBCHANNEL_ATTRIBUTES 37
|
||||
#define MAX_BUFFER_SIZE_FOR_DEVICE_ATTRIBUTES 16
|
||||
#define MAX_BUF_SIZE 256
|
||||
#define PREFIX_ID_LENGTH 4
|
||||
#define SHORT_ID_LENGTH 4
|
||||
#define CHPIDS_SEGMENT_LENGTH 8
|
||||
@@ -310,8 +309,8 @@ static bool in_devtypes_list(char *dtype)
|
||||
*/
|
||||
static int fill_device_info(struct util_rec *rec, char *path, char *device)
|
||||
{
|
||||
char buf[MAX_BUFFER_SIZE_FOR_DEVICE_ATTRIBUTES];
|
||||
unsigned long int val_ul;
|
||||
char buf[MAX_BUF_SIZE];
|
||||
|
||||
if (!path || !device) {
|
||||
if (cmd.opt_devtype && cmd.dev_count > 0)
|
||||
@@ -403,7 +402,7 @@ static bool is_sch_vfio(char *path)
|
||||
*/
|
||||
static int fill_vfio_devid(struct util_rec *rec, char *path)
|
||||
{
|
||||
char *device, buf[MAX_BUFFER_SIZE_FOR_SUBCHANNEL_ATTRIBUTES];
|
||||
char *device, buf[MAX_BUF_SIZE];
|
||||
struct dirent **de_vec;
|
||||
int count;
|
||||
|
||||
@@ -433,7 +432,7 @@ static int fill_vfio_devid(struct util_rec *rec, char *path)
|
||||
*/
|
||||
static int fill_io_devid(struct util_rec *rec, char *path)
|
||||
{
|
||||
char *device, buf[MAX_BUFFER_SIZE_FOR_SUBCHANNEL_ATTRIBUTES];
|
||||
char *device, buf[MAX_BUF_SIZE];
|
||||
struct dirent **de_vec;
|
||||
int count;
|
||||
|
||||
@@ -479,8 +478,8 @@ static int fill_io_devid(struct util_rec *rec, char *path)
|
||||
*/
|
||||
static void print_sch_io(struct util_rec *rec, char *path, char *sch_dir)
|
||||
{
|
||||
char buf[MAX_BUFFER_SIZE_FOR_SUBCHANNEL_ATTRIBUTES];
|
||||
unsigned int pim, pam, pom;
|
||||
char buf[MAX_BUF_SIZE];
|
||||
|
||||
/* Fill in subchannel ID */
|
||||
if (cmd.opt_short) {
|
||||
@@ -560,7 +559,7 @@ static void print_sch_io(struct util_rec *rec, char *path, char *sch_dir)
|
||||
*/
|
||||
static void print_sch_chsc(struct util_rec *rec, char *sch_dir)
|
||||
{
|
||||
char buf[MAX_BUFFER_SIZE_FOR_DEVICE_ATTRIBUTES];
|
||||
char buf[MAX_BUF_SIZE];
|
||||
|
||||
/* Skip entry if devrange or devtype option is active */
|
||||
if (cmd.opt_devrange && cmd.rng_count > 0)
|
||||
@@ -596,7 +595,7 @@ static void print_sch_chsc(struct util_rec *rec, char *sch_dir)
|
||||
*/
|
||||
static void print_sch_eadm(struct util_rec *rec, char *sch_dir)
|
||||
{
|
||||
char buf[MAX_BUFFER_SIZE_FOR_DEVICE_ATTRIBUTES];
|
||||
char buf[MAX_BUF_SIZE];
|
||||
|
||||
/* Skip entry if devrange or devtype option is active */
|
||||
if (cmd.opt_devrange && cmd.rng_count > 0)
|
||||
@@ -632,7 +631,7 @@ static void print_sch_eadm(struct util_rec *rec, char *sch_dir)
|
||||
*/
|
||||
static void print_defunct_devices(struct util_rec *rec, char *path)
|
||||
{
|
||||
char *device, buf[MAX_BUFFER_SIZE_FOR_DEVICE_ATTRIBUTES];
|
||||
char *device, buf[MAX_BUF_SIZE];
|
||||
struct dirent **de_vec;
|
||||
int i, count;
|
||||
|
||||
|
||||
78
zconf/lsluns
78
zconf/lsluns
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# lsluns - Tool to list all available LUNs
|
||||
# lsluns - list LUNs discovered in the FC SAN, or show encryption state of attached LUNs
|
||||
#
|
||||
# Copyright IBM Corp. 2008, 2017
|
||||
#
|
||||
@@ -169,32 +169,51 @@ sub get_lun_hash
|
||||
|
||||
sub lsluns_usage {
|
||||
print <<EOD;
|
||||
Usage: $PROGRAM_NAME [<options>]
|
||||
Usage:
|
||||
This tool is designed for environments where all SCSI devices are attached
|
||||
through the zfcp device driver. Expect error messages in mixed environments
|
||||
such as with iSCSI.
|
||||
|
||||
lsluns provides information for LUNs.
|
||||
$PROGRAM_NAME [-c <busid>] ... [-p <wwpn>] ... [-h] [-v]
|
||||
|
||||
The default is to list all LUNs that are available via the attached ports.
|
||||
The display can be limited by specifying an adapter or a port.
|
||||
List LUNs discovered in the Fibre Channel (FC) Storage Area Network (SAN).
|
||||
This causes extra SAN traffic for each target port WWPN.
|
||||
Discovering LUNs only makes sense for NPIV-enabled FCP devices
|
||||
without zfcp automatic LUN scan. zfcp automatic LUN scan is available
|
||||
as of kernel version 2.6.37, if not disabled with zfcp.allow_lun_scan=0.
|
||||
For storage products that do not support a REPORT LUNS
|
||||
well-known logical unit (such as IBM Storwize products),
|
||||
ensure that LUN 0 represents a valid peripheral device type.
|
||||
See the man page for more information.
|
||||
|
||||
$PROGRAM_NAME -a [-c <busid>] ... [-p <wwpn>] ... [-h] [-v]
|
||||
|
||||
Show encryption state of the attached LUNs.
|
||||
This causes extra SAN traffic for each attached LUN.
|
||||
|
||||
For all other uses, such as listing attached LUNs or properties other than
|
||||
encryption, use other tools such as "lszfcp -D" or "lsscsi -tv"
|
||||
or "lszdev zfcp-lun -ii".
|
||||
|
||||
Limit the listing by specifying one or more adapters (FCP device
|
||||
bus-IDs) or target port WWPNs or both.
|
||||
|
||||
Options:
|
||||
-a, --active
|
||||
Shows all activated LUNs.
|
||||
In addition LUN encryption information is provided.
|
||||
e.g. "lsluns -a"
|
||||
-c <busid>, --ccw <busid>
|
||||
Filter LUNs by adapter with the specified FCP device bus-ID. Can be
|
||||
specified multiple times.
|
||||
For example: "$PROGRAM_NAME -c 0.0.3922"
|
||||
|
||||
-c, --ccw
|
||||
Shows LUNs for a specific ccw device.
|
||||
e.g. "lsluns -c 0.0.3922"
|
||||
|
||||
-p, --port
|
||||
Shows LUNs for a specific port.
|
||||
e.g. "lsluns -p 0x5005123456789000"
|
||||
-p <wwpn>, --port <wwpn>
|
||||
Filter LUNs by target port with the specified WWPN. Can be specified
|
||||
multiple times.
|
||||
For example: "$PROGRAM_NAME -p 0x5005123456789000"
|
||||
|
||||
-h, --help
|
||||
Print help message and exit.
|
||||
Print help message and exit.
|
||||
|
||||
-v, --version
|
||||
Display version info and exit.
|
||||
Display version information and exit.
|
||||
EOD
|
||||
exit 0;
|
||||
}
|
||||
@@ -215,11 +234,9 @@ sub get_env_list
|
||||
my $p_ref_list = shift();
|
||||
my @res ;
|
||||
my %res_hash;
|
||||
my @t_arr;
|
||||
|
||||
@res = </sys/bus/ccw/drivers/zfcp/*.*.*/0x*>;
|
||||
return () if (!@res);
|
||||
reload:
|
||||
foreach my $entry (@res) {
|
||||
my $a = ${[split('/', $entry)]}[-2];
|
||||
my $p = ${[split('/', $entry)]}[-1];
|
||||
@@ -227,28 +244,9 @@ reload:
|
||||
next if (@$p_ref_list && "@$p_ref_list" !~ /$p/);
|
||||
push @{ $res_hash{$a} }, $p;
|
||||
}
|
||||
foreach my $a (sort @$a_ref_list) {
|
||||
if ("@{[keys %res_hash]}" !~ /$a/) {
|
||||
print "\tNo valid combination found for adapter '$a'. ",
|
||||
"Removing from resource list.\n";
|
||||
}
|
||||
}
|
||||
|
||||
push @t_arr, map { @{$res_hash{$_}} } keys %res_hash;
|
||||
foreach my $p (@$p_ref_list) {
|
||||
if ("@t_arr" !~ /$p/) {
|
||||
print "\tNo valid combination found for port '$p'. ",
|
||||
"Removing from resource list.\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!%res_hash) {
|
||||
print "\nNo valid parameters left, ",
|
||||
"using all available resources in system.\n\n";
|
||||
@$a_ref_list = ();
|
||||
@$p_ref_list = ();
|
||||
@t_arr = ();
|
||||
goto reload;
|
||||
print "$PROGRAM_NAME: Adapter and/or port filter(s) did not match anything\n";
|
||||
}
|
||||
return %res_hash;
|
||||
}
|
||||
|
||||
152
zconf/lsluns.8
152
zconf/lsluns.8
@@ -2,62 +2,140 @@
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.TH LSLUNS 8 "June 2008" "s390-tools"
|
||||
.TH LSLUNS 8 "2017-02-17" "s390-tools"
|
||||
.SH NAME
|
||||
lsluns \- list available LUNs
|
||||
lsluns \- list LUNs discovered in the FC SAN through zfcp, or show encryption state of
|
||||
zfcp-attached LUNs
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B lsluns
|
||||
.RB [ \-h]
|
||||
.RB [ \-v]
|
||||
.RB [ \-c
|
||||
.IR adapter id:0.0.XXXX ]
|
||||
.RB [ \-p
|
||||
.IR port number:0xXXXXXXXXXXXXXXXX ]
|
||||
.RB [\| \-c
|
||||
.IR busid \|]\ .\|.\|.
|
||||
.RB [\| \-p
|
||||
.IR wwpn \|]\ .\|.\|.
|
||||
.\" --active
|
||||
.br
|
||||
.B lsluns \-a
|
||||
.RB [\| \-c
|
||||
.IR busid \|]\ .\|.\|.
|
||||
.RB [\| \-p
|
||||
.IR wwpn \|]\ .\|.\|.
|
||||
.\" --help and --version
|
||||
.br
|
||||
.B lsluns
|
||||
.RB [\| \-h \|]
|
||||
.RB [\| \-v \|]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
.B lsluns
|
||||
does a listing of all available LUNs.
|
||||
This tool is designed for environments where all SCSI devices are attached
|
||||
through the zfcp device driver. Expect error messages in mixed environments
|
||||
such as with iSCSI.
|
||||
|
||||
The default is to list all LUNs that are found. The listing can be
|
||||
limited by specifying an adapter or a port.
|
||||
.B lsluns
|
||||
lists all logical unit numbers (LUNs) discovered in the
|
||||
Fibre Channel (FC) Storage Area Network (SAN).
|
||||
This causes extra SAN traffic for each target port WWPN.
|
||||
|
||||
.B lsluns -a
|
||||
shows the encryption state of the attached LUNs.
|
||||
This causes extra SAN traffic for each attached LUN.
|
||||
|
||||
Limit the listing by specifying one or more adapters (FCP device
|
||||
bus-IDs) or target port WWPNs or both.
|
||||
|
||||
For all other uses, such as listing attached LUNs or properties other than
|
||||
encryption, use other tools such as
|
||||
.B lszfcp \-D
|
||||
or
|
||||
.BR "lsscsi \-tv"
|
||||
or
|
||||
.BR "lszdev zfcp-lun \-ii" .
|
||||
|
||||
.SS Details on lsluns without -a option
|
||||
|
||||
.TP
|
||||
Prerequisite
|
||||
Discovering LUNs only makes sense for NPIV-enabled FCP devices
|
||||
without zfcp automatic LUN scan. zfcp automatic LUN scan is available
|
||||
as of kernel version 2.6.37, if not disabled with zfcp.allow_lun_scan=0.
|
||||
|
||||
With available and enabled zfcp automatic LUN scan,
|
||||
the kernel already performs LUN discovery.
|
||||
|
||||
.TP
|
||||
Temporary LUN Attachment
|
||||
If not attached already, lsluns temporarily attaches LUN 0
|
||||
(or if this fails the WLUN 0xc101000000000000) during runtime.
|
||||
Do not terminate lsluns with a signal. Signals interfere
|
||||
with the removal of temporarily attached LUNs.
|
||||
|
||||
.TP
|
||||
Storage Products
|
||||
Some storage products return a peripheral device type of 31==0x1f
|
||||
with peripheral qualifier 0 in a SCSI standard INQUIRY command
|
||||
for an unmapped FCP LUN 0. Examples are: IBM Storwize products,
|
||||
including IBM V7000, IBM V840, IBM V9000, and IBM SAN Volume Controller.
|
||||
For lsluns to work with such storage products,
|
||||
you must have a host mapping on the storage, which maps some volume
|
||||
to exported FCP LUN 0x0000000000000000 (Storwize host map property "SCSI ID" 0)
|
||||
for each used FCP-device initiator WWPN. The volume can be
|
||||
a minimum-sized thin-provisioned shared stand-in volume.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -h, --help
|
||||
.BR \-a ", " \-\-active
|
||||
Show the encryption state of the attached LUNs. Encrypted devices are indicated
|
||||
with a bracketed X immediately following the LUN number.
|
||||
.TP
|
||||
.BI \-c\ busid \fR,\ \fB\-\-ccw= busid
|
||||
Filter LUNs by adapter with the specified FCP device bus-ID. This option can be
|
||||
specified multiple times. When used in conjunction with \fB\-p\fR, only those
|
||||
LUNs are listed that also satisfy at least one of the \fB\-p\fR constraints.
|
||||
.TP
|
||||
.BI \-p\ wwpn \fR,\ \fB\-\-port= wwpn
|
||||
Filter LUNs by target port with the specified WWPN. This option can be
|
||||
specified multiple times. When used in conjunction with \fB\-c\fR, only those
|
||||
LUNs are listed that also satisfy at least one of the \fB\-c\fR constraints.
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Print help message and exit.
|
||||
.TP
|
||||
.B -v, --version
|
||||
Display version info and exit.
|
||||
.TP
|
||||
.B -c, --ccw
|
||||
Shows LUNs for a specific adapter.
|
||||
.TP
|
||||
.B -p, --port
|
||||
Shows LUNs for a specific port.
|
||||
.TP
|
||||
.B -a, --active
|
||||
Shows all activated LUNs. In addition information is provided
|
||||
whether the LUN is encrypted or not. This is indicated with a bracketed X
|
||||
right after the LUN number.
|
||||
.BR \-v ", " \-\-version
|
||||
Display version information and exit.
|
||||
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
.IP "lsluns"
|
||||
.TP
|
||||
.B "lsluns"
|
||||
.RS
|
||||
Shows all available LUNs.
|
||||
Lists all LUNs discovered in the FC SAN.
|
||||
.RE
|
||||
.IP "lsluns -c 0.0.3922"
|
||||
Shows all LUNs found on adapter 0.0.3922.
|
||||
.IP "lsluns -p 0x5005123456789000"
|
||||
Shows all LUNs for port 0x5005123456789000.
|
||||
.IP "lsluns -c 0.0.3922 -p 0x5005123456789000"
|
||||
Shows all LUNs for adapter 0.0.3922 and port 0x5005123456789000.
|
||||
.IP "lsluns -a "
|
||||
.TP
|
||||
.BI "lsluns \-c " 0.0.3922
|
||||
Lists all LUNs discovered in the FC SAN on adapter \fI0.0.3922\fR.
|
||||
.TP
|
||||
.BI "lsluns \-p " 0x5005123456789000
|
||||
Lists all LUNs discovered in the FC SAN on target port
|
||||
\fI0x5005123456789000\fR.
|
||||
.TP
|
||||
.BI "lsluns \-c " 0.0.3922 " \-c " 0.0.fc00 \
|
||||
" \-p " 0x5005123456789000 " \-p " 0x5005abcdefabc000
|
||||
Lists all LUNs discovered in the FC SAN on:
|
||||
adpater \fI0.0.3922\fR and port \fI0x5005123456789000\fR,
|
||||
adapter \fI0.0.3922\fR and port \fI0x5005abcdefabc000\fR,
|
||||
adapter \fI0.0.fc00\fR and port \fI0x5005123456789000\fR, or
|
||||
adapter \fI0.0.fc00\fR and port \fI0x5005abcdefabc000\fR.
|
||||
.TP
|
||||
.B "lsluns -a"
|
||||
adapter = 0.0.3c02
|
||||
port = 0x500507630300c562
|
||||
lun = 0x401040a200000000(X) /dev/sg0 Disk IBM:2107900
|
||||
lun = 0x401040a300000000 /dev/sg1 Disk IBM:2107900
|
||||
|
||||
Shows all active LUNs including the information whether the device is encrypted or not.
|
||||
Shows the encryption status of attached LUNs. A bracketed X suffixed to a LUN
|
||||
indicates that the device is encrypted.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR lszfcp (8),
|
||||
.BR lsscsi (8),
|
||||
.BR lszdev (8)
|
||||
|
||||
172
zconf/lsmem
172
zconf/lsmem
@@ -1,172 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# lsmem - Tool to show memory hotplug status
|
||||
#
|
||||
# Copyright IBM Corp. 2010, 2017
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
#
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long qw(:config no_ignore_case no_auto_abbrev);
|
||||
use File::Basename;
|
||||
|
||||
my $script_name = fileparse($0);
|
||||
my $memdir = "/sys/devices/system/memory";
|
||||
my $block_size = 0;
|
||||
my $list_all = 0;
|
||||
my $dev_size = 0;
|
||||
my @entries;
|
||||
|
||||
|
||||
sub lsmem_read_attr($$$$)
|
||||
# parameters: state, rem, device, block_nr
|
||||
{
|
||||
my @attributes = qw(state removable phys_device);
|
||||
foreach (0..2) {
|
||||
$_[$_] = `cat $memdir/memory$_[3]/$attributes[$_]`;
|
||||
chomp($_[$_]);
|
||||
}
|
||||
}
|
||||
|
||||
sub lsmem_get_dev_size()
|
||||
{
|
||||
my ($device, $old_device, $block, $old_block) = (0, 0, 0, 0);
|
||||
|
||||
foreach (@entries) {
|
||||
$_ =~ /memory(\d+)/;
|
||||
$block = $1;
|
||||
$device = `cat $_/phys_device`;
|
||||
chomp($device);
|
||||
if ($device > $old_device) {
|
||||
$dev_size = int((($block - $old_block) * $block_size) /
|
||||
($device - $old_device));
|
||||
last;
|
||||
}
|
||||
$dev_size += $block_size;
|
||||
$old_block = $block;
|
||||
}
|
||||
}
|
||||
|
||||
sub lsmem_list()
|
||||
{
|
||||
my $block = 0;
|
||||
my ($start, $end, $size) = (0, 0, 0);
|
||||
my ($state, $next_state) = (0, 0);
|
||||
my ($rem, $next_rem) = (0, 0);
|
||||
my ($device, $next_device, $end_dev) = (0, 0, 0);
|
||||
my ($mem_online, $mem_offline) = (0, 0);
|
||||
my $mem_hole;
|
||||
|
||||
$block_size = `cat $memdir/block_size_bytes`;
|
||||
chomp($block_size);
|
||||
if ($block_size =~ /(?:0x)?([[:xdigit:]]+)/) {
|
||||
$block_size = unpack("Q", pack("H16",
|
||||
substr("0" x 16 . $1, -16)));
|
||||
$block_size = $block_size >> 20;
|
||||
} else {
|
||||
die "lsmem: Unknown block size format in sysfs.\n";
|
||||
}
|
||||
lsmem_get_dev_size();
|
||||
# Start with $mem_hole = 1 to initialize $start, $state, $rem, $device
|
||||
$mem_hole = 1;
|
||||
|
||||
print <<HERE;
|
||||
Address Range Size (MB) State Removable Device
|
||||
===============================================================================
|
||||
HERE
|
||||
foreach (@entries) {
|
||||
$_ =~ /memory(\d+)/;
|
||||
$block = $1;
|
||||
if ($mem_hole) {
|
||||
lsmem_read_attr($state, $rem, $device, $block);
|
||||
$start = ($block) * ($block_size << 20);
|
||||
$mem_hole = 0;
|
||||
}
|
||||
# check next block or memory hole
|
||||
$block++;
|
||||
if (-d "$memdir/memory".$block) {
|
||||
lsmem_read_attr($next_state, $next_rem, $next_device,
|
||||
$block);
|
||||
} else {
|
||||
$mem_hole = 1
|
||||
}
|
||||
if ($state ne $next_state || $rem != $next_rem || $list_all ||
|
||||
$mem_hole) {
|
||||
$end = ($block) * ($block_size << 20) - 1;
|
||||
$size = ($end - $start + 1) >> 20;
|
||||
if ($state eq "going-offline") {
|
||||
$state = "on->off";
|
||||
}
|
||||
printf("0x%016x-0x%016x %10lu %-7s ", $start, $end,
|
||||
$size, $state);
|
||||
if ($state eq "online") {
|
||||
printf(" %-9s ", $rem ? "yes" : "no");
|
||||
$mem_online += $size;
|
||||
} else {
|
||||
printf(" %-9s ", "-");
|
||||
$mem_offline += $size;
|
||||
}
|
||||
$end_dev = ($end / $dev_size) >> 20;
|
||||
if ($device == $end_dev) {
|
||||
printf("%d\n", $device);
|
||||
} else {
|
||||
printf("%d-%d\n", $device, $end_dev);
|
||||
}
|
||||
$state = $next_state;
|
||||
$rem = $next_rem;
|
||||
$device = $end_dev + 1;
|
||||
$start = $end + 1;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
printf("Memory device size : %lu MB\n", $dev_size);
|
||||
printf("Memory block size : %lu MB\n", $block_size);
|
||||
printf("Total online memory : %lu MB\n", $mem_online);
|
||||
printf("Total offline memory: %lu MB\n", $mem_offline);
|
||||
}
|
||||
|
||||
sub lsmem_usage()
|
||||
{
|
||||
print <<HERE;
|
||||
Usage: $script_name [OPTIONS]
|
||||
|
||||
The $script_name command lists the ranges of available memory with their online
|
||||
status. The listed memory blocks correspond to the memory block representation
|
||||
in sysfs. The command also shows the memory block size, the device size, and
|
||||
the amount of memory in online and offline state.
|
||||
|
||||
OPTIONS
|
||||
-a, --all
|
||||
List each individual memory block, instead of combining memory blocks
|
||||
with similar attributes.
|
||||
|
||||
-h, --help
|
||||
Print a short help text, then exit.
|
||||
|
||||
-v, --version
|
||||
Print the version number, then exit.
|
||||
HERE
|
||||
}
|
||||
|
||||
sub lsmem_version()
|
||||
{
|
||||
print "$script_name: version %S390_TOOLS_VERSION%\n";
|
||||
print "Copyright IBM Corp. 2010, 2017\n";
|
||||
}
|
||||
|
||||
|
||||
# Main
|
||||
unless (GetOptions('v|version' => sub {lsmem_version(); exit 0;},
|
||||
'h|help' => sub {lsmem_usage(); exit 0;},
|
||||
'a|all' => \$list_all)) {
|
||||
die "Try '$script_name --help' for more information.\n";
|
||||
};
|
||||
|
||||
@entries = (sort {length($a) <=> length($b) || $a cmp $b} <$memdir/memory*>);
|
||||
if (@entries == 0) {
|
||||
die "lsmem: No memory hotplug interface in sysfs ($memdir).\n";
|
||||
}
|
||||
lsmem_list();
|
||||
@@ -1,73 +0,0 @@
|
||||
.\" Copyright 2017 IBM Corp.
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.TH LSMEM 8 "Apr 2010" s390\-tools
|
||||
.
|
||||
.
|
||||
.SH NAME
|
||||
lsmem \- list the ranges of available memory with their online status.
|
||||
.
|
||||
.
|
||||
.SH SYNOPSIS
|
||||
.B lsmem
|
||||
.RB [OPTIONS]
|
||||
.
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
The lsmem command lists the ranges of available memory with their online
|
||||
status. The listed memory blocks correspond to the memory block representation
|
||||
in sysfs. The command also shows the memory block size, the device size, and
|
||||
the amount of memory in online and offline state.
|
||||
.
|
||||
.SS "Column description"
|
||||
.
|
||||
.TP 4
|
||||
Address Range
|
||||
Start and end address of the memory range.
|
||||
.
|
||||
.TP 4
|
||||
Size
|
||||
Size of the memory range in MB (1024 x 1024 bytes).
|
||||
.
|
||||
.TP 4
|
||||
State
|
||||
Indication of the online status of the memory range. State on->off means
|
||||
that the address range is in transition from online to offline.
|
||||
.
|
||||
.TP 4
|
||||
Removable
|
||||
"yes" if the memory range can be set offline, "no" if it cannot be set offline.
|
||||
A dash ("\-") means that the range is already offline.
|
||||
.
|
||||
.TP 4
|
||||
Device
|
||||
Device number or numbers that correspond to the memory range.
|
||||
|
||||
Each device represents a memory unit for the hypervisor in control of the
|
||||
memory. The hypervisor cannot reuse a memory unit unless the corresponding
|
||||
memory range is completely offline. For best memory utilization, each device
|
||||
should either be completely online or completely offline.
|
||||
|
||||
The chmem command with the size parameter automatically chooses the best suited
|
||||
device or devices when setting memory online or offline. The device size depends
|
||||
on the hypervisor and on the amount of total online and offline memory.
|
||||
.
|
||||
.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-a ", " \-\-all
|
||||
List each individual memory block, instead of combining memory blocks with
|
||||
similar attributes.
|
||||
.
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Print a short help text, then exit.
|
||||
.
|
||||
.TP
|
||||
.BR \-v ", " \-\-version
|
||||
Print the version number, then exit.
|
||||
.
|
||||
.
|
||||
.SH SEE ALSO
|
||||
.BR chmem (8)
|
||||
@@ -105,6 +105,7 @@ function debug() {
|
||||
function search_cu_tcpip() {
|
||||
local scu=$1
|
||||
local i
|
||||
for ((i=0; i < ${#CU_TCPIP[@]}; i++)); do
|
||||
if [ "$scu" == "${CU_TCPIP[i]}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -547,6 +547,22 @@ static void setup_rec_long(struct util_rec *rec)
|
||||
util_rec_def(rec, "ipa", UTIL_REC_ALIGN_LEFT, 0, "ipa");
|
||||
util_rec_def(rec, "vipa", UTIL_REC_ALIGN_LEFT, 0, "vipa");
|
||||
util_rec_def(rec, "parp", UTIL_REC_ALIGN_LEFT, 0, "parp");
|
||||
util_rec_def(rec, "vnicc/bridge_invisible", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/bridge_invisible");
|
||||
util_rec_def(rec, "vnicc/flooding", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/flooding");
|
||||
util_rec_def(rec, "vnicc/learning", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/learning");
|
||||
util_rec_def(rec, "vnicc/learning_timeout", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/learning_timeout");
|
||||
util_rec_def(rec, "vnicc/mcast_flooding", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/mcast_flooding");
|
||||
util_rec_def(rec, "vnicc/rx_bcast", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/rx_bcast");
|
||||
util_rec_def(rec, "vnicc/takeover_learning", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/takeover_learning");
|
||||
util_rec_def(rec, "vnicc/takeover_setvmac", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/takeover_setvmac");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -560,7 +576,7 @@ static struct util_rec *setup_rec()
|
||||
rec = util_rec_new_wide("-");
|
||||
setup_rec_wide(rec);
|
||||
} else {
|
||||
rec = util_rec_new_long("-", ":", "if_name", 30, 42);
|
||||
rec = util_rec_new_long("-", ":", "if_name", 32, 40);
|
||||
setup_rec_long(rec);
|
||||
}
|
||||
return rec;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.TH CHZCRYPT 8 "AUG 2008" "s390-tools"
|
||||
.TH CHZCRYPT 8 "OCT 2017" "s390-tools"
|
||||
.SH NAME
|
||||
chzcrypt \- modify zcrypt configuration
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -286,7 +286,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
const char *online, *online_text = NULL, *poll_thread, *config_time;
|
||||
const char *poll_timeout, *default_domain;
|
||||
char *path, *dev_path, *dev, *dev_list, device[256], online_read[2];
|
||||
char *path, *dev_path, *dev, *dev_list, device[256], online_read[32];
|
||||
bool all = false, actionset = false;
|
||||
size_t len;
|
||||
int id, dom, c, i, j;
|
||||
@@ -406,12 +406,14 @@ int main(int argc, char *argv[])
|
||||
if (!util_path_is_dir(dev_path))
|
||||
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", device);
|
||||
if (!util_path_is_writable("%s/online", dev_path))
|
||||
continue;
|
||||
errx(EXIT_FAILURE, "Error - can't write to %s/online.\n Wrong permissions"
|
||||
" or wrong tools version.", dev_path);
|
||||
verbose("Setting cryptographic device %s %s\n", device, online_text);
|
||||
util_file_write_s(online, "%s/online", dev_path);
|
||||
util_file_read_line(online_read, sizeof(online_read), "%s/online", dev_path);
|
||||
if (strcmp(online, online_read) != 0)
|
||||
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.", device, online_text);
|
||||
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.",
|
||||
device, online_text);
|
||||
free(dev_path);
|
||||
}
|
||||
free(dev_list);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
.\" nroff -man lszcrypt.8
|
||||
.\" to process this source
|
||||
.\"
|
||||
.TH LSZCRYPT 8 "AUG 2008" "s390-tools"
|
||||
.TH LSZCRYPT 8 "OCT 2017" "s390-tools"
|
||||
.SH NAME
|
||||
lszcrypt \- display zcrypt device and configuration information
|
||||
.SH SYNOPSIS
|
||||
@@ -18,12 +18,12 @@ lszcrypt \- display zcrypt device and configuration information
|
||||
.B lszcrypt
|
||||
.RB "[ " -V " ] "
|
||||
[
|
||||
.I <device id>
|
||||
.I <device-id>
|
||||
[...]]
|
||||
.TP
|
||||
.B lszcrypt
|
||||
.B -c
|
||||
<device id>
|
||||
<card-id>
|
||||
.TP
|
||||
.B lszcrypt -b
|
||||
.TP
|
||||
@@ -57,18 +57,17 @@ With this verbose level additional information like hardware card type,
|
||||
hardware queue depth, pending request queue count, outstanding
|
||||
request queue count, and installed function facilities are displayed.
|
||||
.TP 8
|
||||
.B <device id>
|
||||
.B <device-id>
|
||||
Specifies a cryptographic device to display. A cryptographic device can be
|
||||
either a card device or a queue device. If no devices are specified information
|
||||
about all available devices is displayed.
|
||||
|
||||
Please note that the card device representation and the queue device are both
|
||||
in hexadecimal notation.
|
||||
Please note that the card device representation and the queue device
|
||||
are both in hexadecimal notation.
|
||||
.TP 8
|
||||
.B -b, --bus
|
||||
Displays the AP bus attributes and exits.
|
||||
.TP 8
|
||||
.B -c, --capability <card device id>
|
||||
.B -c, --capability <card-id>
|
||||
Shows the capabilities of a cryptographic card device of hardware type 6 or
|
||||
higher. The card device id value may be given as decimal or hex value (with
|
||||
a leading 0x). The capabilities of a cryptographic card device depend on
|
||||
@@ -86,18 +85,25 @@ EP11 Secure Key
|
||||
.IP "o"
|
||||
Long RNG
|
||||
.RE
|
||||
|
||||
.RS 8
|
||||
The CCA Secure Key capability may be limited by a hypervisor
|
||||
layer. The remarks 'full function set' or 'restricted function set' may
|
||||
reflect this. For details about these limitations please check the
|
||||
hypervisor documentation.
|
||||
.RE
|
||||
.TP 8
|
||||
.B -d, --domains
|
||||
Shows the usage and control domains of the cryptographic devices.
|
||||
The displayed domains of the cryptographic device depends on the initial
|
||||
cryptographic configuration.
|
||||
.RS
|
||||
.IP "o" 2
|
||||
'C' indicate a control domain
|
||||
.IP "o" 3
|
||||
C - indicate a control domain
|
||||
.IP "o"
|
||||
'U' indicate a usage domain
|
||||
U - indicate a usage domain
|
||||
.IP "o"
|
||||
'B' indicate both (control and usage domain)
|
||||
B - indicate both (control and usage domain)
|
||||
.RE
|
||||
.TP 8
|
||||
.B -h, --help
|
||||
|
||||
@@ -42,11 +42,19 @@ struct lszcrypt_l *lszcrypt_l = &l;
|
||||
/*
|
||||
* Card types
|
||||
*/
|
||||
#define MASK_APSC 0x80000000
|
||||
#define MASK_RSA4K 0x60000000
|
||||
#define MASK_COPRO 0x10000000
|
||||
#define MASK_ACCEL 0x08000000
|
||||
#define MASK_EP11 0x04000000
|
||||
#define MASK_APSC 0x80000000
|
||||
#define MASK_RSA4K 0x60000000
|
||||
#define MASK_COPRO 0x10000000
|
||||
#define MASK_ACCEL 0x08000000
|
||||
#define MASK_EP11 0x04000000
|
||||
|
||||
/*
|
||||
* Classification
|
||||
*/
|
||||
#define MASK_CLASS_FULL 0x00800000
|
||||
#define CLASS_FULL "full function set"
|
||||
#define MASK_CLASS_STATELESS 0x00400000
|
||||
#define CLASS_STATELESS "restricted function set"
|
||||
|
||||
/*
|
||||
* Program configuration
|
||||
@@ -168,7 +176,7 @@ static void show_domains_util_rec(char *domain_array[])
|
||||
*/
|
||||
static void show_domains(void)
|
||||
{
|
||||
char ctrl_domain_mask[67], usag_domain_mask[67], byte_str[3] = {};
|
||||
char ctrl_domain_mask[80], usag_domain_mask[80], byte_str[3] = {};
|
||||
int ctrl_chunk, usag_chunk;
|
||||
char *ap, *domain_array[32 * 8 + 4];
|
||||
int i, x, n;
|
||||
@@ -181,8 +189,12 @@ static void show_domains(void)
|
||||
|
||||
util_file_read_line(ctrl_domain_mask, sizeof(ctrl_domain_mask),
|
||||
"%s/ap_control_domain_mask", ap);
|
||||
if (strstr(ctrl_domain_mask, "not"))
|
||||
errx(EXIT_FAILURE, "Control domain mask not available.");
|
||||
util_file_read_line(usag_domain_mask, sizeof(usag_domain_mask),
|
||||
"%s/ap_usage_domain_mask", ap);
|
||||
if (strstr(usag_domain_mask, "not"))
|
||||
errx(EXIT_FAILURE, "Usage domain mask not available.");
|
||||
/* remove leading '0x' from domain mask string */
|
||||
memmove(&ctrl_domain_mask[0], &ctrl_domain_mask[2],
|
||||
sizeof(ctrl_domain_mask) - 2);
|
||||
@@ -222,7 +234,7 @@ static void show_capability(const char *id_str)
|
||||
{
|
||||
unsigned long func_val;
|
||||
long hwtype, id;
|
||||
char *p, *ap, *dev, card[7];
|
||||
char *p, *ap, *dev, card[16], cbuf[256];
|
||||
|
||||
/* check if ap driver is available */
|
||||
ap = util_path_sysfs("bus/ap");
|
||||
@@ -246,6 +258,11 @@ static void show_capability(const char *id_str)
|
||||
printf("Detailed capability information for %s (hardware type %ld) is not available.\n", card, hwtype);
|
||||
return;
|
||||
}
|
||||
cbuf[0] = '\0';
|
||||
if (func_val & MASK_CLASS_FULL)
|
||||
snprintf(cbuf, sizeof(cbuf), "%s", CLASS_FULL);
|
||||
else if (func_val & MASK_CLASS_STATELESS)
|
||||
snprintf(cbuf, sizeof(cbuf), "%s", CLASS_STATELESS);
|
||||
printf("%s provides capability for:\n", card);
|
||||
switch (hwtype) {
|
||||
case 6:
|
||||
@@ -258,11 +275,15 @@ static void show_capability(const char *id_str)
|
||||
case 7:
|
||||
case 9:
|
||||
printf("%s\n", CAP_RSA4K);
|
||||
printf("%s\n", CAP_CCA);
|
||||
if (cbuf[0])
|
||||
printf("%s (%s)\n", CAP_CCA, cbuf);
|
||||
else
|
||||
printf("%s\n", CAP_CCA);
|
||||
printf("%s", CAP_RNG);
|
||||
break;
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
if (func_val & MASK_ACCEL) {
|
||||
if (func_val & MASK_RSA4K)
|
||||
printf("%s", CAP_RSA4K);
|
||||
@@ -270,12 +291,14 @@ static void show_capability(const char *id_str)
|
||||
printf("%s", CAP_RSA2K);
|
||||
} else if (func_val & MASK_COPRO) {
|
||||
printf("%s\n", CAP_RSA4K);
|
||||
printf("%s\n", CAP_CCA);
|
||||
if (cbuf[0])
|
||||
printf("%s (%s)\n", CAP_CCA, cbuf);
|
||||
else
|
||||
printf("%s\n", CAP_CCA);
|
||||
printf("%s", CAP_RNG);
|
||||
} else if (func_val & MASK_EP11) {
|
||||
printf("%s", CAP_EP11);
|
||||
} else {
|
||||
|
||||
printf("Detailed capability information for %s (hardware type %ld) is not available.", card, hwtype);
|
||||
}
|
||||
break;
|
||||
@@ -450,7 +473,7 @@ static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
|
||||
*/
|
||||
static void show_device(struct util_rec *rec, const char *device)
|
||||
{
|
||||
char *grp_dev, card[3];
|
||||
char *grp_dev, card[16];
|
||||
|
||||
util_rec_set(rec, "card", card);
|
||||
|
||||
@@ -540,7 +563,7 @@ static void show_devices_argv(char *argv[])
|
||||
{
|
||||
struct util_rec *rec = util_rec_new_wide("-");
|
||||
struct dirent **dev_vec, **subdev_vec;
|
||||
char *ap, *grp_dev, *path, card[7], sub_dev[7];
|
||||
char *ap, *grp_dev, *path, card[16], sub_dev[16];
|
||||
int id, dom, i, n, dev_cnt, sub_cnt;
|
||||
|
||||
/* check if ap driver is available */
|
||||
|
||||
@@ -35,7 +35,7 @@ installkernel() {
|
||||
}
|
||||
|
||||
install() {
|
||||
local _tempfile=$(mktemp dracut-zdev.XXXX)
|
||||
local _tempfile=$(mktemp --tmpdir dracut-zdev.XXXXXX)
|
||||
|
||||
if chzdev --export - --persistent --by-path / >/dev/null 2>&1 ; then
|
||||
# Use persistent configuration
|
||||
|
||||
@@ -157,10 +157,6 @@ char *misc_asprintf(const char *, ...);
|
||||
int misc_system(err_t, const char *, ...);
|
||||
bool misc_read_dir(const char *, struct util_list *,
|
||||
bool (*)(const char *, void *), void *);
|
||||
bool path_exists(const char *);
|
||||
bool file_exists(const char *);
|
||||
bool file_writable(const char *);
|
||||
bool dir_exists(const char *);
|
||||
bool file_is_devnode(const char *);
|
||||
exit_code_t remove_file(const char *);
|
||||
char *misc_read_text_file(const char *, int, err_t);
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#define PATH_PROC "/proc"
|
||||
|
||||
#define PATH_UDEVADM "udevadm"
|
||||
#define PATH_VMCP "/usr/sbin/vmcp"
|
||||
#define PATH_VMCP TOOLS_BINDIR "/vmcp"
|
||||
#define PATH_IP "ip"
|
||||
|
||||
#define PATH_ROOT "/"
|
||||
|
||||
@@ -620,13 +620,13 @@ Answer all confirmation questions with 'yes'.
|
||||
.
|
||||
.B Persistently configure root device:
|
||||
.RS 4
|
||||
.CL chzdev \-\-by\-path / \-\-persistent
|
||||
.CL chzdev \-\-by\-path / \-\-persistent \-\-enable
|
||||
.RE
|
||||
.PP
|
||||
.
|
||||
.B Disable device that provides networking interface eth0:
|
||||
.RS 4
|
||||
.CL chzdev \-\-by\-interface eth0 \-\-active
|
||||
.CL chzdev \-\-by\-interface eth0 \-\-active \-\-disable
|
||||
.RE
|
||||
.PP
|
||||
.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "ccw.h"
|
||||
@@ -1165,15 +1166,10 @@ out:
|
||||
|
||||
static void read_grouped(struct ccw_devinfo *info, const char *path)
|
||||
{
|
||||
char *file_path;
|
||||
|
||||
file_path = misc_asprintf("%s/group_device", path);
|
||||
if (path_exists(file_path))
|
||||
if (util_path_exists("%s/group_device", path))
|
||||
info->grouped = 1;
|
||||
else
|
||||
info->grouped = 0;
|
||||
|
||||
free(file_path);
|
||||
}
|
||||
|
||||
static void read_cutype(struct ccw_devinfo *info, const char *path)
|
||||
@@ -1229,7 +1225,7 @@ static struct ccw_devinfo *ccw_devinfo_read(struct ccw_devid *devid)
|
||||
|
||||
id = ccw_devid_to_str(devid);
|
||||
path = path_get_ccw_device(NULL, id);
|
||||
if (!dir_exists(path))
|
||||
if (!util_path_is_dir(path))
|
||||
goto out;
|
||||
|
||||
info->exists = 1;
|
||||
@@ -1354,7 +1350,7 @@ bool ccw_exists(const char *drv, const char *mod, const char *id)
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
rc = dir_exists(path);
|
||||
rc = util_path_is_dir(path);
|
||||
free(path);
|
||||
|
||||
return rc;
|
||||
@@ -1428,7 +1424,7 @@ static exit_code_t ccw_st_read_active(struct subtype *st, struct device *dev,
|
||||
state->definable = 0;
|
||||
|
||||
path = path_get_ccw_device(drv, id);
|
||||
if (path_exists(path)) {
|
||||
if (util_path_exists(path)) {
|
||||
state->exists = 1;
|
||||
device_read_active_settings(dev, scope);
|
||||
} else
|
||||
@@ -1641,7 +1637,7 @@ static void ccw_st_add_errors(struct subtype *st, const char *id,
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
if (!path_exists(path)) {
|
||||
if (!util_path_exists(path)) {
|
||||
strlist_add(errors, "CCW device %s does not exist", id);
|
||||
goto out;
|
||||
}
|
||||
@@ -1662,9 +1658,7 @@ static void ccw_st_add_errors(struct subtype *st, const char *id,
|
||||
"paths", id);
|
||||
goto out;
|
||||
}
|
||||
free(apath);
|
||||
apath = misc_asprintf("%s/driver", path);
|
||||
if (!path_exists(apath)) {
|
||||
if (!util_path_exists("%s/driver", path)) {
|
||||
strlist_add(errors, "CCW device %s is not bound to a driver",
|
||||
id);
|
||||
goto out;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "ccw.h"
|
||||
@@ -557,7 +558,7 @@ static bool read_full_id(struct ccwgroup_devid *devid_ptr, const char *drv,
|
||||
bool result = false;
|
||||
|
||||
path = path_get_ccwgroup_device(drv, id);
|
||||
if (!dir_exists(path))
|
||||
if (!util_path_is_dir(path))
|
||||
goto out;
|
||||
|
||||
memset(&devid, 0, sizeof(struct ccwgroup_devid));
|
||||
@@ -625,7 +626,7 @@ static void ccwgroup_add_ids(const char *drv, const char *mod,
|
||||
path = path_get_ccwgroup_devices(drv);
|
||||
if (mod)
|
||||
module_try_load_once(mod, path);
|
||||
if (dir_exists(path))
|
||||
if (util_path_is_dir(path))
|
||||
path_for_each(path, get_ids_cb, &cb_data);
|
||||
free(path);
|
||||
}
|
||||
@@ -663,7 +664,7 @@ static exit_code_t ccwgroup_st_read_active(struct subtype *st,
|
||||
state->definable = 0;
|
||||
|
||||
path = ccwgroup_get_dev_path_by_devid(drv, devid);
|
||||
if (path_exists(path)) {
|
||||
if (util_path_exists(path)) {
|
||||
state->exists = 1;
|
||||
device_read_active_settings(dev, scope);
|
||||
} else
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#include "attrib.h"
|
||||
@@ -2502,7 +2503,7 @@ static exit_code_t do_export(struct options *opts)
|
||||
info("Exporting configuration data to standard output\n");
|
||||
} else {
|
||||
info("Exporting configuration data to %s\n", opts->export);
|
||||
if (!path_exists(opts->export)) {
|
||||
if (!util_path_exists(opts->export)) {
|
||||
rc = path_create(opts->export);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "ccw.h"
|
||||
#include "ccwgroup.h"
|
||||
#include "ctc.h"
|
||||
@@ -125,13 +127,13 @@ static struct util_list *read_sorted_ctc_devinfos(void)
|
||||
/* Add CCW devices bound to the CTC CCW device driver. */
|
||||
module_try_load_once(CTC_MOD_NAME, NULL);
|
||||
path = path_get_sys_bus_drv(CCW_BUS_NAME, CTC_CCWDRV_NAME);
|
||||
if (dir_exists(path))
|
||||
if (util_path_is_dir(path))
|
||||
path_for_each(path, add_cb, infos);
|
||||
free(path);
|
||||
|
||||
/* Add CCW devices bound to the LCS CCW device driver. */
|
||||
path = path_get_sys_bus_drv(CCW_BUS_NAME, LCS_CCWDRV_NAME);
|
||||
if (dir_exists(path))
|
||||
if (util_path_is_dir(path))
|
||||
path_for_each(path, add_cb, infos);
|
||||
free(path);
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "device.h"
|
||||
#include "devtype.h"
|
||||
@@ -480,7 +482,8 @@ void device_read_active_settings(struct device *dev, read_scope_t scope)
|
||||
a = attrib_find(st->dev_attribs, name);
|
||||
s = setting_list_apply_actual(dev->active.settings, a, name,
|
||||
value);
|
||||
if (link || (scope == scope_all && !file_writable(path)))
|
||||
if (link || (scope == scope_all &&
|
||||
!util_path_is_writable(path)))
|
||||
s->readonly = 1;
|
||||
if (link)
|
||||
free(link);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <sys/sysmacros.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "devnode.h"
|
||||
#include "misc.h"
|
||||
#include "path.h"
|
||||
@@ -230,7 +232,7 @@ static exit_code_t add_block_cb(const char *path, const char *filename,
|
||||
|
||||
/* Add additional nodes. */
|
||||
cb_data->prefix = filename;
|
||||
if (dir_exists(path))
|
||||
if (util_path_is_dir(path))
|
||||
path_for_each(path, add_part_cb, cb_data);
|
||||
|
||||
return EXIT_OK;
|
||||
@@ -249,7 +251,7 @@ int devnode_add_block_from_sysfs(struct util_list *list, const char *path)
|
||||
cb_data.prefix = NULL;
|
||||
|
||||
blkpath = misc_asprintf("%s/block", path);
|
||||
if (dir_exists(blkpath))
|
||||
if (util_path_is_dir(blkpath))
|
||||
path_for_each(blkpath, add_block_cb, &cb_data);
|
||||
free(blkpath);
|
||||
|
||||
@@ -283,7 +285,7 @@ int devnode_add_net_from_sysfs(struct util_list *list, const char *path)
|
||||
cb_data.prefix = NULL;
|
||||
|
||||
netpath = misc_asprintf("%s/net", path);
|
||||
if (dir_exists(netpath))
|
||||
if (util_path_is_dir(netpath))
|
||||
path_for_each(netpath, add_net_cb, &cb_data);
|
||||
free(netpath);
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "ccw.h"
|
||||
#include "ccwgroup.h"
|
||||
@@ -162,7 +164,7 @@ static void generic_ccw_st_add_devnodes(struct subtype *st, const char *id,
|
||||
cb_data.devnodes = devnodes;
|
||||
cb_data.id = id;
|
||||
path = path_get_sys_dev_char_devices();
|
||||
if (dir_exists(path))
|
||||
if (util_path_is_dir(path))
|
||||
path_for_each(path, add_cb, &cb_data);
|
||||
free(path);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "ccw.h"
|
||||
#include "ccwgroup.h"
|
||||
#include "ctc.h"
|
||||
@@ -129,13 +131,13 @@ static struct util_list *read_sorted_lcs_devinfos(void)
|
||||
/* Add CCW devices bound to the LCS CCW device driver. */
|
||||
module_try_load_once(LCS_MOD_NAME, NULL);
|
||||
path = path_get_sys_bus_drv(CCW_BUS_NAME, LCS_CCWDRV_NAME);
|
||||
if (dir_exists(path))
|
||||
if (util_path_is_dir(path))
|
||||
path_for_each(path, add_cb, infos);
|
||||
free(path);
|
||||
|
||||
/* Add CCW devices bound to the CTC CCW device driver. */
|
||||
path = path_get_sys_bus_drv(CCW_BUS_NAME, CTC_CCWDRV_NAME);
|
||||
if (dir_exists(path))
|
||||
if (util_path_is_dir(path))
|
||||
path_for_each(path, add_cb, infos);
|
||||
free(path);
|
||||
|
||||
|
||||
@@ -889,69 +889,6 @@ void ptrlist_move(struct util_list *to, struct util_list *from,
|
||||
util_list_add_tail(to, node);
|
||||
}
|
||||
|
||||
/* Check if a path exists. */
|
||||
bool path_exists(const char *path)
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
debug("Checking if file exists: %s\n", path);
|
||||
if (stat(path, &s) != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check if a file exists. */
|
||||
bool file_exists(const char *path)
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
debug("Checking if regular file exists: %s\n", path);
|
||||
if (stat(path, &s) != 0)
|
||||
return false;
|
||||
|
||||
if (!S_ISREG(s.st_mode))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check if a file is writable. */
|
||||
bool file_writable(const char *path)
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
debug("Checking if regular file is writable: %s\n", path);
|
||||
if (stat(path, &s) != 0)
|
||||
return false;
|
||||
|
||||
if (!S_ISREG(s.st_mode))
|
||||
return false;
|
||||
|
||||
if (!(s.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check if a directory exists. */
|
||||
bool dir_exists(const char *path)
|
||||
{
|
||||
bool result = false;
|
||||
struct stat s;
|
||||
|
||||
debug("Checking if directory exists: %s\n", path);
|
||||
if (stat(path, &s) != 0)
|
||||
goto out;
|
||||
if (!S_ISDIR(s.st_mode))
|
||||
goto out;
|
||||
result = true;
|
||||
out:
|
||||
debug("Result: %d\n", result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Check if file is a block or character special file. */
|
||||
bool file_is_devnode(const char *path)
|
||||
{
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "misc.h"
|
||||
#include "modprobe.h"
|
||||
@@ -376,7 +378,7 @@ exit_code_t modprobe_read_settings(const char *path, const char *mod,
|
||||
struct modprobe_file *mf;
|
||||
exit_code_t rc;
|
||||
|
||||
if (!file_exists(path)) {
|
||||
if (!util_path_is_reg_file(path)) {
|
||||
*settings = NULL;
|
||||
return EXIT_OK;
|
||||
}
|
||||
@@ -398,7 +400,7 @@ exit_code_t modprobe_write_settings(const char *path, const char *mod,
|
||||
exit_code_t rc;
|
||||
unsigned long lines;
|
||||
|
||||
if (file_exists(path)) {
|
||||
if (util_path_is_reg_file(path)) {
|
||||
rc = modprobe_read(path, &mf);
|
||||
if (rc)
|
||||
return rc;
|
||||
@@ -414,7 +416,7 @@ exit_code_t modprobe_write_settings(const char *path, const char *mod,
|
||||
lines = util_list_len(&mf->lines);
|
||||
if (lines == 0 || (lines == 1 && find_chzdev_comment(mf))) {
|
||||
/* Do not write empty files. */
|
||||
if (file_exists(path))
|
||||
if (util_path_is_reg_file(path))
|
||||
rc = remove_file(path);
|
||||
} else
|
||||
rc = modprobe_write(mf);
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "misc.h"
|
||||
#include "module.h"
|
||||
@@ -34,7 +36,7 @@ bool module_loaded(const char *mod)
|
||||
char *path = path_get_sys_module(mod);
|
||||
bool rc;
|
||||
|
||||
rc = dir_exists(path);
|
||||
rc = util_path_is_dir(path);
|
||||
free(path);
|
||||
|
||||
return rc;
|
||||
@@ -229,7 +231,7 @@ void module_try_load_once(const char *mod, const char *path)
|
||||
} else
|
||||
tried_loading = strlist_new();
|
||||
strlist_add(tried_loading, mod);
|
||||
if (path && path_exists(path))
|
||||
if (path && util_path_exists(path))
|
||||
return;
|
||||
if (module_loaded(mod))
|
||||
return;
|
||||
@@ -275,7 +277,7 @@ bool module_set_params(const char *mod, struct setting_list *settings)
|
||||
return false;
|
||||
}
|
||||
path = path_get_sys_module_param(mod, s->name);
|
||||
result = file_writable(path);
|
||||
result = util_path_is_writable(path);
|
||||
free(path);
|
||||
if (!result) {
|
||||
/* Sysfs file is not writable. */
|
||||
|
||||
306
zdev/src/qeth.c
306
zdev/src/qeth.c
@@ -258,11 +258,17 @@ struct qeth_attrib_data {
|
||||
layer_2,
|
||||
layer_3
|
||||
} layer_type;
|
||||
enum qeth_attr_group_type {
|
||||
group_none,
|
||||
group_bridge,
|
||||
group_vnicc
|
||||
} attr_group;
|
||||
};
|
||||
|
||||
#define QETH_DATA(layer) \
|
||||
#define QETH_DATA(layer, group) \
|
||||
((struct qeth_attrib_data []) { { \
|
||||
.layer_type = layer, \
|
||||
.attr_group = group, \
|
||||
} })
|
||||
|
||||
/*
|
||||
@@ -304,7 +310,7 @@ static struct attrib qeth_attr_portname = {
|
||||
.order_cmp = ccw_offline_only_order_cmp,
|
||||
.check = ccw_offline_only_check,
|
||||
.map = VALUE_MAP_ARRAY(VALUE_MAP("no portname required", "")),
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_priority_queueing = {
|
||||
@@ -335,7 +341,7 @@ static struct attrib qeth_attr_priority_queueing = {
|
||||
ACCEPT_STR("no_prio_queueing:3")
|
||||
),
|
||||
.unstable = 1,
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_buffer_count = {
|
||||
@@ -348,7 +354,7 @@ static struct attrib qeth_attr_buffer_count = {
|
||||
.order_cmp = ccw_offline_only_order_cmp,
|
||||
.check = ccw_offline_only_check,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(8, 128)),
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_portno = {
|
||||
@@ -360,7 +366,7 @@ static struct attrib qeth_attr_portno = {
|
||||
.order_cmp = ccw_offline_only_order_cmp,
|
||||
.check = ccw_offline_only_check,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_hsuid = {
|
||||
@@ -370,7 +376,7 @@ static struct attrib qeth_attr_hsuid = {
|
||||
"Specify a 1-8 character identifier used to identify a HiperSockets\n"
|
||||
"QETH device in the AF_IUCV addressing family support.\n",
|
||||
.defval = "",
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_recover = {
|
||||
@@ -386,7 +392,7 @@ static struct attrib qeth_attr_recover = {
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_NUM(1)),
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_isolation = {
|
||||
@@ -401,7 +407,7 @@ static struct attrib qeth_attr_isolation = {
|
||||
.defval = "none",
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_STR("none"), ACCEPT_STR("drop"),
|
||||
ACCEPT_STR("forward")),
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_performance_stats = {
|
||||
@@ -413,7 +419,7 @@ static struct attrib qeth_attr_performance_stats = {
|
||||
" 1: Performance statistics data is collected\n",
|
||||
.defval = "0",
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_hw_trap = {
|
||||
@@ -428,7 +434,7 @@ static struct attrib qeth_attr_hw_trap = {
|
||||
.defval = "disarm",
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_STR("disarm"), ACCEPT_STR("arm"),
|
||||
ACCEPT_STR("trap")),
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_route4 = {
|
||||
@@ -464,7 +470,7 @@ static struct attrib qeth_attr_route4 = {
|
||||
"secondary_connector"),
|
||||
VALUE_MAP("secondary connector",
|
||||
"secondary_connector")),
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_route6 = {
|
||||
@@ -501,7 +507,7 @@ static struct attrib qeth_attr_route6 = {
|
||||
VALUE_MAP("secondary connector",
|
||||
"secondary_connector")),
|
||||
.unstable = 1,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_fake_broadcast = {
|
||||
@@ -515,7 +521,7 @@ static struct attrib qeth_attr_fake_broadcast = {
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_enable = {
|
||||
@@ -529,7 +535,7 @@ static struct attrib qeth_attr_ipa_takeover_enable = {
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_add4 = {
|
||||
@@ -544,7 +550,7 @@ static struct attrib qeth_attr_ipa_takeover_add4 = {
|
||||
.multi = 1,
|
||||
.activerem = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_add6 = {
|
||||
@@ -559,7 +565,7 @@ static struct attrib qeth_attr_ipa_takeover_add6 = {
|
||||
.multi = 1,
|
||||
.activerem = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_del4 = {
|
||||
@@ -573,7 +579,7 @@ static struct attrib qeth_attr_ipa_takeover_del4 = {
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_del6 = {
|
||||
@@ -586,7 +592,7 @@ static struct attrib qeth_attr_ipa_takeover_del6 = {
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_invert4 = {
|
||||
@@ -601,7 +607,7 @@ static struct attrib qeth_attr_ipa_takeover_invert4 = {
|
||||
.defval = "0",
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_invert6 = {
|
||||
@@ -616,7 +622,7 @@ static struct attrib qeth_attr_ipa_takeover_invert6 = {
|
||||
.defval = "0",
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_rxip_add4 = {
|
||||
@@ -629,20 +635,20 @@ static struct attrib qeth_attr_rxip_add4 = {
|
||||
.multi = 1,
|
||||
.activerem = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_rxip_add6 = {
|
||||
.name = "rxip/add6",
|
||||
.title = "Add IPv6 address to ARP proxy list",
|
||||
.title = "Add IPv6 address to NDP proxy list",
|
||||
.desc =
|
||||
"Write an IPv6 address to this attribute to add it to the list of\n"
|
||||
"addresses for which this QETH device should act as ARP proxy.\n",
|
||||
"addresses for which this QETH device should act as NDP proxy.\n",
|
||||
.defval = "",
|
||||
.multi = 1,
|
||||
.activerem = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_rxip_del4 = {
|
||||
@@ -654,19 +660,19 @@ static struct attrib qeth_attr_rxip_del4 = {
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_rxip_del6 = {
|
||||
.name = "rxip/del6",
|
||||
.title = "Remove IPv6 address from ARP proxy list",
|
||||
.title = "Remove IPv6 address from NDP proxy list",
|
||||
.desc =
|
||||
"Write an IPv6 address to this attribute to remove it from the list\n"
|
||||
"of addresses for which this QETH device acts as an ARP proxy.\n",
|
||||
"of addresses for which this QETH device acts as an NDP proxy.\n",
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_sniffer = {
|
||||
@@ -679,7 +685,7 @@ static struct attrib qeth_attr_sniffer = {
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vipa_add4 = {
|
||||
@@ -692,7 +698,7 @@ static struct attrib qeth_attr_vipa_add4 = {
|
||||
.multi = 1,
|
||||
.activerem = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vipa_add6 = {
|
||||
@@ -705,7 +711,7 @@ static struct attrib qeth_attr_vipa_add6 = {
|
||||
.multi = 1,
|
||||
.activerem = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vipa_del4 = {
|
||||
@@ -717,7 +723,7 @@ static struct attrib qeth_attr_vipa_del4 = {
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vipa_del6 = {
|
||||
@@ -729,7 +735,7 @@ static struct attrib qeth_attr_vipa_del6 = {
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_bridge_role = {
|
||||
@@ -739,13 +745,16 @@ static struct attrib qeth_attr_bridge_role = {
|
||||
"Configure a QETH device as a bridge port:\n"
|
||||
" primary: The device acts as the primary bridge port\n"
|
||||
" secondary: The device acts as a secondary bridge port\n"
|
||||
" none: The device has no bridge port role\n",
|
||||
" none: The device has no bridge port role\n"
|
||||
" n/a (VNIC characteristics):\n"
|
||||
" The device is configured with VNIC characteristics\n"
|
||||
" and cannot have a bridge role (read-only)\n",
|
||||
.defval = "none",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_STR("primary"),
|
||||
ACCEPT_STR("secondary"),
|
||||
ACCEPT_STR("none")),
|
||||
.st_data = QETH_DATA(layer_2),
|
||||
.st_data = QETH_DATA(layer_2, group_bridge),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_bridge_hostnotify = {
|
||||
@@ -755,11 +764,14 @@ static struct attrib qeth_attr_bridge_hostnotify = {
|
||||
"Control whether host connection and disconnection events are\n"
|
||||
"reported through kernel uevents:\n"
|
||||
" 0: Notifications are disabled\n"
|
||||
" 1: Notifications are enabled\n",
|
||||
" 1: Notifications are enabled\n"
|
||||
" n/a (VNIC characteristics):\n"
|
||||
" The device is configured with VNIC characteristics\n"
|
||||
" and cannot have a bridge role (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2),
|
||||
.st_data = QETH_DATA(layer_2, group_bridge),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_bridge_reflect_promisc = {
|
||||
@@ -773,13 +785,159 @@ static struct attrib qeth_attr_bridge_reflect_promisc = {
|
||||
" primary: Attempt to configure the device as the primary bridge\n"
|
||||
" port\n"
|
||||
" secondary: Attempt to configure the device as a secondary bridge\n"
|
||||
" port\n",
|
||||
" port\n"
|
||||
" n/a (VNIC characteristics):\n"
|
||||
" The device is configured with VNIC characteristics\n"
|
||||
" and cannot have a bridge role (read-only)\n",
|
||||
.defval = "none",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_STR("primary"),
|
||||
ACCEPT_STR("secondary"),
|
||||
ACCEPT_STR("none")),
|
||||
.st_data = QETH_DATA(layer_2),
|
||||
.st_data = QETH_DATA(layer_2, group_bridge),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_flooding = {
|
||||
.name = "vnicc/flooding",
|
||||
.title = "Control setting of VNICC flooding",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic flooding\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Flooding disabled\n"
|
||||
" 1: Flooding enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_mcast_flooding = {
|
||||
.name = "vnicc/mcast_flooding",
|
||||
.title = "Control setting of VNICC multicast flooding",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic multicast flooding\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Multicast flooding disabled\n"
|
||||
" 1: Multicast flooding enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_learning = {
|
||||
.name = "vnicc/learning",
|
||||
.title = "Control setting of VNICC learning",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic learning\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Learning disabled\n"
|
||||
" 1: Learning enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_learning_timeout = {
|
||||
.name = "vnicc/learning_timeout",
|
||||
.title = "Control setting of the VNICC learning timeout",
|
||||
.desc =
|
||||
"Control and show the timeout of the VNIC characteristic learning\n"
|
||||
"on the networking device:\n"
|
||||
" <N>: Timeout in seconds\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "600",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(60, 86400)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_takeover_setvmac = {
|
||||
.name = "vnicc/takeover_setvmac",
|
||||
.title = "Control setting of VNICC takeover SETVMAC",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic takeover SETVMAC\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Takeover SETVMAC disabled\n"
|
||||
" 1: Takeover SETVMAC enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_takeover_learning = {
|
||||
.name = "vnicc/takeover_learning",
|
||||
.title = "Control setting of VNICC takeover learning",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic takeover learning\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Takeover learning disabled\n"
|
||||
" 1: Takeover learning enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_bridge_invisible = {
|
||||
.name = "vnicc/bridge_invisible",
|
||||
.title = "Control setting of VNICC bridge invisible",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic bridge invisible\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Bridge invisible disabled\n"
|
||||
" 1: Bridge invisible enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_rx_bcast = {
|
||||
.name = "vnicc/rx_bcast",
|
||||
.title = "Control setting of VNICC receive broadcast",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic receive broadcast\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Receive broadcast disabled\n"
|
||||
" 1: Receive broadcast enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "1",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -913,7 +1071,11 @@ static exit_code_t setting_ineffective(struct setting *s, int layer2)
|
||||
|
||||
static enum qeth_layer_type get_layer_type(struct setting *s)
|
||||
{
|
||||
struct qeth_attrib_data *data = s->attrib->st_data;
|
||||
struct qeth_attrib_data *data;
|
||||
|
||||
if (!s->attrib)
|
||||
return layer_any;
|
||||
data = s->attrib->st_data;
|
||||
|
||||
if (!data)
|
||||
return layer_any;
|
||||
@@ -921,6 +1083,20 @@ static enum qeth_layer_type get_layer_type(struct setting *s)
|
||||
return data->layer_type;
|
||||
}
|
||||
|
||||
static enum qeth_attr_group_type get_attr_group_type(struct setting *s)
|
||||
{
|
||||
struct qeth_attrib_data *data;
|
||||
|
||||
if (!s->attrib)
|
||||
return group_none;
|
||||
data = s->attrib->st_data;
|
||||
|
||||
if (!data)
|
||||
return group_none;
|
||||
else
|
||||
return data->attr_group;
|
||||
}
|
||||
|
||||
static void add_layer2_setting(struct setting_list *list, int layer2)
|
||||
{
|
||||
setting_list_apply(list, &qeth_attr_layer2,
|
||||
@@ -994,6 +1170,38 @@ static exit_code_t check_ineffective_settings(struct setting_list *list,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Check if there are conflicting attribute settings */
|
||||
static exit_code_t check_conflicting_settings(struct setting_list *list)
|
||||
{
|
||||
const char *text = "Settings %s and %s are in conflict\n";
|
||||
struct setting *bridge = NULL, *vnicc = NULL;
|
||||
enum qeth_attr_group_type t;
|
||||
struct setting *s;
|
||||
|
||||
util_list_iterate(&list->list, s) {
|
||||
if (s->removed)
|
||||
continue;
|
||||
t = get_attr_group_type(s);
|
||||
if (t == group_bridge && (!bridge || !bridge->specified))
|
||||
bridge = s;
|
||||
if (t == group_vnicc && (!vnicc || !vnicc->specified))
|
||||
vnicc = s;
|
||||
}
|
||||
|
||||
/* BridgePort and VNICC cannot both be configured at the same time */
|
||||
if (bridge && vnicc && (bridge->specified || vnicc->specified)) {
|
||||
if (force) {
|
||||
delayed_warn(text, bridge->attrib->name,
|
||||
vnicc->attrib->name);
|
||||
return EXIT_OK;
|
||||
}
|
||||
delayed_forceable(text, bridge->attrib->name,
|
||||
vnicc->attrib->name);
|
||||
return EXIT_INVALID_CONFIG;
|
||||
}
|
||||
return EXIT_OK;
|
||||
}
|
||||
|
||||
/* Check if layer2 setting can be correctly applied. */
|
||||
static exit_code_t check_layer2(struct device *dev, config_t config)
|
||||
{
|
||||
@@ -1045,7 +1253,17 @@ static exit_code_t check_layer2(struct device *dev, config_t config)
|
||||
if (SCOPE_PERSISTENT(config)) {
|
||||
rc = check_ineffective_settings(dev->persistent.settings,
|
||||
layer2_persistent);
|
||||
if (rc)
|
||||
goto out;
|
||||
}
|
||||
/* check for conflicting layer2 attribute groups */
|
||||
if (SCOPE_ACTIVE(config)) {
|
||||
rc = check_conflicting_settings(dev->active.settings);
|
||||
if (rc)
|
||||
goto out;
|
||||
}
|
||||
if (SCOPE_PERSISTENT(config))
|
||||
rc = check_conflicting_settings(dev->persistent.settings);
|
||||
|
||||
out:
|
||||
return rc;
|
||||
@@ -1195,6 +1413,14 @@ static struct subtype qeth_subtype_qeth = {
|
||||
&qeth_attr_bridge_role,
|
||||
&qeth_attr_bridge_hostnotify,
|
||||
&qeth_attr_bridge_reflect_promisc,
|
||||
&qeth_attr_vnicc_flooding,
|
||||
&qeth_attr_vnicc_mcast_flooding,
|
||||
&qeth_attr_vnicc_learning,
|
||||
&qeth_attr_vnicc_learning_timeout,
|
||||
&qeth_attr_vnicc_takeover_setvmac,
|
||||
&qeth_attr_vnicc_takeover_learning,
|
||||
&qeth_attr_vnicc_bridge_invisible,
|
||||
&qeth_attr_vnicc_rx_bcast,
|
||||
),
|
||||
.unknown_dev_attribs = 1,
|
||||
.support_definable = 1,
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "ccw.h"
|
||||
#include "ccwgroup.h"
|
||||
#include "device.h"
|
||||
@@ -277,7 +279,7 @@ static struct util_list *read_sorted_qeth_devinfos(void)
|
||||
/* Get CHPID information for all devices bound to the QETH driver. */
|
||||
infos = ptrlist_new();
|
||||
path = path_get_sys_bus_drv(CCW_BUS_NAME, QETH_CCWDRV_NAME);
|
||||
if (dir_exists(path))
|
||||
if (util_path_is_dir(path))
|
||||
path_for_each(path, add_cb, infos);
|
||||
free(path);
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "device.h"
|
||||
#include "devtype.h"
|
||||
#include "misc.h"
|
||||
@@ -35,9 +37,14 @@ exit_code_t root_check(void)
|
||||
/* Get list of devices that provide the root device. */
|
||||
selected = selected_dev_list_new();
|
||||
rc = select_by_path(NULL, selected, config_active, scope_mandatory,
|
||||
NULL, NULL, PATH_ROOT, err_print);
|
||||
if (rc)
|
||||
NULL, NULL, PATH_ROOT, err_ignore);
|
||||
if (rc) {
|
||||
/* Running from an unknown root device is not an error. */
|
||||
verb("Note: Could not determine if root device configuration "
|
||||
"needs to be updated\n");
|
||||
rc = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Determine if any of the devices or device types has been modified. */
|
||||
mod = strlist_new();
|
||||
@@ -69,7 +76,7 @@ exit_code_t root_check(void)
|
||||
"required.\n");
|
||||
|
||||
/* Check if script is available. */
|
||||
if (!file_exists(PATH_ROOT_SCRIPT))
|
||||
if (!util_path_is_reg_file(PATH_ROOT_SCRIPT))
|
||||
goto out;
|
||||
|
||||
/* Ask for confirmation. */
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "misc.h"
|
||||
#include "path.h"
|
||||
#include "scsi.h"
|
||||
@@ -253,7 +255,7 @@ static struct util_list *read_scsi_zfcp_list(void)
|
||||
|
||||
list = ptrlist_new();
|
||||
path = path_get_sys_bus_dev("scsi", NULL);
|
||||
if (dir_exists(path))
|
||||
if (util_path_is_dir(path))
|
||||
path_for_each(path, add_ids_cb, list);
|
||||
free(path);
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "blkinfo.h"
|
||||
#include "ccw.h"
|
||||
#include "device.h"
|
||||
@@ -622,7 +624,7 @@ exit_code_t select_by_path(struct select_opts *select,
|
||||
struct ptrlist_node *p;
|
||||
exit_code_t rc;
|
||||
|
||||
if (!path_exists(path)) {
|
||||
if (!util_path_exists(path)) {
|
||||
err_t_print(err, "Path not found: %s\n", path);
|
||||
return EXIT_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "ccw.h"
|
||||
#include "device.h"
|
||||
@@ -391,7 +393,7 @@ exit_code_t udev_remove_rule(const char *type, const char *id)
|
||||
exit_code_t rc = EXIT_OK;
|
||||
|
||||
path = path_get_udev_rule(type, id);
|
||||
if (file_exists(path))
|
||||
if (util_path_is_reg_file(path))
|
||||
rc = remove_file(path);
|
||||
free(path);
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "ccw.h"
|
||||
#include "device.h"
|
||||
@@ -33,7 +35,7 @@ bool udev_ccw_exists(const char *type, const char *id)
|
||||
return false;
|
||||
|
||||
path = path_get_udev_rule(type, normid);
|
||||
rc = file_exists(path);
|
||||
rc = util_path_is_reg_file(path);
|
||||
free(path);
|
||||
free(normid);
|
||||
|
||||
@@ -150,7 +152,7 @@ exit_code_t udev_ccw_write_device(struct device *dev)
|
||||
|
||||
path = path_get_udev_rule(type, id);
|
||||
debug("Writing %s udev rule file %s\n", type, path);
|
||||
if (!path_exists(path)) {
|
||||
if (!util_path_exists(path)) {
|
||||
rc = path_create(path);
|
||||
if (rc)
|
||||
goto out;
|
||||
@@ -243,7 +245,7 @@ exit_code_t udev_ccw_write_cio_ignore(const char *id_list)
|
||||
|
||||
if (!*id_list) {
|
||||
/* Empty id_list string - remove file. */
|
||||
if (!file_exists(path)) {
|
||||
if (!util_path_is_reg_file(path)) {
|
||||
/* Already removed. */
|
||||
goto out;
|
||||
}
|
||||
@@ -256,7 +258,7 @@ exit_code_t udev_ccw_write_cio_ignore(const char *id_list)
|
||||
goto out;
|
||||
|
||||
debug("Writing cio-ignore udev rule file %s\n", path);
|
||||
if (!path_exists(path)) {
|
||||
if (!util_path_exists(path)) {
|
||||
rc = path_create(path);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "ccwgroup.h"
|
||||
#include "device.h"
|
||||
@@ -53,7 +55,7 @@ bool udev_ccwgroup_exists(const char *type, const char *id)
|
||||
path = get_rule_path(type, id);
|
||||
if (!path)
|
||||
return false;
|
||||
rc = file_exists(path);
|
||||
rc = util_path_is_reg_file(path);
|
||||
free(path);
|
||||
|
||||
return rc;
|
||||
@@ -215,7 +217,7 @@ exit_code_t udev_ccwgroup_write_device(struct device *dev)
|
||||
list = setting_list_get_sorted(dev->persistent.settings);
|
||||
|
||||
debug("Writing %s udev rule file %s\n", type, path);
|
||||
if (!path_exists(path)) {
|
||||
if (!util_path_exists(path)) {
|
||||
rc = path_create(path);
|
||||
if (rc)
|
||||
goto out;
|
||||
@@ -364,7 +366,7 @@ void udev_ccwgroup_add_device_ids(const char *type, struct util_list *list)
|
||||
cb_data.prefix = misc_asprintf("%s-%s-", UDEV_PREFIX, type);
|
||||
cb_data.ids = list;
|
||||
|
||||
if (dir_exists(path))
|
||||
if (util_path_is_dir(path))
|
||||
path_for_each(path, get_ids_cb, &cb_data);
|
||||
|
||||
free(cb_data.prefix);
|
||||
@@ -382,7 +384,7 @@ exit_code_t udev_ccwgroup_remove_rule(const char *type, const char *id)
|
||||
return EXIT_INVALID_ID;
|
||||
|
||||
path = path_get_udev_rule(type, partial_id);
|
||||
if (file_exists(path))
|
||||
if (util_path_is_reg_file(path))
|
||||
rc = remove_file(path);
|
||||
free(path);
|
||||
free(partial_id);
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "device.h"
|
||||
#include "misc.h"
|
||||
@@ -376,7 +378,7 @@ void udev_zfcp_lun_add_device_ids(struct util_list *list)
|
||||
cb_data.list = list;
|
||||
path = path_get_udev_rules();
|
||||
|
||||
if (dir_exists(path))
|
||||
if (util_path_is_dir(path))
|
||||
path_for_each(path, lun_cb, &cb_data);
|
||||
|
||||
free(path);
|
||||
@@ -497,7 +499,7 @@ static exit_code_t write_luns_rule(const char *path, struct util_list *list)
|
||||
return EXIT_INTERNAL_ERROR;
|
||||
hba_id = ccw_devid_to_str(&node->id.fcp_dev);
|
||||
debug("Writing FCP LUN udev rule file %s\n", path);
|
||||
if (!path_exists(path)) {
|
||||
if (!util_path_exists(path)) {
|
||||
rc = path_create(path);
|
||||
if (rc)
|
||||
goto out;
|
||||
@@ -614,7 +616,7 @@ static exit_code_t update_lun_rule(const char *id, struct device_state *state)
|
||||
|
||||
/* Get previous rule data. */
|
||||
luns = zfcp_lun_node_list_new();
|
||||
exists = file_exists(path);
|
||||
exists = util_path_is_reg_file(path);
|
||||
if (exists)
|
||||
udev_read_zfcp_lun_rule(path, luns);
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "ccw.h"
|
||||
#include "device.h"
|
||||
@@ -430,7 +432,7 @@ static exit_code_t zfcp_lun_st_read_active(struct subtype *st,
|
||||
|
||||
/* Check for FC unit. */
|
||||
fc_path = path_get_zfcp_lun_dev(dev->devid);
|
||||
fc_exists = path_exists(fc_path);
|
||||
fc_exists = util_path_exists(fc_path);
|
||||
free(fc_path);
|
||||
|
||||
/* Check for SCSI device. */
|
||||
@@ -478,7 +480,7 @@ static exit_code_t zfcp_lun_add(struct device *dev)
|
||||
/* Check if LUN already exists. */
|
||||
fcp_dev_id = ccw_devid_to_str(&devid->fcp_dev);
|
||||
lunpath = path_get_zfcp_lun_dev(devid);
|
||||
if (dir_exists(lunpath)) {
|
||||
if (util_path_is_dir(lunpath)) {
|
||||
hctl = scsi_hctl_from_zfcp_lun_devid(devid);
|
||||
if (!hctl)
|
||||
goto check_failed;
|
||||
@@ -486,7 +488,7 @@ static exit_code_t zfcp_lun_add(struct device *dev)
|
||||
}
|
||||
|
||||
portpath = path_get_zfcp_port_dev(devid);
|
||||
if (!dir_exists(portpath)) {
|
||||
if (!util_path_is_dir(portpath)) {
|
||||
delayed_err("Target port not found\n");
|
||||
rc = EXIT_ZFCP_WWPN_NOT_FOUND;
|
||||
goto out;
|
||||
@@ -681,14 +683,14 @@ static exit_code_t zfcp_lun_st_device_undefine(struct subtype *st,
|
||||
|
||||
remove_lun:
|
||||
path = path_get_zfcp_lun_dev(devid);
|
||||
if (!path_exists(path))
|
||||
if (!util_path_exists(path))
|
||||
goto out;
|
||||
free(path);
|
||||
path = NULL;
|
||||
|
||||
/* Remove FCP LUN. */
|
||||
devpath = path_get_zfcp_port_dev(devid);
|
||||
if (!dir_exists(devpath)) {
|
||||
if (!util_path_is_dir(devpath)) {
|
||||
rc = EXIT_ZFCP_WWPN_NOT_FOUND;
|
||||
goto out;
|
||||
}
|
||||
@@ -779,7 +781,7 @@ static bool zfcp_lun_fc_lun_exists(const char *id)
|
||||
if (zfcp_lun_parse_devid(&devid, id, err_ignore) != EXIT_OK)
|
||||
return false;
|
||||
path = path_get_zfcp_lun_dev(&devid);
|
||||
result = path_exists(path);
|
||||
result = util_path_exists(path);
|
||||
free(path);
|
||||
|
||||
return result;
|
||||
@@ -910,7 +912,7 @@ static void add_sg_from_sysfs(struct util_list *list, const char *path)
|
||||
char *sgpath;
|
||||
|
||||
sgpath = misc_asprintf("%s/scsi_generic", path);
|
||||
if (dir_exists(sgpath))
|
||||
if (util_path_is_dir(sgpath))
|
||||
path_for_each(sgpath, add_sg_cb, list);
|
||||
free(sgpath);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ struct vol {
|
||||
u64 part_size;
|
||||
u64 mem_start;
|
||||
u64 mem_end;
|
||||
char bus_id[9];
|
||||
char bus_id[10];
|
||||
u32 nr;
|
||||
u16 blk_size;
|
||||
struct df_s390_dumper dumper;
|
||||
|
||||
@@ -75,7 +75,7 @@ static void init_defaults(void)
|
||||
/*
|
||||
* Print "help" hint
|
||||
*/
|
||||
static void print_usage_exit(void)
|
||||
static void __noreturn print_usage_exit(void)
|
||||
{
|
||||
STDERR("Try '%s --help' for more information.\n", g.prog_name);
|
||||
zg_exit(1);
|
||||
@@ -84,7 +84,7 @@ static void print_usage_exit(void)
|
||||
/*
|
||||
* Print help text
|
||||
*/
|
||||
static void print_help_exit(void)
|
||||
static void __noreturn print_help_exit(void)
|
||||
{
|
||||
STDOUT("%s", help_text);
|
||||
zg_exit(0);
|
||||
@@ -93,7 +93,7 @@ static void print_help_exit(void)
|
||||
/*
|
||||
* Print version information
|
||||
*/
|
||||
static void print_version_exit(void)
|
||||
static void __noreturn print_version_exit(void)
|
||||
{
|
||||
STDOUT("%s: Tool for copying and converting dumps version %s\n",
|
||||
g.prog_name, RELEASE_STRING);
|
||||
|
||||
@@ -2,7 +2,25 @@ include ../common.mak
|
||||
|
||||
CPIOINIT = $(call echocmd," CPIOINI ",/$@)./cpioinit
|
||||
|
||||
all: $(ZFCPDUMP_PART_RD)
|
||||
ifeq (${HAVE_LIBC_STATIC},0)
|
||||
|
||||
all:
|
||||
$(SKIP) HAVE_LIBC_STATIC=0
|
||||
|
||||
install:
|
||||
$(SKIP) HAVE_LIBC_STATIC=0
|
||||
|
||||
else
|
||||
|
||||
check_dep:
|
||||
$(call check_dep, \
|
||||
"zfcpdump", \
|
||||
"stdio.h", \
|
||||
"glibc-static or libc-dev", \
|
||||
"HAVE_LIBC_STATIC=0", \
|
||||
"-static")
|
||||
|
||||
all: check_dep $(ZFCPDUMP_PART_RD)
|
||||
|
||||
cpioinit: cpioinit.c
|
||||
$(HOSTCC) $(HOSTCFLAGS) -o $@ $^
|
||||
@@ -19,7 +37,9 @@ $(ZFCPDUMP_PART_RD): cpioinit zfcpdump_part
|
||||
install: all
|
||||
$(INSTALL) -m 611 $(ZFCPDUMP_PART_RD) $(DESTDIR)$(ZFCPDUMP_DIR)
|
||||
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -f *.o *.gz *.tmp *~ zfcpdump_part cpioinit $(ZFCPDUMP_PART_RD)
|
||||
|
||||
.PHONY: all clean install
|
||||
.PHONY: all clean install check_dep
|
||||
|
||||
@@ -58,6 +58,7 @@ sub store_mapper_devices
|
||||
my $src_dir = shift();
|
||||
my @entries = grep { ! /^\./ } dir_content($src_dir);
|
||||
|
||||
foreach my $map_dev (@entries) {
|
||||
my $tf = catfile($src_dir, "$map_dev");
|
||||
my $mm = `stat -L -c%t:%T $tf`;
|
||||
chomp($mm);
|
||||
|
||||
@@ -662,7 +662,7 @@ static int init_adapters(struct adapters *all_adapters, struct options *opts)
|
||||
malloc(sizeof(char)*MAX_HOST_PATH_LEN);
|
||||
sprintf(adapter->q_full_path, "%s/queue_full",
|
||||
opts->host_path[i]);
|
||||
if (stat(adapter->path, &buf)) {
|
||||
if (stat(adapter->q_full_path, &buf)) {
|
||||
fprintf(stderr, "%s: Path does not exist: %s - correct kernel version?\n",
|
||||
toolname, adapter->q_full_path);
|
||||
rc++;
|
||||
@@ -806,7 +806,7 @@ static int check_host_param(long *host_nr, char *host_path)
|
||||
}
|
||||
tmp = malloc(strlen(host_path) + strlen("/queue_full") + 1);
|
||||
sprintf(tmp, "%s/queue_full", host_path);
|
||||
if (stat(host_path, &buf)) {
|
||||
if (stat(tmp, &buf)) {
|
||||
fprintf(stderr, "%s: Cannot access %s."
|
||||
" Your installed kernel is probably too old. Please"
|
||||
" check that your kernel matches the level in the"
|
||||
@@ -1009,7 +1009,7 @@ static int parse_params(int argc, char **argv, struct options *opts)
|
||||
|
||||
if (argc <= 1) {
|
||||
print_help();
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* this is too much, but argc/2 is a reliable upper boundary
|
||||
@@ -1296,6 +1296,7 @@ int main(int argc, char **argv)
|
||||
struct timeval first_interval;
|
||||
struct ioerr_wrp *ioerr = NULL;
|
||||
int rc = 0;
|
||||
int parse_params_rc;
|
||||
|
||||
verbose = 0;
|
||||
keep_running = 1;
|
||||
@@ -1304,9 +1305,13 @@ int main(int argc, char **argv)
|
||||
|
||||
init_opts(&opts);
|
||||
|
||||
if (parse_params(argc, argv, &opts)) {
|
||||
parse_params_rc = parse_params(argc, argv, &opts);
|
||||
if (parse_params_rc < 0) {
|
||||
rc = -1;
|
||||
goto out2;
|
||||
} else if (parse_params_rc > 0) {
|
||||
rc = 0;
|
||||
goto out2;
|
||||
}
|
||||
|
||||
if (opts.msg_q_path && setup_msg_q(&opts)) {
|
||||
|
||||
@@ -623,7 +623,7 @@ sub get_dasd_info($)
|
||||
my $type;
|
||||
local *HANDLE;
|
||||
|
||||
open(HANDLE, "$dasdview -x -f $dev 2>/dev/null|") or
|
||||
open(HANDLE, "$dasdview -x $dev 2>/dev/null|") or
|
||||
# dasdview returned with an error
|
||||
return undef;
|
||||
while (<HANDLE>) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user