├── README.md
├── distr
├── firefly_boot_archive_configure.py
├── firefly_boot_archive_contents_x86.xml
└── firefly_pkg_img_mod.py
├── firefly.xml
├── iso
├── checkrpool
├── nodename
├── nonglobal.db
├── rootpool
├── smf
│ ├── console-login
│ ├── fs-root
│ └── manifest-import
└── sulogin
└── rootpool
├── Makefile
└── rootpool.c
/README.md:
--------------------------------------------------------------------------------
1 | # firefly
2 | failsafe image for illumos-based distros
3 |
4 | How To build failsafe image for OmniOS:
5 |
6 | 1. Install distribution-constructor.
7 | 2. Clone git@github.com:alhazred/firefly.git to /opt/firefly
8 | 3. Copy python scripts from the /opt/firefly/distr directory to /usr/lib/python2.6/vendor-packages/solaris_install/distro_const/checkpoints/
9 | 4. From the /opt/firefly directory, run "distro_const build -v firefly.xml"
10 |
--------------------------------------------------------------------------------
/distr/firefly_boot_archive_configure.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # CDDL HEADER START
4 | #
5 | # The contents of this file are subject to the terms of the
6 | # Common Development and Distribution License (the "License").
7 | # You may not use this file except in compliance with the License.
8 | #
9 | # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 | # or http://www.opensolaris.org/os/licensing.
11 | # See the License for the specific language governing permissions
12 | # and limitations under the License.
13 | #
14 | # When distributing Covered Code, include this CDDL HEADER in each
15 | # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 | # If applicable, add the following below this CDDL HEADER, with the
17 | # fields enclosed by brackets "[]" replaced with your own identifying
18 | # information: Portions Copyright [yyyy] [name of copyright owner]
19 | #
20 | # CDDL HEADER END
21 | #
22 |
23 | #
24 | # Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
25 | # Copyright 2015 Nexenta Systems, Inc. All rights reserved.
26 |
27 | """ boot_archive_configure - configure a populated boot archive area into a
28 | usable boot archive.
29 | """
30 | import os
31 | import os.path
32 | import shutil
33 | import datetime
34 |
35 | from osol_install.install_utils import dir_size
36 | from solaris_install import DC_LABEL, run
37 | from solaris_install.data_object.data_dict import DataObjectDict
38 | from solaris_install.transfer.info import Software, Source, Destination, \
39 | CPIOSpec, Dir
40 | from solaris_install.transfer.media_transfer import TRANSFER_ROOT, \
41 | INSTALL_TARGET_VAR
42 | from solaris_install.engine import InstallEngine
43 | from solaris_install.engine.checkpoint import AbstractCheckpoint as Checkpoint
44 |
45 | # load a table of common unix cli calls
46 | import solaris_install.distro_const.cli as cli
47 | cli = cli.CLI()
48 |
49 |
50 | class BootArchiveConfigure(Checkpoint):
51 | """ class to configure the boot archive
52 | """
53 |
54 | DEFAULT_ARG = {"image_type": None}
55 |
56 | def __init__(self, name, arg=DEFAULT_ARG):
57 | super(BootArchiveConfigure, self).__init__(name)
58 | self.image_type = arg.get("image_type",
59 | self.DEFAULT_ARG.get("image_type"))
60 |
61 | # instance attributes
62 | self.doc = None
63 | self.dc_dict = {}
64 | self.pkg_img_path = None
65 | self.ba_build = None
66 |
67 | # set the file_defaults to the path of this checkpoint/defaultfiles
68 | self.file_defaults = os.path.join(
69 | os.path.dirname(os.path.abspath(__file__)), "defaultfiles")
70 |
71 | def get_progress_estimate(self):
72 | """Returns an estimate of the time this checkpoint will take
73 | """
74 | return 20
75 |
76 | def configure_system(self):
77 | """ class method for the execution of various, isolated shell commands
78 | needed to configure the boot archive.
79 | """
80 | self.logger.info("preparing boot archive")
81 |
82 | # configure devices
83 | cmd = [cli.DEVFSADM, "-r", self.ba_build]
84 | run(cmd)
85 |
86 | # etc/dev/.devfsadm_dev.lock gets created every time
87 | # devfsadm is run. remove it since there's no point
88 | # in carrying it forward through to the image
89 | lockfile = os.path.join(self.ba_build, "etc/dev/.devfsadm_dev.lock")
90 | if os.path.exists(lockfile):
91 | self.logger.debug("removing devfsadm lock file")
92 | os.remove(lockfile)
93 |
94 | # Set a marker so that every boot is a reconfiguration boot
95 | cmd = [cli.TOUCH, os.path.join(self.ba_build, "reconfigure")]
96 | run(cmd)
97 |
98 | # go to the ba_build
99 | self.logger.debug("creating symlinks and mountpoints")
100 | os.chdir(self.ba_build)
101 |
102 | # create ./tmp. mkdir and chmod have to be done seperately
103 | self.logger.debug("creating tmp dir and setting it to 01777")
104 | os.mkdir("tmp")
105 | os.chmod("tmp", 01777)
106 |
107 | # create ./proc
108 | self.logger.debug("creating proc directory")
109 | os.mkdir("proc")
110 |
111 | # create ./mnt
112 | self.logger.debug("creating mnt directory")
113 | os.mkdir("mnt")
114 |
115 | # create bin symlink to /usr/bin if needed
116 | self.logger.debug("checking for symlink of bin -> usr/bin")
117 | if not os.path.islink("bin"):
118 | os.symlink("usr/bin", "bin")
119 |
120 | # create mountpoints for misc and pkg zlibs
121 | self.logger.debug("creating mnt/misc and mnt/pkg mountpoints")
122 | #os.mkdir("mnt/misc", 0755)
123 | #os.mkdir("mnt/pkg", 0755)
124 |
125 | # create volume set id file, use system name + date for uniqueness
126 | with open(".volsetid", "w") as v:
127 | volsetid = os.uname()[1] + '-' + \
128 | datetime.datetime.now().isoformat()
129 | self.logger.debug("setting .volsetid to %s" % volsetid)
130 | v.write(volsetid)
131 |
132 | # chmod it to 444 and set the ownership to root:root (0:0)
133 | os.chmod(".volsetid", 0444)
134 | os.chown(".volsetid", 0, 0)
135 |
136 | # create the file marking the image type (e.g. .autoinstall or
137 | # .livecd)
138 | self.logger.debug("creating image_type file")
139 | with open(self.image_type, "w"):
140 | pass
141 |
142 | # create .cdrom directory
143 | self.logger.debug("creating .cdrom directory")
144 | os.mkdir(".cdrom", 0755)
145 |
146 | # create opt symlink to mnt/misc/opt if needed
147 | #self.logger.debug("checking for symlink of opt -> mnt/misc/opt")
148 | #if not os.path.islink("opt"):
149 | # os.symlink("mnt/misc/opt", "opt")
150 |
151 | tr_uninstall = CPIOSpec()
152 | tr_uninstall.action = CPIOSpec.UNINSTALL
153 | tr_uninstall.contents = ["opt"]
154 |
155 | root_tr_software_node = self.doc.persistent.get_descendants(
156 | name=TRANSFER_ROOT, class_type=Software, not_found_is_err=True)[0]
157 | root_tr_software_node.insert_children(tr_uninstall)
158 |
159 | # copy the SMF repository from pkg_image_path to ba_build
160 | #pkg_img_path_repo = os.path.join(self.pkg_img_path,
161 | # "lib/svc/seed/nonglobal.db")
162 | #ba_build_repo = os.path.join(self.ba_build,
163 | # "etc/svc/repository.db")
164 | #shutil.copy2(pkg_img_path_repo, ba_build_repo)
165 |
166 | shutil.copy2("/opt/firefly/iso/nonglobal.db", self.ba_build + "/etc/svc/repository.db")
167 | shutil.copy2("/opt/firefly/iso/nodename", self.ba_build + "/etc/")
168 | shutil.copy2("/opt/firefly/iso/checkrpool", self.ba_build + "/usr/sbin/")
169 | shutil.copy2("/opt/firefly/iso/smf/console-login", self.ba_build + "/lib/svc/method/")
170 | shutil.copy2("/opt/firefly/iso/smf/fs-root", self.ba_build + "/lib/svc/method/")
171 | shutil.copy2("/opt/firefly/iso/smf/manifest-import", self.ba_build + "/lib/svc/method/")
172 | shutil.copy2("/opt/firefly/iso/rootpool", self.ba_build + "/usr/sbin/")
173 | shutil.copy2("/opt/firefly/iso/sulogin", self.ba_build + "/etc/default/")
174 | shutil.copy2(self.pkg_img_path + "/usr/xpg4/bin/vi", self.ba_build + "/usr/bin/")
175 | shutil.copytree(self.pkg_img_path + "/usr/share/lib/keytables", self.ba_build + "/usr/share/lib/keytables")
176 | shutil.copytree(self.pkg_img_path + "/usr/share/lib/terminfo", self.ba_build + "/usr/share/lib/terminfo")
177 | os.chdir(self.ba_build + "/sbin")
178 | os.unlink("sh")
179 | os.symlink("../usr/bin/bash", "sh")
180 | os.chdir(self.ba_build)
181 |
182 |
183 | def configure_symlinks(self):
184 | """ class method for the configuration of symlinks needed in the boot
185 | archive.
186 | """
187 | self.logger.debug("Creating additional symlinks in ramdisk")
188 |
189 | self.logger.debug("creating set of files in pkg_img_path: %s" % \
190 | self.pkg_img_path)
191 |
192 | # change to the pkg_img_path directory
193 | os.chdir(self.pkg_img_path)
194 |
195 | # walk /etc and /var in pkg_img_path and create a list of
196 | # directories
197 | pkg_img_dirs = []
198 | for rootdir in ["etc", "var"]:
199 | for root, dirs, files in os.walk(rootdir):
200 | for d in dirs:
201 | pkg_img_dirs.append(os.path.join(root, d))
202 |
203 | # change to the boot_archive directory
204 | os.chdir(self.ba_build)
205 |
206 | # walk the pkg_img_dirs list and create each directory that doesn't
207 | # already exist. Also, copy the directory permissions and metadata
208 | # to the new directory
209 | for d in pkg_img_dirs:
210 | ba_path = os.path.join(self.ba_build, d)
211 | pkg_path = os.path.join(self.pkg_img_path, d)
212 |
213 | # split the directory on / to verify parent directories exist
214 | dir_list = d.split("/")
215 |
216 | # keep a 'path' string for verification
217 | path = ""
218 | for subdir in dir_list:
219 | # extend path
220 | path = os.path.join(path, subdir)
221 | full_path = os.path.join(self.ba_build, path)
222 |
223 | # check to see if it exists and is not already a symlink
224 | if not os.path.exists(full_path) and \
225 | not os.path.islink(full_path):
226 |
227 | # create the directory
228 | os.mkdir(os.path.join(self.ba_build, path))
229 |
230 | # copy the metadata from pkg_image to boot_archive
231 | shutil.copystat(os.path.join(self.pkg_img_path, path),
232 | os.path.join(self.ba_build, path))
233 |
234 | # copy the uid/gid as well
235 | pkg_statinfo = os.stat(os.path.join(self.pkg_img_path,
236 | path))
237 |
238 | os.chown(os.path.join(self.ba_build, path),
239 | pkg_statinfo.st_uid, pkg_statinfo.st_gid)
240 |
241 | # now that the directory structure is created, create symlinks for
242 | # all the missing files in the boot_archive
243 |
244 | # change to the pkg_img_path directory
245 | os.chdir(self.pkg_img_path)
246 |
247 | # keep track of all the symlinks created
248 | misc_symlinks = []
249 | for rootdir in ["etc", "var"]:
250 | for root, dirs, files in os.walk(rootdir):
251 | for f in files:
252 | pkg_path = os.path.join(self.pkg_img_path, root, f)
253 |
254 | # skip symlinks
255 | if os.path.islink(pkg_path):
256 | continue
257 |
258 | ba_path = os.path.join(self.ba_build, root, f)
259 | if not os.path.exists(ba_path):
260 | # the file is missing from the boot_archive so
261 | # create a symlink to /mnt/misc/file/path
262 | misc_path = os.path.join("/mnt/misc", root, f)
263 |
264 | # save the cwd
265 | cwd = os.getcwd()
266 |
267 | # changedir to the dirname of the file
268 | os.chdir(os.path.dirname(ba_path))
269 |
270 | # create the symlink
271 | os.symlink(misc_path, f)
272 |
273 | os.chdir(cwd)
274 |
275 | misc_symlinks.append(os.path.join(root, f))
276 |
277 | # We don't want readonly ttymon log in misc
278 | os.remove(os.path.join(self.ba_build,"var/saf/zsmon/log"))
279 |
280 | tr_uninstall = CPIOSpec()
281 | tr_uninstall.action = CPIOSpec.UNINSTALL
282 | tr_uninstall.contents = misc_symlinks
283 |
284 | # Add that into the software transfer list. The list of files to
285 | # uninstall MUST go before the contents to be installed from /mnt/misc
286 | root_tr_software_node = self.doc.persistent.get_descendants(
287 | name=TRANSFER_ROOT, class_type=Software, not_found_is_err=True)[0]
288 |
289 | root_tr_software_node.insert_children(tr_uninstall)
290 |
291 | self.logger.debug(str(self.doc.persistent))
292 |
293 | def parse_doc(self):
294 | """ class method for parsing data object cache (DOC) objects for use by
295 | the checkpoint.
296 | """
297 | self.doc = InstallEngine.get_instance().data_object_cache
298 | self.dc_dict = self.doc.volatile.get_children(name=DC_LABEL,
299 | class_type=DataObjectDict)[0].data_dict
300 |
301 | try:
302 | self.pkg_img_path = self.dc_dict["pkg_img_path"]
303 | self.ba_build = self.dc_dict["ba_build"]
304 | except KeyError:
305 | raise RuntimeError("Error retrieving a value from the DOC")
306 |
307 | def add_root_transfer_to_doc(self):
308 | """ Adds the list of files of directories to be transferred
309 | to the DOC
310 | """
311 | if self.doc is None:
312 | self.doc = InstallEngine.get_instance().data_object_cache
313 |
314 | src_path = Dir("/")
315 | src = Source()
316 | src.insert_children(src_path)
317 |
318 | dst_path = Dir(INSTALL_TARGET_VAR)
319 | dst = Destination()
320 | dst.insert_children(dst_path)
321 |
322 | dot_node = CPIOSpec()
323 | dot_node.action = CPIOSpec.INSTALL
324 | dot_node.size = str(dir_size(os.path.join(self.ba_build, "")))
325 | dot_node.contents = ["."]
326 |
327 | usr_node = CPIOSpec()
328 | usr_node.action = CPIOSpec.INSTALL
329 | usr_node.size = str(dir_size(os.path.join(self.pkg_img_path, "usr")))
330 | usr_node.contents = ["usr"]
331 |
332 | dev_node = CPIOSpec()
333 | dev_node.action = CPIOSpec.INSTALL
334 | dev_node.size = str(dir_size(os.path.join(self.pkg_img_path, "dev")))
335 | dev_node.contents = ["dev"]
336 |
337 | software_node = Software(TRANSFER_ROOT, type="CPIO")
338 | software_node.insert_children([src, dst, dot_node, usr_node, dev_node])
339 |
340 | self.doc.persistent.insert_children(software_node)
341 |
342 | self.logger.debug(str(self.doc.persistent))
343 |
344 | def execute(self, dry_run=False):
345 | """ Primary execution method used by the Checkpoint parent class.
346 | dry_run is not used in DC
347 | """
348 | self.logger.info("=== Executing Boot Archive Configuration" + \
349 | " Checkpoint ===")
350 |
351 | self.parse_doc()
352 |
353 | self.add_root_transfer_to_doc()
354 |
355 | # configure various boot archive files
356 | self.configure_system()
357 |
358 | # configure various symlinks
359 | self.configure_symlinks()
360 |
361 |
362 | class TextBootArchiveConfigure(BootArchiveConfigure, Checkpoint):
363 | """ TextBootArchiveConfigure - class to configure the boot archive
364 | directory specific to the text install media
365 | """
366 |
367 | DEFAULT_ARG = {"image_type": ".textinstall"}
368 |
369 | def __init__(self, name, arg=DEFAULT_ARG):
370 | """ constructor for class.
371 | image_type - string containing the image_type (.autoinstall, .livecd)
372 | """
373 | super(TextBootArchiveConfigure, self).__init__(name, arg)
374 | self.image_type = arg.get("image_type",
375 | self.DEFAULT_ARG.get("image_type"))
376 |
--------------------------------------------------------------------------------
/distr/firefly_boot_archive_contents_x86.xml:
--------------------------------------------------------------------------------
1 |
2 |
26 |
27 | sbin
28 | usr/bin/bash
29 | usr/bin/ckitem
30 | usr/bin/logname
31 | usr/bin/nawk
32 | usr/bin/mkdir
33 | usr/bin/loadkeys
34 | usr/bin/cp
35 | usr/bin/head
36 | usr/bin/sort
37 | usr/bin/svcs
38 | usr/bin/amd64/sort
39 | usr/bin/amd64/truss
40 | usr/bin/i386/wget
41 | usr/bin/pkill
42 | usr/bin/mkfifo
43 | usr/bin/egrep
44 | usr/bin/pgrep
45 | usr/sbin/autopush
46 | usr/sbin/beadm
47 | usr/sbin/pmadm
48 | usr/sbin/format
49 | usr/sbin/fdisk
50 | sbin/biosdev
51 | usr/sbin/bootadm
52 | usr/sbin/cryptoadm
53 | sbin/dhcpagent
54 | sbin/dhcpinfo
55 | usr/sbin/dladm
56 | sbin/dlmgmtd
57 | usr/sbin/dlstat
58 | usr/sbin/fdisk
59 | usr/sbin/fiocompress
60 | usr/sbin/flowadm
61 | usr/sbin/flowstat
62 | usr/sbin/hostconfig
63 | usr/sbin/ifconfig
64 | sbin/ifparse
65 | usr/sbin/init
66 | sbin/in.mpathd
67 | usr/sbin/installgrub
68 | usr/sbin/ipadm
69 | usr/sbin/ipmpstat
70 | usr/bin/jsh
71 | usr/sbin/mount
72 | usr/sbin/mountall
73 | usr/sbin/mount_media
74 | sbin/netstrategy
75 |
77 | usr/bin/pfsh
78 | sbin/rc0
79 | sbin/rc1
80 | sbin/rc2
81 | sbin/rc3
82 | sbin/rc5
83 | sbin/rc6
84 | sbin/rcS
85 | usr/sbin/route
86 | usr/sbin/routeadm
87 | sbin/soconfig
88 | sbin/sh
89 | sbin/su
90 | sbin/sulogin
91 | sbin/swapadd
92 | usr/sbin/sync
93 | usr/sbin/tzreload
94 | usr/sbin/uadmin
95 | usr/sbin/umount
96 | usr/sbin/umountall
97 | usr/bin/uname
98 | usr/sbin/wusbadm
99 | usr/sbin/zfs
100 | usr/bin/zonename
101 | usr/sbin/zpool
102 | usr/sbin/svcadm
103 | usr/sbin/svccfg
104 | usr/sbin/prtconf
105 | usr/sbin/amd64/prtconf
106 |
107 | usr/bin/sh
108 | usr/bin/hostname
109 | usr/sbin/ipsecalgs
110 | usr/sbin/fcadm
111 | usr/lib/sysevent/syseventd
112 | usr/lib/libgcc_s.so.1
113 | usr/lib/libxml2.so
114 | usr/lib/libxml2.so.2
115 | usr/lib/libxml2.so.2.9.1
116 | usr/lib/libdiskmgt.so.1
117 | usr/lib/libz.so.1.2.8
118 | usr/lib/libipsecutil.so.1
119 | usr/lib/libHBAAPI.so.1
120 | usr/lib/libfcoe.so.1
121 | usr/lib/amd64/libsaveargs.so.1
122 | usr/lib/libsmbios.so.1
123 | usr/lib/libtecla.so.1
124 | usr/lib/libl.so.1
125 | usr/lib/libexacct.so.1
126 | usr/lib/libpool.so.1
127 | usr/lib/libidmap.so.1
128 | usr/lib/libldap.so.5
129 | usr/lib/libsldap.so.1
130 | usr/lib/libadutils.so.1
131 | usr/lib/libsasl.so.1
132 | usr/lib/mps/libnspr4.so
133 | usr/lib/mps/libplc4.so
134 | usr/lib/mps/libnss3.so
135 | usr/lib/mps/libssl3.so
136 | usr/lib/mps/libnssutil3.so
137 | usr/lib/mps/libplds4.so
138 | usr/sbin/lofiadm
139 | usr/sbin/devfsadm
140 | usr/sbin/modload
141 | usr/sbin/amd64/modload
142 | usr/sbin/mount
143 | usr/sbin/hostconfig
144 | usr/sbin/chroot
145 | usr/sbin/syslogd
146 | usr/sbin/df
147 | usr/bin/coreadm
148 | usr/bin/bash
149 | usr/bin/ksh
150 | usr/bin/cut
151 | usr/bin/sed
152 | usr/bin/more
153 | usr/bin/cat
154 | usr/bin/echo
155 | usr/bin/false
156 | usr/bin/grep
157 | usr/bin/ls
158 | usr/bin/rm
159 | usr/bin/svcprop
160 | usr/bin/true
161 | usr/bin/cd
162 | usr/bin/test
163 | usr/bin/sleep
164 | usr/bin/expr
165 | usr/bin/wget
166 | usr/lib/fs/hsfs/fstyp
167 | usr/lib/fs/hsfs/fstyp.so.1
168 | usr/lib/fs/hsfs/mount
169 | usr/lib/fs/tmpfs/mount
170 | usr/lib/fs/ufs/fstyp
171 | usr/lib/fs/ufs/fstyp.so.1
172 | usr/lib/fs/ufs/mount
173 | usr/lib/libfstyp.so.1
174 | usr/lib/platexec
175 | usr/lib/devfsadm/linkmod/SUNW_cfg_link.so
176 | usr/lib/devfsadm/linkmod/SUNW_disk_link.so
177 | usr/lib/devfsadm/linkmod/SUNW_fssnap_link.so
178 | usr/lib/devfsadm/linkmod/SUNW_ieee1394_link.so
179 | usr/lib/devfsadm/linkmod/SUNW_lofi_link.so
180 | usr/lib/devfsadm/linkmod/SUNW_misc_link.so
181 | usr/lib/devfsadm/linkmod/SUNW_misc_link_i386.so
182 | usr/lib/devfsadm/linkmod/SUNW_port_link.so
183 | usr/lib/devfsadm/linkmod/SUNW_ramdisk_link.so
184 | usr/lib/devfsadm/linkmod/SUNW_sgen_link.so
185 | usr/lib/devfsadm/linkmod/SUNW_tape_link.so
186 | usr/lib/devfsadm/linkmod/SUNW_usb_link.so
187 | usr/lib/devfsadm/linkmod/SUNW_zfs_link.so
188 | usr/lib/devfsadm/devfsadmd
189 | usr/lib/iconv/alias
190 | usr/lib/iconv/646%UTF-8.so
191 | usr/lib/iconv/UTF-8%646.so
192 | usr/lib/libm.so.2
193 | usr/lib/libm.so
194 | usr/lib/libfstyp.so
195 | usr/lib/libz.so
196 | usr/lib/libz.so.1
197 | usr/bin/i86/ksh
198 | usr/bin/i86/ksh93
199 | usr/lib/isaexec
200 | usr/lib/libast.so.1
201 | usr/lib/libcmd.so.1
202 | usr/lib/libdll.so.1
203 | usr/lib/libshell.so.1
204 | usr/lib/libcrypt.so.1
205 | usr/lib/inet/wanboot/netbootinfo
206 |
207 | usr/lib/libwanbootutil.so.1
208 | usr/lib/libwanboot.so.1
209 | usr/lib/libidn.so.11
210 | usr/lib/libidn.so.11.6.13
211 | usr/lib/libmapmalloc.so.1
212 | usr/lib/libcrypto.so.1.0.0
213 | usr/lib/libssl.so.1.0.0
214 | usr/share/lib/xml/dtd/service_bundle.dtd.1
215 | usr/share/lib/termcap
216 | var/sadm/install/admin/default
217 | var/sadm/system/admin/default_java
218 | var/sadm/install/contents
219 | var/adm/utmpx
220 | var/adm/wtmpx
221 | var/adm/aculog
222 | var/log/authlog
223 | var/log/syslog
224 | var/run
225 | var/spool/cron/crontabs/adm
226 | var/spool/cron/crontabs/root
227 | var/yp/aliases
228 | var/yp/nicknames
229 |
230 | usr/lib/fm/libtopo.so.1
231 | usr/lib/fm/amd64/libtopo.so.1
232 | usr/lib/fm/libfmd_agent.so.1
233 |
234 | usr/lib/libipmi.so.1
235 | usr/lib/amd64/libipmi.so.1
236 | usr/lib/libcurl.so.4
237 | usr/lib/libcurl.so.4.3.0
238 | usr/lib/libgss.so.1
239 |
240 | usr/lib/libpkcs11.so.1
241 | usr/lib/amd64/libpkcs11.so.1
242 | usr/lib/fm/topo/plugins/fac_prov_ipmi.so
243 | usr/lib/fm/topo/plugins/disk.so
244 |
245 | usr/lib/fm/topo/plugins/xfp.so
246 |
247 | usr/lib/fm/topo/plugins/ses.so
248 | usr/lib/fm/topo/plugins/ipmi.so
249 | usr/lib/fm/topo/maps/xfp-hc-topology.xml
250 | usr/platform/i86pc/lib/fm/topo/plugins/x86pi.so
251 | usr/platform/i86pc/lib/fm/topo/plugins/pcibus.so
252 | usr/platform/i86pc/lib/fm/topo/plugins/chip.so
253 | usr/platform/i86pc/lib/fm/topo/plugins/hostbridge.so
254 | usr/platform/i86pc/lib/fm/topo/maps/i86pc-hc-topology.xml
255 | usr/platform/i86pc/lib/fm/topo/maps/i86pc-legacy-hc-topology.xml
256 | usr/platform/i86pc/lib/fm/topo/maps/chassis-hc-topology.xml
257 | usr/platform/i86pc/lib/fm/topo/maps/Sun-Fire-X4600-M2-disk-hc-topology.xml
258 | usr/platform/i86pc/lib/fm/topo/maps/chip-hc-topology.xml
259 | usr/platform/i86pc/lib/fm/topo/maps/Sun-Fire-X4500-disk-hc-topology.xml
260 | usr/platform/i86pc/lib/fm/topo/maps/Netra-X4200-M2-disk-hc-topology.xml
261 | usr/platform/i86pc/lib/fm/topo/maps/Sun-Fire-X4200-Server-disk-hc-topology.xml
262 | usr/platform/i86pc/lib/fm/topo/maps/psu-hc-topology.xml
263 | usr/platform/i86pc/lib/fm/topo/maps/fan-hc-topology.xml
264 | usr/platform/i86pc/lib/fm/topo/maps/Sun-Fire-X4200-M2-disk-hc-topology.xml
265 | usr/platform/i86pc/lib/fm/topo/maps/SUN-FIRE-X4270-M2-SERVER-disk-hc-topology.xml
266 | usr/platform/i86pc/lib/fm/topo/maps/Sun-Fire-X4540-disk-hc-topology.xml
267 | usr/share/lib/xml/dtd/topology.dtd.1
268 |
269 |
270 | usr/bin/su
271 | usr/lib/libproject.so.1
272 | usr/lib/security/pam_authtok_get.so.1
273 | usr/lib/security/pam_dhkeys.so.1
274 | usr/lib/security/pam_unix_cred.so.1
275 | usr/lib/security/pam_unix_auth.so.1
276 | usr/lib/security/pam_dial_auth.so.1
277 |
278 |
--------------------------------------------------------------------------------
/distr/firefly_pkg_img_mod.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # CDDL HEADER START
4 | #
5 | # The contents of this file are subject to the terms of the
6 | # Common Development and Distribution License (the "License").
7 | # You may not use this file except in compliance with the License.
8 | #
9 | # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 | # or http://www.opensolaris.org/os/licensing.
11 | # See the License for the specific language governing permissions
12 | # and limitations under the License.
13 | #
14 | # When distributing Covered Code, include this CDDL HEADER in each
15 | # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 | # If applicable, add the following below this CDDL HEADER, with the
17 | # fields enclosed by brackets "[]" replaced with your own identifying
18 | # information: Portions Copyright [yyyy] [name of copyright owner]
19 | #
20 | # CDDL HEADER END
21 | #
22 |
23 | #
24 | # Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
25 | # Copyright 2015 Nexenta Systems, Inc. All rights reserved.
26 |
27 | """ pkg_img_mod
28 |
29 | Customizations to the package image area after the boot archive
30 | has been created
31 |
32 | """
33 | import os
34 | import platform
35 | import shutil
36 |
37 | from osol_install.install_utils import dir_size, file_size
38 | from solaris_install import CalledProcessError, DC_LABEL, Popen, run
39 | from solaris_install.data_object.data_dict import DataObjectDict
40 | from solaris_install.engine import InstallEngine
41 | from solaris_install.engine.checkpoint import AbstractCheckpoint as Checkpoint
42 | from solaris_install.transfer.info import Software, Source, Destination, \
43 | CPIOSpec, Dir
44 | from solaris_install.transfer.media_transfer import TRANSFER_MEDIA, \
45 | INSTALL_TARGET_VAR, MEDIA_DIR_VAR, TRANSFER_MANIFEST_NAME, \
46 | TRANSFER_MISC
47 | from solaris_install.manifest.writer import ManifestWriter
48 |
49 | # load a table of common unix cli calls
50 | import solaris_install.distro_const.cli as cli
51 | cli = cli.CLI()
52 |
53 |
54 | class PkgImgMod(Checkpoint):
55 | """ PkgImgMod - class to modify the pkg_image directory after the boot
56 | archive is built.
57 | """
58 |
59 | DEFAULT_ARG = {"compression_type": "gzip"}
60 | VALID_COMPRESSION = ["gzip", "lzma"]
61 |
62 | def __init__(self, name, arg=DEFAULT_ARG):
63 | super(PkgImgMod, self).__init__(name)
64 | self.compression_type = arg.get("compression_type",
65 | self.DEFAULT_ARG.get("compression_type"))
66 |
67 | if self.compression_type not in self.VALID_COMPRESSION:
68 | raise RuntimeError("invalid compression_type: " +
69 | self.compression_type)
70 |
71 | self.dist_iso_sort = arg.get("dist_iso_sort")
72 |
73 | # instance attributes
74 | self.doc = None
75 | self.dc_dict = {}
76 | self.pkg_img_path = None
77 | self.ba_build = None
78 | self.tmp_dir = None
79 |
80 | def get_progress_estimate(self):
81 | """Returns an estimate of the time this checkpoint will take"""
82 | return 415
83 |
84 | def parse_doc(self):
85 | """ class method for parsing data object cache (DOC) objects for use by
86 | the checkpoint.
87 | """
88 | self.doc = InstallEngine.get_instance().data_object_cache
89 | self.dc_dict = self.doc.volatile.get_children(name=DC_LABEL,
90 | class_type=DataObjectDict)[0].data_dict
91 |
92 | try:
93 | self.pkg_img_path = self.dc_dict["pkg_img_path"]
94 | self.tmp_dir = self.dc_dict["tmp_dir"]
95 | self.ba_build = self.dc_dict["ba_build"]
96 | except KeyError, msg:
97 | raise RuntimeError("Error retrieving a value from the DOC: " +
98 | str(msg))
99 |
100 | def strip_root(self):
101 | """ class method to clean up the root of the package image path
102 | """
103 | if not os.path.isdir(self.pkg_img_path):
104 | raise RuntimeError("Package Image path " + self.pkg_img_path +
105 | " is not valid")
106 |
107 | # Copy the volsetid to the root of the image
108 | shutil.copy(os.path.join(self.ba_build, ".volsetid"),
109 | self.pkg_img_path)
110 |
111 | # Remove the password lock file left around from user actions
112 | # during package installation; if left in place it becomes a
113 | # symlink into /mnt/misc which causes installer's attempt to
114 | # create a user account to fail
115 | if os.path.exists(os.path.join(self.pkg_img_path,
116 | "etc/.pwd.lock")):
117 | os.remove(self.pkg_img_path + "/etc/.pwd.lock")
118 |
119 | os.chdir(self.pkg_img_path)
120 |
121 | # sbin, kernel and lib are contained within the boot_archive
122 | # Thus, not needed in the pkg_image area
123 | self.logger.info("Removing sbin, kernel and lib from " +
124 | "pkg_image area")
125 | shutil.rmtree("sbin", ignore_errors=True)
126 | shutil.rmtree("kernel", ignore_errors=True)
127 | shutil.rmtree("lib", ignore_errors=True)
128 | os.unlink("bin")
129 | shutil.rmtree("usr", ignore_errors=True)
130 | shutil.rmtree("sbin", ignore_errors=True)
131 | shutil.rmtree("etc", ignore_errors=True)
132 | shutil.rmtree("home", ignore_errors=True)
133 | shutil.rmtree("tmp", ignore_errors=True)
134 | shutil.rmtree("jack", ignore_errors=True)
135 | shutil.rmtree("system", ignore_errors=True)
136 | shutil.rmtree("opt", ignore_errors=True)
137 | shutil.rmtree("root", ignore_errors=True)
138 | shutil.rmtree("proc", ignore_errors=True)
139 | shutil.rmtree("export", ignore_errors=True)
140 | shutil.rmtree("dev", ignore_errors=True)
141 | shutil.rmtree("devices", ignore_errors=True)
142 | shutil.rmtree("var", ignore_errors=True)
143 | shutil.rmtree("save", ignore_errors=True)
144 | shutil.rmtree("mnt", ignore_errors=True)
145 | os.unlink("reconfigure")
146 |
147 |
148 | def strip_x86_platform(self):
149 | """ class method to clean up the package image path for x86 systems
150 | """
151 | # save the current working directory
152 | cwd = os.getcwd()
153 |
154 | os.chdir(os.path.join(self.pkg_img_path, "platform"))
155 | # walk the directory tree and remove anything other than the kernel
156 | # and boot_archive files
157 | for (root, _none, files) in os.walk("."):
158 | for f in files:
159 | if f == "unix" or f == "boot_archive":
160 | continue
161 | else:
162 | self.logger.debug("removing " + os.path.join(root, f))
163 | os.unlink(os.path.join(root, f))
164 |
165 | # copy the platform directory to /boot since grub does not understand
166 | # symlinks
167 | os.chdir(self.pkg_img_path)
168 | shutil.copytree(os.path.join(self.pkg_img_path, "platform"),
169 | os.path.join(self.pkg_img_path, "boot/platform"),
170 | symlinks=True)
171 |
172 | os.chdir(cwd)
173 |
174 | def strip_sparc_platform(self):
175 | """ class method to clean up the package image path for sparc systems
176 | """
177 | os.chdir(os.path.join(self.pkg_img_path, "platform"))
178 | # walk the directory tree and remove anything other than wanboot
179 | # and boot_archive files
180 | for (root, _none, files) in os.walk("."):
181 | for f in files:
182 | if f == "wanboot" or f == "boot_archive":
183 | continue
184 | else:
185 | self.logger.debug("removing " + os.path.join(root, f))
186 | os.unlink(os.path.join(root, f))
187 |
188 | # symlink the platform directory in boot:
189 | # boot/platform -> ../platform
190 | os.chdir(self.pkg_img_path)
191 | os.symlink(os.path.join("..", "platform"),
192 | os.path.join(self.pkg_img_path, "boot/platform"))
193 |
194 | def add_content_list_to_doc(self, content_list):
195 | src_path = Dir(MEDIA_DIR_VAR)
196 | src = Source()
197 | src.insert_children(src_path)
198 |
199 | dst_path = Dir(INSTALL_TARGET_VAR)
200 | dst = Destination()
201 | dst.insert_children(dst_path)
202 |
203 | media_install = CPIOSpec()
204 | media_install.action = CPIOSpec.INSTALL
205 | media_install.contents = content_list
206 | total_size_byte = 0
207 | for content in content_list:
208 | content_path = os.path.join(self.pkg_img_path, content)
209 | # only want to calculate the size of files, since directories
210 | # are traversed and it's files are included in the list.
211 | if not os.path.isdir(content_path):
212 | total_size_byte += file_size(content_path)
213 | media_install.size = str(total_size_byte)
214 |
215 | media_soft_node = Software(TRANSFER_MEDIA, type="CPIO")
216 | media_soft_node.insert_children([src, dst, media_install])
217 |
218 | # Add that into the software transfer list.
219 | self.doc.persistent.insert_children(media_soft_node)
220 |
221 | # call manifest writer to write out the content of
222 | # the transfer manifest
223 | manifest_out = os.path.join(self.pkg_img_path, TRANSFER_MANIFEST_NAME)
224 | xslt_name = os.path.join(os.path.dirname(os.path.abspath(__file__)),
225 | "xslt", "doc2_media_transfer.xslt")
226 | manifest_writer = ManifestWriter("manifest-writer",
227 | manifest_out, xslt_file=xslt_name)
228 | manifest_writer.write(self.doc)
229 |
230 | def populate_livecd_content(self):
231 | """ class method to populate content of live media's root into DOC
232 | """
233 | # save the current working directory
234 | cwd = os.getcwd()
235 |
236 | # change to the pkg_img_path
237 | os.chdir(self.pkg_img_path)
238 |
239 | content_list = []
240 | for root, dirs, files in os.walk("."):
241 | for f in files:
242 | if not f.endswith(".zlib") and not f.endswith(".image_info") \
243 | and not f.endswith("boot_archive") and not \
244 | f.endswith(".media-transfer.xml"):
245 | content_list.append(os.path.join(root, f))
246 | for d in dirs:
247 | content_list.append(os.path.join(root, d))
248 |
249 | self.add_content_list_to_doc(content_list)
250 |
251 | os.chdir(cwd)
252 |
253 | def populate_save_list(self):
254 | '''Store a list of files under the 'save' directory. Net-booted
255 | text installer uses this list to determine what files it needs from
256 | the boot server
257 | '''
258 | save_files = []
259 | save_dir = os.path.join(self.pkg_img_path, "save")
260 | for root, _none, files in os.walk(save_dir):
261 | for f in files:
262 | relpath = os.path.relpath(os.path.join(root, f),
263 | start=self.pkg_img_path)
264 | save_files.append(relpath)
265 |
266 | self.add_content_list_to_doc(save_files)
267 |
268 | def execute(self, dry_run=False):
269 | """Customize the pkg_image area. Assumes that a populated pkg_image
270 | area exists and that the boot_archive has been built
271 | dry_run is not used in DC
272 | """
273 | self.logger.info("=== Executing Pkg Image Modification Checkpoint ===")
274 |
275 | self.parse_doc()
276 |
277 | # clean up the root of the package image path
278 | self.strip_root()
279 |
280 |
281 | class TextPkgImgMod(PkgImgMod, Checkpoint):
282 | """ TextPkgImgMod - class to modify the pkg_image directory after the boot
283 | archive is built for Text media
284 | """
285 |
286 | DEFAULT_ARG = {"compression_type": "gzip"}
287 |
288 | def __init__(self, name, arg=DEFAULT_ARG):
289 | super(TextPkgImgMod, self).__init__(name, arg)
290 |
291 | def execute(self, dry_run=False):
292 | """ Customize the pkg_image area. Assumes that a populated pkg_image
293 | area exists and that the boot_archive has been built
294 | """
295 | self.logger.info("=== Executing Pkg Image Modification Checkpoint ===")
296 |
297 | self.parse_doc()
298 |
299 | # clean up the root of the package image path
300 | self.strip_root()
301 |
302 | # get the platform of the system
303 | arch = platform.processor()
304 |
305 | # save the current working directory
306 | cwd = os.getcwd()
307 | try:
308 | # clean up the package image path based on the platform
309 | if arch == "i386":
310 | self.strip_x86_platform()
311 | else:
312 | self.strip_sparc_platform()
313 |
314 |
315 | # populate live cd's content into DOC
316 | #self.populate_save_list()
317 | finally:
318 | # return to the initial directory
319 | os.chdir(cwd)
320 |
321 |
--------------------------------------------------------------------------------
/firefly.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
29 |
30 |
36 |
37 |
41 |
42 |
43 |
44 |
54 |
55 |
85 |
89 |
90 |
91 |
92 |
93 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
108 |
116 |
117 |
118 |
120 |
121 |
122 |
123 |
124 |
127 |
130 |
131 |
132 |
135 |
142 |
143 |
153 |
154 | pkg:/entire@latest
155 | pkg:/system/install/text-install@latest
156 | pkg:/system/library/install@latest
157 | pkg:/system/install/media/internal@latest
158 | pkg:/system/install/configuration@latest
159 | pkg:/system/install@latest
160 | pkg:/service/storage/media-volume-manager
161 |
162 |
163 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
179 |
180 |
182 |
189 |
190 |
191 |
194 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
206 |
207 | kernel
208 | boot
209 | platform
210 | system
211 | lib
212 | dev
213 | devices
214 | usr/lib/devfsadm/linkmod
215 | root
216 | jack
217 | sbin/ibd_delete_link
218 | sbin/ibd_upgrade
219 | var/svc/manifest
220 | var/svc/profile
221 | var/sadm
222 | etc
223 |
224 |
225 | etc/gconf
226 | etc/brltty
227 | etc/gtk-2.0
228 | etc/notices
229 | var/sadm/pkg
230 |
231 |
232 |
236 |
237 |
241 |
242 | true
243 |
244 |
245 |
249 |
253 |
256 |
260 |
261 |
262 | true
263 |
264 | firefly
265 |
266 |
267 |
268 |
272 |
276 |
277 |
281 |
291 |
292 | gzip
293 | 9
294 | 0
295 | 0
296 |
297 |
298 |
302 |
306 |
311 |
312 |
313 | /usr/share/distro_const/sort/text_x86.sort
314 | lzma
315 |
316 |
317 |
321 |
322 |
327 |
328 |
329 |
334 |
336 |
337 |
338 |
340 |
341 |
342 |
344 |
345 |
346 |
348 |
349 |
350 |
351 |
352 |
--------------------------------------------------------------------------------
/iso/checkrpool:
--------------------------------------------------------------------------------
1 | #!/bin/ksh
2 |
3 | # Discover and mount root pool to /a
4 | # Copyright 2015 Nexenta Systems, Inc. All rights reserved.
5 |
6 | rpool_mount()
7 | {
8 | pool=$1
9 | id=$2
10 |
11 | echo "Mounting pool:$pool with guid:$id to /a"
12 | zpool import -f -N -R /a $id > /dev/null 2>&1
13 | zpool list $pool > /dev/null 2>&1
14 | [[ $? == 0 ]] || ( echo "Can't import $pool" && return )
15 | bootfs=$(zpool get bootfs $pool | grep bootfs | nawk '{ print $3 }')
16 | echo "Mounting $bootfs to /a"
17 | zfs mount $bootfs
18 | [[ $? == 0 ]] || ( echo "Can't mount $bootfs" && return )
19 |
20 | }
21 |
22 | poolnum=0
23 | pools=
24 |
25 | rootpool > /tmp/rootpool 2>&1
26 |
27 | cat /tmp/rootpool | while read line ; do
28 | if echo $line | egrep "^[a-zA-Z0-9_.-]+;.*" >/dev/null; then
29 | poolnum=`expr $poolnum + 1`
30 | name=$(echo $line | nawk '{ split ($0,a,";"); print a[1] }')
31 | id=$(echo $line | nawk '{ split ($0,a,";"); print a[2] }')
32 | pools="$pools $name:$id"
33 | fi
34 | done
35 |
36 | if [ "$poolnum" -eq 0 ]; then
37 | echo "No operating system found, exiting to shell"
38 | elif [ "$poolnum" -eq 1 ]; then
39 | name=$(echo ${pools%%:*})
40 | id=$(echo ${pools##*:})
41 | echo "Found installed operating system at pool:$name"
42 | rpool_mount $name $id
43 | else
44 | echo "Found multiple operating system instances:"
45 | choice=$(ckitem -p "To select which root pool to import, enter a number" ${pools[*]})
46 | name=$(echo ${choice%%:*})
47 | id=$(echo ${choice##*:})
48 | rpool_mount $name $id
49 | fi
50 |
--------------------------------------------------------------------------------
/iso/nodename:
--------------------------------------------------------------------------------
1 | firefly
2 |
3 |
--------------------------------------------------------------------------------
/iso/nonglobal.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alhazred/firefly/f62b72d0df3d66a1c97d0c333c3c385e5cc1d878/iso/nonglobal.db
--------------------------------------------------------------------------------
/iso/rootpool:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alhazred/firefly/f62b72d0df3d66a1c97d0c333c3c385e5cc1d878/iso/rootpool
--------------------------------------------------------------------------------
/iso/smf/console-login:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright 2015 Nexenta Systems, Inc. All rights reserved.
4 |
5 | TERM=sun-color
6 | USER=root
7 | HOME=/root
8 | PATH=/sbin:/usr/sbin:/usr/bin
9 | TERMINFO=/usr/share/lib/terminfo
10 | EDITOR=vi
11 | SHELL=bash
12 | PAGER='/usr/bin/less -ins'
13 | PS1="\e[0;32m\u@\h# \e[m"
14 |
15 | export TERM USER HOME PATH TERMINFO EDITOR SHELL PAGER PS1
16 |
17 | /usr/sbin/checkrpool
18 |
19 | /sbin/sulogin
20 |
--------------------------------------------------------------------------------
/iso/smf/fs-root:
--------------------------------------------------------------------------------
1 | #!/sbin/sh
2 |
3 | . /lib/svc/share/smf_include.sh
4 | . /lib/svc/share/fs_include.sh
5 |
6 |
7 | # Make sure that the libraries essential to this stage of booting can be found.
8 | LD_LIBRARY_PATH=/lib; export LD_LIBRARY_PATH
9 |
10 | libc_mount() {
11 | #
12 | # If there is an optimized libc available in /usr that fits this
13 | # processor, mount it on top of the base libc.
14 | #
15 | LIBC_MOE_32=`/usr/bin/moe -32 '/usr/lib/libc/$HWCAP'`
16 | if [ -n "$LIBC_MOE_32" ]; then
17 | /usr/sbin/mount | egrep -s "^/lib/libc.so.1 on "
18 | if [ $? -ne 0 ]; then
19 | /usr/sbin/mount -O -F lofs $LIBC_MOE_32 /lib/libc.so.1
20 | fi
21 | fi
22 |
23 | ARCH64=`isainfo | awk '{print $1}'`
24 | LIBC_MOE_64=`/usr/bin/moe -64 /usr/lib/$ARCH64/libc/'$HWCAP'`
25 | if [ -n "$LIBC_MOE_64" ]; then
26 | /usr/sbin/mount | egrep -s "^/lib/$ARCH64/libc.so.1 on "
27 | if [ $? -ne 0 ]; then
28 | /usr/sbin/mount -O -F lofs $LIBC_MOE_64 \
29 | /lib/$ARCH64/libc.so.1
30 | fi
31 | fi
32 | }
33 |
34 | #
35 | # Update kernel driver.conf cache with any additional driver.conf
36 | # files found on /usr, and device permissions from /etc/minor_perm.
37 | #
38 | /usr/sbin/devfsadm -I -P
39 |
40 | libc_mount
41 |
42 | # Remount root RW
43 | #
44 | echo "\rRemounting root read/write" > /dev/msglog
45 | # x86 label
46 | /sbin/mount -o remount,rw /devices/ramdisk:a /
47 |
48 | #
49 | # Workaround for devfs lazy init. The sd nodes are not
50 | # created till you try to access them.
51 | #
52 | echo "Probing for device nodes ..." > /dev/msglog
53 |
54 | ls -lR /devices/* > /dev/null
55 |
56 | exit $SMF_EXIT_OK
57 |
--------------------------------------------------------------------------------
/iso/smf/manifest-import:
--------------------------------------------------------------------------------
1 | #!/sbin/sh
2 | exit 0
3 |
4 |
--------------------------------------------------------------------------------
/iso/sulogin:
--------------------------------------------------------------------------------
1 | PASSREQ=NO
2 |
--------------------------------------------------------------------------------
/rootpool/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | gcc -Wall -o rootpool rootpool.c -lzfs -lnvpair
3 |
--------------------------------------------------------------------------------
/rootpool/rootpool.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file and its contents are supplied under the terms of the
3 | * Common Development and Distribution License ("CDDL"), version 1.0.
4 | * You may only use this file in accordance with the terms of version
5 | * 1.0 of the CDDL.
6 | *
7 | * A full copy of the text of the CDDL should have accompanied this
8 | * source. A copy of the CDDL is also available via the Internet at
9 | * http://www.illumos.org/license/CDDL.
10 | *
11 | * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
12 | *
13 | * This hook tries disks for the pool with bootfs property and print
14 | * its name, guid, state and bootfs:
15 | * rpool;9213225939923529766;ONLINE;rpool/ROOT/illumos
16 | */
17 |
18 | #include
19 |
20 | int
21 | main(int argc, char **argv)
22 | {
23 | char **searchdirs = NULL;
24 | nvlist_t *pools = NULL;
25 | nvpair_t *elem;
26 | nvlist_t *config;
27 | uint64_t searchguid = 0;
28 | char *searchname = NULL;
29 | char *cachefile = NULL;
30 | importargs_t pdata = { 0 };
31 | libzfs_handle_t *g_zfs;
32 | vdev_stat_t *vs;
33 | char *name;
34 | uint64_t guid;
35 | nvlist_t *nvroot;
36 | const char *health;
37 | uint_t vsc;
38 | char *bootfs;
39 |
40 | if ((g_zfs = libzfs_init()) == NULL)
41 | return (1);
42 |
43 | if ((searchdirs = calloc(1, sizeof (char *))) == NULL)
44 | return (1);
45 |
46 | searchdirs[0] = "/dev/dsk";
47 | pdata.path = searchdirs;
48 | pdata.paths = 1;
49 | pdata.poolname = searchname;
50 | pdata.guid = searchguid;
51 | pdata.cachefile = cachefile;
52 |
53 | pools = zpool_search_import(g_zfs, &pdata);
54 | if (pools == NULL) {
55 | free(searchdirs);
56 | return (1);
57 | }
58 |
59 | elem = NULL;
60 | while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
61 | verify(nvpair_value_nvlist(elem, &config) == 0);
62 | verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
63 | &name) == 0);
64 | verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
65 | &guid) == 0);
66 | verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
67 | &nvroot) == 0);
68 | verify(nvlist_lookup_uint64_array(nvroot,
69 | ZPOOL_CONFIG_VDEV_STATS,
70 | (uint64_t **)&vs, &vsc) == 0);
71 | if (nvlist_lookup_string(config, ZPOOL_CONFIG_BOOTFS,
72 | &bootfs) != 0)
73 | continue;
74 |
75 | health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
76 | (void) printf("%s;%llu;%s;%s\n", name,
77 | (u_longlong_t)guid, health, bootfs);
78 | }
79 | nvlist_free(pools);
80 | free(searchdirs);
81 | return (0);
82 | }
83 |
--------------------------------------------------------------------------------