2 * Copyright (c) 1999-2000, 2002, 2004, 2007-2008 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 * Copyright (c) 1980, 1986, 1993
25 * The Regents of the University of California. All rights reserved.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgement:
37 * This product includes software developed by the University of
38 * California, Berkeley and its contributors.
39 * 4. Neither the name of the University nor the names of its contributors
40 * may be used to endorse or promote products derived from this software
41 * without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 #include <sys/types.h>
58 #include <sys/errno.h>
59 #include <sys/syslimits.h>
68 #include <sys/sysctl.h>
73 char *rawname
__P((char *name
));
74 char *unrawname
__P((char *name
));
84 pfatal("INTERNAL ERROR: GOT TO reply()");
85 persevere
= !strcmp(question
, "CONTINUE");
87 if (!persevere
&& (nflag
|| fswritefd
< 0)) {
88 plog("%s? no\n\n", question
);
91 if (yflag
|| (persevere
&& nflag
)) {
92 plog("%s? yes\n\n", question
);
96 plog("%s? [yn] ", question
);
97 (void) fflush(stdout
);
99 while (c
!= '\n' && getc(stdin
) != '\n')
102 } while (c
!= 'y' && c
!= 'Y' && c
!= 'n' && c
!= 'N');
104 if (c
== 'y' || c
== 'Y')
114 // register struct bufarea *bp, *nbp;
115 // int ofsmodified, cnt = 0;
117 (void) CacheDestroy(&fscache
);
120 (void)close(fsreadfd
);
124 flush(fswritefd
, &sblk
);
125 if (havesb
&& sblk
.b_bno
!= SBOFF
/ dev_bsize
&&
126 !preen
&& reply("UPDATE STANDARD SUPERBLOCK")) {
127 sblk
.b_bno
= SBOFF
/ dev_bsize
;
129 flush(fswritefd
, &sblk
);
131 flush(fswritefd
, &cgblk
);
132 free(cgblk
.b_un
.b_buf
);
133 for (bp
= bufhead
.b_prev
; bp
&& bp
!= &bufhead
; bp
= nbp
) {
135 flush(fswritefd
, bp
);
137 free(bp
->b_un
.b_buf
);
140 if (bufhead
.b_size
!= cnt
)
141 errx(EEXIT
, "Panic: lost %d buffers", bufhead
.b_size
- cnt
);
142 pbp
= pdirbp
= (struct bufarea
*)0;
143 if (markclean
&& sblock
.fs_clean
== 0) {
146 ofsmodified
= fsmodified
;
147 flush(fswritefd
, &sblk
);
148 fsmodified
= ofsmodified
;
150 plog("\n***** FILE SYSTEM MARKED CLEAN *****\n");
153 plog("cache missed %ld of %ld (%d%%)\n", diskreads
,
154 totalreads
, (int)(diskreads
* 100 / totalreads
));
156 (void)close(fsreadfd
);
157 (void)close(fswritefd
);
162 blockcheck(char *origname
)
164 struct stat stslash
, stblock
, stchar
;
165 char *newname
, *raw
= NULL
;
169 if (stat("/", &stslash
) < 0) {
171 plog("Can't stat root\n");
176 if (!strncmp(newname
, "/dev/fd/", 8)) {
183 if (stat(newname
, &stblock
) < 0) {
185 plog("Can't stat %s\n", newname
);
188 if ((stblock
.st_mode
& S_IFMT
) == S_IFBLK
) {
189 if (stslash
.st_dev
== stblock
.st_rdev
)
191 raw
= rawname(newname
);
192 if (stat(raw
, &stchar
) < 0) {
194 plog("Can't stat %s\n", raw
);
197 if ((stchar
.st_mode
& S_IFMT
) == S_IFCHR
) {
200 plog("%s is not a character device\n", raw
);
203 } else if ((stblock
.st_mode
& S_IFMT
) == S_IFCHR
&& !retried
) {
204 newname
= unrawname(newname
);
209 * Not a block or character device, just return name and
210 * let the caller decide whether to use it.
220 static char rawbuf
[32];
223 if ((dp
= strrchr(name
, '/')) == 0)
226 (void)strlcpy(rawbuf
, name
, sizeof(rawbuf
));
228 (void)strlcat(rawbuf
, "/r", sizeof(rawbuf
));
229 (void)strlcat(rawbuf
, &dp
[1], sizeof(rawbuf
));
236 unrawname(char *name
)
241 if ((dp
= strrchr(name
, '/')) == 0)
243 if (stat(name
, &stb
) < 0)
245 if ((stb
.st_mode
& S_IFMT
) != S_IFCHR
)
249 memmove(&dp
[1], &dp
[2], strlen(&dp
[2]) + 1);
273 #define FSCK_LOG_FILE "/var/log/fsck_hfs.log"
275 extern char lflag
; // indicates if we're doing a live fsck (defined in fsck_hfs.c)
276 extern char guiControl
; // indicates if we're outputting for the gui (defined in fsck_hfs.c)
277 extern char xmlControl
; // indicates if we're outputting XML output for GUI / Disk Utility (defined in fsck_hfs.c).
279 FILE *log_file
= NULL
;
281 /* Variables for in-memory log for strings that will be written to log file */
282 char *in_mem_log
= NULL
;
283 char *cur_in_mem_log
= NULL
;
284 size_t in_mem_log_size
= 0;
286 /* Variables for in-memory log for strings that will be printed on standard out */
287 char *in_mem_out
= NULL
;
288 char *cur_in_mem_out
= NULL
;
289 size_t in_mem_out_size
= 0;
293 #define DEFAULT_IN_MEM_SIZE 4096
295 static pthread_mutex_t mem_buf_lock
= PTHREAD_MUTEX_INITIALIZER
;
296 static pthread_cond_t mem_buf_cond
;
298 static pthread_t printing_thread
;
299 static pthread_t logging_thread
;
300 static volatile int keep_going
= 1;
306 void print_to_mem(int type
, int mem_type
, const char *fmt
, const char *str
, va_list ap
);
308 #define DO_VPRINT 1 // types for print_to_mem
311 /* Types for mem_type */
312 #define IN_MEM_LOG 1 // in-memory log strings
313 #define IN_MEM_OUT 2 // in-memory stdout strings
316 fsck_logging_thread(void *arg
)
319 char buff
[1024], *ptr
;
321 /* Handle writing to the log file */
322 while(keep_going
|| cur_in_mem_log
!= in_mem_log
) {
324 pthread_mutex_lock(&mem_buf_lock
);
325 while (keep_going
!= 0 && cur_in_mem_log
== in_mem_log
) {
328 err
= pthread_cond_wait(&mem_buf_cond
, &mem_buf_lock
);
330 fprintf(stderr
, "error %d from cond wait\n", err
);
335 copy_amt
= (int)(cur_in_mem_log
- in_mem_log
);
337 pthread_mutex_unlock(&mem_buf_lock
);
341 if (copy_amt
>= sizeof(buff
)) {
342 copy_amt
= sizeof(buff
) - 1;
343 memcpy(buff
, in_mem_log
, copy_amt
);
345 memmove(in_mem_log
, &in_mem_log
[copy_amt
], (cur_in_mem_log
- in_mem_log
) - copy_amt
);
346 cur_in_mem_log
-= copy_amt
;
348 memcpy(buff
, in_mem_log
, copy_amt
);
349 cur_in_mem_log
= in_mem_log
;
352 buff
[copy_amt
] = '\0';
354 pthread_mutex_unlock(&mem_buf_lock
);
356 for(ptr
=buff
; *ptr
; ) {
360 while(*ptr
&& *ptr
!= '\n') {
366 fprintf(log_file
, "%s: %s\n", cdevname
? cdevname
: "UNKNOWN-DEV", start
);
370 fprintf(log_file
, "%s", start
);
383 fsck_printing_thread(void *arg
)
386 char buff
[1024], *ptr
;
388 /* Handle writing to the out file */
389 while(keep_going
|| cur_in_mem_out
!= in_mem_out
) {
391 pthread_mutex_lock(&mem_buf_lock
);
392 while (keep_going
!= 0 && cur_in_mem_out
== in_mem_out
) {
395 err
= pthread_cond_wait(&mem_buf_cond
, &mem_buf_lock
);
397 fprintf(stderr
, "error %d from cond wait\n", err
);
402 copy_amt
= (int)(cur_in_mem_out
- in_mem_out
);
404 pthread_mutex_unlock(&mem_buf_lock
);
408 if (copy_amt
>= sizeof(buff
)) {
409 copy_amt
= sizeof(buff
) - 1;
410 memcpy(buff
, in_mem_out
, copy_amt
);
412 memmove(in_mem_out
, &in_mem_out
[copy_amt
], (cur_in_mem_out
- in_mem_out
) - copy_amt
);
413 cur_in_mem_out
-= copy_amt
;
415 memcpy(buff
, in_mem_out
, copy_amt
);
416 cur_in_mem_out
= in_mem_out
;
419 buff
[copy_amt
] = '\0';
421 pthread_mutex_unlock(&mem_buf_lock
);
423 for(ptr
=buff
; *ptr
; ) {
427 while(*ptr
&& *ptr
!= '\n') {
432 printf("%s\n", start
);
446 safely_open_log_file(const char *path
)
448 int fd
= open(path
, O_CREAT
| O_APPEND
| O_WRONLY
| O_NOFOLLOW
, 0666);
453 if (fstat(fd
, &sb
) || !S_ISREG(sb
.st_mode
)) {
459 return fdopen(fd
, "a");
462 int was_signaled
= 0;
465 shutdown_logging(void)
470 /* Log fsck_hfs check completion time */
473 va_list empty_list
= {0};
474 print_to_mem(DO_STR
, IN_MEM_LOG
, "fsck_hfs completed at %s\n", ctime(&t
), empty_list
);
476 fprintf(log_file
, "%s: fsck_hfs completed at %s\n", cdevname
? cdevname
: "UNKNOWN-DEV", ctime(&t
));
480 // if we were signaled, we can't really call any of these
481 // functions from the context of a signal handler (which
482 // is how we're called if we don't have a signal handler).
483 // so we have our own signal handler which sets this var
484 // which tells us to just bail out.
488 if (log_file
&& !live_fsck
) {
492 } else if ((in_mem_out
|| in_mem_log
) && live_fsck
&& log_file
) {
493 // make sure the printing and logging threads are woken up...
494 pthread_mutex_lock(&mem_buf_lock
);
495 pthread_cond_broadcast(&mem_buf_cond
);
496 pthread_mutex_unlock(&mem_buf_lock
);
498 // then wait for them
499 pthread_join(printing_thread
, NULL
);
500 pthread_join(logging_thread
, NULL
);
503 in_mem_out
= cur_in_mem_out
= NULL
;
507 in_mem_log
= cur_in_mem_log
= NULL
;
515 } else if (in_mem_log
) {
519 // just in case, flush any pending output
524 // fork so that the child can wait around until the
525 // root volume is mounted read-write and we can add
526 // our output to the log
530 // if we're not root we don't need to fork
535 char *fname
= FSCK_LOG_FILE
, path
[PATH_MAX
];
537 // Disk Management waits for fsck_hfs' stdout to close rather
538 // than the process death to understand if fsck_hfs has exited
539 // or not. Since we do not use stdout any further, close all
540 // the file descriptors so that Disk Management does not wait
541 // for 60 seconds unnecessarily on read-only boot volumes.
546 // non-root will never be able to write to /var/log
547 // so point the file somewhere else.
551 // each user will get their own log as ~/Library/Logs/fsck_hfs.log
552 pwd
= getpwuid(getuid());
554 snprintf(path
, sizeof(path
), "%s/Library/Logs/fsck_hfs.log", pwd
->pw_dir
);
559 for(i
=0; i
< 60; i
++) {
560 log_file
= safely_open_log_file(fname
);
562 fwrite(in_mem_log
, cur_in_mem_log
- in_mem_log
, 1, log_file
);
569 in_mem_log
= cur_in_mem_log
= NULL
;
574 // hmmm, failed to open the output file so wait
575 // a while only if the fs is read-only and then
577 if (errno
== EROFS
) {
589 my_sighandler(int sig
)
600 static int at_exit_setup
= 0;
603 // if this is set, we don't have to do anything
614 // Do not create a log file
618 // our copy of this variable since we may
619 // need to change it to make the right thing
620 // happen for fsck on the root volume.
621 live_fsck
= (int)lflag
;
623 if (log_file
== NULL
) {
624 log_file
= safely_open_log_file(FSCK_LOG_FILE
);
626 setlinebuf(log_file
);
629 // if we can't open the output file it's either because
630 // we're being run on the root volume during early boot
631 // or we were not run as the root user and so we can't
632 // write to /var/log/fsck_hfs.log. in either case we
633 // turn off "live_fsck" so that the right thing happens
634 // in here with respect to where output goes.
639 if (!live_fsck
&& log_file
) {
641 fprintf(log_file
, "\n%s: fsck_hfs started at %s", cdevname
? cdevname
: "UNKNOWN-DEV", ctime(&t
));
644 } else if (live_fsck
|| in_mem_log
== NULL
|| in_mem_out
== NULL
) {
646 // hmm, we couldn't open the log file (or it's a
647 // live fsck). let's just squirrel away a copy
648 // of the data in memory and then deal with it
649 // later (or print it out from a separate thread
650 // if we're doing a live fsck).
652 in_mem_log
= (char *)malloc(DEFAULT_IN_MEM_SIZE
);
653 in_mem_out
= (char *)malloc(DEFAULT_IN_MEM_SIZE
);
654 if ((in_mem_log
!= NULL
) && (in_mem_out
!= NULL
)) {
655 in_mem_log_size
= DEFAULT_IN_MEM_SIZE
;
656 in_mem_log
[0] = '\0';
657 cur_in_mem_log
= in_mem_log
;
659 in_mem_out_size
= DEFAULT_IN_MEM_SIZE
;
660 in_mem_out
[0] = '\0';
661 cur_in_mem_out
= in_mem_out
;
664 va_list empty_list
= {0};
665 print_to_mem(DO_STR
, IN_MEM_LOG
, "\nfsck_hfs started at %s", ctime(&t
), empty_list
);
667 if (live_fsck
&& log_file
) {
668 pthread_cond_init(&mem_buf_cond
, NULL
);
670 signal(SIGINT
, my_sighandler
);
671 signal(SIGHUP
, my_sighandler
);
672 signal(SIGTERM
, my_sighandler
);
673 signal(SIGQUIT
, my_sighandler
);
674 signal(SIGBUS
, my_sighandler
);
675 signal(SIGSEGV
, my_sighandler
);
676 signal(SIGILL
, my_sighandler
);
678 pthread_create(&printing_thread
, NULL
, fsck_printing_thread
, NULL
);
679 pthread_create(&logging_thread
, NULL
, fsck_logging_thread
, NULL
);
685 if (at_exit_setup
== 0 && (log_file
|| in_mem_log
|| in_mem_out
)) {
686 atexit(shutdown_logging
);
694 print_to_mem(int type
, int mem_type
, const char *fmt
, const char *str
, va_list ap
)
697 size_t size_remaining
;
701 size_t in_mem_data_size
;
703 if (type
== DO_VPRINT
) {
704 va_copy(ap_copy
, ap
);
707 /* Grab the lock only when adding output strings to the in-memory data */
708 if (live_fsck
&& (mem_type
== IN_MEM_OUT
)) {
709 pthread_mutex_lock(&mem_buf_lock
);
712 if (mem_type
== IN_MEM_LOG
) {
713 cur_in_mem
= cur_in_mem_log
;
714 in_mem_data
= in_mem_log
;
715 in_mem_data_size
= in_mem_log_size
;
717 cur_in_mem
= cur_in_mem_out
;
718 in_mem_data
= in_mem_out
;
719 in_mem_data_size
= in_mem_out_size
;
722 size_remaining
= in_mem_data_size
- (ptrdiff_t)(cur_in_mem
- in_mem_data
);
723 if (type
== DO_VPRINT
) {
724 ret
= vsnprintf(cur_in_mem
, size_remaining
, fmt
, ap
);
726 ret
= snprintf(cur_in_mem
, size_remaining
, fmt
, str
);
728 if (ret
> size_remaining
) {
732 if (ret
>= DEFAULT_IN_MEM_SIZE
) {
733 amt
= (ret
+ 4095) & (~4095); // round up to a 4k boundary
735 amt
= DEFAULT_IN_MEM_SIZE
;
738 new_log
= realloc(in_mem_data
, in_mem_data_size
+ amt
);
742 in_mem_data_size
+= amt
;
743 cur_in_mem
= new_log
+ (cur_in_mem
- in_mem_data
);
744 in_mem_data
= new_log
;
745 size_remaining
= in_mem_data_size
- (ptrdiff_t)(cur_in_mem
- new_log
);
746 if (type
== DO_VPRINT
) {
747 ret
= vsnprintf(cur_in_mem
, size_remaining
, fmt
, ap_copy
);
749 ret
= snprintf(cur_in_mem
, size_remaining
, fmt
, str
);
751 if (ret
<= size_remaining
) {
760 if (mem_type
== IN_MEM_LOG
) {
761 cur_in_mem_log
= cur_in_mem
;
762 in_mem_log
= in_mem_data
;
763 in_mem_log_size
= in_mem_data_size
;
765 cur_in_mem_out
= cur_in_mem
;
766 in_mem_out
= in_mem_data
;
767 in_mem_out_size
= in_mem_data_size
;
770 if (live_fsck
&& (mem_type
== IN_MEM_OUT
)) {
771 pthread_cond_signal(&mem_buf_cond
);
772 pthread_mutex_unlock(&mem_buf_lock
);
775 if (type
== DO_VPRINT
) {
781 static int need_prefix
=1;
785 fprintf(log_file, "%s: ", cdevname); \
786 if (strchr(fmt, '\n')) { \
791 } else if (strchr(fmt, '\n')) { \
795 /* Print output string on given stream or store it into in-memory buffer */
796 #define VOUT(stream, fmt, ap) \
798 vfprintf(stream, fmt, ap); \
800 print_to_mem(DO_VPRINT, IN_MEM_OUT, fmt, NULL, ap); \
803 #define FOUT(fmt, str) \
804 print_to_mem(DO_STR, IN_MEM_OUT, fmt, str, NULL);
806 /* Store output string written to fsck_hfs.log into file or in-memory buffer */
807 #define VLOG(fmt, ap) \
809 VLOG_INTERNAL(fmt, ap);
811 #define VLOG_INTERNAL(fmt, ap) \
812 if (log_file && !live_fsck) { \
814 vfprintf(log_file, fmt, ap); \
816 print_to_mem(DO_VPRINT, IN_MEM_LOG, fmt, NULL, ap); \
819 #define FLOG(fmt, str) \
820 if (log_file && !live_fsck) { \
822 fprintf(log_file, fmt, str); \
824 va_list empty_list = {0}; \
825 print_to_mem(DO_STR, IN_MEM_LOG, fmt, str, empty_list); \
836 * An unexpected inconsistency occurred.
837 * Die if preening, otherwise just print message and continue.
841 pfatal(const char *fmt
, ...)
843 pfatal(fmt
, va_alist
)
858 (void)vfprintf(stderr
, fmt
, ap
);
864 (void)fprintf(stderr
, "%s: ", cdevname
);
865 FLOG("%s: ", cdevname
);
868 (void)vfprintf(stderr
, fmt
, ap
);
872 (void)fprintf(stderr
,
873 "\n%s: UNEXPECTED INCONSISTENCY; RUN fsck_hfs MANUALLY.\n",
875 FLOG("\n%s: UNEXPECTED INCONSISTENCY; RUN fsck_hfs MANUALLY.\n", cdevname
);
881 * Pwarn just prints a message when not preening,
882 * or a warning (preceded by filename) when preening.
886 pwarn(const char *fmt
, ...)
903 (void)fprintf(stderr
, "%s: ", cdevname
);
904 FLOG("%s: ", cdevname
);
907 (void)vfprintf(stderr
, fmt
, ap
);
913 /* Write a string and parameters, if any, directly to the log file.
914 * These strings will not be printed to standard out/error.
917 logstring(void *c
, const char *str
)
922 /* Write a string and parameters, if any, directly to standard out/error.
923 * These strings will not be printed to log file.
926 outstring(void *c
, const char *str
)
931 /* Write to both standard out and log file */
933 plog(const char *fmt
, ...)
941 /* Write to only standard out */
943 olog(const char *fmt
, ...)
951 * For live fsck_hfs, add output strings to in-memory log,
952 * and for non-live fsck_hfs, print output to stdout.
954 VOUT(stdout
, fmt
, ap
);
959 /* Write to only log file */
961 llog(const char *fmt
, ...)
973 /* Write to both standard out and log file */
975 vplog(const char *fmt
, va_list ap
)
979 va_copy(copy_ap
, ap
);
983 /* Always print prefix to strings written to log files */
986 /* Handle output strings, print to stdout or store in-memory, if not running in XML mode */
987 if (xmlControl
== 0) {
989 * If running in XML mode do not put non-XML formatted output into stdout, as it may cause
990 * DiskMgmt to complain.
992 VOUT(stdout
, fmt
, ap
);
995 /* Add log strings to the log file. VLOG() handles live case internally */
996 VLOG_INTERNAL(fmt
, copy_ap
);
999 /* Write to both the given stream (usually stderr!) and log file */
1001 fplog(FILE *stream
, const char *fmt
, ...)
1003 va_list ap
, copy_ap
;
1005 va_copy(copy_ap
, ap
);
1010 /* Handle output strings, print to given stream or store in-memory */
1011 VOUT(stream
, fmt
, ap
);
1013 /* Add log strings to the log file. VLOG() handles live case internally */
1019 #define kProgressToggle "kern.progressmeterenable"
1020 #define kProgress "kern.progressmeter"
1023 start_progress(void)
1029 rv
= sysctlbyname(kProgressToggle
, NULL
, NULL
, &enable
, sizeof(enable
));
1030 if (debug
&& rv
== -1 && errno
!= ENOENT
) {
1031 warn("sysctl(%s) failed", kProgressToggle
);
1036 draw_progress(int pct
)
1041 rv
= sysctlbyname(kProgress
, NULL
, NULL
, &pct
, sizeof(pct
));
1042 if (debug
&& rv
== -1 && errno
!= ENOENT
) {
1043 warn("sysctl(%s) failed", kProgress
);
1054 rv
= sysctlbyname(kProgressToggle
, NULL
, NULL
, &enable
, sizeof(enable
));
1055 if (debug
&& rv
== -1 && errno
!= ENOENT
) {
1056 warn("sysctl(%s) failed", kProgressToggle
);