]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/initscripts/system/functions
e44a2b4a1353ae716b9f209547a73a6c66d09b51
[people/pmueller/ipfire-2.x.git] / src / initscripts / system / functions
1 #!/bin/sh
2 ########################################################################
3 # Begin $rc_base/init.d/functions
4 #
5 # Description : Run Level Control Functions
6 #
7 # Authors : Gerard Beekmans - gerard@linuxfromscratch.org
8 #
9 # Version : 00.00
10 #
11 # Notes : With code based on Matthias Benkmann's simpleinit-msb
12 # http://winterdrache.de/linux/newboot/index.html
13 #
14 ########################################################################
15
16 ## Environmental setup
17 # Setup default values for environment
18 umask 022
19 export PATH="/bin:/usr/bin:/sbin:/usr/sbin"
20
21 # Signal sent to running processes to refresh their configuration
22 RELOADSIG="HUP"
23
24 # Number of seconds between STOPSIG and FALLBACK when stopping processes
25 KILLDELAY="10"
26
27 ## Screen Dimensions
28 # Find current screen size
29 if [ -z "${COLUMNS}" ]; then
30 COLUMNS=$(stty size 2>/dev/null)
31 COLUMNS=${COLUMNS##* }
32 fi
33
34 # When using remote connections, such as a serial port, stty size returns 0
35 if [ "${COLUMNS}" = "0" ]; then
36 COLUMNS=80
37 fi
38
39 ## Measurements for positioning result messages
40 COL=$((${COLUMNS} - 8))
41 WCOL=$((${COL} - 2))
42
43 ## Set Cursor Position Commands, used via echo -e
44 SET_COL="\\033[${COL}G" # at the $COL char
45 SET_WCOL="\\033[${WCOL}G" # at the $WCOL char
46 CURS_UP="\\033[1A\\033[0G" # Up one line, at the 0'th char
47
48 ## Set color commands, used via echo -e
49 # Please consult `man console_codes for more information
50 # under the "ECMA-48 Set Graphics Rendition" section
51 #
52 # Warning: when switching from a 8bit to a 9bit font,
53 # the linux console will reinterpret the bold (1;) to
54 # the top 256 glyphs of the 9bit font. This does
55 # not affect framebuffer consoles
56 NORMAL="\\033[0;39m" # Standard console grey
57 SUCCESS="\\033[1;32m" # Success is green
58 WARNING="\\033[1;33m" # Warnings are yellow
59 FAILURE="\\033[1;31m" # Failures are red
60 INFO="\\033[1;36m" # Information is light cyan
61 BRACKET="\\033[1;34m" # Brackets are blue
62
63 STRING_LENGTH="0" # the length of the current message
64
65 #*******************************************************************************
66 # Function - boot_mesg()
67 #
68 # Purpose: Sending information from bootup scripts to the console
69 #
70 # Inputs: $1 is the message
71 # $2 is the colorcode for the console
72 #
73 # Outputs: Standard Output
74 #
75 # Dependencies: - sed for parsing strings.
76 # - grep for counting string length.
77 #
78 # Todo:
79 #*******************************************************************************
80 boot_mesg()
81 {
82 local ECHOPARM=""
83
84 while true
85 do
86 case "${1}" in
87 -n)
88 ECHOPARM=" -n "
89 shift 1
90 ;;
91 -*)
92 echo "Unknown Option: ${1}"
93 return 1
94 ;;
95 *)
96 break
97 ;;
98 esac
99 done
100
101 ## Figure out the length of what is to be printed to be used
102 ## for warning messges.
103 STRING_LENGTH="`echo "${1}" | sed \
104 -e 's,.,.,g' -e 'l 1' | grep -c \$`"
105
106 # Print the message to the screen
107 echo ${ECHOPARM} -e "${2}${1}"
108
109 }
110
111 boot_mesg_flush()
112 {
113 # Reset STRING_LENGTH for next message
114 STRING_LENGTH="0"
115 }
116
117 boot_log()
118 {
119 # Left in for backwards compatibility
120 echo -n ""
121 }
122
123 echo_ok()
124 {
125 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${SUCCESS} OK ${BRACKET}]"
126 echo -e "${NORMAL}"
127 boot_mesg_flush
128 }
129
130 echo_failure()
131 {
132 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]"
133 echo -e "${NORMAL}"
134 boot_mesg_flush
135 }
136
137 echo_warning()
138 {
139 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${WARNING} WARN ${BRACKET}]"
140 echo -e "${NORMAL}"
141 boot_mesg_flush
142 }
143
144 print_error_msg()
145 {
146 echo_failure
147 # $i is inherited by the rc script
148 boot_mesg -n "FAILURE:\n\nYou should not be reading this error message.\n\n" ${FAILURE}
149 boot_mesg -n " It means that an unforeseen error took"
150 boot_mesg -n " place in ${i}, which exited with a return value of"
151 boot_mesg " ${error_value}.\n"
152 boot_mesg_flush
153 boot_mesg -n "If you're able to track this"
154 boot_mesg -n " error down to a bug in one of the files provided by"
155 boot_mesg -n " ipfire, please be so kind to inform us at"
156 boot_mesg " https://bugzilla.ipfire.org.\n"
157 boot_mesg_flush
158 boot_mesg -n "Press Enter to continue or wait a minute..." ${INFO}
159 boot_mesg "" ${NORMAL}
160 read -t 60 ENTER
161 }
162
163 check_script_status()
164 {
165 # $i is inherited by the rc script
166 if [ ! -f ${i} ]; then
167 boot_mesg "${i} is not a valid symlink." ${WARNING}
168 echo_warning
169 continue
170 fi
171
172 if [ ! -x ${i} ]; then
173 boot_mesg "${i} is not executable, skipping." ${WARNING}
174 echo_warning
175 continue
176 fi
177 }
178
179 evaluate_retval()
180 {
181 error_value="${?}"
182
183 if [ ${error_value} = 0 ]; then
184 echo_ok
185 else
186 echo_failure
187 fi
188
189 # This prevents the 'An Unexpected Error Has Occurred' from trivial
190 # errors.
191 return 0
192 }
193
194 print_status()
195 {
196 if [ "${#}" = "0" ]; then
197 echo "Usage: ${0} {success|warning|failure}"
198 return 1
199 fi
200
201 case "${1}" in
202
203 success)
204 echo_ok
205 ;;
206
207 warning)
208 # Leave this extra case in because old scripts
209 # may call it this way.
210 case "${2}" in
211 running)
212 echo -e -n "${CURS_UP}"
213 echo -e -n "\\033[${STRING_LENGTH}G "
214 boot_mesg "Already running." ${WARNING}
215 echo_warning
216 ;;
217 not_running)
218 echo -e -n "${CURS_UP}"
219 echo -e -n "\\033[${STRING_LENGTH}G "
220 boot_mesg "Not running." ${WARNING}
221 echo_warning
222 ;;
223 not_available)
224 echo -e -n "${CURS_UP}"
225 echo -e -n "\\033[${STRING_LENGTH}G "
226 boot_mesg "Not available." ${WARNING}
227 echo_warning
228 ;;
229 *)
230 # This is how it is supposed to
231 # be called
232 echo_warning
233 ;;
234 esac
235 ;;
236
237 failure)
238 echo_failure
239 ;;
240
241 esac
242
243 }
244
245 reloadproc()
246 {
247 if [ "${#}" = "0" ]; then
248 echo "Usage: reloadproc [{program}]"
249 exit 1
250 fi
251
252 getpids "${1}"
253
254 if [ -n "${pidlist}" ]; then
255 failure="0"
256 for pid in ${pidlist}
257 do
258 kill -"${RELOADSIG}" "${pid}" || failure="1"
259 done
260
261 (exit ${failure})
262 evaluate_retval
263
264 else
265 boot_mesg "Process ${1} not running." ${WARNING}
266 echo_warning
267 fi
268 }
269
270 statusproc()
271 {
272 if [ "${#}" = "0" ]
273 then
274 echo "Usage: statusproc {program}"
275 exit 1
276 fi
277
278 getpids "${1}"
279
280 if [ -n "${pidlist}" ]; then
281 echo -e "${INFO}${base} is running with Process"\
282 "ID(s) ${pidlist}.${NORMAL}"
283 else
284 if [ -n "${base}" -a -e "/var/run/${base}.pid" ]; then
285 echo -e "${WARNING}${1} is not running but"\
286 "/var/run/${base}.pid exists.${NORMAL}"
287 else
288 if [ -n "${PIDFILE}" -a -e "${PIDFILE}" ]; then
289 echo -e "${WARNING}${1} is not running"\
290 "but ${PIDFILE} exists.${NORMAL}"
291 else
292 echo -e "${INFO}${1} is not running.${NORMAL}"
293 fi
294 fi
295 fi
296 }
297
298 # The below functions are documented in the LSB-generic 2.1.0
299
300 #*******************************************************************************
301 # Function - pidofproc [-s] [-p pidfile] pathname
302 #
303 # Purpose: This function returns one or more pid(s) for a particular daemon
304 #
305 # Inputs: -p pidfile, use the specified pidfile instead of pidof
306 # pathname, path to the specified program
307 #
308 # Outputs: return 0 - Success, pid's in stdout
309 # return 1 - Program is dead, pidfile exists
310 # return 2 - Invalid or excessive number of arguments,
311 # warning in stdout
312 # return 3 - Program is not running
313 #
314 # Dependencies: pidof, echo, head
315 #
316 # Todo: Remove dependency on head
317 # This depreciates getpids
318 # Test changes to pidof
319 #
320 #*******************************************************************************
321 pidofproc()
322 {
323 local pidfile=""
324 local lpids=""
325 local silent=""
326 pidlist=""
327 while true
328 do
329 case "${1}" in
330 -p)
331 pidfile="${2}"
332 shift 2
333 ;;
334
335 -s)
336 # Added for legacy opperation of getpids
337 # eliminates several '> /dev/null'
338 silent="1"
339 shift 1
340 ;;
341 -*)
342 log_failure_msg "Unknown Option: ${1}"
343 return 2
344 ;;
345 *)
346 break
347 ;;
348 esac
349 done
350
351 if [ "${#}" != "1" ]; then
352 shift 1
353 log_failure_msg "Usage: pidofproc [-s] [-p pidfile] pathname"
354 return 2
355 fi
356
357 if [ -n "${pidfile}" ]; then
358 if [ ! -r "${pidfile}" ]; then
359 return 3 # Program is not running
360 fi
361
362 lpids=`head -n 1 ${pidfile}`
363 for pid in ${lpids}
364 do
365 if [ "${pid}" -ne "$$" -a "${pid}" -ne "${PPID}" ]; then
366 kill -0 "${pid}" > /dev/null &&
367 pidlist="${pidlist} ${pid}"
368 fi
369
370 if [ "${silent}" -ne "1" ]; then
371 echo "${pidlist}"
372 fi
373
374 test -z "${pidlist}" &&
375 # Program is dead, pidfile exists
376 return 1
377 # else
378 return 0
379 done
380
381 else
382 pidlist=`pidof -o $$ -o $PPID -x "$1"`
383 if [ "x${silent}" != "x1" ]; then
384 echo "${pidlist}"
385 fi
386
387 # Get provide correct running status
388 if [ -n "${pidlist}" ]; then
389 return 0
390 else
391 return 3
392 fi
393
394 fi
395
396 if [ "$?" != "0" ]; then
397 return 3 # Program is not running
398 fi
399 }
400
401 # This will ensure compatibility with previous LFS Bootscripts
402 getpids()
403 {
404 if [ -z "${PIDFILE}" ]; then
405 pidofproc -s -p "${PIDFILE}" $@
406 else
407 pidofproc -s $@
408 fi
409 base="${1##*/}"
410 }
411
412 #*******************************************************************************
413 # Function - loadproc [-f] [-n nicelevel] [-p pidfile] pathname [args]
414 #
415 # Purpose: This runs the specified program as a daemon
416 #
417 # Inputs: -f, run the program even if it is already running
418 # -n nicelevel, specifies a nice level. See nice(1).
419 # -p pidfile, uses the specified pidfile
420 # pathname, pathname to the specified program
421 # args, arguments to pass to specified program
422 #
423 # Outputs: return 0 - Success
424 # return 2 - Invalid of excessive number of arguments,
425 # warning in stdout
426 # return 4 - Program or service status is unknown
427 #
428 # Dependencies: nice
429 #
430 # Todo: LSB says this should be called start_daemon
431 # LSB does not say that it should call evaluate_retval
432 # It checks for PIDFILE, which is deprecated.
433 # Will be removed after BLFS 6.0
434 # loadproc returns 0 if program is already running, not LSB compliant
435 #
436 #*******************************************************************************
437 loadproc()
438 {
439 local background=""
440 local pidfile=""
441 local forcestart=""
442 local nicelevel=""
443
444 # This will ensure compatibility with previous LFS Bootscripts
445 if [ -n "${PIDFILE}" ]; then
446 pidfile="${PIDFILE}"
447 fi
448
449 while true
450 do
451 case "${1}" in
452 -b)
453 background="1"
454 shift 1
455 ;;
456 -f)
457 forcestart="1"
458 shift 1
459 ;;
460 -n)
461 nicelevel="${2}"
462 shift 2
463 ;;
464 -p)
465 pidfile="${2}"
466 shift 2
467 ;;
468 -*)
469 log_failure_msg "Unknown Option: ${1}"
470 return 2 #invalid or excess argument(s)
471 ;;
472 *)
473 break
474 ;;
475 esac
476 done
477
478 if [ "${#}" = "0" ]; then
479 log_failure_msg "Usage: loadproc [-f] [-n nicelevel] [-p pidfile] pathname [args]"
480 return 2 #invalid or excess argument(s)
481 fi
482
483 if [ -z "${forcestart}" ]; then
484 if [ -z "${pidfile}" ]; then
485 pidofproc -s "${1}"
486 else
487 pidofproc -s -p "${pidfile}" "${1}"
488 fi
489
490 case "${?}" in
491 0)
492 log_warning_msg "Unable to continue: ${1} is running"
493 return 0 # 4
494 ;;
495 1)
496 log_warning_msg "Unable to continue: ${pidfile} exists"
497 return 0 # 4
498 ;;
499 3)
500 ;;
501 *)
502 log_failure_msg "Unknown error code from pidofproc: ${?}"
503 return 4
504 ;;
505 esac
506 fi
507
508 local cmd="${@}"
509
510 if [ -n "${nicelevel}" ]; then
511 cmd="nice -n "${nicelevel}" ${cmd}"
512 fi
513
514 if [ -n "${background}" ]; then
515 (
516 ${cmd} &>/dev/null
517 ) &
518 evaluate_retval
519 else
520 ${cmd}
521 evaluate_retval # This is "Probably" not LSB compliant, but required to be compatible with older bootscripts
522 fi
523
524 return 0
525 }
526
527 #*******************************************************************************
528 # Function - killproc [-p pidfile] pathname [signal]
529 #
530 # Purpose:
531 #
532 # Inputs: -p pidfile, uses the specified pidfile
533 # pathname, pathname to the specified program
534 # signal, send this signal to pathname
535 #
536 # Outputs: return 0 - Success
537 # return 2 - Invalid of excessive number of arguments,
538 # warning in stdout
539 # return 4 - Unknown Status
540 #
541 # Dependencies: kill
542 #
543 # Todo: LSB does not say that it should call evaluate_retval
544 # It checks for PIDFILE, which is deprecated.
545 # Will be removed after BLFS 6.0
546 #
547 #*******************************************************************************
548 killproc()
549 {
550 local pidfile=""
551 local killsig=""
552 pidlist=""
553
554 # This will ensure compatibility with previous LFS Bootscripts
555 if [ -n "${PIDFILE}" ]; then
556 pidfile="${PIDFILE}"
557 fi
558
559 while true
560 do
561 case "${1}" in
562 -p)
563 pidfile="${2}"
564 shift 2
565 ;;
566 -*)
567 log_failure_msg "Unknown Option: ${1}"
568 return 2
569 ;;
570 *)
571 break
572 ;;
573 esac
574 done
575
576 if [ "${#}" = "2" ]; then
577 killsig="${2}"
578 elif [ "${#}" != "1" ]; then
579 shift 2
580 log_failure_msg "Usage: killproc [-p pidfile] pathname [signal]"
581 return 2
582 fi
583
584 if [ -z "${pidfile}" ]; then
585 pidofproc -s "${1}"
586 else
587 pidofproc -s -p "${pidfile}" "${1}"
588 fi
589
590 # Change....
591 if [ -n "${pidlist}" ]; then
592 for pid in ${pidlist}
593 do
594 kill -${killsig:-TERM} ${pid} 2>/dev/null
595 if [ -z "${killsig}" ]; then
596 # Wait up to 3 seconds, for ${pid} to terminate
597 local dtime=${KILLDELAY}
598 while [ "${dtime}" != "0" ]
599 do
600 kill -0 ${pid} 2>/dev/null || break
601 sleep 1
602 dtime=$(( ${dtime} - 1))
603 done
604 # If ${pid} is still running, kill it
605 kill -0 ${pid} 2>/dev/null && kill -KILL ${pid} 2>/dev/null
606 fi
607 done
608
609 if [ -z "${killsig}" ]; then
610 pidofproc -s "${1}"
611
612 # Program was terminated
613 if [ "$?" != "0" ]; then
614 # Pidfile Exists
615 if [ -f "${pidfile}" ]; then
616 rm -f "${pidfile}"
617 fi
618 echo_ok
619 return 0
620 else # Program is still running
621 echo_failure
622 return 4 # Unknown Status
623 fi
624 else
625 if [ -z "${pidfile}" ]; then
626 pidofproc -s "${1}"
627 else
628 pidofproc -s -p "${pidfile}" "${1}"
629 fi
630 fi
631
632 evaluate_retval # This is "Probably" not LSB compliant, but required to be compatible with older bootscripts
633
634 else
635 print_status warning not_running
636 fi
637 }
638
639
640 #*******************************************************************************
641 # Function - log_success_msg "message"
642 #
643 # Purpose: Print a success message
644 #
645 # Inputs: $@ - Message
646 #
647 # Outputs: Text output to screen
648 #
649 # Dependencies: echo
650 #
651 # Todo: logging
652 #
653 #*******************************************************************************
654 log_success_msg()
655 {
656 echo -n -e "${BOOTMESG_PREFIX}${@}"
657 echo -e "${SET_COL}""${BRACKET}""[""${SUCCESS}"" OK ""${BRACKET}""]""${NORMAL}"
658 return 0
659 }
660
661 #*******************************************************************************
662 # Function - log_failure_msg "message"
663 #
664 # Purpose: Print a failure message
665 #
666 # Inputs: $@ - Message
667 #
668 # Outputs: Text output to screen
669 #
670 # Dependencies: echo
671 #
672 # Todo: logging
673 #
674 #*******************************************************************************
675 log_failure_msg() {
676 echo -n -e "${BOOTMESG_PREFIX}${@}"
677 echo -e "${SET_COL}""${BRACKET}""[""${FAILURE}"" FAIL ""${BRACKET}""]""${NORMAL}"
678 return 0
679 }
680
681 #*******************************************************************************
682 # Function - log_warning_msg "message"
683 #
684 # Purpose: print a warning message
685 #
686 # Inputs: $@ - Message
687 #
688 # Outputs: Text output to screen
689 #
690 # Dependencies: echo
691 #
692 # Todo: logging
693 #
694 #*******************************************************************************
695 log_warning_msg() {
696 echo -n -e "${BOOTMESG_PREFIX}${@}"
697 echo -e "${SET_COL}""${BRACKET}""[""${WARNING}"" WARN ""${BRACKET}""]""${NORMAL}"
698 return 0
699 }
700
701 run_subdir() {
702 DIR=$1
703 for i in $(ls -v ${DIR}* 2> /dev/null); do
704 check_script_status
705 OUT=$(echo $(basename ${i}) | awk -F- '{ print $2 }')
706 case "$OUT" in
707 S) ${i} start ;;
708 K) ${i} stop ;;
709 RS) ${i} restart ;;
710 RL) ${i} reload ;;
711 U) ${i} up ;;
712 D) ${i} down ;;
713 *) ${i} ;;
714 esac
715 done
716 }
717
718 mem_amount() {
719 local pagesize="$(getconf PAGESIZE)"
720 local pages="$(getconf _PHYS_PAGES)"
721
722 echo "$(( ${pagesize} * ${pages} / 1024 / 1024 ))"
723 }
724
725 use_ramdisk() {
726 eval $(/usr/local/bin/readhash /etc/sysconfig/ramdisk)
727
728 case "${RAMDISK_MODE}" in
729 # Don't use ramdisk
730 0)
731 return 1
732 ;;
733
734 # Always use ramdisk
735 1)
736 return 0
737 ;;
738
739 # Automatic mode - use ramdisk if sufficient
740 # memory is available
741 2)
742 local mem_avail="$(mem_amount)"
743
744 if [ ${mem_avail} -ge 400 ]; then
745 return 0
746 else
747 return 1
748 fi
749 ;;
750
751 # Fail for everything else
752 *)
753 return 2
754 ;;
755 esac
756 }
757
758 mount_ramdisk() {
759 local path="${1}"
760 local path_tmpfs="${path}.tmpfs"
761
762 # Check if the ramdisk is already mounted
763 if mountpoint "${path}" &>/dev/null; then
764 return 0
765 fi
766
767 # Create ramdisk
768 mkdir -p "${path_tmpfs}"
769 mount -t tmpfs none "${path_tmpfs}"
770
771 # Restore ramdisk content
772 cp -pR ${path}/* "${path_tmpfs}"
773
774 # Move ramdisk to final destination
775 mount --move "${path_tmpfs}" "${path}"
776 rm -rf "${path_tmpfs}"
777 }
778
779 umount_ramdisk() {
780 local path="${1}"
781 local path_tmpfs="${path}.tmpfs"
782
783 # Check if a ramdisk is actually mounted
784 if ! mountpoint "${path}" &>/dev/null; then
785 return 0
786 fi
787
788 # Move the ramdisk
789 mkdir -p "${path_tmpfs}"
790 mount --move "${path}" "${path_tmpfs}"
791
792 # Backup ramdisk content
793 cp -pR ${path_tmpfs}/* "${path}"
794
795 # Destroy the ramdisk
796 umount "${path_tmpfs}"
797 rm -rf "${path_tmpfs}"
798 }
799
800 # Returns true when this system running in a virtual environment
801 running_on_hypervisor() {
802 grep -qE "^flags\s+:.*hypervisor" /proc/cpuinfo
803 }
804
805 # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html
806 running_on_ec2() {
807 local uuid
808
809 # Check if the DMI product UUID starts with EC2
810 if [ -r "/sys/devices/virtual/dmi/id/product_uuid" ]; then
811 uuid=$(</sys/devices/virtual/dmi/id/product_uuid)
812
813 # Convert the UUID as uppercase
814 uuid="${uuid^^}"
815
816 [ "${uuid:0:3}" = "EC2" ] && return 0
817 fi
818
819 # We are not running on AWS EC2
820 return 1
821 }
822
823 running_on_azure() {
824 # Check if the vendor is Microsoft
825 if [ -r "/sys/devices/virtual/dmi/id/sys_vendor" ] && \
826 [ "$(</sys/devices/virtual/dmi/id/sys_vendor)" = "Microsoft Corporation" ]; then
827 # Check if this product is a "Virtual Machine"
828 if [ -r "/sys/devices/virtual/dmi/id/product_name" ] && \
829 [ "$(</sys/devices/virtual/dmi/id/product_name)" = "Virtual Machine" ]; then
830 # Yes, we are running on Azure
831 return 0
832 fi
833 fi
834
835 # We are not running on Azure
836 return 1
837 }
838
839 running_on_exoscale() {
840 if [ -r "/sys/devices/virtual/dmi/id/sys_vendor" ]; then
841 local sys_vendor="$(</sys/devices/virtual/dmi/id/sys_vendor)"
842
843 [ "${sys_vendor}" = "Exoscale" ] && return 0
844 fi
845
846 # We are not running on Exoscale
847 return 1
848 }
849
850 running_on_gcp() {
851 # Check if the BIOS vendor is "Google"
852 if [ -r "/sys/devices/virtual/dmi/id/bios_vendor" ]; then
853 local bios_vendor="$(</sys/devices/virtual/dmi/id/bios_vendor)"
854
855 [ "${bios_vendor}" = "Google" ] && return 0
856 fi
857
858 # We are not running on GCP
859 return 1
860 }
861
862 running_on_oci() {
863 if [ -r "/sys/devices/virtual/dmi/id/chassis_asset_tag" ]; then
864 local asset_tag="$(</sys/devices/virtual/dmi/id/chassis_asset_tag)"
865
866 [ "${asset_tag}" = "OracleCloud.com" ] && return 0
867 fi
868
869 # We are not running on OCI
870 return 1
871 }
872
873 # End $rc_base/init.d/functions