From b567315ffc246d1c4ce006fb4f96441082c6c870 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 14 Dec 2014 13:38:10 +0000 Subject: [PATCH 01/64] Pull in r221170 from upstream clang trunk (by Roman Divacky): Implement vaarg lowering for ppc32. Lowering of scalars and aggregates is supported. Complex numbers are not. This adds va_args support for PowerPC (32 bit) to clang. Reviewed by: jhibbits MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D1308 --- .../tools/clang/lib/CodeGen/TargetInfo.cpp | 104 +++++++++++++++++- 1 file changed, 101 insertions(+), 3 deletions(-) diff --git a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp index 45eaec6c844..3672f336f78 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp @@ -2733,11 +2733,19 @@ llvm::Value *NaClX86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, // PowerPC-32 - namespace { -class PPC32TargetCodeGenInfo : public DefaultTargetCodeGenInfo { +/// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information. +class PPC32_SVR4_ABIInfo : public DefaultABIInfo { public: - PPC32TargetCodeGenInfo(CodeGenTypes &CGT) : DefaultTargetCodeGenInfo(CGT) {} + PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const; +}; + +class PPC32TargetCodeGenInfo : public TargetCodeGenInfo { +public: + PPC32TargetCodeGenInfo(CodeGenTypes &CGT) : TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT)) {} int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { // This is recovered from gcc output. @@ -2750,6 +2758,96 @@ public: } +llvm::Value *PPC32_SVR4_ABIInfo::EmitVAArg(llvm::Value *VAListAddr, + QualType Ty, + CodeGenFunction &CGF) const { + if (const ComplexType *CTy = Ty->getAs()) { + // TODO: Implement this. For now ignore. + (void)CTy; + return NULL; + } + + bool isI64 = Ty->isIntegerType() && getContext().getTypeSize(Ty) == 64; + bool isInt = Ty->isIntegerType() || Ty->isPointerType() || Ty->isAggregateType(); + llvm::Type *CharPtr = CGF.Int8PtrTy; + llvm::Type *CharPtrPtr = CGF.Int8PtrPtrTy; + + CGBuilderTy &Builder = CGF.Builder; + llvm::Value *GPRPtr = Builder.CreateBitCast(VAListAddr, CharPtr, "gprptr"); + llvm::Value *GPRPtrAsInt = Builder.CreatePtrToInt(GPRPtr, CGF.Int32Ty); + llvm::Value *FPRPtrAsInt = Builder.CreateAdd(GPRPtrAsInt, Builder.getInt32(1)); + llvm::Value *FPRPtr = Builder.CreateIntToPtr(FPRPtrAsInt, CharPtr); + llvm::Value *OverflowAreaPtrAsInt = Builder.CreateAdd(FPRPtrAsInt, Builder.getInt32(3)); + llvm::Value *OverflowAreaPtr = Builder.CreateIntToPtr(OverflowAreaPtrAsInt, CharPtrPtr); + llvm::Value *RegsaveAreaPtrAsInt = Builder.CreateAdd(OverflowAreaPtrAsInt, Builder.getInt32(4)); + llvm::Value *RegsaveAreaPtr = Builder.CreateIntToPtr(RegsaveAreaPtrAsInt, CharPtrPtr); + llvm::Value *GPR = Builder.CreateLoad(GPRPtr, false, "gpr"); + // Align GPR when TY is i64. + if (isI64) { + llvm::Value *GPRAnd = Builder.CreateAnd(GPR, Builder.getInt8(1)); + llvm::Value *CC64 = Builder.CreateICmpEQ(GPRAnd, Builder.getInt8(1)); + llvm::Value *GPRPlusOne = Builder.CreateAdd(GPR, Builder.getInt8(1)); + GPR = Builder.CreateSelect(CC64, GPRPlusOne, GPR); + } + llvm::Value *FPR = Builder.CreateLoad(FPRPtr, false, "fpr"); + llvm::Value *OverflowArea = Builder.CreateLoad(OverflowAreaPtr, false, "overflow_area"); + llvm::Value *OverflowAreaAsInt = Builder.CreatePtrToInt(OverflowArea, CGF.Int32Ty); + llvm::Value *RegsaveArea = Builder.CreateLoad(RegsaveAreaPtr, false, "regsave_area"); + llvm::Value *RegsaveAreaAsInt = Builder.CreatePtrToInt(RegsaveArea, CGF.Int32Ty); + + llvm::Value *CC = Builder.CreateICmpULT(isInt ? GPR : FPR, + Builder.getInt8(8), "cond"); + + llvm::Value *RegConstant = Builder.CreateMul(isInt ? GPR : FPR, + Builder.getInt8(isInt ? 4 : 8)); + + llvm::Value *OurReg = Builder.CreateAdd(RegsaveAreaAsInt, Builder.CreateSExt(RegConstant, CGF.Int32Ty)); + + if (Ty->isFloatingType()) + OurReg = Builder.CreateAdd(OurReg, Builder.getInt32(32)); + + llvm::BasicBlock *UsingRegs = CGF.createBasicBlock("using_regs"); + llvm::BasicBlock *UsingOverflow = CGF.createBasicBlock("using_overflow"); + llvm::BasicBlock *Cont = CGF.createBasicBlock("cont"); + + Builder.CreateCondBr(CC, UsingRegs, UsingOverflow); + + CGF.EmitBlock(UsingRegs); + + llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); + llvm::Value *Result1 = Builder.CreateIntToPtr(OurReg, PTy); + // Increase the GPR/FPR indexes. + if (isInt) { + GPR = Builder.CreateAdd(GPR, Builder.getInt8(isI64 ? 2 : 1)); + Builder.CreateStore(GPR, GPRPtr); + } else { + FPR = Builder.CreateAdd(FPR, Builder.getInt8(1)); + Builder.CreateStore(FPR, FPRPtr); + } + CGF.EmitBranch(Cont); + + CGF.EmitBlock(UsingOverflow); + + // Increase the overflow area. + llvm::Value *Result2 = Builder.CreateIntToPtr(OverflowAreaAsInt, PTy); + OverflowAreaAsInt = Builder.CreateAdd(OverflowAreaAsInt, Builder.getInt32(isInt ? 4 : 8)); + Builder.CreateStore(Builder.CreateIntToPtr(OverflowAreaAsInt, CharPtr), OverflowAreaPtr); + CGF.EmitBranch(Cont); + + CGF.EmitBlock(Cont); + + llvm::PHINode *Result = CGF.Builder.CreatePHI(PTy, 2, "vaarg.addr"); + Result->addIncoming(Result1, UsingRegs); + Result->addIncoming(Result2, UsingOverflow); + + if (Ty->isAggregateType()) { + llvm::Value *AGGPtr = Builder.CreateBitCast(Result, CharPtrPtr, "aggrptr") ; + return Builder.CreateLoad(AGGPtr, false, "aggr"); + } + + return Result; +} + bool PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const { From be038cc81f299a5c72e0f8b81110071e17832227 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 14 Dec 2014 13:40:42 +0000 Subject: [PATCH 02/64] Add clang patch corresponding to r275759. --- ...patch-r275759-clang-r221170-ppc-vaarg.diff | 241 ++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 contrib/llvm/patches/patch-r275759-clang-r221170-ppc-vaarg.diff diff --git a/contrib/llvm/patches/patch-r275759-clang-r221170-ppc-vaarg.diff b/contrib/llvm/patches/patch-r275759-clang-r221170-ppc-vaarg.diff new file mode 100644 index 00000000000..61ace4c0885 --- /dev/null +++ b/contrib/llvm/patches/patch-r275759-clang-r221170-ppc-vaarg.diff @@ -0,0 +1,241 @@ +Pull in r221170 from upstream clang trunk (by Roman Divacky): + + Implement vaarg lowering for ppc32. Lowering of scalars and + aggregates is supported. Complex numbers are not. + +This adds va_args support for PowerPC (32 bit) to clang. + +Introduced here: http://svnweb.freebsd.org/changeset/base/275759 + +Index: tools/clang/lib/CodeGen/TargetInfo.cpp +=================================================================== +--- tools/clang/lib/CodeGen/TargetInfo.cpp ++++ tools/clang/lib/CodeGen/TargetInfo.cpp +@@ -2733,12 +2733,20 @@ llvm::Value *NaClX86_64ABIInfo::EmitVAArg(llvm::Va + + + // PowerPC-32 +- + namespace { +-class PPC32TargetCodeGenInfo : public DefaultTargetCodeGenInfo { ++/// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information. ++class PPC32_SVR4_ABIInfo : public DefaultABIInfo { + public: +- PPC32TargetCodeGenInfo(CodeGenTypes &CGT) : DefaultTargetCodeGenInfo(CGT) {} ++ PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + ++ llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, ++ CodeGenFunction &CGF) const; ++}; ++ ++class PPC32TargetCodeGenInfo : public TargetCodeGenInfo { ++public: ++ PPC32TargetCodeGenInfo(CodeGenTypes &CGT) : TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT)) {} ++ + int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { + // This is recovered from gcc output. + return 1; // r1 is the dedicated stack pointer +@@ -2750,6 +2758,96 @@ namespace { + + } + ++llvm::Value *PPC32_SVR4_ABIInfo::EmitVAArg(llvm::Value *VAListAddr, ++ QualType Ty, ++ CodeGenFunction &CGF) const { ++ if (const ComplexType *CTy = Ty->getAs()) { ++ // TODO: Implement this. For now ignore. ++ (void)CTy; ++ return NULL; ++ } ++ ++ bool isI64 = Ty->isIntegerType() && getContext().getTypeSize(Ty) == 64; ++ bool isInt = Ty->isIntegerType() || Ty->isPointerType() || Ty->isAggregateType(); ++ llvm::Type *CharPtr = CGF.Int8PtrTy; ++ llvm::Type *CharPtrPtr = CGF.Int8PtrPtrTy; ++ ++ CGBuilderTy &Builder = CGF.Builder; ++ llvm::Value *GPRPtr = Builder.CreateBitCast(VAListAddr, CharPtr, "gprptr"); ++ llvm::Value *GPRPtrAsInt = Builder.CreatePtrToInt(GPRPtr, CGF.Int32Ty); ++ llvm::Value *FPRPtrAsInt = Builder.CreateAdd(GPRPtrAsInt, Builder.getInt32(1)); ++ llvm::Value *FPRPtr = Builder.CreateIntToPtr(FPRPtrAsInt, CharPtr); ++ llvm::Value *OverflowAreaPtrAsInt = Builder.CreateAdd(FPRPtrAsInt, Builder.getInt32(3)); ++ llvm::Value *OverflowAreaPtr = Builder.CreateIntToPtr(OverflowAreaPtrAsInt, CharPtrPtr); ++ llvm::Value *RegsaveAreaPtrAsInt = Builder.CreateAdd(OverflowAreaPtrAsInt, Builder.getInt32(4)); ++ llvm::Value *RegsaveAreaPtr = Builder.CreateIntToPtr(RegsaveAreaPtrAsInt, CharPtrPtr); ++ llvm::Value *GPR = Builder.CreateLoad(GPRPtr, false, "gpr"); ++ // Align GPR when TY is i64. ++ if (isI64) { ++ llvm::Value *GPRAnd = Builder.CreateAnd(GPR, Builder.getInt8(1)); ++ llvm::Value *CC64 = Builder.CreateICmpEQ(GPRAnd, Builder.getInt8(1)); ++ llvm::Value *GPRPlusOne = Builder.CreateAdd(GPR, Builder.getInt8(1)); ++ GPR = Builder.CreateSelect(CC64, GPRPlusOne, GPR); ++ } ++ llvm::Value *FPR = Builder.CreateLoad(FPRPtr, false, "fpr"); ++ llvm::Value *OverflowArea = Builder.CreateLoad(OverflowAreaPtr, false, "overflow_area"); ++ llvm::Value *OverflowAreaAsInt = Builder.CreatePtrToInt(OverflowArea, CGF.Int32Ty); ++ llvm::Value *RegsaveArea = Builder.CreateLoad(RegsaveAreaPtr, false, "regsave_area"); ++ llvm::Value *RegsaveAreaAsInt = Builder.CreatePtrToInt(RegsaveArea, CGF.Int32Ty); ++ ++ llvm::Value *CC = Builder.CreateICmpULT(isInt ? GPR : FPR, ++ Builder.getInt8(8), "cond"); ++ ++ llvm::Value *RegConstant = Builder.CreateMul(isInt ? GPR : FPR, ++ Builder.getInt8(isInt ? 4 : 8)); ++ ++ llvm::Value *OurReg = Builder.CreateAdd(RegsaveAreaAsInt, Builder.CreateSExt(RegConstant, CGF.Int32Ty)); ++ ++ if (Ty->isFloatingType()) ++ OurReg = Builder.CreateAdd(OurReg, Builder.getInt32(32)); ++ ++ llvm::BasicBlock *UsingRegs = CGF.createBasicBlock("using_regs"); ++ llvm::BasicBlock *UsingOverflow = CGF.createBasicBlock("using_overflow"); ++ llvm::BasicBlock *Cont = CGF.createBasicBlock("cont"); ++ ++ Builder.CreateCondBr(CC, UsingRegs, UsingOverflow); ++ ++ CGF.EmitBlock(UsingRegs); ++ ++ llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); ++ llvm::Value *Result1 = Builder.CreateIntToPtr(OurReg, PTy); ++ // Increase the GPR/FPR indexes. ++ if (isInt) { ++ GPR = Builder.CreateAdd(GPR, Builder.getInt8(isI64 ? 2 : 1)); ++ Builder.CreateStore(GPR, GPRPtr); ++ } else { ++ FPR = Builder.CreateAdd(FPR, Builder.getInt8(1)); ++ Builder.CreateStore(FPR, FPRPtr); ++ } ++ CGF.EmitBranch(Cont); ++ ++ CGF.EmitBlock(UsingOverflow); ++ ++ // Increase the overflow area. ++ llvm::Value *Result2 = Builder.CreateIntToPtr(OverflowAreaAsInt, PTy); ++ OverflowAreaAsInt = Builder.CreateAdd(OverflowAreaAsInt, Builder.getInt32(isInt ? 4 : 8)); ++ Builder.CreateStore(Builder.CreateIntToPtr(OverflowAreaAsInt, CharPtr), OverflowAreaPtr); ++ CGF.EmitBranch(Cont); ++ ++ CGF.EmitBlock(Cont); ++ ++ llvm::PHINode *Result = CGF.Builder.CreatePHI(PTy, 2, "vaarg.addr"); ++ Result->addIncoming(Result1, UsingRegs); ++ Result->addIncoming(Result2, UsingOverflow); ++ ++ if (Ty->isAggregateType()) { ++ llvm::Value *AGGPtr = Builder.CreateBitCast(Result, CharPtrPtr, "aggrptr") ; ++ return Builder.CreateLoad(AGGPtr, false, "aggr"); ++ } ++ ++ return Result; ++} ++ + bool + PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, + llvm::Value *Address) const { +Index: tools/clang/test/CodeGen/ppc64-varargs-struct.c +=================================================================== +--- tools/clang/test/CodeGen/ppc64-varargs-struct.c ++++ tools/clang/test/CodeGen/ppc64-varargs-struct.c +@@ -1,5 +1,6 @@ + // REQUIRES: ppc64-registered-target + // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s ++// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-PPC + + #include + +@@ -17,6 +18,46 @@ void testva (int n, ...) + // CHECK: bitcast %struct.x* %t to i8* + // CHECK: bitcast %struct.x* %{{[0-9]+}} to i8* + // CHECK: call void @llvm.memcpy ++// CHECK-PPC: %arraydecay = getelementptr inbounds [1 x %struct.__va_list_tag]* %ap, i32 0, i32 0 ++// CHECK-PPC-NEXT: %gprptr = bitcast %struct.__va_list_tag* %arraydecay to i8* ++// CHECK-PPC-NEXT: %0 = ptrtoint i8* %gprptr to i32 ++// CHECK-PPC-NEXT: %1 = add i32 %0, 1 ++// CHECK-PPC-NEXT: %2 = inttoptr i32 %1 to i8* ++// CHECK-PPC-NEXT: %3 = add i32 %1, 3 ++// CHECK-PPC-NEXT: %4 = inttoptr i32 %3 to i8** ++// CHECK-PPC-NEXT: %5 = add i32 %3, 4 ++// CHECK-PPC-NEXT: %6 = inttoptr i32 %5 to i8** ++// CHECK-PPC-NEXT: %gpr = load i8* %gprptr ++// CHECK-PPC-NEXT: %fpr = load i8* %2 ++// CHECK-PPC-NEXT: %overflow_area = load i8** %4 ++// CHECK-PPC-NEXT: %7 = ptrtoint i8* %overflow_area to i32 ++// CHECK-PPC-NEXT: %regsave_area = load i8** %6 ++// CHECK-PPC-NEXT: %8 = ptrtoint i8* %regsave_area to i32 ++// CHECK-PPC-NEXT: %cond = icmp ult i8 %gpr, 8 ++// CHECK-PPC-NEXT: %9 = mul i8 %gpr, 4 ++// CHECK-PPC-NEXT: %10 = sext i8 %9 to i32 ++// CHECK-PPC-NEXT: %11 = add i32 %8, %10 ++// CHECK-PPC-NEXT: br i1 %cond, label %using_regs, label %using_overflow ++// ++// CHECK-PPC-LABEL:using_regs: ; preds = %entry ++// CHECK-PPC-NEXT: %12 = inttoptr i32 %11 to %struct.x* ++// CHECK-PPC-NEXT: %13 = add i8 %gpr, 1 ++// CHECK-PPC-NEXT: store i8 %13, i8* %gprptr ++// CHECK-PPC-NEXT: br label %cont ++// ++// CHECK-PPC-LABEL:using_overflow: ; preds = %entry ++// CHECK-PPC-NEXT: %14 = inttoptr i32 %7 to %struct.x* ++// CHECK-PPC-NEXT: %15 = add i32 %7, 4 ++// CHECK-PPC-NEXT: %16 = inttoptr i32 %15 to i8* ++// CHECK-PPC-NEXT: store i8* %16, i8** %4 ++// CHECK-PPC-NEXT: br label %cont ++// ++// CHECK-PPC-LABEL:cont: ; preds = %using_overflow, %using_regs ++// CHECK-PPC-NEXT: %vaarg.addr = phi %struct.x* [ %12, %using_regs ], [ %14, %using_overflow ] ++// CHECK-PPC-NEXT: %aggrptr = bitcast %struct.x* %vaarg.addr to i8** ++// CHECK-PPC-NEXT: %aggr = load i8** %aggrptr ++// CHECK-PPC-NEXT: %17 = bitcast %struct.x* %t to i8* ++// CHECK-PPC-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %17, i8* %aggr, i32 16, i32 8, i1 false) + + int v = va_arg (ap, int); + // CHECK: ptrtoint i8* %{{[a-z.0-9]*}} to i64 +@@ -23,8 +64,48 @@ void testva (int n, ...) + // CHECK: add i64 %{{[0-9]+}}, 4 + // CHECK: inttoptr i64 %{{[0-9]+}} to i8* + // CHECK: bitcast i8* %{{[0-9]+}} to i32* ++// CHECK-PPC: %arraydecay1 = getelementptr inbounds [1 x %struct.__va_list_tag]* %ap, i32 0, i32 0 ++// CHECK-PPC-NEXT: %gprptr2 = bitcast %struct.__va_list_tag* %arraydecay1 to i8* ++// CHECK-PPC-NEXT: %18 = ptrtoint i8* %gprptr2 to i32 ++// CHECK-PPC-NEXT: %19 = add i32 %18, 1 ++// CHECK-PPC-NEXT: %20 = inttoptr i32 %19 to i8* ++// CHECK-PPC-NEXT: %21 = add i32 %19, 3 ++// CHECK-PPC-NEXT: %22 = inttoptr i32 %21 to i8** ++// CHECK-PPC-NEXT: %23 = add i32 %21, 4 ++// CHECK-PPC-NEXT: %24 = inttoptr i32 %23 to i8** ++// CHECK-PPC-NEXT: %gpr3 = load i8* %gprptr2 ++// CHECK-PPC-NEXT: %fpr4 = load i8* %20 ++// CHECK-PPC-NEXT: %overflow_area5 = load i8** %22 ++// CHECK-PPC-NEXT: %25 = ptrtoint i8* %overflow_area5 to i32 ++// CHECK-PPC-NEXT: %regsave_area6 = load i8** %24 ++// CHECK-PPC-NEXT: %26 = ptrtoint i8* %regsave_area6 to i32 ++// CHECK-PPC-NEXT: %cond7 = icmp ult i8 %gpr3, 8 ++// CHECK-PPC-NEXT: %27 = mul i8 %gpr3, 4 ++// CHECK-PPC-NEXT: %28 = sext i8 %27 to i32 ++// CHECK-PPC-NEXT: %29 = add i32 %26, %28 ++// CHECK-PPC-NEXT: br i1 %cond7, label %using_regs8, label %using_overflow9 ++// ++// CHECK-PPC-LABEL:using_regs8: ; preds = %cont ++// CHECK-PPC-NEXT: %30 = inttoptr i32 %29 to i32* ++// CHECK-PPC-NEXT: %31 = add i8 %gpr3, 1 ++// CHECK-PPC-NEXT: store i8 %31, i8* %gprptr2 ++// CHECK-PPC-NEXT: br label %cont10 ++// ++// CHECK-PPC-LABEL:using_overflow9: ; preds = %cont ++// CHECK-PPC-NEXT: %32 = inttoptr i32 %25 to i32* ++// CHECK-PPC-NEXT: %33 = add i32 %25, 4 ++// CHECK-PPC-NEXT: %34 = inttoptr i32 %33 to i8* ++// CHECK-PPC-NEXT: store i8* %34, i8** %22 ++// CHECK-PPC-NEXT: br label %cont10 ++// ++// CHECK-PPC-LABEL:cont10: ; preds = %using_overflow9, %using_regs8 ++// CHECK-PPC-NEXT: %vaarg.addr11 = phi i32* [ %30, %using_regs8 ], [ %32, %using_overflow9 ] ++// CHECK-PPC-NEXT: %35 = load i32* %vaarg.addr11 ++// CHECK-PPC-NEXT: store i32 %35, i32* %v, align 4 + ++#ifdef __powerpc64__ + __int128_t u = va_arg (ap, __int128_t); ++#endif + // CHECK: bitcast i8* %{{[a-z.0-9]+}} to i128* + // CHECK-NEXT: load i128* %{{[0-9]+}} + } From cc13f05d04e32abe92dbfa3732ae6dc7915304de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sun, 14 Dec 2014 16:17:48 +0000 Subject: [PATCH 03/64] Clean up, reindent, add a special case for NIS / LDAP line MFC after: 1 week --- usr.sbin/chkgrp/chkgrp.c | 258 +++++++++++++++++++-------------------- 1 file changed, 128 insertions(+), 130 deletions(-) diff --git a/usr.sbin/chkgrp/chkgrp.c b/usr.sbin/chkgrp/chkgrp.c index c9515b5c479..d7c15067102 100644 --- a/usr.sbin/chkgrp/chkgrp.c +++ b/usr.sbin/chkgrp/chkgrp.c @@ -40,154 +40,152 @@ __FBSDID("$FreeBSD$"); #include #include -static char empty[] = { 0 }; - static void __dead2 usage(void) { - fprintf(stderr, "usage: chkgrp [groupfile]\n"); - exit(EX_USAGE); + + fprintf(stderr, "usage: chkgrp [-q] [groupfile]\n"); + exit(EX_USAGE); } int main(int argc, char *argv[]) { - unsigned int i; - size_t len; - int quiet; - int ch; - int n = 0, k, e = 0; - char *line, *f[4], *p; - const char *cp, *gfn; - FILE *gf; + FILE *gf; + unsigned long gid; + unsigned int i; + size_t len; + int opt, quiet; + int n = 0, k, e = 0; + const char *cp, *f[4], *gfn, *p; + char *line; - quiet = 0; - while ((ch = getopt(argc, argv, "q")) != -1) { - switch (ch) { + quiet = 0; + while ((opt = getopt(argc, argv, "q")) != -1) { + switch (opt) { case 'q': quiet = 1; break; - case '?': default: usage(); - } - } - - if (optind == argc) - gfn = "/etc/group"; - else if (optind == argc - 1) - gfn = argv[optind]; - else - usage(); - - /* open group file */ - if ((gf = fopen(gfn, "r")) == NULL) - err(EX_NOINPUT, "%s", gfn); - - /* check line by line */ - while (++n) { - if ((line = fgetln(gf, &len)) == NULL) - break; - if (len > 0 && line[len - 1] != '\n') { - warnx("%s: line %d: no newline character", gfn, n); - e = 1; + } } - while (len && isspace(line[len-1])) - len--; - /* ignore blank lines and comments */ - for (p = line; p < (line + len); p++) - if (!isspace(*p)) break; - if (!len || (*p == '#')) { -#if 0 - /* entry is correct, so print it */ - printf("%*.*s\n", len, len, line); -#endif - continue; - } + argc -= optind; + argv += optind; + + if (argc == 0) + gfn = "/etc/group"; + else if (argc == 1) + gfn = argv[0]; + else + usage(); + + /* open group file */ + if ((gf = fopen(gfn, "r")) == NULL) + err(EX_NOINPUT, "%s", gfn); + + /* check line by line */ + while (++n) { + if ((line = fgetln(gf, &len)) == NULL) + break; + if (len > 0 && line[len - 1] != '\n') { + warnx("%s: line %d: no newline character", gfn, n); + e = 1; + } + while (len && isspace(line[len-1])) + len--; + + /* ignore blank lines and comments */ + for (p = line; p < line + len; p++) + if (!isspace(*p)) break; + if (!len || *p == '#') + continue; + + /* + * Hack: special case for + line + */ + if (strncmp(line, "+:::", len) == 0) + continue; + + /* + * A correct group entry has four colon-separated fields, + * the third of which must be entirely numeric and the + * fourth of which may be empty. + */ + for (i = k = 0; k < 4; k++) { + for (f[k] = line + i; i < len && line[i] != ':'; i++) + /* nothing */ ; + if (k < 3 && line[i] != ':') + break; + line[i++] = 0; + } + + if (k < 4) { + warnx("%s: line %d: missing field(s)", gfn, n); + while (k < 4) + f[k++] = ""; + e = 1; + } + + for (cp = f[0] ; *cp ; cp++) { + if (!isalnum(*cp) && *cp != '.' && *cp != '_' && + *cp != '-' && (cp > f[0] || *cp != '+')) { + warnx("%s: line %d: '%c' invalid character", + gfn, n, *cp); + e = 1; + } + } + + for (cp = f[3] ; *cp ; cp++) { + if (!isalnum(*cp) && *cp != '.' && *cp != '_' && + *cp != '-' && *cp != ',') { + warnx("%s: line %d: '%c' invalid character", + gfn, n, *cp); + e = 1; + } + } + + /* check if fourth field ended with a colon */ + if (i < len) { + warnx("%s: line %d: too many fields", gfn, n); + e = 1; + } - /* - * A correct group entry has four colon-separated fields, the third - * of which must be entirely numeric and the fourth of which may - * be empty. - */ - for (i = k = 0; k < 4; k++) { - for (f[k] = line+i; (i < len) && (line[i] != ':'); i++) - /* nothing */ ; - if ((k < 3) && (line[i] != ':')) - break; - line[i++] = 0; + /* check that none of the fields contain whitespace */ + for (k = 0; k < 4; k++) { + if (strcspn(f[k], " \t") != strlen(f[k])) { + warnx("%s: line %d: field %d contains whitespace", + gfn, n, k+1); + e = 1; + } + } + + /* check that the GID is numeric */ + if (strspn(f[2], "0123456789") != strlen(f[2])) { + warnx("%s: line %d: group id is not numeric", gfn, n); + e = 1; + } + + /* check the range of the group id */ + errno = 0; + gid = strtoul(f[2], NULL, 10); + if (errno != 0) { + warnx("%s: line %d: strtoul failed", gfn, n); + } else if (gid > GID_MAX) { + warnx("%s: line %d: group id is too large (%ju > %ju)", + gfn, n, (uintmax_t)gid, (uintmax_t)GID_MAX); + e = 1; + } } - if (k < 4) { - warnx("%s: line %d: missing field(s)", gfn, n); - for ( ; k < 4; k++) - f[k] = empty; - e = 1; - } + /* check what broke the loop */ + if (ferror(gf)) + err(EX_IOERR, "%s: line %d", gfn, n); - for (cp = f[0] ; *cp ; cp++) { - if (!isalnum(*cp) && *cp != '.' && *cp != '_' && *cp != '-' && - (cp > f[0] || *cp != '+')) { - warnx("%s: line %d: '%c' invalid character", gfn, n, *cp); - e = 1; - } - } - - for (cp = f[3] ; *cp ; cp++) { - if (!isalnum(*cp) && *cp != '.' && *cp != '_' && *cp != '-' && - *cp != ',') { - warnx("%s: line %d: '%c' invalid character", gfn, n, *cp); - e = 1; - } - } - - /* check if fourth field ended with a colon */ - if (i < len) { - warnx("%s: line %d: too many fields", gfn, n); - e = 1; - } - - /* check that none of the fields contain whitespace */ - for (k = 0; k < 4; k++) { - if (strcspn(f[k], " \t") != strlen(f[k])) { - warnx("%s: line %d: field %d contains whitespace", - gfn, n, k+1); - e = 1; - } - } - - /* check that the GID is numeric */ - if (strspn(f[2], "0123456789") != strlen(f[2])) { - warnx("%s: line %d: GID is not numeric", gfn, n); - e = 1; - } - - /* check the range of the group id */ - errno = 0; - unsigned long groupid = strtoul(f[2], NULL, 10); - if (errno != 0) { - warnx("%s: line %d: strtoul failed", gfn, n); - } - else if (groupid > GID_MAX) { - warnx("%s: line %d: group id is too large (> %ju)", - gfn, n, (uintmax_t)GID_MAX); - e = 1; - } - -#if 0 - /* entry is correct, so print it */ - printf("%s:%s:%s:%s\n", f[0], f[1], f[2], f[3]); -#endif - } - - /* check what broke the loop */ - if (ferror(gf)) - err(EX_IOERR, "%s: line %d", gfn, n); - - /* done */ - fclose(gf); - if (e == 0 && quiet == 0) - printf("%s is fine\n", gfn); - exit(e ? EX_DATAERR : EX_OK); + /* done */ + fclose(gf); + if (e == 0 && quiet == 0) + printf("%s is fine\n", gfn); + exit(e ? EX_DATAERR : EX_OK); } From 88ef06f3a9582f4f17a1cdb306cca14bf91c32bf Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 14 Dec 2014 16:26:19 +0000 Subject: [PATCH 04/64] sh: Make sure output suitable as shell input is also printable. Commands like 'export -p', 'set' and 'trap', and tracing enabled via 'set -x' generate output suitable as shell input by adding quotes as necessary. If there are control characters other than newline or invalid UTF-8 sequences, use $'...' and \OOO to display them safely. The resulting output is not parsable by a strict POSIX.1-2008 shell but sh from FreeBSD 9.0 and newer and many other shells can parse it. --- bin/sh/output.c | 90 +++++++++++++++++++++++++-------- bin/sh/tests/execution/Makefile | 1 + bin/sh/tests/execution/set-x4.0 | 7 +++ 3 files changed, 76 insertions(+), 22 deletions(-) create mode 100644 bin/sh/tests/execution/set-x4.0 diff --git a/bin/sh/output.c b/bin/sh/output.c index c6d118f1153..39b722fdba2 100644 --- a/bin/sh/output.c +++ b/bin/sh/output.c @@ -54,6 +54,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include "shell.h" #include "syntax.h" @@ -111,42 +113,86 @@ outstr(const char *p, struct output *file) outbin(p, strlen(p), file); } +static void +byteseq(int ch, struct output *file) +{ + char seq[4]; + + seq[0] = '\\'; + seq[1] = (ch >> 6 & 0x3) + '0'; + seq[2] = (ch >> 3 & 0x7) + '0'; + seq[3] = (ch & 0x7) + '0'; + outbin(seq, 4, file); +} + +static void +outdqstr(const char *p, struct output *file) +{ + const char *end; + mbstate_t mbs; + size_t clen; + wchar_t wc; + + memset(&mbs, '\0', sizeof(mbs)); + end = p + strlen(p); + outstr("$'", file); + while ((clen = mbrtowc(&wc, p, end - p + 1, &mbs)) != 0) { + if (clen == (size_t)-2) { + while (p < end) + byteseq(*p++, file); + break; + } + if (clen == (size_t)-1) { + memset(&mbs, '\0', sizeof(mbs)); + byteseq(*p++, file); + continue; + } + if (wc == L'\n') + outcslow('\n', file), p++; + else if (wc == L'\r') + outstr("\\r", file), p++; + else if (wc == L'\t') + outstr("\\t", file), p++; + else if (!iswprint(wc)) { + for (; clen > 0; clen--) + byteseq(*p++, file); + } else { + if (wc == L'\'' || wc == L'\\') + outcslow('\\', file); + outbin(p, clen, file); + p += clen; + } + } + outcslow('\'', file); +} + /* Like outstr(), but quote for re-input into the shell. */ void outqstr(const char *p, struct output *file) { - char ch; - int inquotes; + int i; if (p[0] == '\0') { outstr("''", file); return; } - if (p[strcspn(p, "|&;<>()$`\\\"' \t\n*?[~#=")] == '\0' || + for (i = 0; p[i] != '\0'; i++) { + if ((p[i] > '\0' && p[i] < ' ' && p[i] != '\n') || + (p[i] & 0x80) != 0 || p[i] == '\'') { + outdqstr(p, file); + return; + } + } + + if (p[strcspn(p, "|&;<>()$`\\\" \n*?[~#=")] == '\0' || strcmp(p, "[") == 0) { outstr(p, file); return; } - inquotes = 0; - while ((ch = *p++) != '\0') { - switch (ch) { - case '\'': - /* Can't quote single quotes inside single quotes. */ - if (inquotes) - outcslow('\'', file); - inquotes = 0; - outstr("\\'", file); - break; - default: - if (!inquotes) - outcslow('\'', file); - inquotes = 1; - outc(ch, file); - } - } - if (inquotes) - outcslow('\'', file); + outcslow('\'', file); + outstr(p, file); + outcslow('\'', file); } void diff --git a/bin/sh/tests/execution/Makefile b/bin/sh/tests/execution/Makefile index 2653d5ffe79..638492bb96a 100644 --- a/bin/sh/tests/execution/Makefile +++ b/bin/sh/tests/execution/Makefile @@ -44,6 +44,7 @@ FILES+= set-n4.0 FILES+= set-x1.0 FILES+= set-x2.0 FILES+= set-x3.0 +FILES+= set-x4.0 FILES+= shellproc1.0 FILES+= subshell1.0 subshell1.0.stdout FILES+= subshell2.0 diff --git a/bin/sh/tests/execution/set-x4.0 b/bin/sh/tests/execution/set-x4.0 new file mode 100644 index 00000000000..0904766ccdd --- /dev/null +++ b/bin/sh/tests/execution/set-x4.0 @@ -0,0 +1,7 @@ +# $FreeBSD$ + +key=`printf '\r\t\001\200\300'` +r=`{ set -x; : "$key"; } 2>&1 >/dev/null` +case $r in +*[![:print:]]*) echo fail; exit 3 +esac From 17a2c536c86a51ec83d4a4213427ff98bbd22a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sun, 14 Dec 2014 16:40:46 +0000 Subject: [PATCH 05/64] Add a vigr(8) utility which does for /etc/group what vipw(8) does for /etc/master.passwd. --- usr.sbin/Makefile | 1 + usr.sbin/vigr/Makefile | 6 +++ usr.sbin/vigr/vigr.8 | 71 +++++++++++++++++++++++++++++++ usr.sbin/vigr/vigr.sh | 95 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 173 insertions(+) create mode 100644 usr.sbin/vigr/Makefile create mode 100644 usr.sbin/vigr/vigr.8 create mode 100644 usr.sbin/vigr/vigr.sh diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 7c444816f42..8c92af1e0ff 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -94,6 +94,7 @@ SUBDIR= adduser \ trpt \ tzsetup \ ugidfw \ + vigr \ vipw \ wake \ watch \ diff --git a/usr.sbin/vigr/Makefile b/usr.sbin/vigr/Makefile new file mode 100644 index 00000000000..d71998b4732 --- /dev/null +++ b/usr.sbin/vigr/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +SCRIPTS= vigr +MAN= vigr.8 + +.include diff --git a/usr.sbin/vigr/vigr.8 b/usr.sbin/vigr/vigr.8 new file mode 100644 index 00000000000..3fd582b2cd9 --- /dev/null +++ b/usr.sbin/vigr/vigr.8 @@ -0,0 +1,71 @@ +.\"- +.\" Copyright (c) 2014 Dag-Erling Smørgrav +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd December 14, 2014 +.Dt VIGR 8 +.Os +.Sh NAME +.Nm vigr +.Nd edit the group file +.Sh SYNOPSIS +.Nm +.Op Fl d Ar directory +.Sh DESCRIPTION +The +.Nm +utility makes a temporary copy of the group file, allows the user to +edit it, then verifies that the edited file is valid before installing +it. +.Pp +The following options are available: +.Bl -tag -width Fl +.It Fl d Ar directory +Edit the group file in the specified directory instead of the default +.Pa /etc/group . +.El +.Sh ENVIRONMENT +.Bl -tag -width EDITOR +.It Ev EDITOR +The editor to use instead of +.Xr vi 1 . +.It Ev TMPDIR +The directory in which to store the temporary copy of the group file. +.El +.Sh SEE ALSO +.Xr group 5 , +.Xr chkgrp 8 , +.Xr vipw 8 +.Sh HISTORY +The +.Nm +utility appeared in +.Fx 11.0 . +.Sh AUTHORS +The +.Nm +utility and this manual page were written by +.An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org . diff --git a/usr.sbin/vigr/vigr.sh b/usr.sbin/vigr/vigr.sh new file mode 100644 index 00000000000..c5dc65d8be1 --- /dev/null +++ b/usr.sbin/vigr/vigr.sh @@ -0,0 +1,95 @@ +#!/bin/sh +#- +# Copyright (c) 2014 Dag-Erling Smørgrav +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +error() { + echo "$@" >&2 + exit 1 +} + +usage() { + error "usage: vigr [-d dir]" +} + +# Check arguments +while getopts d: opt ; do + case $opt in + d) + etcdir="${OPTARG}" + ;; + *) + usage + ;; + esac +done + +# Look for the current group file +grpfile="${etcdir:-/etc}/group" +if [ ! -f "${grpfile}" ] ; then + error "Missing group file" +fi + +# Create a secure temporary working directory +tmpdir=$(mktemp -d -t vigr) +if [ -z "${tmpdir}" -o ! -d "${tmpdir}" ] ; then + error "Unable to create the temporary directory" +fi +tmpfile="${tmpdir}/group" + +# Clean up on exit +trap "exit 1" INT +trap "rm -rf '${tmpdir}'" EXIT +set -e + +# Make a copy of the group file for the user to edit +cp "${grpfile}" "${tmpfile}" + +while :; do + # Let the user edit the file + ${EDITOR:-/usr/bin/vi} "${tmpfile}" + + # If the result is valid, install it and exit + if chkgrp -q "${tmpfile}" ; then + install -b -m 0644 -C -S "${tmpfile}" "${grpfile}" + exit 0 + fi + + # If it is not, offer to re-edit + while :; do + echo -n "Re-edit the group file? " + read ans + case $ans in + [Yy]|[Yy][Ee][Ss]) + break + ;; + [Nn]|[Nn][Oo]) + exit 1 + ;; + esac + done +done From f843434e3708f728ecfb3fba10a0ac6f7b319b7d Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 14 Dec 2014 18:16:49 +0000 Subject: [PATCH 06/64] Update clang patch for r275759 to use correct test cases. --- ...patch-r275759-clang-r221170-ppc-vaarg.diff | 245 +++++++++++------- 1 file changed, 151 insertions(+), 94 deletions(-) diff --git a/contrib/llvm/patches/patch-r275759-clang-r221170-ppc-vaarg.diff b/contrib/llvm/patches/patch-r275759-clang-r221170-ppc-vaarg.diff index 61ace4c0885..0562a68cb01 100644 --- a/contrib/llvm/patches/patch-r275759-clang-r221170-ppc-vaarg.diff +++ b/contrib/llvm/patches/patch-r275759-clang-r221170-ppc-vaarg.diff @@ -3,6 +3,18 @@ Pull in r221170 from upstream clang trunk (by Roman Divacky): Implement vaarg lowering for ppc32. Lowering of scalars and aggregates is supported. Complex numbers are not. +Pull in r221174 from upstream clang trunk (by Roman Divacky): + + Require asserts to unbreak the buildbots. + +Pull in r221284 from upstream clang trunk (by Roman Divacky): + + Rewrite the test to not require asserts. + +Pull in r221285 from upstream clang trunk (by Roman Divacky): + + Since the file has both ppc and ppc64 tests in it rename it. + This adds va_args support for PowerPC (32 bit) to clang. Introduced here: http://svnweb.freebsd.org/changeset/base/275759 @@ -136,106 +148,151 @@ Index: tools/clang/test/CodeGen/ppc64-varargs-struct.c =================================================================== --- tools/clang/test/CodeGen/ppc64-varargs-struct.c +++ tools/clang/test/CodeGen/ppc64-varargs-struct.c -@@ -1,5 +1,6 @@ - // REQUIRES: ppc64-registered-target - // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s +@@ -1,30 +0,0 @@ +-// REQUIRES: ppc64-registered-target +-// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s +- +-#include +- +-struct x { +- long a; +- double b; +-}; +- +-void testva (int n, ...) +-{ +- va_list ap; +- +- struct x t = va_arg (ap, struct x); +-// CHECK: bitcast i8* %{{[a-z.0-9]*}} to %struct.x* +-// CHECK: bitcast %struct.x* %t to i8* +-// CHECK: bitcast %struct.x* %{{[0-9]+}} to i8* +-// CHECK: call void @llvm.memcpy +- +- int v = va_arg (ap, int); +-// CHECK: ptrtoint i8* %{{[a-z.0-9]*}} to i64 +-// CHECK: add i64 %{{[0-9]+}}, 4 +-// CHECK: inttoptr i64 %{{[0-9]+}} to i8* +-// CHECK: bitcast i8* %{{[0-9]+}} to i32* +- +- __int128_t u = va_arg (ap, __int128_t); +-// CHECK: bitcast i8* %{{[a-z.0-9]+}} to i128* +-// CHECK-NEXT: load i128* %{{[0-9]+}} +-} +Index: tools/clang/test/CodeGen/ppc-varargs-struct.c +=================================================================== +--- tools/clang/test/CodeGen/ppc-varargs-struct.c ++++ tools/clang/test/CodeGen/ppc-varargs-struct.c +@@ -0,0 +1,112 @@ ++// REQUIRES: ppc64-registered-target ++// REQUIRES: asserts ++// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-PPC - - #include - -@@ -17,6 +18,46 @@ void testva (int n, ...) - // CHECK: bitcast %struct.x* %t to i8* - // CHECK: bitcast %struct.x* %{{[0-9]+}} to i8* - // CHECK: call void @llvm.memcpy -+// CHECK-PPC: %arraydecay = getelementptr inbounds [1 x %struct.__va_list_tag]* %ap, i32 0, i32 0 -+// CHECK-PPC-NEXT: %gprptr = bitcast %struct.__va_list_tag* %arraydecay to i8* -+// CHECK-PPC-NEXT: %0 = ptrtoint i8* %gprptr to i32 -+// CHECK-PPC-NEXT: %1 = add i32 %0, 1 -+// CHECK-PPC-NEXT: %2 = inttoptr i32 %1 to i8* -+// CHECK-PPC-NEXT: %3 = add i32 %1, 3 -+// CHECK-PPC-NEXT: %4 = inttoptr i32 %3 to i8** -+// CHECK-PPC-NEXT: %5 = add i32 %3, 4 -+// CHECK-PPC-NEXT: %6 = inttoptr i32 %5 to i8** -+// CHECK-PPC-NEXT: %gpr = load i8* %gprptr -+// CHECK-PPC-NEXT: %fpr = load i8* %2 -+// CHECK-PPC-NEXT: %overflow_area = load i8** %4 -+// CHECK-PPC-NEXT: %7 = ptrtoint i8* %overflow_area to i32 -+// CHECK-PPC-NEXT: %regsave_area = load i8** %6 -+// CHECK-PPC-NEXT: %8 = ptrtoint i8* %regsave_area to i32 -+// CHECK-PPC-NEXT: %cond = icmp ult i8 %gpr, 8 -+// CHECK-PPC-NEXT: %9 = mul i8 %gpr, 4 -+// CHECK-PPC-NEXT: %10 = sext i8 %9 to i32 -+// CHECK-PPC-NEXT: %11 = add i32 %8, %10 -+// CHECK-PPC-NEXT: br i1 %cond, label %using_regs, label %using_overflow ++ ++#include ++ ++struct x { ++ long a; ++ double b; ++}; ++ ++void testva (int n, ...) ++{ ++ va_list ap; ++ ++ struct x t = va_arg (ap, struct x); ++// CHECK: bitcast i8* %{{[a-z.0-9]*}} to %struct.x* ++// CHECK: bitcast %struct.x* %t to i8* ++// CHECK: bitcast %struct.x* %{{[0-9]+}} to i8* ++// CHECK: call void @llvm.memcpy ++// CHECK-PPC: [[ARRAYDECAY:%[a-z0-9]+]] = getelementptr inbounds [1 x %struct.__va_list_tag]* %ap, i32 0, i32 0 ++// CHECK-PPC-NEXT: [[GPRPTR:%[a-z0-9]+]] = bitcast %struct.__va_list_tag* [[ARRAYDECAY]] to i8* ++// CHECK-PPC-NEXT: [[ZERO:%[0-9]+]] = ptrtoint i8* [[GPRPTR]] to i32 ++// CHECK-PPC-NEXT: [[ONE:%[0-9]+]] = add i32 [[ZERO]], 1 ++// CHECK-PPC-NEXT: [[TWO:%[0-9]+]] = inttoptr i32 [[ONE]] to i8* ++// CHECK-PPC-NEXT: [[THREE:%[0-9]+]] = add i32 [[ONE]], 3 ++// CHECK-PPC-NEXT: [[FOUR:%[0-9]+]] = inttoptr i32 [[THREE]] to i8** ++// CHECK-PPC-NEXT: [[FIVE:%[0-9]+]] = add i32 [[THREE]], 4 ++// CHECK-PPC-NEXT: [[SIX:%[0-9]+]] = inttoptr i32 [[FIVE]] to i8** ++// CHECK-PPC-NEXT: [[GPR:%[a-z0-9]+]] = load i8* [[GPRPTR]] ++// CHECK-PPC-NEXT: [[FPR:%[a-z0-9]+]] = load i8* [[TWO]] ++// CHECK-PPC-NEXT: [[OVERFLOW_AREA:%[a-z_0-9]+]] = load i8** [[FOUR]] ++// CHECK-PPC-NEXT: [[SEVEN:%[0-9]+]] = ptrtoint i8* [[OVERFLOW_AREA]] to i32 ++// CHECK-PPC-NEXT: [[REGSAVE_AREA:%[a-z_0-9]+]] = load i8** [[SIX]] ++// CHECK-PPC-NEXT: [[EIGHT:%[0-9]+]] = ptrtoint i8* [[REGSAVE_AREA]] to i32 ++// CHECK-PPC-NEXT: [[COND:%[a-z0-9]+]] = icmp ult i8 [[GPR]], 8 ++// CHECK-PPC-NEXT: [[NINE:%[0-9]+]] = mul i8 [[GPR]], 4 ++// CHECK-PPC-NEXT: [[TEN:%[0-9]+]] = sext i8 [[NINE]] to i32 ++// CHECK-PPC-NEXT: [[ELEVEN:%[0-9]+]] = add i32 [[EIGHT]], [[TEN]] ++// CHECK-PPC-NEXT: br i1 [[COND]], label [[USING_REGS:%[a-z_0-9]+]], label [[USING_OVERFLOW:%[a-z_0-9]+]] +// -+// CHECK-PPC-LABEL:using_regs: ; preds = %entry -+// CHECK-PPC-NEXT: %12 = inttoptr i32 %11 to %struct.x* -+// CHECK-PPC-NEXT: %13 = add i8 %gpr, 1 -+// CHECK-PPC-NEXT: store i8 %13, i8* %gprptr -+// CHECK-PPC-NEXT: br label %cont ++// CHECK-PPC1:[[USING_REGS]] ++// CHECK-PPC: [[TWELVE:%[0-9]+]] = inttoptr i32 [[ELEVEN]] to %struct.x* ++// CHECK-PPC-NEXT: [[THIRTEEN:%[0-9]+]] = add i8 [[GPR]], 1 ++// CHECK-PPC-NEXT: store i8 [[THIRTEEN]], i8* [[GPRPTR]] ++// CHECK-PPC-NEXT: br label [[CONT:%[a-z0-9]+]] +// -+// CHECK-PPC-LABEL:using_overflow: ; preds = %entry -+// CHECK-PPC-NEXT: %14 = inttoptr i32 %7 to %struct.x* -+// CHECK-PPC-NEXT: %15 = add i32 %7, 4 -+// CHECK-PPC-NEXT: %16 = inttoptr i32 %15 to i8* -+// CHECK-PPC-NEXT: store i8* %16, i8** %4 -+// CHECK-PPC-NEXT: br label %cont ++// CHECK-PPC1:[[USING_OVERFLOW]] ++// CHECK-PPC: [[FOURTEEN:%[0-9]+]] = inttoptr i32 [[SEVEN]] to %struct.x* ++// CHECK-PPC-NEXT: [[FIFTEEN:%[0-9]+]] = add i32 [[SEVEN]], 4 ++// CHECK-PPC-NEXT: [[SIXTEEN:%[0-9]+]] = inttoptr i32 [[FIFTEEN]] to i8* ++// CHECK-PPC-NEXT: store i8* [[SIXTEEN]], i8** [[FOUR]] ++// CHECK-PPC-NEXT: br label [[CONT]] +// -+// CHECK-PPC-LABEL:cont: ; preds = %using_overflow, %using_regs -+// CHECK-PPC-NEXT: %vaarg.addr = phi %struct.x* [ %12, %using_regs ], [ %14, %using_overflow ] -+// CHECK-PPC-NEXT: %aggrptr = bitcast %struct.x* %vaarg.addr to i8** -+// CHECK-PPC-NEXT: %aggr = load i8** %aggrptr -+// CHECK-PPC-NEXT: %17 = bitcast %struct.x* %t to i8* -+// CHECK-PPC-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %17, i8* %aggr, i32 16, i32 8, i1 false) - - int v = va_arg (ap, int); - // CHECK: ptrtoint i8* %{{[a-z.0-9]*}} to i64 -@@ -23,8 +64,48 @@ void testva (int n, ...) - // CHECK: add i64 %{{[0-9]+}}, 4 - // CHECK: inttoptr i64 %{{[0-9]+}} to i8* - // CHECK: bitcast i8* %{{[0-9]+}} to i32* -+// CHECK-PPC: %arraydecay1 = getelementptr inbounds [1 x %struct.__va_list_tag]* %ap, i32 0, i32 0 -+// CHECK-PPC-NEXT: %gprptr2 = bitcast %struct.__va_list_tag* %arraydecay1 to i8* -+// CHECK-PPC-NEXT: %18 = ptrtoint i8* %gprptr2 to i32 -+// CHECK-PPC-NEXT: %19 = add i32 %18, 1 -+// CHECK-PPC-NEXT: %20 = inttoptr i32 %19 to i8* -+// CHECK-PPC-NEXT: %21 = add i32 %19, 3 -+// CHECK-PPC-NEXT: %22 = inttoptr i32 %21 to i8** -+// CHECK-PPC-NEXT: %23 = add i32 %21, 4 -+// CHECK-PPC-NEXT: %24 = inttoptr i32 %23 to i8** -+// CHECK-PPC-NEXT: %gpr3 = load i8* %gprptr2 -+// CHECK-PPC-NEXT: %fpr4 = load i8* %20 -+// CHECK-PPC-NEXT: %overflow_area5 = load i8** %22 -+// CHECK-PPC-NEXT: %25 = ptrtoint i8* %overflow_area5 to i32 -+// CHECK-PPC-NEXT: %regsave_area6 = load i8** %24 -+// CHECK-PPC-NEXT: %26 = ptrtoint i8* %regsave_area6 to i32 -+// CHECK-PPC-NEXT: %cond7 = icmp ult i8 %gpr3, 8 -+// CHECK-PPC-NEXT: %27 = mul i8 %gpr3, 4 -+// CHECK-PPC-NEXT: %28 = sext i8 %27 to i32 -+// CHECK-PPC-NEXT: %29 = add i32 %26, %28 -+// CHECK-PPC-NEXT: br i1 %cond7, label %using_regs8, label %using_overflow9 ++// CHECK-PPC1:[[CONT]] ++// CHECK-PPC: [[VAARG_ADDR:%[a-z.0-9]+]] = phi %struct.x* [ [[TWELVE]], [[USING_REGS]] ], [ [[FOURTEEN]], [[USING_OVERFLOW]] ] ++// CHECK-PPC-NEXT: [[AGGRPTR:%[a-z0-9]+]] = bitcast %struct.x* [[VAARG_ADDR]] to i8** ++// CHECK-PPC-NEXT: [[AGGR:%[a-z0-9]+]] = load i8** [[AGGRPTR]] ++// CHECK-PPC-NEXT: [[SEVENTEEN:%[0-9]+]] = bitcast %struct.x* %t to i8* ++// CHECK-PPC-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[SEVENTEEN]], i8* [[AGGR]], i32 16, i32 8, i1 false) ++ ++ int v = va_arg (ap, int); ++// CHECK: ptrtoint i8* %{{[a-z.0-9]*}} to i64 ++// CHECK: add i64 %{{[0-9]+}}, 4 ++// CHECK: inttoptr i64 %{{[0-9]+}} to i8* ++// CHECK: bitcast i8* %{{[0-9]+}} to i32* ++// CHECK-PPC: [[ARRAYDECAY1:%[a-z0-9]+]] = getelementptr inbounds [1 x %struct.__va_list_tag]* %ap, i32 0, i32 0 ++// CHECK-PPC-NEXT: [[GPRPTR1:%[a-z0-9]+]] = bitcast %struct.__va_list_tag* [[ARRAYDECAY1]] to i8* ++// CHECK-PPC-NEXT: [[EIGHTEEN:%[0-9]+]] = ptrtoint i8* [[GPRPTR1]] to i32 ++// CHECK-PPC-NEXT: [[NINETEEN:%[0-9]+]] = add i32 [[EIGHTEEN]], 1 ++// CHECK-PPC-NEXT: [[TWENTY:%[0-9]+]] = inttoptr i32 [[NINETEEN]] to i8* ++// CHECK-PPC-NEXT: [[TWENTYONE:%[0-9]+]] = add i32 [[NINETEEN]], 3 ++// CHECK-PPC-NEXT: [[TWENTYTWO:%[0-9]+]] = inttoptr i32 [[TWENTYONE]] to i8** ++// CHECK-PPC-NEXT: [[TWENTYTHREE:%[0-9]+]] = add i32 [[TWENTYONE]], 4 ++// CHECK-PPC-NEXT: [[TWENTYFOUR:%[0-9]+]] = inttoptr i32 [[TWENTYTHREE]] to i8** ++// CHECK-PPC-NEXT: [[GPR1:%[a-z0-9]+]] = load i8* [[GPRPTR1]] ++// CHECK-PPC-NEXT: [[FPR1:%[a-z0-9]+]] = load i8* [[TWENTY]] ++// CHECK-PPC-NEXT: [[OVERFLOW_AREA1:%[a-z_0-9]+]] = load i8** [[TWENTYTWO]] ++// CHECK-PPC-NEXT: [[TWENTYFIVE:%[0-9]+]] = ptrtoint i8* [[OVERFLOW_AREA1]] to i32 ++// CHECK-PPC-NEXT: [[REGSAVE_AREA1:%[a-z_0-9]+]] = load i8** [[TWENTYFOUR]] ++// CHECK-PPC-NEXT: [[TWENTYSIX:%[0-9]+]] = ptrtoint i8* [[REGSAVE_AREA1]] to i32 ++// CHECK-PPC-NEXT: [[COND1:%[a-z0-9]+]] = icmp ult i8 [[GPR1]], 8 ++// CHECK-PPC-NEXT: [[TWENTYSEVEN:%[0-9]+]] = mul i8 [[GPR1]], 4 ++// CHECK-PPC-NEXT: [[TWENTYEIGHT:%[0-9]+]] = sext i8 [[TWENTYSEVEN]] to i32 ++// CHECK-PPC-NEXT: [[TWENTYNINE:%[0-9]+]] = add i32 [[TWENTYSIX]], [[TWENTYEIGHT]] ++// CHECK-PPC-NEXT: br i1 [[COND1]], label [[USING_REGS1:%[a-z_0-9]+]], label [[USING_OVERFLOW1:%[a-z_0-9]+]] +// -+// CHECK-PPC-LABEL:using_regs8: ; preds = %cont -+// CHECK-PPC-NEXT: %30 = inttoptr i32 %29 to i32* -+// CHECK-PPC-NEXT: %31 = add i8 %gpr3, 1 -+// CHECK-PPC-NEXT: store i8 %31, i8* %gprptr2 -+// CHECK-PPC-NEXT: br label %cont10 ++// CHECK-PPC1:[[USING_REGS1]]: ++// CHECK-PPC: [[THIRTY:%[0-9]+]] = inttoptr i32 [[TWENTYNINE]] to i32* ++// CHECK-PPC-NEXT: [[THIRTYONE:%[0-9]+]] = add i8 [[GPR1]], 1 ++// CHECK-PPC-NEXT: store i8 [[THIRTYONE]], i8* [[GPRPTR1]] ++// CHECK-PPC-NEXT: br label [[CONT1:%[a-z0-9]+]] +// -+// CHECK-PPC-LABEL:using_overflow9: ; preds = %cont -+// CHECK-PPC-NEXT: %32 = inttoptr i32 %25 to i32* -+// CHECK-PPC-NEXT: %33 = add i32 %25, 4 -+// CHECK-PPC-NEXT: %34 = inttoptr i32 %33 to i8* -+// CHECK-PPC-NEXT: store i8* %34, i8** %22 -+// CHECK-PPC-NEXT: br label %cont10 ++// CHECK-PPC1:[[USING_OVERFLOW1]]: ++// CHECK-PPC: [[THIRTYTWO:%[0-9]+]] = inttoptr i32 [[TWENTYFIVE]] to i32* ++// CHECK-PPC-NEXT: [[THIRTYTHREE:%[0-9]+]] = add i32 [[TWENTYFIVE]], 4 ++// CHECK-PPC-NEXT: [[THIRTYFOUR:%[0-9]+]] = inttoptr i32 [[THIRTYTHREE]] to i8* ++// CHECK-PPC-NEXT: store i8* [[THIRTYFOUR]], i8** [[TWENTYTWO]] ++// CHECK-PPC-NEXT: br label [[CONT1]] +// -+// CHECK-PPC-LABEL:cont10: ; preds = %using_overflow9, %using_regs8 -+// CHECK-PPC-NEXT: %vaarg.addr11 = phi i32* [ %30, %using_regs8 ], [ %32, %using_overflow9 ] -+// CHECK-PPC-NEXT: %35 = load i32* %vaarg.addr11 -+// CHECK-PPC-NEXT: store i32 %35, i32* %v, align 4 - ++// CHECK-PPC1:[[CONT1]]: ++// CHECK-PPC: [[VAARG_ADDR1:%[a-z.0-9]+]] = phi i32* [ [[THIRTY]], [[USING_REGS1]] ], [ [[THIRTYTWO]], [[USING_OVERFLOW1]] ] ++// CHECK-PPC-NEXT: [[THIRTYFIVE:%[0-9]+]] = load i32* [[VAARG_ADDR1]] ++// CHECK-PPC-NEXT: store i32 [[THIRTYFIVE]], i32* %v, align 4 ++ +#ifdef __powerpc64__ - __int128_t u = va_arg (ap, __int128_t); ++ __int128_t u = va_arg (ap, __int128_t); +#endif - // CHECK: bitcast i8* %{{[a-z.0-9]+}} to i128* - // CHECK-NEXT: load i128* %{{[0-9]+}} - } ++// CHECK: bitcast i8* %{{[a-z.0-9]+}} to i128* ++// CHECK-NEXT: load i128* %{{[0-9]+}} ++} From 5cead939e94d02f27837a074a9f2f0d48babc5d0 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Sun, 14 Dec 2014 22:41:08 +0000 Subject: [PATCH 07/64] Move ofw_cpu.c to sys/dev/ofw so that it can be used by other architectures. Differential Revision: https://reviews.freebsd.org/D1307 Reviewed by: jhibbits --- sys/conf/files.powerpc | 2 +- sys/{powerpc => dev}/ofw/ofw_cpu.c | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename sys/{powerpc => dev}/ofw/ofw_cpu.c (100%) diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index 62f645e0bc6..5bac8476524 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -44,6 +44,7 @@ dev/nand/nfc_fsl.c optional nand mpc85xx dev/ofw/openfirm.c optional aim dev/ofw/openfirmio.c optional aim dev/ofw/ofw_bus_if.m optional aim +dev/ofw/ofw_cpu.c optional aim dev/ofw/ofw_if.m optional aim dev/ofw/ofw_bus_subr.c optional aim dev/ofw/ofw_console.c optional aim @@ -135,7 +136,6 @@ powerpc/mpc85xx/lbc.c optional mpc85xx powerpc/mpc85xx/mpc85xx.c optional mpc85xx powerpc/mpc85xx/platform_mpc85xx.c optional mpc85xx powerpc/mpc85xx/pci_mpc85xx.c optional pci mpc85xx -powerpc/ofw/ofw_cpu.c optional aim powerpc/ofw/ofw_machdep.c standard powerpc/ofw/ofw_pci.c optional pci powerpc/ofw/ofw_pcibus.c optional pci diff --git a/sys/powerpc/ofw/ofw_cpu.c b/sys/dev/ofw/ofw_cpu.c similarity index 100% rename from sys/powerpc/ofw/ofw_cpu.c rename to sys/dev/ofw/ofw_cpu.c From 71819267417982084c34494fed56e87d3ded67f2 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 15 Dec 2014 07:59:33 +0000 Subject: [PATCH 08/64] 5369 arc flags should be an enum 5370 consistent arc_buf_hdr_t naming scheme Reviewed by: Matthew Ahrens Reviewed by: Alex Reece Reviewed by: Sebastien Roy Reviewed by: Richard Elling Approved by: Richard Lowe Author: George Wilson illumos/illumos-gate@7adb730b589e553bf3b1ccfd9bae2df91c5c1061 --- cmd/zdb/zdb.c | 2 +- uts/common/fs/zfs/arc.c | 671 +++++++++++++++---------------- uts/common/fs/zfs/dbuf.c | 11 +- uts/common/fs/zfs/dmu_diff.c | 2 +- uts/common/fs/zfs/dmu_objset.c | 6 +- uts/common/fs/zfs/dmu_send.c | 6 +- uts/common/fs/zfs/dmu_traverse.c | 12 +- uts/common/fs/zfs/dsl_scan.c | 8 +- uts/common/fs/zfs/sys/arc.h | 41 +- uts/common/fs/zfs/zil.c | 4 +- uts/common/fs/zfs/zio.c | 2 +- 11 files changed, 387 insertions(+), 378 deletions(-) diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 84df1996b7b..d1798c4f871 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -1157,7 +1157,7 @@ visit_indirect(spa_t *spa, const dnode_phys_t *dnp, print_indirect(bp, zb, dnp); if (BP_GET_LEVEL(bp) > 0 && !BP_IS_HOLE(bp)) { - uint32_t flags = ARC_WAIT; + arc_flags_t flags = ARC_FLAG_WAIT; int i; blkptr_t *cbp; int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT; diff --git a/uts/common/fs/zfs/arc.c b/uts/common/fs/zfs/arc.c index 57171d7d21b..435096becc7 100644 --- a/uts/common/fs/zfs/arc.c +++ b/uts/common/fs/zfs/arc.c @@ -500,7 +500,7 @@ struct arc_buf_hdr { arc_buf_hdr_t *b_hash_next; arc_buf_t *b_buf; - uint32_t b_flags; + arc_flags_t b_flags; uint32_t b_datacnt; arc_callback_t *b_acb; @@ -528,50 +528,26 @@ struct arc_buf_hdr { static arc_buf_t *arc_eviction_list; static kmutex_t arc_eviction_mtx; static arc_buf_hdr_t arc_eviction_hdr; -static void arc_get_data_buf(arc_buf_t *buf); -static void arc_access(arc_buf_hdr_t *buf, kmutex_t *hash_lock); -static int arc_evict_needed(arc_buf_contents_t type); -static void arc_evict_ghost(arc_state_t *state, uint64_t spa, int64_t bytes); -static void arc_buf_watch(arc_buf_t *buf); - -static boolean_t l2arc_write_eligible(uint64_t spa_guid, arc_buf_hdr_t *ab); #define GHOST_STATE(state) \ ((state) == arc_mru_ghost || (state) == arc_mfu_ghost || \ (state) == arc_l2c_only) -/* - * Private ARC flags. These flags are private ARC only flags that will show up - * in b_flags in the arc_hdr_buf_t. Some flags are publicly declared, and can - * be passed in as arc_flags in things like arc_read. However, these flags - * should never be passed and should only be set by ARC code. When adding new - * public flags, make sure not to smash the private ones. - */ - -#define ARC_IN_HASH_TABLE (1 << 9) /* this buffer is hashed */ -#define ARC_IO_IN_PROGRESS (1 << 10) /* I/O in progress for buf */ -#define ARC_IO_ERROR (1 << 11) /* I/O failed for buf */ -#define ARC_FREED_IN_READ (1 << 12) /* buf freed while in read */ -#define ARC_BUF_AVAILABLE (1 << 13) /* block not in active use */ -#define ARC_INDIRECT (1 << 14) /* this is an indirect block */ -#define ARC_FREE_IN_PROGRESS (1 << 15) /* hdr about to be freed */ -#define ARC_L2_WRITING (1 << 16) /* L2ARC write in progress */ -#define ARC_L2_EVICTED (1 << 17) /* evicted during I/O */ -#define ARC_L2_WRITE_HEAD (1 << 18) /* head of write list */ - -#define HDR_IN_HASH_TABLE(hdr) ((hdr)->b_flags & ARC_IN_HASH_TABLE) -#define HDR_IO_IN_PROGRESS(hdr) ((hdr)->b_flags & ARC_IO_IN_PROGRESS) -#define HDR_IO_ERROR(hdr) ((hdr)->b_flags & ARC_IO_ERROR) -#define HDR_PREFETCH(hdr) ((hdr)->b_flags & ARC_PREFETCH) -#define HDR_FREED_IN_READ(hdr) ((hdr)->b_flags & ARC_FREED_IN_READ) -#define HDR_BUF_AVAILABLE(hdr) ((hdr)->b_flags & ARC_BUF_AVAILABLE) -#define HDR_FREE_IN_PROGRESS(hdr) ((hdr)->b_flags & ARC_FREE_IN_PROGRESS) -#define HDR_L2CACHE(hdr) ((hdr)->b_flags & ARC_L2CACHE) -#define HDR_L2_READING(hdr) ((hdr)->b_flags & ARC_IO_IN_PROGRESS && \ - (hdr)->b_l2hdr != NULL) -#define HDR_L2_WRITING(hdr) ((hdr)->b_flags & ARC_L2_WRITING) -#define HDR_L2_EVICTED(hdr) ((hdr)->b_flags & ARC_L2_EVICTED) -#define HDR_L2_WRITE_HEAD(hdr) ((hdr)->b_flags & ARC_L2_WRITE_HEAD) +#define HDR_IN_HASH_TABLE(hdr) ((hdr)->b_flags & ARC_FLAG_IN_HASH_TABLE) +#define HDR_IO_IN_PROGRESS(hdr) ((hdr)->b_flags & ARC_FLAG_IO_IN_PROGRESS) +#define HDR_IO_ERROR(hdr) ((hdr)->b_flags & ARC_FLAG_IO_ERROR) +#define HDR_PREFETCH(hdr) ((hdr)->b_flags & ARC_FLAG_PREFETCH) +#define HDR_FREED_IN_READ(hdr) ((hdr)->b_flags & ARC_FLAG_FREED_IN_READ) +#define HDR_BUF_AVAILABLE(hdr) ((hdr)->b_flags & ARC_FLAG_BUF_AVAILABLE) +#define HDR_FREE_IN_PROGRESS(hdr) \ + ((hdr)->b_flags & ARC_FLAG_FREE_IN_PROGRESS) +#define HDR_L2CACHE(hdr) ((hdr)->b_flags & ARC_FLAG_L2CACHE) +#define HDR_L2_READING(hdr) \ + ((hdr)->b_flags & ARC_FLAG_IO_IN_PROGRESS && \ + (hdr)->b_l2hdr != NULL) +#define HDR_L2_WRITING(hdr) ((hdr)->b_flags & ARC_FLAG_L2_WRITING) +#define HDR_L2_EVICTED(hdr) ((hdr)->b_flags & ARC_FLAG_L2_EVICTED) +#define HDR_L2_WRITE_HEAD(hdr) ((hdr)->b_flags & ARC_FLAG_L2_WRITE_HEAD) /* * Other sizes @@ -703,14 +679,20 @@ static kmutex_t l2arc_feed_thr_lock; static kcondvar_t l2arc_feed_thr_cv; static uint8_t l2arc_thread_exit; -static void l2arc_read_done(zio_t *zio); +static void arc_get_data_buf(arc_buf_t *); +static void arc_access(arc_buf_hdr_t *, kmutex_t *); +static int arc_evict_needed(arc_buf_contents_t); +static void arc_evict_ghost(arc_state_t *, uint64_t, int64_t); +static void arc_buf_watch(arc_buf_t *); + +static boolean_t l2arc_write_eligible(uint64_t, arc_buf_hdr_t *); +static void l2arc_read_done(zio_t *); static void l2arc_hdr_stat_add(void); static void l2arc_hdr_stat_remove(void); -static boolean_t l2arc_compress_buf(l2arc_buf_hdr_t *l2hdr); -static void l2arc_decompress_zio(zio_t *zio, arc_buf_hdr_t *hdr, - enum zio_compress c); -static void l2arc_release_cdata_buf(arc_buf_hdr_t *ab); +static boolean_t l2arc_compress_buf(l2arc_buf_hdr_t *); +static void l2arc_decompress_zio(zio_t *, arc_buf_hdr_t *, enum zio_compress); +static void l2arc_release_cdata_buf(arc_buf_hdr_t *); static uint64_t buf_hash(uint64_t spa, const dva_t *dva, uint64_t birth) @@ -755,14 +737,14 @@ buf_hash_find(uint64_t spa, const blkptr_t *bp, kmutex_t **lockp) uint64_t birth = BP_PHYSICAL_BIRTH(bp); uint64_t idx = BUF_HASH_INDEX(spa, dva, birth); kmutex_t *hash_lock = BUF_HASH_LOCK(idx); - arc_buf_hdr_t *buf; + arc_buf_hdr_t *hdr; mutex_enter(hash_lock); - for (buf = buf_hash_table.ht_table[idx]; buf != NULL; - buf = buf->b_hash_next) { - if (BUF_EQUAL(spa, dva, birth, buf)) { + for (hdr = buf_hash_table.ht_table[idx]; hdr != NULL; + hdr = hdr->b_hash_next) { + if (BUF_EQUAL(spa, dva, birth, hdr)) { *lockp = hash_lock; - return (buf); + return (hdr); } } mutex_exit(hash_lock); @@ -777,27 +759,27 @@ buf_hash_find(uint64_t spa, const blkptr_t *bp, kmutex_t **lockp) * Otherwise returns NULL. */ static arc_buf_hdr_t * -buf_hash_insert(arc_buf_hdr_t *buf, kmutex_t **lockp) +buf_hash_insert(arc_buf_hdr_t *hdr, kmutex_t **lockp) { - uint64_t idx = BUF_HASH_INDEX(buf->b_spa, &buf->b_dva, buf->b_birth); + uint64_t idx = BUF_HASH_INDEX(hdr->b_spa, &hdr->b_dva, hdr->b_birth); kmutex_t *hash_lock = BUF_HASH_LOCK(idx); - arc_buf_hdr_t *fbuf; + arc_buf_hdr_t *fhdr; uint32_t i; - ASSERT(!DVA_IS_EMPTY(&buf->b_dva)); - ASSERT(buf->b_birth != 0); - ASSERT(!HDR_IN_HASH_TABLE(buf)); + ASSERT(!DVA_IS_EMPTY(&hdr->b_dva)); + ASSERT(hdr->b_birth != 0); + ASSERT(!HDR_IN_HASH_TABLE(hdr)); *lockp = hash_lock; mutex_enter(hash_lock); - for (fbuf = buf_hash_table.ht_table[idx], i = 0; fbuf != NULL; - fbuf = fbuf->b_hash_next, i++) { - if (BUF_EQUAL(buf->b_spa, &buf->b_dva, buf->b_birth, fbuf)) - return (fbuf); + for (fhdr = buf_hash_table.ht_table[idx], i = 0; fhdr != NULL; + fhdr = fhdr->b_hash_next, i++) { + if (BUF_EQUAL(hdr->b_spa, &hdr->b_dva, hdr->b_birth, fhdr)) + return (fhdr); } - buf->b_hash_next = buf_hash_table.ht_table[idx]; - buf_hash_table.ht_table[idx] = buf; - buf->b_flags |= ARC_IN_HASH_TABLE; + hdr->b_hash_next = buf_hash_table.ht_table[idx]; + buf_hash_table.ht_table[idx] = hdr; + hdr->b_flags |= ARC_FLAG_IN_HASH_TABLE; /* collect some hash table performance data */ if (i > 0) { @@ -815,22 +797,22 @@ buf_hash_insert(arc_buf_hdr_t *buf, kmutex_t **lockp) } static void -buf_hash_remove(arc_buf_hdr_t *buf) +buf_hash_remove(arc_buf_hdr_t *hdr) { - arc_buf_hdr_t *fbuf, **bufp; - uint64_t idx = BUF_HASH_INDEX(buf->b_spa, &buf->b_dva, buf->b_birth); + arc_buf_hdr_t *fhdr, **hdrp; + uint64_t idx = BUF_HASH_INDEX(hdr->b_spa, &hdr->b_dva, hdr->b_birth); ASSERT(MUTEX_HELD(BUF_HASH_LOCK(idx))); - ASSERT(HDR_IN_HASH_TABLE(buf)); + ASSERT(HDR_IN_HASH_TABLE(hdr)); - bufp = &buf_hash_table.ht_table[idx]; - while ((fbuf = *bufp) != buf) { - ASSERT(fbuf != NULL); - bufp = &fbuf->b_hash_next; + hdrp = &buf_hash_table.ht_table[idx]; + while ((fhdr = *hdrp) != hdr) { + ASSERT(fhdr != NULL); + hdrp = &fhdr->b_hash_next; } - *bufp = buf->b_hash_next; - buf->b_hash_next = NULL; - buf->b_flags &= ~ARC_IN_HASH_TABLE; + *hdrp = hdr->b_hash_next; + hdr->b_hash_next = NULL; + hdr->b_flags &= ~ARC_FLAG_IN_HASH_TABLE; /* collect some hash table performance data */ ARCSTAT_BUMPDOWN(arcstat_hash_elements); @@ -867,12 +849,12 @@ buf_fini(void) static int hdr_cons(void *vbuf, void *unused, int kmflag) { - arc_buf_hdr_t *buf = vbuf; + arc_buf_hdr_t *hdr = vbuf; - bzero(buf, sizeof (arc_buf_hdr_t)); - refcount_create(&buf->b_refcnt); - cv_init(&buf->b_cv, NULL, CV_DEFAULT, NULL); - mutex_init(&buf->b_freeze_lock, NULL, MUTEX_DEFAULT, NULL); + bzero(hdr, sizeof (arc_buf_hdr_t)); + refcount_create(&hdr->b_refcnt); + cv_init(&hdr->b_cv, NULL, CV_DEFAULT, NULL); + mutex_init(&hdr->b_freeze_lock, NULL, MUTEX_DEFAULT, NULL); arc_space_consume(sizeof (arc_buf_hdr_t), ARC_SPACE_HDRS); return (0); @@ -899,12 +881,12 @@ buf_cons(void *vbuf, void *unused, int kmflag) static void hdr_dest(void *vbuf, void *unused) { - arc_buf_hdr_t *buf = vbuf; + arc_buf_hdr_t *hdr = vbuf; - ASSERT(BUF_EMPTY(buf)); - refcount_destroy(&buf->b_refcnt); - cv_destroy(&buf->b_cv); - mutex_destroy(&buf->b_freeze_lock); + ASSERT(BUF_EMPTY(hdr)); + refcount_destroy(&hdr->b_refcnt); + cv_destroy(&hdr->b_cv); + mutex_destroy(&hdr->b_freeze_lock); arc_space_return(sizeof (arc_buf_hdr_t), ARC_SPACE_HDRS); } @@ -986,7 +968,7 @@ arc_cksum_verify(arc_buf_t *buf) mutex_enter(&buf->b_hdr->b_freeze_lock); if (buf->b_hdr->b_freeze_cksum == NULL || - (buf->b_hdr->b_flags & ARC_IO_ERROR)) { + (buf->b_hdr->b_flags & ARC_FLAG_IO_ERROR)) { mutex_exit(&buf->b_hdr->b_freeze_lock); return; } @@ -1077,7 +1059,7 @@ arc_buf_thaw(arc_buf_t *buf) if (zfs_flags & ZFS_DEBUG_MODIFY) { if (buf->b_hdr->b_state != arc_anon) panic("modifying non-anon buffer!"); - if (buf->b_hdr->b_flags & ARC_IO_IN_PROGRESS) + if (buf->b_hdr->b_flags & ARC_FLAG_IO_IN_PROGRESS) panic("modifying buffer while i/o in progress!"); arc_cksum_verify(buf); } @@ -1118,54 +1100,54 @@ arc_buf_freeze(arc_buf_t *buf) } static void -add_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag) +add_reference(arc_buf_hdr_t *hdr, kmutex_t *hash_lock, void *tag) { ASSERT(MUTEX_HELD(hash_lock)); - if ((refcount_add(&ab->b_refcnt, tag) == 1) && - (ab->b_state != arc_anon)) { - uint64_t delta = ab->b_size * ab->b_datacnt; - list_t *list = &ab->b_state->arcs_list[ab->b_type]; - uint64_t *size = &ab->b_state->arcs_lsize[ab->b_type]; + if ((refcount_add(&hdr->b_refcnt, tag) == 1) && + (hdr->b_state != arc_anon)) { + uint64_t delta = hdr->b_size * hdr->b_datacnt; + list_t *list = &hdr->b_state->arcs_list[hdr->b_type]; + uint64_t *size = &hdr->b_state->arcs_lsize[hdr->b_type]; - ASSERT(!MUTEX_HELD(&ab->b_state->arcs_mtx)); - mutex_enter(&ab->b_state->arcs_mtx); - ASSERT(list_link_active(&ab->b_arc_node)); - list_remove(list, ab); - if (GHOST_STATE(ab->b_state)) { - ASSERT0(ab->b_datacnt); - ASSERT3P(ab->b_buf, ==, NULL); - delta = ab->b_size; + ASSERT(!MUTEX_HELD(&hdr->b_state->arcs_mtx)); + mutex_enter(&hdr->b_state->arcs_mtx); + ASSERT(list_link_active(&hdr->b_arc_node)); + list_remove(list, hdr); + if (GHOST_STATE(hdr->b_state)) { + ASSERT0(hdr->b_datacnt); + ASSERT3P(hdr->b_buf, ==, NULL); + delta = hdr->b_size; } ASSERT(delta > 0); ASSERT3U(*size, >=, delta); atomic_add_64(size, -delta); - mutex_exit(&ab->b_state->arcs_mtx); + mutex_exit(&hdr->b_state->arcs_mtx); /* remove the prefetch flag if we get a reference */ - if (ab->b_flags & ARC_PREFETCH) - ab->b_flags &= ~ARC_PREFETCH; + if (hdr->b_flags & ARC_FLAG_PREFETCH) + hdr->b_flags &= ~ARC_FLAG_PREFETCH; } } static int -remove_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag) +remove_reference(arc_buf_hdr_t *hdr, kmutex_t *hash_lock, void *tag) { int cnt; - arc_state_t *state = ab->b_state; + arc_state_t *state = hdr->b_state; ASSERT(state == arc_anon || MUTEX_HELD(hash_lock)); ASSERT(!GHOST_STATE(state)); - if (((cnt = refcount_remove(&ab->b_refcnt, tag)) == 0) && + if (((cnt = refcount_remove(&hdr->b_refcnt, tag)) == 0) && (state != arc_anon)) { - uint64_t *size = &state->arcs_lsize[ab->b_type]; + uint64_t *size = &state->arcs_lsize[hdr->b_type]; ASSERT(!MUTEX_HELD(&state->arcs_mtx)); mutex_enter(&state->arcs_mtx); - ASSERT(!list_link_active(&ab->b_arc_node)); - list_insert_head(&state->arcs_list[ab->b_type], ab); - ASSERT(ab->b_datacnt > 0); - atomic_add_64(size, ab->b_size * ab->b_datacnt); + ASSERT(!list_link_active(&hdr->b_arc_node)); + list_insert_head(&state->arcs_list[hdr->b_type], hdr); + ASSERT(hdr->b_datacnt > 0); + atomic_add_64(size, hdr->b_size * hdr->b_datacnt); mutex_exit(&state->arcs_mtx); } return (cnt); @@ -1176,19 +1158,20 @@ remove_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag) * for the buffer must be held by the caller. */ static void -arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock) +arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *hdr, + kmutex_t *hash_lock) { - arc_state_t *old_state = ab->b_state; - int64_t refcnt = refcount_count(&ab->b_refcnt); + arc_state_t *old_state = hdr->b_state; + int64_t refcnt = refcount_count(&hdr->b_refcnt); uint64_t from_delta, to_delta; ASSERT(MUTEX_HELD(hash_lock)); ASSERT3P(new_state, !=, old_state); - ASSERT(refcnt == 0 || ab->b_datacnt > 0); - ASSERT(ab->b_datacnt == 0 || !GHOST_STATE(new_state)); - ASSERT(ab->b_datacnt <= 1 || old_state != arc_anon); + ASSERT(refcnt == 0 || hdr->b_datacnt > 0); + ASSERT(hdr->b_datacnt == 0 || !GHOST_STATE(new_state)); + ASSERT(hdr->b_datacnt <= 1 || old_state != arc_anon); - from_delta = to_delta = ab->b_datacnt * ab->b_size; + from_delta = to_delta = hdr->b_datacnt * hdr->b_size; /* * If this buffer is evictable, transfer it from the @@ -1197,22 +1180,22 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock) if (refcnt == 0) { if (old_state != arc_anon) { int use_mutex = !MUTEX_HELD(&old_state->arcs_mtx); - uint64_t *size = &old_state->arcs_lsize[ab->b_type]; + uint64_t *size = &old_state->arcs_lsize[hdr->b_type]; if (use_mutex) mutex_enter(&old_state->arcs_mtx); - ASSERT(list_link_active(&ab->b_arc_node)); - list_remove(&old_state->arcs_list[ab->b_type], ab); + ASSERT(list_link_active(&hdr->b_arc_node)); + list_remove(&old_state->arcs_list[hdr->b_type], hdr); /* * If prefetching out of the ghost cache, * we will have a non-zero datacnt. */ - if (GHOST_STATE(old_state) && ab->b_datacnt == 0) { + if (GHOST_STATE(old_state) && hdr->b_datacnt == 0) { /* ghost elements have a ghost size */ - ASSERT(ab->b_buf == NULL); - from_delta = ab->b_size; + ASSERT(hdr->b_buf == NULL); + from_delta = hdr->b_size; } ASSERT3U(*size, >=, from_delta); atomic_add_64(size, -from_delta); @@ -1222,18 +1205,19 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock) } if (new_state != arc_anon) { int use_mutex = !MUTEX_HELD(&new_state->arcs_mtx); - uint64_t *size = &new_state->arcs_lsize[ab->b_type]; + uint64_t *size = &new_state->arcs_lsize[hdr->b_type]; if (use_mutex) mutex_enter(&new_state->arcs_mtx); - list_insert_head(&new_state->arcs_list[ab->b_type], ab); + list_insert_head(&new_state->arcs_list[hdr->b_type], + hdr); /* ghost elements have a ghost size */ if (GHOST_STATE(new_state)) { - ASSERT(ab->b_datacnt == 0); - ASSERT(ab->b_buf == NULL); - to_delta = ab->b_size; + ASSERT(hdr->b_datacnt == 0); + ASSERT(hdr->b_buf == NULL); + to_delta = hdr->b_size; } atomic_add_64(size, to_delta); @@ -1242,9 +1226,9 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock) } } - ASSERT(!BUF_EMPTY(ab)); - if (new_state == arc_anon && HDR_IN_HASH_TABLE(ab)) - buf_hash_remove(ab); + ASSERT(!BUF_EMPTY(hdr)); + if (new_state == arc_anon && HDR_IN_HASH_TABLE(hdr)) + buf_hash_remove(hdr); /* adjust state sizes */ if (to_delta) @@ -1253,7 +1237,7 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock) ASSERT3U(old_state->arcs_size, >=, from_delta); atomic_add_64(&old_state->arcs_size, -from_delta); } - ab->b_state = new_state; + hdr->b_state = new_state; /* adjust l2arc hdr stats */ if (new_state == arc_l2c_only) @@ -1455,7 +1439,7 @@ arc_buf_add_ref(arc_buf_t *buf, void* tag) arc_access(hdr, hash_lock); mutex_exit(hash_lock); ARCSTAT_BUMP(arcstat_hits); - ARCSTAT_CONDSTAT(!(hdr->b_flags & ARC_PREFETCH), + ARCSTAT_CONDSTAT(!(hdr->b_flags & ARC_FLAG_PREFETCH), demand, prefetch, hdr->b_type != ARC_BUFC_METADATA, data, metadata, hits); } @@ -1656,7 +1640,7 @@ arc_buf_free(arc_buf_t *buf, void *tag) } else { ASSERT(buf == hdr->b_buf); ASSERT(buf->b_efunc == NULL); - hdr->b_flags |= ARC_BUF_AVAILABLE; + hdr->b_flags |= ARC_FLAG_BUF_AVAILABLE; } mutex_exit(hash_lock); } else if (HDR_IO_IN_PROGRESS(hdr)) { @@ -1707,7 +1691,7 @@ arc_buf_remove_ref(arc_buf_t *buf, void* tag) } else if (no_callback) { ASSERT(hdr->b_buf == buf && buf->b_next == NULL); ASSERT(buf->b_efunc == NULL); - hdr->b_flags |= ARC_BUF_AVAILABLE; + hdr->b_flags |= ARC_FLAG_BUF_AVAILABLE; } ASSERT(no_callback || hdr->b_datacnt > 1 || refcount_is_zero(&hdr->b_refcnt)); @@ -1782,7 +1766,7 @@ arc_evict(arc_state_t *state, uint64_t spa, int64_t bytes, boolean_t recycle, { arc_state_t *evicted_state; uint64_t bytes_evicted = 0, skipped = 0, missed = 0; - arc_buf_hdr_t *ab, *ab_prev = NULL; + arc_buf_hdr_t *hdr, *hdr_prev = NULL; kmutex_t *hash_lock; boolean_t have_lock; void *stolen = NULL; @@ -1840,24 +1824,24 @@ arc_evict(arc_state_t *state, uint64_t spa, int64_t bytes, boolean_t recycle, list_t *list = &state->arcs_list[type]; - for (ab = list_tail(list); ab; ab = ab_prev) { - ab_prev = list_prev(list, ab); + for (hdr = list_tail(list); hdr; hdr = hdr_prev) { + hdr_prev = list_prev(list, hdr); /* prefetch buffers have a minimum lifespan */ - if (HDR_IO_IN_PROGRESS(ab) || - (spa && ab->b_spa != spa) || - (ab->b_flags & (ARC_PREFETCH|ARC_INDIRECT) && - ddi_get_lbolt() - ab->b_arc_access < + if (HDR_IO_IN_PROGRESS(hdr) || + (spa && hdr->b_spa != spa) || + (hdr->b_flags & (ARC_FLAG_PREFETCH | ARC_FLAG_INDIRECT) && + ddi_get_lbolt() - hdr->b_arc_access < arc_min_prefetch_lifespan)) { skipped++; continue; } /* "lookahead" for better eviction candidate */ - if (recycle && ab->b_size != bytes && - ab_prev && ab_prev->b_size == bytes) + if (recycle && hdr->b_size != bytes && + hdr_prev && hdr_prev->b_size == bytes) continue; /* ignore markers */ - if (ab->b_spa == 0) + if (hdr->b_spa == 0) continue; /* @@ -1870,34 +1854,34 @@ arc_evict(arc_state_t *state, uint64_t spa, int64_t bytes, boolean_t recycle, * the hot code path, so don't sleep. */ if (!recycle && count++ > arc_evict_iterations) { - list_insert_after(list, ab, &marker); + list_insert_after(list, hdr, &marker); mutex_exit(&evicted_state->arcs_mtx); mutex_exit(&state->arcs_mtx); kpreempt(KPREEMPT_SYNC); mutex_enter(&state->arcs_mtx); mutex_enter(&evicted_state->arcs_mtx); - ab_prev = list_prev(list, &marker); + hdr_prev = list_prev(list, &marker); list_remove(list, &marker); count = 0; continue; } - hash_lock = HDR_LOCK(ab); + hash_lock = HDR_LOCK(hdr); have_lock = MUTEX_HELD(hash_lock); if (have_lock || mutex_tryenter(hash_lock)) { - ASSERT0(refcount_count(&ab->b_refcnt)); - ASSERT(ab->b_datacnt > 0); - while (ab->b_buf) { - arc_buf_t *buf = ab->b_buf; + ASSERT0(refcount_count(&hdr->b_refcnt)); + ASSERT(hdr->b_datacnt > 0); + while (hdr->b_buf) { + arc_buf_t *buf = hdr->b_buf; if (!mutex_tryenter(&buf->b_evict_lock)) { missed += 1; break; } if (buf->b_data) { - bytes_evicted += ab->b_size; - if (recycle && ab->b_type == type && - ab->b_size == bytes && - !HDR_L2_WRITING(ab)) { + bytes_evicted += hdr->b_size; + if (recycle && hdr->b_type == type && + hdr->b_size == bytes && + !HDR_L2_WRITING(hdr)) { stolen = buf->b_data; recycle = FALSE; } @@ -1906,7 +1890,7 @@ arc_evict(arc_state_t *state, uint64_t spa, int64_t bytes, boolean_t recycle, mutex_enter(&arc_eviction_mtx); arc_buf_destroy(buf, buf->b_data == stolen, FALSE); - ab->b_buf = buf->b_next; + hdr->b_buf = buf->b_next; buf->b_hdr = &arc_eviction_hdr; buf->b_next = arc_eviction_list; arc_eviction_list = buf; @@ -1919,26 +1903,26 @@ arc_evict(arc_state_t *state, uint64_t spa, int64_t bytes, boolean_t recycle, } } - if (ab->b_l2hdr) { + if (hdr->b_l2hdr) { ARCSTAT_INCR(arcstat_evict_l2_cached, - ab->b_size); + hdr->b_size); } else { - if (l2arc_write_eligible(ab->b_spa, ab)) { + if (l2arc_write_eligible(hdr->b_spa, hdr)) { ARCSTAT_INCR(arcstat_evict_l2_eligible, - ab->b_size); + hdr->b_size); } else { ARCSTAT_INCR( arcstat_evict_l2_ineligible, - ab->b_size); + hdr->b_size); } } - if (ab->b_datacnt == 0) { - arc_change_state(evicted_state, ab, hash_lock); - ASSERT(HDR_IN_HASH_TABLE(ab)); - ab->b_flags |= ARC_IN_HASH_TABLE; - ab->b_flags &= ~ARC_BUF_AVAILABLE; - DTRACE_PROBE1(arc__evict, arc_buf_hdr_t *, ab); + if (hdr->b_datacnt == 0) { + arc_change_state(evicted_state, hdr, hash_lock); + ASSERT(HDR_IN_HASH_TABLE(hdr)); + hdr->b_flags |= ARC_FLAG_IN_HASH_TABLE; + hdr->b_flags &= ~ARC_FLAG_BUF_AVAILABLE; + DTRACE_PROBE1(arc__evict, arc_buf_hdr_t *, hdr); } if (!have_lock) mutex_exit(hash_lock); @@ -1979,7 +1963,7 @@ arc_evict(arc_state_t *state, uint64_t spa, int64_t bytes, boolean_t recycle, static void arc_evict_ghost(arc_state_t *state, uint64_t spa, int64_t bytes) { - arc_buf_hdr_t *ab, *ab_prev; + arc_buf_hdr_t *hdr, *hdr_prev; arc_buf_hdr_t marker = { 0 }; list_t *list = &state->arcs_list[ARC_BUFC_DATA]; kmutex_t *hash_lock; @@ -1990,18 +1974,18 @@ arc_evict_ghost(arc_state_t *state, uint64_t spa, int64_t bytes) ASSERT(GHOST_STATE(state)); top: mutex_enter(&state->arcs_mtx); - for (ab = list_tail(list); ab; ab = ab_prev) { - ab_prev = list_prev(list, ab); - if (ab->b_type > ARC_BUFC_NUMTYPES) - panic("invalid ab=%p", (void *)ab); - if (spa && ab->b_spa != spa) + for (hdr = list_tail(list); hdr; hdr = hdr_prev) { + hdr_prev = list_prev(list, hdr); + if (hdr->b_type > ARC_BUFC_NUMTYPES) + panic("invalid hdr=%p", (void *)hdr); + if (spa && hdr->b_spa != spa) continue; /* ignore markers */ - if (ab->b_spa == 0) + if (hdr->b_spa == 0) continue; - hash_lock = HDR_LOCK(ab); + hash_lock = HDR_LOCK(hdr); /* caller may be trying to modify this buffer, skip it */ if (MUTEX_HELD(hash_lock)) continue; @@ -2013,35 +1997,35 @@ top: * before reacquiring the lock. */ if (count++ > arc_evict_iterations) { - list_insert_after(list, ab, &marker); + list_insert_after(list, hdr, &marker); mutex_exit(&state->arcs_mtx); kpreempt(KPREEMPT_SYNC); mutex_enter(&state->arcs_mtx); - ab_prev = list_prev(list, &marker); + hdr_prev = list_prev(list, &marker); list_remove(list, &marker); count = 0; continue; } if (mutex_tryenter(hash_lock)) { - ASSERT(!HDR_IO_IN_PROGRESS(ab)); - ASSERT(ab->b_buf == NULL); + ASSERT(!HDR_IO_IN_PROGRESS(hdr)); + ASSERT(hdr->b_buf == NULL); ARCSTAT_BUMP(arcstat_deleted); - bytes_deleted += ab->b_size; + bytes_deleted += hdr->b_size; - if (ab->b_l2hdr != NULL) { + if (hdr->b_l2hdr != NULL) { /* * This buffer is cached on the 2nd Level ARC; * don't destroy the header. */ - arc_change_state(arc_l2c_only, ab, hash_lock); + arc_change_state(arc_l2c_only, hdr, hash_lock); mutex_exit(hash_lock); } else { - arc_change_state(arc_anon, ab, hash_lock); + arc_change_state(arc_anon, hdr, hash_lock); mutex_exit(hash_lock); - arc_hdr_destroy(ab); + arc_hdr_destroy(hdr); } - DTRACE_PROBE1(arc__delete, arc_buf_hdr_t *, ab); + DTRACE_PROBE1(arc__delete, arc_buf_hdr_t *, hdr); if (bytes >= 0 && bytes_deleted >= bytes) break; } else if (bytes < 0) { @@ -2050,12 +2034,12 @@ top: * hash lock to become available. Once its * available, restart from where we left off. */ - list_insert_after(list, ab, &marker); + list_insert_after(list, hdr, &marker); mutex_exit(&state->arcs_mtx); mutex_enter(hash_lock); mutex_exit(hash_lock); mutex_enter(&state->arcs_mtx); - ab_prev = list_prev(list, &marker); + hdr_prev = list_prev(list, &marker); list_remove(list, &marker); } else { bufs_skipped += 1; @@ -2571,7 +2555,8 @@ arc_get_data_buf(arc_buf_t *buf) * will end up on the mru list; so steal space from there. */ if (state == arc_mfu_ghost) - state = buf->b_hdr->b_flags & ARC_PREFETCH ? arc_mru : arc_mfu; + state = buf->b_hdr->b_flags & ARC_FLAG_PREFETCH ? + arc_mru : arc_mfu; else if (state == arc_mru_ghost) state = arc_mru; @@ -2626,25 +2611,25 @@ out: * NOTE: the hash lock is dropped in this function. */ static void -arc_access(arc_buf_hdr_t *buf, kmutex_t *hash_lock) +arc_access(arc_buf_hdr_t *hdr, kmutex_t *hash_lock) { clock_t now; ASSERT(MUTEX_HELD(hash_lock)); - if (buf->b_state == arc_anon) { + if (hdr->b_state == arc_anon) { /* * This buffer is not in the cache, and does not * appear in our "ghost" list. Add the new buffer * to the MRU state. */ - ASSERT(buf->b_arc_access == 0); - buf->b_arc_access = ddi_get_lbolt(); - DTRACE_PROBE1(new_state__mru, arc_buf_hdr_t *, buf); - arc_change_state(arc_mru, buf, hash_lock); + ASSERT(hdr->b_arc_access == 0); + hdr->b_arc_access = ddi_get_lbolt(); + DTRACE_PROBE1(new_state__mru, arc_buf_hdr_t *, hdr); + arc_change_state(arc_mru, hdr, hash_lock); - } else if (buf->b_state == arc_mru) { + } else if (hdr->b_state == arc_mru) { now = ddi_get_lbolt(); /* @@ -2655,14 +2640,14 @@ arc_access(arc_buf_hdr_t *buf, kmutex_t *hash_lock) * - move the buffer to the head of the list if this is * another prefetch (to make it less likely to be evicted). */ - if ((buf->b_flags & ARC_PREFETCH) != 0) { - if (refcount_count(&buf->b_refcnt) == 0) { - ASSERT(list_link_active(&buf->b_arc_node)); + if ((hdr->b_flags & ARC_FLAG_PREFETCH) != 0) { + if (refcount_count(&hdr->b_refcnt) == 0) { + ASSERT(list_link_active(&hdr->b_arc_node)); } else { - buf->b_flags &= ~ARC_PREFETCH; + hdr->b_flags &= ~ARC_FLAG_PREFETCH; ARCSTAT_BUMP(arcstat_mru_hits); } - buf->b_arc_access = now; + hdr->b_arc_access = now; return; } @@ -2671,18 +2656,18 @@ arc_access(arc_buf_hdr_t *buf, kmutex_t *hash_lock) * but it is still in the cache. Move it to the MFU * state. */ - if (now > buf->b_arc_access + ARC_MINTIME) { + if (now > hdr->b_arc_access + ARC_MINTIME) { /* * More than 125ms have passed since we * instantiated this buffer. Move it to the * most frequently used state. */ - buf->b_arc_access = now; - DTRACE_PROBE1(new_state__mfu, arc_buf_hdr_t *, buf); - arc_change_state(arc_mfu, buf, hash_lock); + hdr->b_arc_access = now; + DTRACE_PROBE1(new_state__mfu, arc_buf_hdr_t *, hdr); + arc_change_state(arc_mfu, hdr, hash_lock); } ARCSTAT_BUMP(arcstat_mru_hits); - } else if (buf->b_state == arc_mru_ghost) { + } else if (hdr->b_state == arc_mru_ghost) { arc_state_t *new_state; /* * This buffer has been "accessed" recently, but @@ -2690,21 +2675,21 @@ arc_access(arc_buf_hdr_t *buf, kmutex_t *hash_lock) * MFU state. */ - if (buf->b_flags & ARC_PREFETCH) { + if (hdr->b_flags & ARC_FLAG_PREFETCH) { new_state = arc_mru; - if (refcount_count(&buf->b_refcnt) > 0) - buf->b_flags &= ~ARC_PREFETCH; - DTRACE_PROBE1(new_state__mru, arc_buf_hdr_t *, buf); + if (refcount_count(&hdr->b_refcnt) > 0) + hdr->b_flags &= ~ARC_FLAG_PREFETCH; + DTRACE_PROBE1(new_state__mru, arc_buf_hdr_t *, hdr); } else { new_state = arc_mfu; - DTRACE_PROBE1(new_state__mfu, arc_buf_hdr_t *, buf); + DTRACE_PROBE1(new_state__mfu, arc_buf_hdr_t *, hdr); } - buf->b_arc_access = ddi_get_lbolt(); - arc_change_state(new_state, buf, hash_lock); + hdr->b_arc_access = ddi_get_lbolt(); + arc_change_state(new_state, hdr, hash_lock); ARCSTAT_BUMP(arcstat_mru_ghost_hits); - } else if (buf->b_state == arc_mfu) { + } else if (hdr->b_state == arc_mfu) { /* * This buffer has been accessed more than once and is * still in the cache. Keep it in the MFU state. @@ -2714,13 +2699,13 @@ arc_access(arc_buf_hdr_t *buf, kmutex_t *hash_lock) * If it was a prefetch, we will explicitly move it to * the head of the list now. */ - if ((buf->b_flags & ARC_PREFETCH) != 0) { - ASSERT(refcount_count(&buf->b_refcnt) == 0); - ASSERT(list_link_active(&buf->b_arc_node)); + if ((hdr->b_flags & ARC_FLAG_PREFETCH) != 0) { + ASSERT(refcount_count(&hdr->b_refcnt) == 0); + ASSERT(list_link_active(&hdr->b_arc_node)); } ARCSTAT_BUMP(arcstat_mfu_hits); - buf->b_arc_access = ddi_get_lbolt(); - } else if (buf->b_state == arc_mfu_ghost) { + hdr->b_arc_access = ddi_get_lbolt(); + } else if (hdr->b_state == arc_mfu_ghost) { arc_state_t *new_state = arc_mfu; /* * This buffer has been accessed more than once but has @@ -2728,28 +2713,28 @@ arc_access(arc_buf_hdr_t *buf, kmutex_t *hash_lock) * MFU state. */ - if (buf->b_flags & ARC_PREFETCH) { + if (hdr->b_flags & ARC_FLAG_PREFETCH) { /* * This is a prefetch access... * move this block back to the MRU state. */ - ASSERT0(refcount_count(&buf->b_refcnt)); + ASSERT0(refcount_count(&hdr->b_refcnt)); new_state = arc_mru; } - buf->b_arc_access = ddi_get_lbolt(); - DTRACE_PROBE1(new_state__mfu, arc_buf_hdr_t *, buf); - arc_change_state(new_state, buf, hash_lock); + hdr->b_arc_access = ddi_get_lbolt(); + DTRACE_PROBE1(new_state__mfu, arc_buf_hdr_t *, hdr); + arc_change_state(new_state, hdr, hash_lock); ARCSTAT_BUMP(arcstat_mfu_ghost_hits); - } else if (buf->b_state == arc_l2c_only) { + } else if (hdr->b_state == arc_l2c_only) { /* * This buffer is on the 2nd Level ARC. */ - buf->b_arc_access = ddi_get_lbolt(); - DTRACE_PROBE1(new_state__mfu, arc_buf_hdr_t *, buf); - arc_change_state(arc_mfu, buf, hash_lock); + hdr->b_arc_access = ddi_get_lbolt(); + DTRACE_PROBE1(new_state__mfu, arc_buf_hdr_t *, hdr); + arc_change_state(arc_mfu, hdr, hash_lock); } else { ASSERT(!"invalid arc state"); } @@ -2817,9 +2802,9 @@ arc_read_done(zio_t *zio) (found == hdr && HDR_L2_READING(hdr))); } - hdr->b_flags &= ~ARC_L2_EVICTED; - if (l2arc_noprefetch && (hdr->b_flags & ARC_PREFETCH)) - hdr->b_flags &= ~ARC_L2CACHE; + hdr->b_flags &= ~ARC_FLAG_L2_EVICTED; + if (l2arc_noprefetch && (hdr->b_flags & ARC_FLAG_PREFETCH)) + hdr->b_flags &= ~ARC_FLAG_L2CACHE; /* byteswap if necessary */ callback_list = hdr->b_acb; @@ -2859,18 +2844,18 @@ arc_read_done(zio_t *zio) } } hdr->b_acb = NULL; - hdr->b_flags &= ~ARC_IO_IN_PROGRESS; + hdr->b_flags &= ~ARC_FLAG_IO_IN_PROGRESS; ASSERT(!HDR_BUF_AVAILABLE(hdr)); if (abuf == buf) { ASSERT(buf->b_efunc == NULL); ASSERT(hdr->b_datacnt == 1); - hdr->b_flags |= ARC_BUF_AVAILABLE; + hdr->b_flags |= ARC_FLAG_BUF_AVAILABLE; } ASSERT(refcount_is_zero(&hdr->b_refcnt) || callback_list != NULL); if (zio->io_error != 0) { - hdr->b_flags |= ARC_IO_ERROR; + hdr->b_flags |= ARC_FLAG_IO_ERROR; if (hdr->b_state != arc_anon) arc_change_state(arc_anon, hdr, hash_lock); if (HDR_IN_HASH_TABLE(hdr)) @@ -2936,8 +2921,8 @@ arc_read_done(zio_t *zio) */ int arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, - void *private, zio_priority_t priority, int zio_flags, uint32_t *arc_flags, - const zbookmark_phys_t *zb) + void *private, zio_priority_t priority, int zio_flags, + arc_flags_t *arc_flags, const zbookmark_phys_t *zb) { arc_buf_hdr_t *hdr = NULL; arc_buf_t *buf = NULL; @@ -2959,16 +2944,16 @@ top: if (hdr != NULL && hdr->b_datacnt > 0) { - *arc_flags |= ARC_CACHED; + *arc_flags |= ARC_FLAG_CACHED; if (HDR_IO_IN_PROGRESS(hdr)) { - if (*arc_flags & ARC_WAIT) { + if (*arc_flags & ARC_FLAG_WAIT) { cv_wait(&hdr->b_cv, hash_lock); mutex_exit(hash_lock); goto top; } - ASSERT(*arc_flags & ARC_NOWAIT); + ASSERT(*arc_flags & ARC_FLAG_NOWAIT); if (done) { arc_callback_t *acb = NULL; @@ -3006,24 +2991,24 @@ top: ASSERT(buf->b_data); if (HDR_BUF_AVAILABLE(hdr)) { ASSERT(buf->b_efunc == NULL); - hdr->b_flags &= ~ARC_BUF_AVAILABLE; + hdr->b_flags &= ~ARC_FLAG_BUF_AVAILABLE; } else { buf = arc_buf_clone(buf); } - } else if (*arc_flags & ARC_PREFETCH && + } else if (*arc_flags & ARC_FLAG_PREFETCH && refcount_count(&hdr->b_refcnt) == 0) { - hdr->b_flags |= ARC_PREFETCH; + hdr->b_flags |= ARC_FLAG_PREFETCH; } DTRACE_PROBE1(arc__hit, arc_buf_hdr_t *, hdr); arc_access(hdr, hash_lock); - if (*arc_flags & ARC_L2CACHE) - hdr->b_flags |= ARC_L2CACHE; - if (*arc_flags & ARC_L2COMPRESS) - hdr->b_flags |= ARC_L2COMPRESS; + if (*arc_flags & ARC_FLAG_L2CACHE) + hdr->b_flags |= ARC_FLAG_L2CACHE; + if (*arc_flags & ARC_FLAG_L2COMPRESS) + hdr->b_flags |= ARC_FLAG_L2COMPRESS; mutex_exit(hash_lock); ARCSTAT_BUMP(arcstat_hits); - ARCSTAT_CONDSTAT(!(hdr->b_flags & ARC_PREFETCH), + ARCSTAT_CONDSTAT(!(hdr->b_flags & ARC_FLAG_PREFETCH), demand, prefetch, hdr->b_type != ARC_BUFC_METADATA, data, metadata, hits); @@ -3057,18 +3042,19 @@ top: (void) arc_buf_remove_ref(buf, private); goto top; /* restart the IO request */ } + /* if this is a prefetch, we don't have a reference */ - if (*arc_flags & ARC_PREFETCH) { + if (*arc_flags & ARC_FLAG_PREFETCH) { (void) remove_reference(hdr, hash_lock, private); - hdr->b_flags |= ARC_PREFETCH; + hdr->b_flags |= ARC_FLAG_PREFETCH; } - if (*arc_flags & ARC_L2CACHE) - hdr->b_flags |= ARC_L2CACHE; - if (*arc_flags & ARC_L2COMPRESS) - hdr->b_flags |= ARC_L2COMPRESS; + if (*arc_flags & ARC_FLAG_L2CACHE) + hdr->b_flags |= ARC_FLAG_L2CACHE; + if (*arc_flags & ARC_FLAG_L2COMPRESS) + hdr->b_flags |= ARC_FLAG_L2COMPRESS; if (BP_GET_LEVEL(bp) > 0) - hdr->b_flags |= ARC_INDIRECT; + hdr->b_flags |= ARC_FLAG_INDIRECT; } else { /* this block is in the ghost cache */ ASSERT(GHOST_STATE(hdr->b_state)); @@ -3077,14 +3063,14 @@ top: ASSERT(hdr->b_buf == NULL); /* if this is a prefetch, we don't have a reference */ - if (*arc_flags & ARC_PREFETCH) - hdr->b_flags |= ARC_PREFETCH; + if (*arc_flags & ARC_FLAG_PREFETCH) + hdr->b_flags |= ARC_FLAG_PREFETCH; else add_reference(hdr, hash_lock, private); - if (*arc_flags & ARC_L2CACHE) - hdr->b_flags |= ARC_L2CACHE; - if (*arc_flags & ARC_L2COMPRESS) - hdr->b_flags |= ARC_L2COMPRESS; + if (*arc_flags & ARC_FLAG_L2CACHE) + hdr->b_flags |= ARC_FLAG_L2CACHE; + if (*arc_flags & ARC_FLAG_L2COMPRESS) + hdr->b_flags |= ARC_FLAG_L2COMPRESS; buf = kmem_cache_alloc(buf_cache, KM_PUSHPAGE); buf->b_hdr = hdr; buf->b_data = NULL; @@ -3106,7 +3092,7 @@ top: ASSERT(hdr->b_acb == NULL); hdr->b_acb = acb; - hdr->b_flags |= ARC_IO_IN_PROGRESS; + hdr->b_flags |= ARC_FLAG_IO_IN_PROGRESS; if (hdr->b_l2hdr != NULL && (vd = hdr->b_l2hdr->b_dev->l2ad_vdev) != NULL) { @@ -3133,7 +3119,7 @@ top: DTRACE_PROBE4(arc__miss, arc_buf_hdr_t *, hdr, blkptr_t *, bp, uint64_t, size, zbookmark_phys_t *, zb); ARCSTAT_BUMP(arcstat_misses); - ARCSTAT_CONDSTAT(!(hdr->b_flags & ARC_PREFETCH), + ARCSTAT_CONDSTAT(!(hdr->b_flags & ARC_FLAG_PREFETCH), demand, prefetch, hdr->b_type != ARC_BUFC_METADATA, data, metadata, misses); @@ -3195,12 +3181,12 @@ top: zio_t *, rzio); ARCSTAT_INCR(arcstat_l2_read_bytes, b_asize); - if (*arc_flags & ARC_NOWAIT) { + if (*arc_flags & ARC_FLAG_NOWAIT) { zio_nowait(rzio); return (0); } - ASSERT(*arc_flags & ARC_WAIT); + ASSERT(*arc_flags & ARC_FLAG_WAIT); if (zio_wait(rzio) == 0) return (0); @@ -3226,10 +3212,10 @@ top: rzio = zio_read(pio, spa, bp, buf->b_data, size, arc_read_done, buf, priority, zio_flags, zb); - if (*arc_flags & ARC_WAIT) + if (*arc_flags & ARC_FLAG_WAIT) return (zio_wait(rzio)); - ASSERT(*arc_flags & ARC_NOWAIT); + ASSERT(*arc_flags & ARC_FLAG_NOWAIT); zio_nowait(rzio); } return (0); @@ -3266,7 +3252,7 @@ arc_freed(spa_t *spa, const blkptr_t *bp) if (HDR_BUF_AVAILABLE(hdr)) { arc_buf_t *buf = hdr->b_buf; add_reference(hdr, hash_lock, FTAG); - hdr->b_flags &= ~ARC_BUF_AVAILABLE; + hdr->b_flags &= ~ARC_FLAG_BUF_AVAILABLE; mutex_exit(hash_lock); arc_release(buf, FTAG); @@ -3333,7 +3319,7 @@ arc_clear_callback(arc_buf_t *buf) arc_buf_destroy(buf, FALSE, TRUE); } else { ASSERT(buf == hdr->b_buf); - hdr->b_flags |= ARC_BUF_AVAILABLE; + hdr->b_flags |= ARC_FLAG_BUF_AVAILABLE; mutex_exit(&buf->b_evict_lock); } @@ -3439,7 +3425,7 @@ arc_release(arc_buf_t *buf, void *tag) nhdr->b_buf = buf; nhdr->b_state = arc_anon; nhdr->b_arc_access = 0; - nhdr->b_flags = flags & ARC_L2_WRITING; + nhdr->b_flags = flags & ARC_FLAG_L2_WRITING; nhdr->b_l2hdr = NULL; nhdr->b_datacnt = 1; nhdr->b_freeze_cksum = NULL; @@ -3523,7 +3509,7 @@ arc_write_ready(zio_t *zio) mutex_exit(&hdr->b_freeze_lock); } arc_cksum_compute(buf, B_FALSE); - hdr->b_flags |= ARC_IO_IN_PROGRESS; + hdr->b_flags |= ARC_FLAG_IO_IN_PROGRESS; } /* @@ -3604,13 +3590,13 @@ arc_write_done(zio_t *zio) ASSERT(BP_GET_LEVEL(zio->io_bp) == 0); } } - hdr->b_flags &= ~ARC_IO_IN_PROGRESS; + hdr->b_flags &= ~ARC_FLAG_IO_IN_PROGRESS; /* if it's not anon, we are doing a scrub */ if (!exists && hdr->b_state == arc_anon) arc_access(hdr, hash_lock); mutex_exit(hash_lock); } else { - hdr->b_flags &= ~ARC_IO_IN_PROGRESS; + hdr->b_flags &= ~ARC_FLAG_IO_IN_PROGRESS; } ASSERT(!refcount_is_zero(&hdr->b_refcnt)); @@ -3633,12 +3619,12 @@ arc_write(zio_t *pio, spa_t *spa, uint64_t txg, ASSERT(ready != NULL); ASSERT(done != NULL); ASSERT(!HDR_IO_ERROR(hdr)); - ASSERT((hdr->b_flags & ARC_IO_IN_PROGRESS) == 0); + ASSERT((hdr->b_flags & ARC_FLAG_IO_IN_PROGRESS) == 0); ASSERT(hdr->b_acb == NULL); if (l2arc) - hdr->b_flags |= ARC_L2CACHE; + hdr->b_flags |= ARC_FLAG_L2CACHE; if (l2arc_compress) - hdr->b_flags |= ARC_L2COMPRESS; + hdr->b_flags |= ARC_FLAG_L2COMPRESS; callback = kmem_zalloc(sizeof (arc_write_callback_t), KM_SLEEP); callback->awcb_ready = ready; callback->awcb_physdone = physdone; @@ -4085,7 +4071,7 @@ arc_fini(void) */ static boolean_t -l2arc_write_eligible(uint64_t spa_guid, arc_buf_hdr_t *ab) +l2arc_write_eligible(uint64_t spa_guid, arc_buf_hdr_t *hdr) { /* * A buffer is *not* eligible for the L2ARC if it: @@ -4094,8 +4080,8 @@ l2arc_write_eligible(uint64_t spa_guid, arc_buf_hdr_t *ab) * 3. has an I/O in progress (it may be an incomplete read). * 4. is flagged not eligible (zfs property). */ - if (ab->b_spa != spa_guid || ab->b_l2hdr != NULL || - HDR_IO_IN_PROGRESS(ab) || !HDR_L2CACHE(ab)) + if (hdr->b_spa != spa_guid || hdr->b_l2hdr != NULL || + HDR_IO_IN_PROGRESS(hdr) || !HDR_L2CACHE(hdr)) return (B_FALSE); return (B_TRUE); @@ -4256,7 +4242,7 @@ l2arc_write_done(zio_t *zio) l2arc_write_callback_t *cb; l2arc_dev_t *dev; list_t *buflist; - arc_buf_hdr_t *head, *ab, *ab_prev; + arc_buf_hdr_t *head, *hdr, *hdr_prev; l2arc_buf_hdr_t *abl2; kmutex_t *hash_lock; int64_t bytes_dropped = 0; @@ -4280,17 +4266,17 @@ l2arc_write_done(zio_t *zio) /* * All writes completed, or an error was hit. */ - for (ab = list_prev(buflist, head); ab; ab = ab_prev) { - ab_prev = list_prev(buflist, ab); - abl2 = ab->b_l2hdr; + for (hdr = list_prev(buflist, head); hdr; hdr = hdr_prev) { + hdr_prev = list_prev(buflist, hdr); + abl2 = hdr->b_l2hdr; /* * Release the temporary compressed buffer as soon as possible. */ if (abl2->b_compress != ZIO_COMPRESS_OFF) - l2arc_release_cdata_buf(ab); + l2arc_release_cdata_buf(hdr); - hash_lock = HDR_LOCK(ab); + hash_lock = HDR_LOCK(hdr); if (!mutex_tryenter(hash_lock)) { /* * This buffer misses out. It may be in a stage @@ -4305,18 +4291,18 @@ l2arc_write_done(zio_t *zio) /* * Error - drop L2ARC entry. */ - list_remove(buflist, ab); + list_remove(buflist, hdr); ARCSTAT_INCR(arcstat_l2_asize, -abl2->b_asize); bytes_dropped += abl2->b_asize; - ab->b_l2hdr = NULL; + hdr->b_l2hdr = NULL; kmem_free(abl2, sizeof (l2arc_buf_hdr_t)); - ARCSTAT_INCR(arcstat_l2_size, -ab->b_size); + ARCSTAT_INCR(arcstat_l2_size, -hdr->b_size); } /* * Allow ARC to begin reads to this L2ARC entry. */ - ab->b_flags &= ~ARC_L2_WRITING; + hdr->b_flags &= ~ARC_FLAG_L2_WRITING; mutex_exit(hash_lock); } @@ -4463,7 +4449,7 @@ l2arc_evict(l2arc_dev_t *dev, uint64_t distance, boolean_t all) { list_t *buflist; l2arc_buf_hdr_t *abl2; - arc_buf_hdr_t *ab, *ab_prev; + arc_buf_hdr_t *hdr, *hdr_prev; kmutex_t *hash_lock; uint64_t taddr; int64_t bytes_evicted = 0; @@ -4495,10 +4481,10 @@ l2arc_evict(l2arc_dev_t *dev, uint64_t distance, boolean_t all) top: mutex_enter(&l2arc_buflist_mtx); - for (ab = list_tail(buflist); ab; ab = ab_prev) { - ab_prev = list_prev(buflist, ab); + for (hdr = list_tail(buflist); hdr; hdr = hdr_prev) { + hdr_prev = list_prev(buflist, hdr); - hash_lock = HDR_LOCK(ab); + hash_lock = HDR_LOCK(hdr); if (!mutex_tryenter(hash_lock)) { /* * Missed the hash lock. Retry. @@ -4510,19 +4496,19 @@ top: goto top; } - if (HDR_L2_WRITE_HEAD(ab)) { + if (HDR_L2_WRITE_HEAD(hdr)) { /* * We hit a write head node. Leave it for * l2arc_write_done(). */ - list_remove(buflist, ab); + list_remove(buflist, hdr); mutex_exit(hash_lock); continue; } - if (!all && ab->b_l2hdr != NULL && - (ab->b_l2hdr->b_daddr > taddr || - ab->b_l2hdr->b_daddr < dev->l2ad_hand)) { + if (!all && hdr->b_l2hdr != NULL && + (hdr->b_l2hdr->b_daddr > taddr || + hdr->b_l2hdr->b_daddr < dev->l2ad_hand)) { /* * We've evicted to the target address, * or the end of the device. @@ -4531,7 +4517,7 @@ top: break; } - if (HDR_FREE_IN_PROGRESS(ab)) { + if (HDR_FREE_IN_PROGRESS(hdr)) { /* * Already on the path to destruction. */ @@ -4539,44 +4525,44 @@ top: continue; } - if (ab->b_state == arc_l2c_only) { - ASSERT(!HDR_L2_READING(ab)); + if (hdr->b_state == arc_l2c_only) { + ASSERT(!HDR_L2_READING(hdr)); /* * This doesn't exist in the ARC. Destroy. * arc_hdr_destroy() will call list_remove() * and decrement arcstat_l2_size. */ - arc_change_state(arc_anon, ab, hash_lock); - arc_hdr_destroy(ab); + arc_change_state(arc_anon, hdr, hash_lock); + arc_hdr_destroy(hdr); } else { /* * Invalidate issued or about to be issued * reads, since we may be about to write * over this location. */ - if (HDR_L2_READING(ab)) { + if (HDR_L2_READING(hdr)) { ARCSTAT_BUMP(arcstat_l2_evict_reading); - ab->b_flags |= ARC_L2_EVICTED; + hdr->b_flags |= ARC_FLAG_L2_EVICTED; } /* * Tell ARC this no longer exists in L2ARC. */ - if (ab->b_l2hdr != NULL) { - abl2 = ab->b_l2hdr; + if (hdr->b_l2hdr != NULL) { + abl2 = hdr->b_l2hdr; ARCSTAT_INCR(arcstat_l2_asize, -abl2->b_asize); bytes_evicted += abl2->b_asize; - ab->b_l2hdr = NULL; + hdr->b_l2hdr = NULL; kmem_free(abl2, sizeof (l2arc_buf_hdr_t)); - ARCSTAT_INCR(arcstat_l2_size, -ab->b_size); + ARCSTAT_INCR(arcstat_l2_size, -hdr->b_size); } - list_remove(buflist, ab); + list_remove(buflist, hdr); /* * This may have been leftover after a * failed write. */ - ab->b_flags &= ~ARC_L2_WRITING; + hdr->b_flags &= ~ARC_FLAG_L2_WRITING; } mutex_exit(hash_lock); } @@ -4589,7 +4575,7 @@ top: /* * Find and write ARC buffers to the L2ARC device. * - * An ARC_L2_WRITING flag is set so that the L2ARC buffers are not valid + * An ARC_FLAG_L2_WRITING flag is set so that the L2ARC buffers are not valid * for reading until they have completed writing. * The headroom_boost is an in-out parameter used to maintain headroom boost * state between calls to this function. @@ -4601,7 +4587,7 @@ static uint64_t l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz, boolean_t *headroom_boost) { - arc_buf_hdr_t *ab, *ab_prev, *head; + arc_buf_hdr_t *hdr, *hdr_prev, *head; list_t *list; uint64_t write_asize, write_psize, write_sz, headroom, buf_compress_minsz; @@ -4622,7 +4608,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz, write_sz = write_asize = write_psize = 0; full = B_FALSE; head = kmem_cache_alloc(hdr_cache, KM_PUSHPAGE); - head->b_flags |= ARC_L2_WRITE_HEAD; + head->b_flags |= ARC_FLAG_L2_WRITE_HEAD; /* * We will want to try to compress buffers that are at least 2x the @@ -4646,25 +4632,25 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz, * head of the ARC lists rather than the tail. */ if (arc_warm == B_FALSE) - ab = list_head(list); + hdr = list_head(list); else - ab = list_tail(list); + hdr = list_tail(list); headroom = target_sz * l2arc_headroom; if (do_headroom_boost) headroom = (headroom * l2arc_headroom_boost) / 100; - for (; ab; ab = ab_prev) { + for (; hdr; hdr = hdr_prev) { l2arc_buf_hdr_t *l2hdr; kmutex_t *hash_lock; uint64_t buf_sz; if (arc_warm == B_FALSE) - ab_prev = list_next(list, ab); + hdr_prev = list_next(list, hdr); else - ab_prev = list_prev(list, ab); + hdr_prev = list_prev(list, hdr); - hash_lock = HDR_LOCK(ab); + hash_lock = HDR_LOCK(hdr); if (!mutex_tryenter(hash_lock)) { /* * Skip this buffer rather than waiting. @@ -4672,7 +4658,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz, continue; } - passed_sz += ab->b_size; + passed_sz += hdr->b_size; if (passed_sz > headroom) { /* * Searched too far. @@ -4681,12 +4667,12 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz, break; } - if (!l2arc_write_eligible(guid, ab)) { + if (!l2arc_write_eligible(guid, hdr)) { mutex_exit(hash_lock); continue; } - if ((write_sz + ab->b_size) > target_sz) { + if ((write_sz + hdr->b_size) > target_sz) { full = B_TRUE; mutex_exit(hash_lock); break; @@ -4713,31 +4699,31 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz, */ l2hdr = kmem_zalloc(sizeof (l2arc_buf_hdr_t), KM_SLEEP); l2hdr->b_dev = dev; - ab->b_flags |= ARC_L2_WRITING; + hdr->b_flags |= ARC_FLAG_L2_WRITING; /* * Temporarily stash the data buffer in b_tmp_cdata. * The subsequent write step will pick it up from - * there. This is because can't access ab->b_buf + * there. This is because can't access hdr->b_buf * without holding the hash_lock, which we in turn * can't access without holding the ARC list locks * (which we want to avoid during compression/writing). */ l2hdr->b_compress = ZIO_COMPRESS_OFF; - l2hdr->b_asize = ab->b_size; - l2hdr->b_tmp_cdata = ab->b_buf->b_data; + l2hdr->b_asize = hdr->b_size; + l2hdr->b_tmp_cdata = hdr->b_buf->b_data; - buf_sz = ab->b_size; - ab->b_l2hdr = l2hdr; + buf_sz = hdr->b_size; + hdr->b_l2hdr = l2hdr; - list_insert_head(dev->l2ad_buflist, ab); + list_insert_head(dev->l2ad_buflist, hdr); /* * Compute and store the buffer cksum before * writing. On debug the cksum is verified first. */ - arc_cksum_verify(ab->b_buf); - arc_cksum_compute(ab->b_buf, B_TRUE); + arc_cksum_verify(hdr->b_buf); + arc_cksum_compute(hdr->b_buf, B_TRUE); mutex_exit(hash_lock); @@ -4763,21 +4749,22 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz, * and work backwards, retracing the course of the buffer selector * loop above. */ - for (ab = list_prev(dev->l2ad_buflist, head); ab; - ab = list_prev(dev->l2ad_buflist, ab)) { + for (hdr = list_prev(dev->l2ad_buflist, head); hdr; + hdr = list_prev(dev->l2ad_buflist, hdr)) { l2arc_buf_hdr_t *l2hdr; uint64_t buf_sz; /* * We shouldn't need to lock the buffer here, since we flagged - * it as ARC_L2_WRITING in the previous step, but we must take - * care to only access its L2 cache parameters. In particular, - * ab->b_buf may be invalid by now due to ARC eviction. + * it as ARC_FLAG_L2_WRITING in the previous step, but we must + * take care to only access its L2 cache parameters. In + * particular, hdr->b_buf may be invalid by now due to + * ARC eviction. */ - l2hdr = ab->b_l2hdr; + l2hdr = hdr->b_l2hdr; l2hdr->b_daddr = dev->l2ad_hand; - if ((ab->b_flags & ARC_L2COMPRESS) && + if ((hdr->b_flags & ARC_FLAG_L2COMPRESS) && l2hdr->b_asize >= buf_compress_minsz) { if (l2arc_compress_buf(l2hdr)) { /* @@ -4981,9 +4968,9 @@ l2arc_decompress_zio(zio_t *zio, arc_buf_hdr_t *hdr, enum zio_compress c) * done, we can dispose of it. */ static void -l2arc_release_cdata_buf(arc_buf_hdr_t *ab) +l2arc_release_cdata_buf(arc_buf_hdr_t *hdr) { - l2arc_buf_hdr_t *l2hdr = ab->b_l2hdr; + l2arc_buf_hdr_t *l2hdr = hdr->b_l2hdr; if (l2hdr->b_compress == ZIO_COMPRESS_LZ4) { /* @@ -4991,7 +4978,7 @@ l2arc_release_cdata_buf(arc_buf_hdr_t *ab) * temporary buffer for it, so now we need to release it. */ ASSERT(l2hdr->b_tmp_cdata != NULL); - zio_data_buf_free(l2hdr->b_tmp_cdata, ab->b_size); + zio_data_buf_free(l2hdr->b_tmp_cdata, hdr->b_size); } l2hdr->b_tmp_cdata = NULL; } diff --git a/uts/common/fs/zfs/dbuf.c b/uts/common/fs/zfs/dbuf.c index bcf66bc53d7..fd539c838d0 100644 --- a/uts/common/fs/zfs/dbuf.c +++ b/uts/common/fs/zfs/dbuf.c @@ -507,7 +507,7 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t *flags) { dnode_t *dn; zbookmark_phys_t zb; - uint32_t aflags = ARC_NOWAIT; + arc_flags_t aflags = ARC_FLAG_NOWAIT; DB_DNODE_ENTER(db); dn = DB_DNODE(db); @@ -560,9 +560,9 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t *flags) mutex_exit(&db->db_mtx); if (DBUF_IS_L2CACHEABLE(db)) - aflags |= ARC_L2CACHE; + aflags |= ARC_FLAG_L2CACHE; if (DBUF_IS_L2COMPRESSIBLE(db)) - aflags |= ARC_L2COMPRESS; + aflags |= ARC_FLAG_L2COMPRESS; SET_BOOKMARK(&zb, db->db_objset->os_dsl_dataset ? db->db_objset->os_dsl_dataset->ds_object : DMU_META_OBJSET, @@ -574,7 +574,7 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t *flags) dbuf_read_done, db, ZIO_PRIORITY_SYNC_READ, (*flags & DB_RF_CANFAIL) ? ZIO_FLAG_CANFAIL : ZIO_FLAG_MUSTSUCCEED, &aflags, &zb); - if (aflags & ARC_CACHED) + if (aflags & ARC_FLAG_CACHED) *flags |= DB_RF_CACHED; } @@ -1863,7 +1863,8 @@ dbuf_prefetch(dnode_t *dn, uint64_t blkid, zio_priority_t prio) if (dbuf_findbp(dn, 0, blkid, TRUE, &db, &bp) == 0) { if (bp && !BP_IS_HOLE(bp) && !BP_IS_EMBEDDED(bp)) { dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset; - uint32_t aflags = ARC_NOWAIT | ARC_PREFETCH; + arc_flags_t aflags = + ARC_FLAG_NOWAIT | ARC_FLAG_PREFETCH; zbookmark_phys_t zb; SET_BOOKMARK(&zb, ds ? ds->ds_object : DMU_META_OBJSET, diff --git a/uts/common/fs/zfs/dmu_diff.c b/uts/common/fs/zfs/dmu_diff.c index 32e451a7777..91415d0d2dc 100644 --- a/uts/common/fs/zfs/dmu_diff.c +++ b/uts/common/fs/zfs/dmu_diff.c @@ -129,7 +129,7 @@ diff_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, } else if (zb->zb_level == 0) { dnode_phys_t *blk; arc_buf_t *abuf; - uint32_t aflags = ARC_WAIT; + arc_flags_t aflags = ARC_FLAG_WAIT; int blksz = BP_GET_LSIZE(bp); int i; diff --git a/uts/common/fs/zfs/dmu_objset.c b/uts/common/fs/zfs/dmu_objset.c index e39264cc2f9..36ac27a5e0d 100644 --- a/uts/common/fs/zfs/dmu_objset.c +++ b/uts/common/fs/zfs/dmu_objset.c @@ -293,15 +293,15 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, os->os_spa = spa; os->os_rootbp = bp; if (!BP_IS_HOLE(os->os_rootbp)) { - uint32_t aflags = ARC_WAIT; + arc_flags_t aflags = ARC_FLAG_WAIT; zbookmark_phys_t zb; SET_BOOKMARK(&zb, ds ? ds->ds_object : DMU_META_OBJSET, ZB_ROOT_OBJECT, ZB_ROOT_LEVEL, ZB_ROOT_BLKID); if (DMU_OS_IS_L2CACHEABLE(os)) - aflags |= ARC_L2CACHE; + aflags |= ARC_FLAG_L2CACHE; if (DMU_OS_IS_L2COMPRESSIBLE(os)) - aflags |= ARC_L2COMPRESS; + aflags |= ARC_FLAG_L2COMPRESS; dprintf_bp(os->os_rootbp, "reading %s", ""); err = arc_read(NULL, spa, os->os_rootbp, diff --git a/uts/common/fs/zfs/dmu_send.c b/uts/common/fs/zfs/dmu_send.c index dc9f81cd2f2..4bb1290a07c 100644 --- a/uts/common/fs/zfs/dmu_send.c +++ b/uts/common/fs/zfs/dmu_send.c @@ -458,7 +458,7 @@ backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, dnode_phys_t *blk; int i; int blksz = BP_GET_LSIZE(bp); - uint32_t aflags = ARC_WAIT; + arc_flags_t aflags = ARC_FLAG_WAIT; arc_buf_t *abuf; if (arc_read(NULL, spa, bp, arc_getbuf_func, &abuf, @@ -476,7 +476,7 @@ backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, } (void) arc_buf_remove_ref(abuf, &abuf); } else if (type == DMU_OT_SA) { - uint32_t aflags = ARC_WAIT; + arc_flags_t aflags = ARC_FLAG_WAIT; arc_buf_t *abuf; int blksz = BP_GET_LSIZE(bp); @@ -493,7 +493,7 @@ backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, err = dump_write_embedded(dsp, zb->zb_object, zb->zb_blkid * blksz, blksz, bp); } else { /* it's a level-0 block of a regular object */ - uint32_t aflags = ARC_WAIT; + arc_flags_t aflags = ARC_FLAG_WAIT; arc_buf_t *abuf; int blksz = BP_GET_LSIZE(bp); uint64_t offset; diff --git a/uts/common/fs/zfs/dmu_traverse.c b/uts/common/fs/zfs/dmu_traverse.c index bffdff65d62..7b1d6befa6a 100644 --- a/uts/common/fs/zfs/dmu_traverse.c +++ b/uts/common/fs/zfs/dmu_traverse.c @@ -178,7 +178,7 @@ static void traverse_prefetch_metadata(traverse_data_t *td, const blkptr_t *bp, const zbookmark_phys_t *zb) { - uint32_t flags = ARC_NOWAIT | ARC_PREFETCH; + arc_flags_t flags = ARC_FLAG_NOWAIT | ARC_FLAG_PREFETCH; if (!(td->td_flags & TRAVERSE_PREFETCH_METADATA)) return; @@ -275,7 +275,7 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp, } if (BP_GET_LEVEL(bp) > 0) { - uint32_t flags = ARC_WAIT; + arc_flags_t flags = ARC_FLAG_WAIT; int i; blkptr_t *cbp; int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT; @@ -303,7 +303,7 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp, break; } } else if (BP_GET_TYPE(bp) == DMU_OT_DNODE) { - uint32_t flags = ARC_WAIT; + arc_flags_t flags = ARC_FLAG_WAIT; int i; int epb = BP_GET_LSIZE(bp) >> DNODE_SHIFT; @@ -326,7 +326,7 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp, break; } } else if (BP_GET_TYPE(bp) == DMU_OT_OBJSET) { - uint32_t flags = ARC_WAIT; + arc_flags_t flags = ARC_FLAG_WAIT; objset_phys_t *osp; dnode_phys_t *dnp; @@ -442,7 +442,7 @@ traverse_prefetcher(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, const zbookmark_phys_t *zb, const dnode_phys_t *dnp, void *arg) { prefetch_data_t *pfd = arg; - uint32_t aflags = ARC_NOWAIT | ARC_PREFETCH; + arc_flags_t aflags = ARC_FLAG_NOWAIT | ARC_FLAG_PREFETCH; ASSERT(pfd->pd_blks_fetched >= 0); if (pfd->pd_cancel) @@ -533,7 +533,7 @@ traverse_impl(spa_t *spa, dsl_dataset_t *ds, uint64_t objset, blkptr_t *rootbp, /* See comment on ZIL traversal in dsl_scan_visitds. */ if (ds != NULL && !dsl_dataset_is_snapshot(ds) && !BP_IS_HOLE(rootbp)) { - uint32_t flags = ARC_WAIT; + arc_flags_t flags = ARC_FLAG_WAIT; objset_phys_t *osp; arc_buf_t *buf; diff --git a/uts/common/fs/zfs/dsl_scan.c b/uts/common/fs/zfs/dsl_scan.c index 5c9e68fb2ee..a372b2cdc0c 100644 --- a/uts/common/fs/zfs/dsl_scan.c +++ b/uts/common/fs/zfs/dsl_scan.c @@ -546,7 +546,7 @@ dsl_scan_prefetch(dsl_scan_t *scn, arc_buf_t *buf, blkptr_t *bp, uint64_t objset, uint64_t object, uint64_t blkid) { zbookmark_phys_t czb; - uint32_t flags = ARC_NOWAIT | ARC_PREFETCH; + arc_flags_t flags = ARC_FLAG_NOWAIT | ARC_FLAG_PREFETCH; if (zfs_no_scrub_prefetch) return; @@ -611,7 +611,7 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_dataset_t *ds, dmu_objset_type_t ostype, int err; if (BP_GET_LEVEL(bp) > 0) { - uint32_t flags = ARC_WAIT; + arc_flags_t flags = ARC_FLAG_WAIT; int i; blkptr_t *cbp; int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT; @@ -638,7 +638,7 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_dataset_t *ds, dmu_objset_type_t ostype, } (void) arc_buf_remove_ref(buf, &buf); } else if (BP_GET_TYPE(bp) == DMU_OT_DNODE) { - uint32_t flags = ARC_WAIT; + arc_flags_t flags = ARC_FLAG_WAIT; dnode_phys_t *cdnp; int i, j; int epb = BP_GET_LSIZE(bp) >> DNODE_SHIFT; @@ -664,7 +664,7 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_dataset_t *ds, dmu_objset_type_t ostype, (void) arc_buf_remove_ref(buf, &buf); } else if (BP_GET_TYPE(bp) == DMU_OT_OBJSET) { - uint32_t flags = ARC_WAIT; + arc_flags_t flags = ARC_FLAG_WAIT; objset_phys_t *osp; arc_buf_t *buf; diff --git a/uts/common/fs/zfs/sys/arc.h b/uts/common/fs/zfs/sys/arc.h index 02643bd732d..83ea6f7fbc7 100644 --- a/uts/common/fs/zfs/sys/arc.h +++ b/uts/common/fs/zfs/sys/arc.h @@ -46,6 +46,36 @@ typedef int arc_evict_func_t(void *private); arc_done_func_t arc_bcopy_func; arc_done_func_t arc_getbuf_func; +typedef enum arc_flags +{ + /* + * Public flags that can be passed into the ARC by external consumers. + */ + ARC_FLAG_NONE = 1 << 0, /* No flags set */ + ARC_FLAG_WAIT = 1 << 1, /* perform sync I/O */ + ARC_FLAG_NOWAIT = 1 << 2, /* perform async I/O */ + ARC_FLAG_PREFETCH = 1 << 3, /* I/O is a prefetch */ + ARC_FLAG_CACHED = 1 << 4, /* I/O was in cache */ + ARC_FLAG_L2CACHE = 1 << 5, /* cache in L2ARC */ + ARC_FLAG_L2COMPRESS = 1 << 6, /* compress in L2ARC */ + + /* + * Private ARC flags. These flags are private ARC only flags that + * will show up in b_flags in the arc_hdr_buf_t. These flags should + * only be set by ARC code. + */ + ARC_FLAG_IN_HASH_TABLE = 1 << 7, /* buffer is hashed */ + ARC_FLAG_IO_IN_PROGRESS = 1 << 8, /* I/O in progress */ + ARC_FLAG_IO_ERROR = 1 << 9, /* I/O failed for buf */ + ARC_FLAG_FREED_IN_READ = 1 << 10, /* freed during read */ + ARC_FLAG_BUF_AVAILABLE = 1 << 11, /* block not in use */ + ARC_FLAG_INDIRECT = 1 << 12, /* indirect block */ + ARC_FLAG_FREE_IN_PROGRESS = 1 << 13, /* about to be freed */ + ARC_FLAG_L2_WRITING = 1 << 14, /* write in progress */ + ARC_FLAG_L2_EVICTED = 1 << 15, /* evicted during I/O */ + ARC_FLAG_L2_WRITE_HEAD = 1 << 16, /* head of write list */ +} arc_flags_t; + struct arc_buf { arc_buf_hdr_t *b_hdr; arc_buf_t *b_next; @@ -60,15 +90,6 @@ typedef enum arc_buf_contents { ARC_BUFC_METADATA, /* buffer contains metadata */ ARC_BUFC_NUMTYPES } arc_buf_contents_t; -/* - * These are the flags we pass into calls to the arc - */ -#define ARC_WAIT (1 << 1) /* perform I/O synchronously */ -#define ARC_NOWAIT (1 << 2) /* perform I/O asynchronously */ -#define ARC_PREFETCH (1 << 3) /* I/O is a prefetch */ -#define ARC_CACHED (1 << 4) /* I/O was already in cache */ -#define ARC_L2CACHE (1 << 5) /* cache in L2ARC */ -#define ARC_L2COMPRESS (1 << 6) /* compress in L2ARC */ /* * The following breakdows of arc_size exist for kstat only. @@ -102,7 +123,7 @@ int arc_referenced(arc_buf_t *buf); int arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, void *private, zio_priority_t priority, int flags, - uint32_t *arc_flags, const zbookmark_phys_t *zb); + arc_flags_t *arc_flags, const zbookmark_phys_t *zb); zio_t *arc_write(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, arc_buf_t *buf, boolean_t l2arc, boolean_t l2arc_compress, const zio_prop_t *zp, arc_done_func_t *ready, arc_done_func_t *physdone, diff --git a/uts/common/fs/zfs/zil.c b/uts/common/fs/zfs/zil.c index 6beacadf710..53944165efb 100644 --- a/uts/common/fs/zfs/zil.c +++ b/uts/common/fs/zfs/zil.c @@ -181,7 +181,7 @@ zil_read_log_block(zilog_t *zilog, const blkptr_t *bp, blkptr_t *nbp, void *dst, char **end) { enum zio_flag zio_flags = ZIO_FLAG_CANFAIL; - uint32_t aflags = ARC_WAIT; + arc_flags_t aflags = ARC_FLAG_WAIT; arc_buf_t *abuf = NULL; zbookmark_phys_t zb; int error; @@ -257,7 +257,7 @@ zil_read_log_data(zilog_t *zilog, const lr_write_t *lr, void *wbuf) { enum zio_flag zio_flags = ZIO_FLAG_CANFAIL; const blkptr_t *bp = &lr->lr_blkptr; - uint32_t aflags = ARC_WAIT; + arc_flags_t aflags = ARC_FLAG_WAIT; arc_buf_t *abuf = NULL; zbookmark_phys_t zb; int error; diff --git a/uts/common/fs/zfs/zio.c b/uts/common/fs/zfs/zio.c index b9b31b375d3..d0a42e9af13 100644 --- a/uts/common/fs/zfs/zio.c +++ b/uts/common/fs/zfs/zio.c @@ -2159,7 +2159,7 @@ zio_ddt_collision(zio_t *zio, ddt_t *ddt, ddt_entry_t *dde) if (ddp->ddp_phys_birth != 0) { arc_buf_t *abuf = NULL; - uint32_t aflags = ARC_WAIT; + arc_flags_t aflags = ARC_FLAG_WAIT; blkptr_t blk = *zio->io_bp; int error; From d45822d0ec4cb46942d86b0e22c6810d007d1d39 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 15 Dec 2014 08:02:22 +0000 Subject: [PATCH 09/64] 5427 memory leak in libzfs when doing rollback Reviewed by: Michael Tsymbalyuk Reviewed by: Steven Hartland Approved by: Dan McDonald Author: Jan Kryl illumos/illumos-gate@b7070b7dbcc2758a7f87cefb69ad42887a287152 --- lib/libzfs/common/libzfs_iter.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/libzfs/common/libzfs_iter.c b/lib/libzfs/common/libzfs_iter.c index f8ad5014cbb..5fdfe1d591a 100644 --- a/lib/libzfs/common/libzfs_iter.c +++ b/lib/libzfs/common/libzfs_iter.c @@ -22,7 +22,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. - * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ #include @@ -186,9 +186,6 @@ zfs_iter_bookmarks(zfs_handle_t *zhp, zfs_iter_f func, void *data) fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_CREATETXG)); fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_CREATION)); - /* Allocate an nvlist to hold the bookmarks. */ - bmarks = fnvlist_alloc(); - if ((err = lzc_get_bookmarks(zhp->zfs_name, props, &bmarks)) != 0) goto out; From 3d9b56b045b7553fb7ca054248ea6530aa675730 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Mon, 15 Dec 2014 09:23:40 +0000 Subject: [PATCH 10/64] Resolve USB driver identification conflict. Reported by: Anish Mistry MFC after: 1 week --- sys/dev/usb/net/if_urndis.c | 14 +++++++------- sys/dev/usb/serial/umodem.c | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/dev/usb/net/if_urndis.c b/sys/dev/usb/net/if_urndis.c index 5d45395d46c..aa88a56148b 100644 --- a/sys/dev/usb/net/if_urndis.c +++ b/sys/dev/usb/net/if_urndis.c @@ -170,15 +170,15 @@ static const struct usb_ether_methods urndis_ue_methods = { }; static const STRUCT_USB_HOST_ID urndis_host_devs[] = { -#if 0 - /* XXX this entry has a conflict an entry the umodem driver XXX */ - {USB_IFACE_CLASS(UICLASS_CDC), USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL), - USB_IFACE_PROTOCOL(0xff)}, -#endif + /* Generic RNDIS class match */ {USB_IFACE_CLASS(UICLASS_WIRELESS), USB_IFACE_SUBCLASS(UISUBCLASS_RF), - USB_IFACE_PROTOCOL(UIPROTO_RNDIS)}, + USB_IFACE_PROTOCOL(UIPROTO_RNDIS)}, {USB_IFACE_CLASS(UICLASS_IAD), USB_IFACE_SUBCLASS(UISUBCLASS_SYNC), - USB_IFACE_PROTOCOL(UIPROTO_ACTIVESYNC)}, + USB_IFACE_PROTOCOL(UIPROTO_ACTIVESYNC)}, + /* HP-WebOS */ + {USB_VENDOR(USB_VENDOR_PALM), USB_IFACE_CLASS(UICLASS_CDC), + USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL), + USB_IFACE_PROTOCOL(0xff)}, }; static int diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c index 982104d2175..68b5ff4f4a6 100644 --- a/sys/dev/usb/serial/umodem.c +++ b/sys/dev/usb/serial/umodem.c @@ -125,7 +125,7 @@ static const STRUCT_USB_HOST_ID umodem_devs[] = { USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL), USB_IFACE_PROTOCOL(UIPROTO_CDC_NONE)}, /* Huawei Modem class match */ - {USB_IFACE_CLASS(UICLASS_CDC), + {USB_VENDOR(USB_VENDOR_HUAWEI),USB_IFACE_CLASS(UICLASS_CDC), USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL), USB_IFACE_PROTOCOL(0xFF)}, /* Kyocera AH-K3001V */ From 50a601af507a6df438177949fdc38ea6b8b7433c Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Mon, 15 Dec 2014 09:35:46 +0000 Subject: [PATCH 11/64] Regenerate usb.conf . MFC after: 1 week --- etc/devd/usb.conf | 87 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 18 deletions(-) diff --git a/etc/devd/usb.conf b/etc/devd/usb.conf index 7828a8561cf..9baa070cf84 100644 --- a/etc/devd/usb.conf +++ b/etc/devd/usb.conf @@ -1017,7 +1017,23 @@ nomatch 32 { match "bus" "uhub[0-9]+"; match "mode" "host"; match "vendor" "0x056e"; - match "product" "(0x200c|0x4002|0x4005|0x400b|0x4010)"; + match "product" "(0x200c|0x4002|0x4005)"; + action "kldload -n if_aue"; +}; + +nomatch 32 { + match "bus" "uhub[0-9]+"; + match "mode" "host"; + match "vendor" "0x056e"; + match "product" "0x4008"; + action "kldload -n if_urtwn"; +}; + +nomatch 32 { + match "bus" "uhub[0-9]+"; + match "mode" "host"; + match "vendor" "0x056e"; + match "product" "(0x400b|0x4010)"; action "kldload -n if_aue"; }; @@ -1177,7 +1193,7 @@ nomatch 32 { match "bus" "uhub[0-9]+"; match "mode" "host"; match "vendor" "0x05c6"; - match "product" "(0x1000|0x6000|0x6613|0x9000|0x9204|0x9205)"; + match "product" "(0x1000|0x6000|0x6500|0x6613|0x9000|0x9204|0x9205)"; action "kldload -n u3g"; }; @@ -2545,7 +2561,7 @@ nomatch 32 { match "bus" "uhub[0-9]+"; match "mode" "host"; match "vendor" "0x0bda"; - match "product" "(0x8176|0x8176|0x8177|0x8178|0x8179|0x817a|0x817b|0x817c|0x817d|0x817e)"; + match "product" "(0x8176|0x8176|0x8177|0x8178|0x8179|0x817a|0x817b|0x817c|0x817d|0x817e|0x817f)"; action "kldload -n if_urtwn"; }; @@ -3617,7 +3633,7 @@ nomatch 32 { match "bus" "uhub[0-9]+"; match "mode" "host"; match "vendor" "0x12d1"; - match "product" "(0x1001|0x1003|0x1004|0x1401|0x1402|0x1403|0x1404|0x1405|0x1406|0x1407|0x1408|0x1409|0x140a|0x140b|0x140c|0x140d|0x140e|0x140f|0x1410|0x1411|0x1412|0x1413|0x1414|0x1415|0x1416|0x1417|0x1418|0x1419|0x141a|0x141b|0x141c|0x141d|0x141e|0x141f|0x1420|0x1421|0x1422|0x1423|0x1424|0x1425|0x1426|0x1427|0x1428|0x1429|0x142a|0x142b|0x142c|0x142d|0x142e|0x142f|0x1430|0x1431|0x1432|0x1433|0x1434|0x1435|0x1436|0x1437|0x1438|0x1439|0x143a|0x143b|0x143c|0x143d|0x143e|0x143f|0x1446|0x1464|0x1465|0x14ac|0x14c9|0x14d1|0x14fe|0x1505|0x1506|0x1520|0x1521)"; + match "product" "(0x1001|0x1003|0x1004|0x1401|0x1402|0x1403|0x1404|0x1405|0x1406|0x1407|0x1408|0x1409|0x140a|0x140b|0x140c|0x140d|0x140e|0x140f|0x1410|0x1411|0x1412|0x1413|0x1414|0x1415|0x1416|0x1417|0x1418|0x1419|0x141a|0x141b|0x141c|0x141d|0x141e|0x141f|0x1420|0x1421|0x1422|0x1423|0x1424|0x1425|0x1426|0x1427|0x1428|0x1429|0x142a|0x142b|0x142c|0x142d|0x142e|0x142f|0x1430|0x1431|0x1432|0x1433|0x1434|0x1435|0x1436|0x1437|0x1438|0x1439|0x143a|0x143b|0x143c|0x143d|0x143e|0x143f|0x1446|0x1464|0x1465|0x14ac|0x14c9|0x14cf|0x14d1|0x14fe|0x1505|0x1506|0x1520|0x1521|0x1526)"; action "kldload -n u3g"; }; @@ -4489,7 +4505,15 @@ nomatch 32 { match "bus" "uhub[0-9]+"; match "mode" "host"; match "vendor" "0x19d2"; - match "product" "(0x0001|0x0002|0x0003|0x0004|0x0005|0x0006|0x0007|0x0008|0x0009|0x000a|0x000b|0x000c|0x000d|0x000e|0x000f|0x0010|0x0011|0x0012|0x0013|0x0014|0x0015|0x0016|0x0017|0x0018|0x0019|0x0020|0x0021|0x0022|0x0023|0x0024|0x0025|0x0026|0x0027|0x0028|0x0029|0x0030|0x0031|0x0032|0x0033|0x0037|0x0039|0x0042|0x0043|0x0048|0x0049|0x0051|0x0052|0x0053|0x0054|0x0055|0x0057|0x0058|0x0059|0x0060|0x0061|0x0062|0x0063|0x0064|0x0066|0x0069|0x0070|0x0073|0x0076|0x0078|0x0082|0x0086|0x0117|0x1179|0x2000|0x2002|0x2003|0xfff1|0xfff5|0xfffe)"; + match "product" "(0x0001|0x0002|0x0003|0x0004|0x0005|0x0006|0x0007|0x0008|0x0009|0x000a|0x000b|0x000c|0x000d|0x000e|0x000f|0x0010|0x0011|0x0012|0x0013|0x0014|0x0015|0x0016|0x0017|0x0018|0x0019|0x0020|0x0021|0x0022|0x0023|0x0024|0x0025|0x0026|0x0027|0x0028|0x0029|0x0030|0x0031|0x0032|0x0033|0x0037|0x0039|0x0042|0x0043|0x0048|0x0049|0x0051|0x0052|0x0053|0x0054|0x0055|0x0057|0x0058|0x0059|0x0060|0x0061|0x0062|0x0063|0x0064|0x0066|0x0069|0x0070|0x0073|0x0076|0x0078|0x0082|0x0086|0x0117|0x1179|0x1181|0x1514|0x1516|0x2000|0x2002|0x2003|0xffdd|0xffde|0xfff1|0xfff5|0xfffe)"; + action "kldload -n u3g"; +}; + +nomatch 32 { + match "bus" "uhub[0-9]+"; + match "mode" "host"; + match "vendor" "0x19f5"; + match "product" "0x9909"; action "kldload -n u3g"; }; @@ -4609,7 +4633,7 @@ nomatch 32 { match "bus" "uhub[0-9]+"; match "mode" "host"; match "vendor" "0x1cf1"; - match "product" "(0x0001|0x0004|0x0022)"; + match "product" "(0x0001|0x0004|0x001c|0x0022)"; action "kldload -n uftdi"; }; @@ -4697,7 +4721,7 @@ nomatch 32 { match "bus" "uhub[0-9]+"; match "mode" "host"; match "vendor" "0x2001"; - match "product" "(0x3307|0x3308|0x3309|0x330a|0x330d|0x330f)"; + match "product" "(0x3307|0x3308|0x3309|0x330a|0x330d|0x330f|0x3310)"; action "kldload -n if_urtwn"; }; @@ -4897,7 +4921,23 @@ nomatch 32 { match "bus" "uhub[0-9]+"; match "mode" "host"; match "vendor" "0x20f4"; - match "product" "(0x624d|0x648b)"; + match "product" "0x624d"; + action "kldload -n if_urtwn"; +}; + +nomatch 32 { + match "bus" "uhub[0-9]+"; + match "mode" "host"; + match "vendor" "0x20f4"; + match "product" "0x646b"; + action "kldload -n if_rsu"; +}; + +nomatch 32 { + match "bus" "uhub[0-9]+"; + match "mode" "host"; + match "vendor" "0x20f4"; + match "product" "0x648b"; action "kldload -n if_urtwn"; }; @@ -5291,6 +5331,16 @@ nomatch 32 { action "kldload -n if_ipheth"; }; +nomatch 32 { + match "bus" "uhub[0-9]+"; + match "mode" "host"; + match "vendor" "0x0830"; + match "intclass" "0x02"; + match "intsubclass" "0x02"; + match "intprotocol" "0xff"; + action "kldload -n if_urndis"; +}; + nomatch 32 { match "bus" "uhub[0-9]+"; match "mode" "host"; @@ -5301,6 +5351,16 @@ nomatch 32 { action "kldload -n ng_ubt"; }; +nomatch 32 { + match "bus" "uhub[0-9]+"; + match "mode" "host"; + match "vendor" "0x12d1"; + match "intclass" "0x02"; + match "intsubclass" "0x02"; + match "intprotocol" "0xff"; + action "kldload -n umodem"; +}; + nomatch 32 { match "bus" "uhub[0-9]+"; match "mode" "host"; @@ -5349,15 +5409,6 @@ nomatch 32 { action "kldload -n umodem"; }; -nomatch 32 { - match "bus" "uhub[0-9]+"; - match "mode" "host"; - match "intclass" "0x02"; - match "intsubclass" "0x02"; - match "intprotocol" "0xff"; - action "kldload -n umodem"; -}; - nomatch 32 { match "bus" "uhub[0-9]+"; match "mode" "host"; @@ -5501,5 +5552,5 @@ nomatch 32 { action "kldload -n umass"; }; -# 2643 USB entries processed +# 2658 USB entries processed From ba2ea14a6a367aecfc588c2655ea77aac4ae7086 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Mon, 15 Dec 2014 09:40:25 +0000 Subject: [PATCH 12/64] Eliminate fdt_data_verify(). The verification it proceed is wrong disallowing us to encode 64-bit register numbers. Discussed with: nwhitehorn, andrew --- sys/dev/fdt/fdt_common.c | 70 ++++------------------------------------ sys/dev/fdt/fdt_common.h | 2 -- 2 files changed, 6 insertions(+), 66 deletions(-) diff --git a/sys/dev/fdt/fdt_common.c b/sys/dev/fdt/fdt_common.c index 117e7de7adc..d99fdf26dcd 100644 --- a/sys/dev/fdt/fdt_common.c +++ b/sys/dev/fdt/fdt_common.c @@ -102,10 +102,9 @@ fdt_get_range_by_busaddr(phandle_t node, u_long addr, u_long *base, tuple_size = addr_cells + par_addr_cells + size_cells; tuples = len / (tuple_size * sizeof(cell_t)); - if (fdt_ranges_verify(ranges, tuples, par_addr_cells, - addr_cells, size_cells)) { + if (par_addr_cells > 2 || addr_cells > 2 || size_cells > 2) return (ERANGE); - } + *base = 0; *size = 0; @@ -173,10 +172,9 @@ fdt_get_range(phandle_t node, int range_id, u_long *base, u_long *size) size_cells); tuples = len / tuple_size; - if (fdt_ranges_verify(ranges, tuples, par_addr_cells, - addr_cells, size_cells)) { + if (par_addr_cells > 2 || addr_cells > 2 || size_cells > 2) return (ERANGE); - } + *base = 0; *size = 0; rangesptr = &ranges[range_id]; @@ -380,20 +378,6 @@ fdt_parent_addr_cells(phandle_t node) return ((int)fdt32_to_cpu(addr_cells)); } -int -fdt_data_verify(void *data, int cells) -{ - uint64_t d64; - - if (cells > 1) { - d64 = fdt64_to_cpu(*((uint64_t *)data)); - if (((d64 >> 32) & 0xffffffffull) != 0 || cells > 2) - return (ERANGE); - } - - return (0); -} - int fdt_pm_is_enabled(phandle_t node) { @@ -440,62 +424,20 @@ fdt_addrsize_cells(phandle_t node, int *addr_cells, int *size_cells) return (0); } -int -fdt_ranges_verify(pcell_t *ranges, int tuples, int par_addr_cells, - int this_addr_cells, int this_size_cells) -{ - int i, rv, ulsz; - - if (par_addr_cells > 2 || this_addr_cells > 2 || this_size_cells > 2) - return (ERANGE); - - /* - * This is the max size the resource manager can handle for addresses - * and sizes. - */ - ulsz = sizeof(u_long); - if (par_addr_cells <= ulsz && this_addr_cells <= ulsz && - this_size_cells <= ulsz) - /* We can handle everything */ - return (0); - - rv = 0; - for (i = 0; i < tuples; i++) { - - if (fdt_data_verify((void *)ranges, par_addr_cells)) - goto err; - ranges += par_addr_cells; - - if (fdt_data_verify((void *)ranges, this_addr_cells)) - goto err; - ranges += this_addr_cells; - - if (fdt_data_verify((void *)ranges, this_size_cells)) - goto err; - ranges += this_size_cells; - } - - return (0); - -err: - debugf("using address range >%d-bit not supported\n", ulsz * 8); - return (ERANGE); -} - int fdt_data_to_res(pcell_t *data, int addr_cells, int size_cells, u_long *start, u_long *count) { /* Address portion. */ - if (fdt_data_verify((void *)data, addr_cells)) + if (addr_cells > 2) return (ERANGE); *start = fdt_data_get((void *)data, addr_cells); data += addr_cells; /* Size portion. */ - if (fdt_data_verify((void *)data, size_cells)) + if (size_cells > 2) return (ERANGE); *count = fdt_data_get((void *)data, size_cells); diff --git a/sys/dev/fdt/fdt_common.h b/sys/dev/fdt/fdt_common.h index 0a79ce03baf..3d05341dad1 100644 --- a/sys/dev/fdt/fdt_common.h +++ b/sys/dev/fdt/fdt_common.h @@ -79,7 +79,6 @@ extern u_char fdt_static_dtb; int fdt_addrsize_cells(phandle_t, int *, int *); u_long fdt_data_get(void *, int); int fdt_data_to_res(pcell_t *, int, int, u_long *, u_long *); -int fdt_data_verify(void *, int); phandle_t fdt_find_compatible(phandle_t, const char *, int); phandle_t fdt_depth_search_compatible(phandle_t, const char *, int); int fdt_get_mem_regions(struct mem_region *, int *, uint32_t *); @@ -94,7 +93,6 @@ int fdt_is_enabled(phandle_t); int fdt_pm_is_enabled(phandle_t); int fdt_is_type(phandle_t, const char *); int fdt_parent_addr_cells(phandle_t); -int fdt_ranges_verify(pcell_t *, int, int, int, int); int fdt_reg_to_rl(phandle_t, struct resource_list *); int fdt_pm(phandle_t); int fdt_get_unit(device_t); From 1f7f3314d1e47f153f0add808e8fb6a30c8eda4c Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Mon, 15 Dec 2014 11:57:39 +0000 Subject: [PATCH 13/64] Follow r275792 eliminating fdt_data_verify(). --- sys/arm/mv/mv_common.c | 3 +-- sys/arm/mv/mv_pci.c | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/sys/arm/mv/mv_common.c b/sys/arm/mv/mv_common.c index d62efc4ca2f..d92f88d10a4 100644 --- a/sys/arm/mv/mv_common.c +++ b/sys/arm/mv/mv_common.c @@ -1939,8 +1939,7 @@ fdt_get_ranges(const char *nodename, void *buf, int size, int *tuples, if (tuples_count <= 0) return (ERANGE); - if (fdt_ranges_verify(buf, tuples_count, par_addr_cells, - addr_cells, size_cells) != 0) + if (par_addr_cells > 2 || addr_cells > 2 || size_cells > 2) return (ERANGE); *tuples = tuples_count; diff --git a/sys/arm/mv/mv_pci.c b/sys/arm/mv/mv_pci.c index 8ac6c76bc0e..061eaffc86f 100644 --- a/sys/arm/mv/mv_pci.c +++ b/sys/arm/mv/mv_pci.c @@ -180,8 +180,7 @@ mv_pci_ranges_decode(phandle_t node, struct mv_pci_range *io_space, rangesptr += offset_cells; } - if (fdt_data_verify((void *)rangesptr, par_addr_cells - - offset_cells)) { + if ((par_addr_cells - offset_cells) > 2) { rv = ERANGE; goto out; } @@ -189,7 +188,7 @@ mv_pci_ranges_decode(phandle_t node, struct mv_pci_range *io_space, par_addr_cells - offset_cells); rangesptr += par_addr_cells - offset_cells; - if (fdt_data_verify((void *)rangesptr, size_cells)) { + if (size_cells > 2) rv = ERANGE; goto out; } From 237623b02808af9a7e6f7476746b7db93367bc61 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 15 Dec 2014 12:01:42 +0000 Subject: [PATCH 14/64] Add a facility for non-init process to declare itself the reaper of the orphaned descendants. Base of the API is modelled after the same feature from the DragonFlyBSD. Requested by: bapt Reviewed by: jilles (previous version) Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 3 weeks --- lib/libc/sys/procctl.2 | 215 +++++++++++- sys/compat/freebsd32/freebsd32.h | 6 + sys/compat/freebsd32/freebsd32_misc.c | 51 ++- sys/conf/files | 1 + sys/kern/init_main.c | 7 +- sys/kern/kern_exit.c | 39 ++- sys/kern/kern_fork.c | 24 +- sys/kern/kern_procctl.c | 460 ++++++++++++++++++++++++++ sys/kern/sys_process.c | 191 ----------- sys/sys/proc.h | 10 + sys/sys/procctl.h | 57 +++- 11 files changed, 850 insertions(+), 211 deletions(-) create mode 100644 sys/kern/kern_procctl.c diff --git a/lib/libc/sys/procctl.2 b/lib/libc/sys/procctl.2 index 6ad0590804a..a5d3d899031 100644 --- a/lib/libc/sys/procctl.2 +++ b/lib/libc/sys/procctl.2 @@ -2,6 +2,10 @@ .\" Written by: John H. Baldwin .\" All rights reserved. .\" +.\" Copyright (c) 2014 The FreeBSD Foundation +.\" Portions of this documentation were written by Konstantin Belousov +.\" under sponsorship from the FreeBSD Foundation. +.\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: @@ -25,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 19, 2013 +.Dd December 15, 2014 .Dt PROCCTL 2 .Os .Sh NAME @@ -67,7 +71,7 @@ The control request to perform is specified by the .Fa cmd argument. The following commands are supported: -.Bl -tag -width "Dv PROC_SPROTECT" +.Bl -tag -width "Dv PROC_REAP_GETPIDS" .It Dv PROC_SPROTECT Set process protection state. This is used to mark a process as protected from being killed if the system @@ -95,6 +99,174 @@ When used with mark all future child processes of each selected process as protected. Future child processes will also mark all of their future child processes. .El +.It Dv PROC_REAP_ACQUIRE +Acquires the reaper status for the current process. +The status means that orphaned children by the reaper descendants, +forked after the acquisition of the status, are reparented to the +reaper. +After the system initialization, +.Xr init 8 +is the default reaper. +.Pp +.It Dv PROC_REAP_RELEASE +Releases the reaper state fpr the current process. +The reaper of the current process becomes the new reaper of the +current process descendants. +.It Dv PROC_REAP_STATUS +Provides the information about the reaper of the specified process, +or the process itself, in case it is a reaper. +The +.Fa data +argument must point to the +.Vt "struct procctl_reaper_status" , +which if filled by the syscall on successfull return. +.Bd -literal +struct procctl_reaper_status { + u_int rs_flags; + u_int rs_children; + u_int rs_descendants; + pid_t rs_reaper; + pid_t rs_pid; +}; +.Ed +The +.Fa rs_flags +may have the following flags returned: +.Bl -tag -width "Dv REAPER_STATUS_REALINIT" +.It Dv REAPER_STATUS_OWNED +The specified process has acquired the reaper status and did not +released it. +When the flag is returned, the +.Fa id +pid identifies reaper, otherwise the +.Fa rs_reaper +field of the structure is the pid of the reaper for passed process id. +.It Dv REAPER_STATUS_REALINIT +The specified process is the root of the reaper tree, i.e. +.Xr init 8. +.El +The +.Fa rs_children +returns the number of the children of the reaper. +The +.Fa rs_descendants +returns the total number of descendants of the reaper, +not counting descendants of the reapers in the subtree. +The +.Fa rs_reaper +returns the reaper pid. +The +.Fa rs_pid +returns pid of some reaper child if there is any descendant. +.It Dv PROC_REAP_GETPIDS +Queries the list of descendants of the reaper of the specified process. +The request takes the pointer to +.Vt "struct procctl_reaper_pids" +as +.Fa data . +.Bd -literal +struct procctl_reaper_pids { + u_int rp_count; + struct procctl_reaper_pidinfo *rp_pids; +}; +.Ed +On call, the +.Fa rp_pids +must point to the array of +.Vt procctl_reaper_pidinfo +structures, to be filled on return, +and the +.Fa rp_count +must specify the size of the array, +no more than rp_count elements is filled by kernel. +.Pp +The +.Vt "struct procctl_reaper_pidinfo" +structure provides some information about one reaper' descendant. +Note that for the descendant which is not child, it is the subject +of usual race with process exiting and pid reuse. +.Bd -literal +struct procctl_reaper_pidinfo { + pid_t pi_pid; + pid_t pi_subtree; + u_int pi_flags; +}; +.Ed +The +.Fa pi_pid +is the process id of the descendant. +The +.Fa pi_subtree +provides the pid of the child of the reaper, which is (grand-)parent +of the process. +The +.Fa pi_flags +returns the following flags, further describing the descendant: +.Bl -tag -width "Dv REAPER_PIDINFO_VALID" +.It Dv REAPER_PIDINFO_VALID +Set for the +.Vt procctl_reaper_pidinfo +structure, which was filled by kernel. +Zero-filling the +.Fa rp_pids +array and testing the flag allows the caller to detect the end +of returned array. +.It Dv REAPER_PIDINFO_CHILD +The +.Fa pi_pid +is the direct child of the reaper. +.El +.It Dv PROC_REAP_KILL +Request to deliver a signal to some subset of descendants of the reaper. +The +.Fa data +must point to +.Vt procctl_reaper_kill +structure, which is used both for parameters and status return. +.Bd -literal +struct procctl_reaper_kill { + int rk_sig; + u_int rk_flags; + pid_t rk_subtree; + u_int rk_killed; + pid_t rk_fpid; +}; +.Ed +The +.Fa rk_sig +specifies the signal to be delivered. +Zero is not a valid signal number, unlike +.Xr kill 2 . +The +.Fa rk_flags +further directs the operation. +It is or-ed from the following flags: +.Bl -tag -width "Dv REAPER_KILL_CHILDREN" +.It Dv REAPER_KILL_CHILDREN +Deliver the specified signal only to direct children of the reaper. +.It Dv REAPER_KILL_SUBTREE +Deliver the specified signal only to descendants which were forked by +the direct child with pid specified in +.Fa rk_subtree . +.El +If no +.Dv REAPER_KILL_CHILDREN +and +.Dv REAPER_KILL_SUBTREE +flags are specified, all current descendants of the reaper are signalled. +.Pp +If signal was delivered to any process, the return value from the request +is zero. +In this case, +.Fa rk_killed +field is filled with the count of processes signalled. +The +.Fa rk_fpid +field is set to the pid of the first process for which signal +delivery failed, e.g. due to the permission problems. +If no such process exist, the +.Fa rk_fpid +is set to -1. .El .Sh RETURN VALUES If an error occurs, a value of -1 is returned and @@ -132,11 +304,48 @@ An invalid operation or flag was passed in for a .Dv PROC_SPROTECT command. +.It Bq Er EPERM +The +.Fa idtype +argument is not equal to +.Dv P_PID , +or +.Fa id +is not equal to the pid of the calling process, for +.Dv PROC_REAP_ACQUIRE +or +.Dv PROC_REAP_RELEASE +requests. +.It Bq Er EINVAL +Invalid or undefined flags were passed to +.Dv PROC_REAP_KILL +request. +.It Bq Er EINVAL +Invalid or zero signal number was requested for +.Dv PROC_REAP_KILL +request. +.It Bq Er EINVAL +The +.Dv PROC_REAP_RELEASE +request was issued by the +.Xr init 8 +process. +.It Bq Er EBUSY +The +.Dv PROC_REAP_ACQUIRE +request was issued by the process which already acquired reaper status +and did not released it. .El .Sh SEE ALSO -.Xr ptrace 2 +.Xr kill 2 , +.Xr ptrace 2 , +.Xr wait 2 , +.Xr init 8 .Sh HISTORY The .Fn procctl function appeared in .Fx 10.0 . +Reaper facility was created based on the similar feature of Linux and +DragonflyBSD, and first appeared in +.Fx 10.2 . diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h index af10055d093..ed3df7ac0ee 100644 --- a/sys/compat/freebsd32/freebsd32.h +++ b/sys/compat/freebsd32/freebsd32.h @@ -390,4 +390,10 @@ struct kld32_file_stat { char pathname[MAXPATHLEN]; }; +struct procctl_reaper_pids32 { + u_int rp_count; + u_int rp_pad0[15]; + uint32_t rp_pids; +}; + #endif /* !_COMPAT_FREEBSD32_FREEBSD32_H_ */ diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 24c57381353..1457f57b78f 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -2957,20 +2957,63 @@ int freebsd32_procctl(struct thread *td, struct freebsd32_procctl_args *uap) { void *data; - int error, flags; + union { + struct procctl_reaper_status rs; + struct procctl_reaper_pids rp; + struct procctl_reaper_kill rk; + } x; + union { + struct procctl_reaper_pids32 rp; + } x32; + int error, error1, flags; switch (uap->com) { case PROC_SPROTECT: error = copyin(PTRIN(uap->data), &flags, sizeof(flags)); - if (error) + if (error != 0) return (error); data = &flags; break; + case PROC_REAP_ACQUIRE: + case PROC_REAP_RELEASE: + if (uap->data != NULL) + return (EINVAL); + data = NULL; + break; + case PROC_REAP_STATUS: + data = &x.rs; + break; + case PROC_REAP_GETPIDS: + error = copyin(uap->data, &x32.rp, sizeof(x32.rp)); + if (error != 0) + return (error); + CP(x32.rp, x.rp, rp_count); + PTRIN_CP(x32.rp, x.rp, rp_pids); + data = &x.rp; + break; + case PROC_REAP_KILL: + error = copyin(uap->data, &x.rk, sizeof(x.rk)); + if (error != 0) + return (error); + data = &x.rk; + break; default: return (EINVAL); } - return (kern_procctl(td, uap->idtype, PAIR32TO64(id_t, uap->id), - uap->com, data)); + error = kern_procctl(td, uap->idtype, PAIR32TO64(id_t, uap->id), + uap->com, data); + switch (uap->com) { + case PROC_REAP_STATUS: + if (error == 0) + error = copyout(&x.rs, uap->data, sizeof(x.rs)); + break; + case PROC_REAP_KILL: + error1 = copyout(&x.rk, uap->data, sizeof(x.rk)); + if (error == 0) + error = error1; + break; + } + return (error); } int diff --git a/sys/conf/files b/sys/conf/files index 018d77bfa84..939b63517d3 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2987,6 +2987,7 @@ kern/kern_pmc.c standard kern/kern_poll.c optional device_polling kern/kern_priv.c standard kern/kern_proc.c standard +kern/kern_procctl.c standard kern/kern_prot.c standard kern/kern_racct.c standard kern/kern_rangelock.c standard diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index e903f4cc89f..beb49bc5696 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -496,7 +496,8 @@ proc0_init(void *dummy __unused) prison0.pr_cpuset = cpuset_ref(td->td_cpuset); p->p_peers = 0; p->p_leader = p; - + p->p_reaper = p; + LIST_INIT(&p->p_reaplist); strncpy(p->p_comm, "kernel", sizeof (p->p_comm)); strncpy(td->td_name, "swapper", sizeof (td->td_name)); @@ -821,8 +822,11 @@ create_init(const void *udata __unused) KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1")); /* divorce init's credentials from the kernel's */ newcred = crget(); + sx_xlock(&proctree_lock); PROC_LOCK(initproc); initproc->p_flag |= P_SYSTEM | P_INMEM; + initproc->p_treeflag |= P_TREE_REAPER; + LIST_INSERT_HEAD(&initproc->p_reaplist, &proc0, p_reapsibling); oldcred = initproc->p_ucred; crcopy(newcred, oldcred); #ifdef MAC @@ -833,6 +837,7 @@ create_init(const void *udata __unused) #endif initproc->p_ucred = newcred; PROC_UNLOCK(initproc); + sx_xunlock(&proctree_lock); crfree(oldcred); cred_update_thread(FIRST_THREAD_IN_PROC(initproc)); cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL); diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index a4313091e44..ce1f8f9e6e3 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -123,6 +123,31 @@ proc_realparent(struct proc *child) return (parent); } +void +reaper_abandon_children(struct proc *p, bool exiting) +{ + struct proc *p1, *p2, *ptmp; + + sx_assert(&proctree_lock, SX_LOCKED); + KASSERT(p != initproc, ("reaper_abandon_children for initproc")); + if ((p->p_treeflag & P_TREE_REAPER) == 0) + return; + p1 = p->p_reaper; + LIST_FOREACH_SAFE(p2, &p->p_reaplist, p_reapsibling, ptmp) { + LIST_REMOVE(p2, p_reapsibling); + p2->p_reaper = p1; + p2->p_reapsubtree = p->p_reapsubtree; + LIST_INSERT_HEAD(&p1->p_reaplist, p2, p_reapsibling); + if (exiting && p2->p_pptr == p) { + PROC_LOCK(p2); + proc_reparent(p2, p1); + PROC_UNLOCK(p2); + } + } + KASSERT(LIST_EMPTY(&p->p_reaplist), ("p_reaplist not empty")); + p->p_treeflag &= ~P_TREE_REAPER; +} + static void clear_orphan(struct proc *p) { @@ -458,14 +483,14 @@ exit1(struct thread *td, int rv) sx_xlock(&proctree_lock); q = LIST_FIRST(&p->p_children); if (q != NULL) /* only need this if any child is S_ZOMB */ - wakeup(initproc); + wakeup(q->p_reaper); for (; q != NULL; q = nq) { nq = LIST_NEXT(q, p_sibling); PROC_LOCK(q); q->p_sigparent = SIGCHLD; if (!(q->p_flag & P_TRACED)) { - proc_reparent(q, initproc); + proc_reparent(q, q->p_reaper); } else { /* * Traced processes are killed since their existence @@ -473,7 +498,7 @@ exit1(struct thread *td, int rv) */ t = proc_realparent(q); if (t == p) { - proc_reparent(q, initproc); + proc_reparent(q, q->p_reaper); } else { PROC_LOCK(t); proc_reparent(q, t); @@ -562,7 +587,7 @@ exit1(struct thread *td, int rv) mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx); pp = p->p_pptr; PROC_UNLOCK(pp); - proc_reparent(p, initproc); + proc_reparent(p, p->p_reaper); p->p_sigparent = SIGCHLD; PROC_LOCK(p->p_pptr); @@ -575,8 +600,8 @@ exit1(struct thread *td, int rv) } else mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx); - if (p->p_pptr == initproc) - kern_psignal(p->p_pptr, SIGCHLD); + if (p->p_pptr == p->p_reaper || p->p_pptr == initproc) + childproc_exited(p); else if (p->p_sigparent != 0) { if (p->p_sigparent == SIGCHLD) childproc_exited(p); @@ -849,6 +874,8 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options) LIST_REMOVE(p, p_list); /* off zombproc */ sx_xunlock(&allproc_lock); LIST_REMOVE(p, p_sibling); + reaper_abandon_children(p, true); + LIST_REMOVE(p, p_reapsibling); PROC_LOCK(p); clear_orphan(p); PROC_UNLOCK(p); diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index c5298388c88..f469db634bc 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -261,11 +261,21 @@ retry: * Scan the active and zombie procs to check whether this pid * is in use. Remember the lowest pid that's greater * than trypid, so we can avoid checking for a while. + * + * Avoid reuse of the process group id, session id or + * the reaper subtree id. Note that for process group + * and sessions, the amount of reserved pids is + * limited by process limit. For the subtree ids, the + * id is kept reserved only while there is a + * non-reaped process in the subtree, so amount of + * reserved pids is limited by process limit times + * two. */ p = LIST_FIRST(&allproc); again: for (; p != NULL; p = LIST_NEXT(p, p_list)) { while (p->p_pid == trypid || + p->p_reapsubtree == trypid || (p->p_pgrp != NULL && (p->p_pgrp->pg_id == trypid || (p->p_session != NULL && @@ -611,12 +621,20 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2, * of init. This effectively disassociates the child from the * parent. */ - if (flags & RFNOWAIT) - pptr = initproc; - else + if ((flags & RFNOWAIT) != 0) { + pptr = p1->p_reaper; + p2->p_reaper = pptr; + } else { + p2->p_reaper = (p1->p_treeflag & P_TREE_REAPER) != 0 ? + p1 : p1->p_reaper; pptr = p1; + } p2->p_pptr = pptr; LIST_INSERT_HEAD(&pptr->p_children, p2, p_sibling); + LIST_INIT(&p2->p_reaplist); + LIST_INSERT_HEAD(&p2->p_reaper->p_reaplist, p2, p_reapsibling); + if (p2->p_reaper == p1) + p2->p_reapsubtree = p2->p_pid; sx_xunlock(&proctree_lock); /* Inform accounting that we have forked. */ diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c new file mode 100644 index 00000000000..5ee2953a169 --- /dev/null +++ b/sys/kern/kern_procctl.c @@ -0,0 +1,460 @@ +/*- + * Copyright (c) 2014 John Baldwin + * Copyright (c) 2014 The FreeBSD Foundation + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int +protect_setchild(struct thread *td, struct proc *p, int flags) +{ + + PROC_LOCK_ASSERT(p, MA_OWNED); + if (p->p_flag & P_SYSTEM || p_cansched(td, p) != 0) + return (0); + if (flags & PPROT_SET) { + p->p_flag |= P_PROTECTED; + if (flags & PPROT_INHERIT) + p->p_flag2 |= P2_INHERIT_PROTECTED; + } else { + p->p_flag &= ~P_PROTECTED; + p->p_flag2 &= ~P2_INHERIT_PROTECTED; + } + return (1); +} + +static int +protect_setchildren(struct thread *td, struct proc *top, int flags) +{ + struct proc *p; + int ret; + + p = top; + ret = 0; + sx_assert(&proctree_lock, SX_LOCKED); + for (;;) { + ret |= protect_setchild(td, p, flags); + PROC_UNLOCK(p); + /* + * If this process has children, descend to them next, + * otherwise do any siblings, and if done with this level, + * follow back up the tree (but not past top). + */ + if (!LIST_EMPTY(&p->p_children)) + p = LIST_FIRST(&p->p_children); + else for (;;) { + if (p == top) { + PROC_LOCK(p); + return (ret); + } + if (LIST_NEXT(p, p_sibling)) { + p = LIST_NEXT(p, p_sibling); + break; + } + p = p->p_pptr; + } + PROC_LOCK(p); + } +} + +static int +protect_set(struct thread *td, struct proc *p, int flags) +{ + int error, ret; + + switch (PPROT_OP(flags)) { + case PPROT_SET: + case PPROT_CLEAR: + break; + default: + return (EINVAL); + } + + if ((PPROT_FLAGS(flags) & ~(PPROT_DESCEND | PPROT_INHERIT)) != 0) + return (EINVAL); + + error = priv_check(td, PRIV_VM_MADV_PROTECT); + if (error) + return (error); + + if (flags & PPROT_DESCEND) + ret = protect_setchildren(td, p, flags); + else + ret = protect_setchild(td, p, flags); + if (ret == 0) + return (EPERM); + return (0); +} + +static int +reap_acquire(struct thread *td, struct proc *p) +{ + + sx_assert(&proctree_lock, SX_XLOCKED); + if (p != curproc) + return (EPERM); + if ((p->p_treeflag & P_TREE_REAPER) != 0) + return (EBUSY); + p->p_treeflag |= P_TREE_REAPER; + /* + * We do not reattach existing children and the whole tree + * under them to us, since p->p_reaper already seen them. + */ + return (0); +} + +static int +reap_release(struct thread *td, struct proc *p) +{ + + sx_assert(&proctree_lock, SX_XLOCKED); + if (p != curproc) + return (EPERM); + if (p == initproc) + return (EINVAL); + if ((p->p_treeflag & P_TREE_REAPER) == 0) + return (EINVAL); + reaper_abandon_children(p, false); + return (0); +} + +static int +reap_status(struct thread *td, struct proc *p, + struct procctl_reaper_status *rs) +{ + struct proc *reap, *p2; + + sx_assert(&proctree_lock, SX_LOCKED); + bzero(rs, sizeof(*rs)); + if ((p->p_treeflag & P_TREE_REAPER) == 0) { + reap = p->p_reaper; + } else { + reap = p; + rs->rs_flags |= REAPER_STATUS_OWNED; + } + if (reap == initproc) + rs->rs_flags |= REAPER_STATUS_REALINIT; + rs->rs_reaper = reap->p_pid; + rs->rs_descendants = 0; + rs->rs_children = 0; + if (!LIST_EMPTY(&reap->p_reaplist)) { + KASSERT(!LIST_EMPTY(&reap->p_children), ("no children")); + rs->rs_pid = LIST_FIRST(&reap->p_children)->p_pid; + LIST_FOREACH(p2, &reap->p_reaplist, p_reapsibling) { + if (proc_realparent(p2) == reap) + rs->rs_children++; + rs->rs_descendants++; + } + } else { + rs->rs_pid = -1; + KASSERT(LIST_EMPTY(&reap->p_reaplist), ("reap children list")); + KASSERT(LIST_EMPTY(&reap->p_children), ("children list")); + } + return (0); +} + +static int +reap_getpids(struct thread *td, struct proc *p, struct procctl_reaper_pids *rp) +{ + struct proc *reap, *p2; + struct procctl_reaper_pidinfo *pi, *pip; + u_int i, n; + int error; + + sx_assert(&proctree_lock, SX_LOCKED); + PROC_UNLOCK(p); + reap = (p->p_treeflag & P_TREE_REAPER) == 0 ? p->p_reaper : p; + n = i = 0; + error = 0; + LIST_FOREACH(p2, &reap->p_reaplist, p_reapsibling) + n++; + sx_unlock(&proctree_lock); + if (rp->rp_count < n) + n = rp->rp_count; + pi = malloc(n * sizeof(*pi), M_TEMP, M_WAITOK); + sx_slock(&proctree_lock); + LIST_FOREACH(p2, &reap->p_reaplist, p_reapsibling) { + if (i == n) + break; + pip = &pi[i]; + bzero(pip, sizeof(*pip)); + pip->pi_pid = p2->p_pid; + pip->pi_subtree = p2->p_reapsubtree; + pip->pi_flags = REAPER_PIDINFO_VALID; + if (proc_realparent(p2) == reap) + pip->pi_flags |= REAPER_PIDINFO_CHILD; + i++; + } + sx_sunlock(&proctree_lock); + error = copyout(pi, rp->rp_pids, i * sizeof(*pi)); + free(pi, M_TEMP); + sx_slock(&proctree_lock); + PROC_LOCK(p); + return (error); +} + +static int +reap_kill(struct thread *td, struct proc *p, struct procctl_reaper_kill *rk) +{ + struct proc *reap, *p2; + ksiginfo_t ksi; + int error, error1; + + sx_assert(&proctree_lock, SX_LOCKED); + PROC_UNLOCK(p); + if (IN_CAPABILITY_MODE(td)) + return (ECAPMODE); + if (rk->rk_sig <= 0 || rk->rk_sig > _SIG_MAXSIG) + return (EINVAL); + if ((rk->rk_flags & ~REAPER_KILL_CHILDREN) != 0) + return (EINVAL); + reap = (p->p_treeflag & P_TREE_REAPER) == 0 ? p->p_reaper : p; + ksiginfo_init(&ksi); + ksi.ksi_signo = rk->rk_sig; + ksi.ksi_code = SI_USER; + ksi.ksi_pid = td->td_proc->p_pid; + ksi.ksi_uid = td->td_ucred->cr_ruid; + error = ESRCH; + rk->rk_killed = 0; + rk->rk_fpid = -1; + for (p2 = (rk->rk_flags & REAPER_KILL_CHILDREN) != 0 ? + LIST_FIRST(&reap->p_children) : LIST_FIRST(&reap->p_reaplist); + p2 != NULL; + p2 = (rk->rk_flags & REAPER_KILL_CHILDREN) != 0 ? + LIST_NEXT(p2, p_sibling) : LIST_NEXT(p2, p_reapsibling)) { + if ((rk->rk_flags & REAPER_KILL_SUBTREE) != 0 && + p2->p_reapsubtree != rk->rk_subtree) + continue; + PROC_LOCK(p2); + error1 = p_cansignal(td, p2, rk->rk_sig); + if (error1 == 0) { + pksignal(p2, rk->rk_sig, &ksi); + rk->rk_killed++; + error = error1; + } else if (error == ESRCH) { + error = error1; + rk->rk_fpid = p2->p_pid; + } + PROC_UNLOCK(p2); + /* Do not end the loop on error, signal everything we can. */ + } + PROC_LOCK(p); + return (error); +} + +#ifndef _SYS_SYSPROTO_H_ +struct procctl_args { + idtype_t idtype; + id_t id; + int com; + void *data; +}; +#endif +/* ARGSUSED */ +int +sys_procctl(struct thread *td, struct procctl_args *uap) +{ + void *data; + union { + struct procctl_reaper_status rs; + struct procctl_reaper_pids rp; + struct procctl_reaper_kill rk; + } x; + int error, error1, flags; + + switch (uap->com) { + case PROC_SPROTECT: + error = copyin(uap->data, &flags, sizeof(flags)); + if (error != 0) + return (error); + data = &flags; + break; + case PROC_REAP_ACQUIRE: + case PROC_REAP_RELEASE: + if (uap->data != NULL) + return (EINVAL); + data = NULL; + break; + case PROC_REAP_STATUS: + data = &x.rs; + break; + case PROC_REAP_GETPIDS: + error = copyin(uap->data, &x.rp, sizeof(x.rp)); + if (error != 0) + return (error); + data = &x.rp; + break; + case PROC_REAP_KILL: + error = copyin(uap->data, &x.rk, sizeof(x.rk)); + if (error != 0) + return (error); + data = &x.rk; + break; + default: + return (EINVAL); + } + error = kern_procctl(td, uap->idtype, uap->id, uap->com, data); + switch (uap->com) { + case PROC_REAP_STATUS: + if (error == 0) + error = copyout(&x.rs, uap->data, sizeof(x.rs)); + case PROC_REAP_KILL: + error1 = copyout(&x.rk, uap->data, sizeof(x.rk)); + if (error == 0) + error = error1; + break; + } + return (error); +} + +static int +kern_procctl_single(struct thread *td, struct proc *p, int com, void *data) +{ + + PROC_LOCK_ASSERT(p, MA_OWNED); + switch (com) { + case PROC_SPROTECT: + return (protect_set(td, p, *(int *)data)); + case PROC_REAP_ACQUIRE: + return (reap_acquire(td, p)); + case PROC_REAP_RELEASE: + return (reap_release(td, p)); + case PROC_REAP_STATUS: + return (reap_status(td, p, data)); + case PROC_REAP_GETPIDS: + return (reap_getpids(td, p, data)); + case PROC_REAP_KILL: + return (reap_kill(td, p, data)); + default: + return (EINVAL); + } +} + +int +kern_procctl(struct thread *td, idtype_t idtype, id_t id, int com, void *data) +{ + struct pgrp *pg; + struct proc *p; + int error, first_error, ok; + + switch (com) { + case PROC_REAP_ACQUIRE: + case PROC_REAP_RELEASE: + case PROC_REAP_STATUS: + case PROC_REAP_GETPIDS: + case PROC_REAP_KILL: + if (idtype != P_PID) + return (EINVAL); + } + + switch (com) { + case PROC_SPROTECT: + case PROC_REAP_STATUS: + case PROC_REAP_GETPIDS: + case PROC_REAP_KILL: + sx_slock(&proctree_lock); + break; + case PROC_REAP_ACQUIRE: + case PROC_REAP_RELEASE: + sx_xlock(&proctree_lock); + break; + default: + return (EINVAL); + } + + switch (idtype) { + case P_PID: + p = pfind(id); + if (p == NULL) { + error = ESRCH; + break; + } + error = p_cansee(td, p); + if (error == 0) + error = kern_procctl_single(td, p, com, data); + PROC_UNLOCK(p); + break; + case P_PGID: + /* + * Attempt to apply the operation to all members of the + * group. Ignore processes in the group that can't be + * seen. Ignore errors so long as at least one process is + * able to complete the request successfully. + */ + pg = pgfind(id); + if (pg == NULL) { + error = ESRCH; + break; + } + PGRP_UNLOCK(pg); + ok = 0; + first_error = 0; + LIST_FOREACH(p, &pg->pg_members, p_pglist) { + PROC_LOCK(p); + if (p->p_state == PRS_NEW || p_cansee(td, p) != 0) { + PROC_UNLOCK(p); + continue; + } + error = kern_procctl_single(td, p, com, data); + PROC_UNLOCK(p); + if (error == 0) + ok = 1; + else if (first_error == 0) + first_error = error; + } + if (ok) + error = 0; + else if (first_error != 0) + error = first_error; + else + /* + * Was not able to see any processes in the + * process group. + */ + error = ESRCH; + break; + default: + error = EINVAL; + break; + } + sx_unlock(&proctree_lock); + return (error); +} diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 3105d94d299..7dd3d175436 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -1234,193 +1233,3 @@ stopevent(struct proc *p, unsigned int event, unsigned int val) msleep(&p->p_step, &p->p_mtx, PWAIT, "stopevent", 0); } while (p->p_step); } - -static int -protect_setchild(struct thread *td, struct proc *p, int flags) -{ - - PROC_LOCK_ASSERT(p, MA_OWNED); - if (p->p_flag & P_SYSTEM || p_cansched(td, p) != 0) - return (0); - if (flags & PPROT_SET) { - p->p_flag |= P_PROTECTED; - if (flags & PPROT_INHERIT) - p->p_flag2 |= P2_INHERIT_PROTECTED; - } else { - p->p_flag &= ~P_PROTECTED; - p->p_flag2 &= ~P2_INHERIT_PROTECTED; - } - return (1); -} - -static int -protect_setchildren(struct thread *td, struct proc *top, int flags) -{ - struct proc *p; - int ret; - - p = top; - ret = 0; - sx_assert(&proctree_lock, SX_LOCKED); - for (;;) { - ret |= protect_setchild(td, p, flags); - PROC_UNLOCK(p); - /* - * If this process has children, descend to them next, - * otherwise do any siblings, and if done with this level, - * follow back up the tree (but not past top). - */ - if (!LIST_EMPTY(&p->p_children)) - p = LIST_FIRST(&p->p_children); - else for (;;) { - if (p == top) { - PROC_LOCK(p); - return (ret); - } - if (LIST_NEXT(p, p_sibling)) { - p = LIST_NEXT(p, p_sibling); - break; - } - p = p->p_pptr; - } - PROC_LOCK(p); - } -} - -static int -protect_set(struct thread *td, struct proc *p, int flags) -{ - int error, ret; - - switch (PPROT_OP(flags)) { - case PPROT_SET: - case PPROT_CLEAR: - break; - default: - return (EINVAL); - } - - if ((PPROT_FLAGS(flags) & ~(PPROT_DESCEND | PPROT_INHERIT)) != 0) - return (EINVAL); - - error = priv_check(td, PRIV_VM_MADV_PROTECT); - if (error) - return (error); - - if (flags & PPROT_DESCEND) - ret = protect_setchildren(td, p, flags); - else - ret = protect_setchild(td, p, flags); - if (ret == 0) - return (EPERM); - return (0); -} - -#ifndef _SYS_SYSPROTO_H_ -struct procctl_args { - idtype_t idtype; - id_t id; - int com; - void *data; -}; -#endif -/* ARGSUSED */ -int -sys_procctl(struct thread *td, struct procctl_args *uap) -{ - int error, flags; - void *data; - - switch (uap->com) { - case PROC_SPROTECT: - error = copyin(uap->data, &flags, sizeof(flags)); - if (error) - return (error); - data = &flags; - break; - default: - return (EINVAL); - } - - return (kern_procctl(td, uap->idtype, uap->id, uap->com, data)); -} - -static int -kern_procctl_single(struct thread *td, struct proc *p, int com, void *data) -{ - - PROC_LOCK_ASSERT(p, MA_OWNED); - switch (com) { - case PROC_SPROTECT: - return (protect_set(td, p, *(int *)data)); - default: - return (EINVAL); - } -} - -int -kern_procctl(struct thread *td, idtype_t idtype, id_t id, int com, void *data) -{ - struct pgrp *pg; - struct proc *p; - int error, first_error, ok; - - sx_slock(&proctree_lock); - switch (idtype) { - case P_PID: - p = pfind(id); - if (p == NULL) { - error = ESRCH; - break; - } - error = p_cansee(td, p); - if (error == 0) - error = kern_procctl_single(td, p, com, data); - PROC_UNLOCK(p); - break; - case P_PGID: - /* - * Attempt to apply the operation to all members of the - * group. Ignore processes in the group that can't be - * seen. Ignore errors so long as at least one process is - * able to complete the request successfully. - */ - pg = pgfind(id); - if (pg == NULL) { - error = ESRCH; - break; - } - PGRP_UNLOCK(pg); - ok = 0; - first_error = 0; - LIST_FOREACH(p, &pg->pg_members, p_pglist) { - PROC_LOCK(p); - if (p->p_state == PRS_NEW || p_cansee(td, p) != 0) { - PROC_UNLOCK(p); - continue; - } - error = kern_procctl_single(td, p, com, data); - PROC_UNLOCK(p); - if (error == 0) - ok = 1; - else if (first_error == 0) - first_error = error; - } - if (ok) - error = 0; - else if (first_error != 0) - error = first_error; - else - /* - * Was not able to see any processes in the - * process group. - */ - error = ESRCH; - break; - default: - error = EINVAL; - break; - } - sx_sunlock(&proctree_lock); - return (error); -} diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 6590394f234..d7a45e97286 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -513,6 +513,11 @@ struct proc { struct proc *p_pptr; /* (c + e) Pointer to parent process. */ LIST_ENTRY(proc) p_sibling; /* (e) List of sibling processes. */ LIST_HEAD(, proc) p_children; /* (e) Pointer to list of children. */ + struct proc *p_reaper; /* (e) My reaper. */ + LIST_HEAD(, proc) p_reaplist; /* (e) List of my descendants + (if I am reaper). */ + LIST_ENTRY(proc) p_reapsibling; /* (e) List of siblings - descendants of + the same reaper. */ struct mtx p_mtx; /* (n) Lock for this struct. */ struct mtx p_statmtx; /* Lock for the stats */ struct mtx p_itimmtx; /* Lock for the virt/prof timers */ @@ -570,6 +575,9 @@ struct proc { rlim_t p_cpulimit; /* (c) Current CPU limit in seconds. */ signed char p_nice; /* (c) Process "nice" value. */ int p_fibnum; /* in this routing domain XXX MRT */ + pid_t p_reapsubtree; /* (e) Pid of the direct child of the + reaper which spawned + our subtree. */ /* End area that is copied on creation. */ #define p_endcopy p_xstat @@ -671,6 +679,7 @@ struct proc { #define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */ #define P_TREE_FIRST_ORPHAN 0x00000002 /* First element of orphan list */ +#define P_TREE_REAPER 0x00000004 /* Reaper of subtree */ /* * These were process status values (p_stat), now they are only used in @@ -920,6 +929,7 @@ void proc_reparent(struct proc *child, struct proc *newparent); struct pstats *pstats_alloc(void); void pstats_fork(struct pstats *src, struct pstats *dst); void pstats_free(struct pstats *ps); +void reaper_abandon_children(struct proc *p, bool exiting); int securelevel_ge(struct ucred *cr, int level); int securelevel_gt(struct ucred *cr, int level); void sess_hold(struct session *); diff --git a/sys/sys/procctl.h b/sys/sys/procctl.h index ff577c06be8..d11b2b29600 100644 --- a/sys/sys/procctl.h +++ b/sys/sys/procctl.h @@ -30,7 +30,17 @@ #ifndef _SYS_PROCCTL_H_ #define _SYS_PROCCTL_H_ +#ifndef _KERNEL +#include +#include +#endif + #define PROC_SPROTECT 1 /* set protected state */ +#define PROC_REAP_ACQUIRE 2 /* reaping enable */ +#define PROC_REAP_RELEASE 3 /* reaping disable */ +#define PROC_REAP_STATUS 4 /* reaping status */ +#define PROC_REAP_GETPIDS 5 /* get descendants */ +#define PROC_REAP_KILL 6 /* kill descendants */ /* Operations for PROC_SPROTECT (passed in integer arg). */ #define PPROT_OP(x) ((x) & 0xf) @@ -42,10 +52,51 @@ #define PPROT_DESCEND 0x10 #define PPROT_INHERIT 0x20 -#ifndef _KERNEL -#include -#include +/* Result of PREAP_STATUS (returned by value). */ +struct procctl_reaper_status { + u_int rs_flags; + u_int rs_children; + u_int rs_descendants; + pid_t rs_reaper; + pid_t rs_pid; + u_int rs_pad0[15]; +}; +/* struct procctl_reaper_status rs_flags */ +#define REAPER_STATUS_OWNED 0x00000001 +#define REAPER_STATUS_REALINIT 0x00000002 + +struct procctl_reaper_pidinfo { + pid_t pi_pid; + pid_t pi_subtree; + u_int pi_flags; + u_int pi_pad0[15]; +}; + +#define REAPER_PIDINFO_VALID 0x00000001 +#define REAPER_PIDINFO_CHILD 0x00000002 + +struct procctl_reaper_pids { + u_int rp_count; + u_int rp_pad0[15]; + struct procctl_reaper_pidinfo *rp_pids; +}; + +struct procctl_reaper_kill { + int rk_sig; /* in - signal to send */ + u_int rk_flags; /* in - REAPER_KILL flags */ + pid_t rk_subtree; /* in - subtree, if REAPER_KILL_SUBTREE */ + u_int rk_killed; /* out - count of processes sucessfully + killed */ + pid_t rk_fpid; /* out - first failed pid for which error + is returned */ + u_int rk_pad0[15]; +}; + +#define REAPER_KILL_CHILDREN 0x00000001 +#define REAPER_KILL_SUBTREE 0x00000002 + +#ifndef _KERNEL __BEGIN_DECLS int procctl(idtype_t, id_t, int, void *); __END_DECLS From dd279f7aaa8500219e22891add4786f286f8f505 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Mon, 15 Dec 2014 12:15:18 +0000 Subject: [PATCH 15/64] Fix typo. --- sys/arm/mv/mv_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm/mv/mv_pci.c b/sys/arm/mv/mv_pci.c index 061eaffc86f..42f9218ee81 100644 --- a/sys/arm/mv/mv_pci.c +++ b/sys/arm/mv/mv_pci.c @@ -188,7 +188,7 @@ mv_pci_ranges_decode(phandle_t node, struct mv_pci_range *io_space, par_addr_cells - offset_cells); rangesptr += par_addr_cells - offset_cells; - if (size_cells > 2) + if (size_cells > 2) { rv = ERANGE; goto out; } From a47f6b781a7778989c0263d14fb245a3825c9e88 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Mon, 15 Dec 2014 14:25:42 +0000 Subject: [PATCH 16/64] Remove empty generated file upon gperf failure Prior to this change the build could fail as follows, if gperf is not available (or fails): - make(1) stops due to the gperf error, but an empty target file (cfns.h) is still created - the empty cfns.h is newer than the source cfns.gperf so it is not regenerated on subsequent builds - the gcc build fails (undefined reference to libc_name_p) Sponsored by: The FreeBSD Foundation MFC after: 3 days --- gnu/usr.bin/cc/cc1plus/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnu/usr.bin/cc/cc1plus/Makefile b/gnu/usr.bin/cc/cc1plus/Makefile index 64a07255e01..5d5a64d2e29 100644 --- a/gnu/usr.bin/cc/cc1plus/Makefile +++ b/gnu/usr.bin/cc/cc1plus/Makefile @@ -30,7 +30,7 @@ LDADD= ${LIBBACKEND} ${LIBCPP} ${LIBDECNUMBER} ${LIBIBERTY} # C++ parser cfns.h: cfns.gperf gperf -o -C -E -k '1-6,$$' -j1 -D -N 'libc_name_p' -L ANSI-C \ - ${.ALLSRC} > ${.TARGET} + ${.ALLSRC} > ${.TARGET} || (rm -f ${.TARGET}; false) CLEANFILES= cfns.h DOBJS+= ${SRCS:N*.h:R:S/$/.o/g} From d38b156d2e33ea903adff68b6037cb2faadb109b Mon Sep 17 00:00:00 2001 From: Jun Kuriyama Date: Mon, 15 Dec 2014 14:36:04 +0000 Subject: [PATCH 17/64] Fix incorrect type of "invalids" argument in __iconv() prototype. --- lib/libc/iconv/iconv.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/iconv/iconv.3 b/lib/libc/iconv/iconv.3 index 6692c47d4f7..c4c250d89ed 100644 --- a/lib/libc/iconv/iconv.3 +++ b/lib/libc/iconv/iconv.3 @@ -48,7 +48,7 @@ .Ft size_t .Fn iconv "iconv_t cd" "char ** restrict src" "size_t * restrict srcleft" "char ** restrict dst" "size_t * restrict dstleft" .Ft size_t -.Fn __iconv "iconv_t cd" "const char ** restrict src" "size_t * restrict srcleft" "char ** restrict dst" "size_t * restrict dstleft" "uint32_t flags" "size_t invalids" +.Fn __iconv "iconv_t cd" "const char ** restrict src" "size_t * restrict srcleft" "char ** restrict dst" "size_t * restrict dstleft" "uint32_t flags" "size_t * invalids" .Sh DESCRIPTION The .Fn iconv_open From 19eaed53533257cc33e54258c2b05bef8b8c79ed Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 15 Dec 2014 14:58:10 +0000 Subject: [PATCH 18/64] Markup fixes for kqueue(2), no content changes. Reviewed by: brueffer (previous version) Sponsored by: The FreeBSD Foundation MFC after: 3 days --- lib/libc/sys/kqueue.2 | 148 +++++++++++++++++++++++++----------------- 1 file changed, 87 insertions(+), 61 deletions(-) diff --git a/lib/libc/sys/kqueue.2 b/lib/libc/sys/kqueue.2 index 9a7cc235e0c..93223f1fea6 100644 --- a/lib/libc/sys/kqueue.2 +++ b/lib/libc/sys/kqueue.2 @@ -162,56 +162,56 @@ struct kevent { The fields of .Fa struct kevent are: -.Bl -tag -width XXXfilter -.It ident +.Bl -tag -width "Fa filter" +.It Fa ident Value used to identify this event. The exact interpretation is determined by the attached filter, but often is a file descriptor. -.It filter +.It Fa filter Identifies the kernel filter used to process this event. The pre-defined system filters are described below. -.It flags +.It Fa flags Actions to perform on the event. -.It fflags +.It Fa fflags Filter-specific flags. -.It data +.It Fa data Filter-specific data value. -.It udata +.It Fa udata Opaque user-defined value passed through the kernel unchanged. .El .Pp The .Va flags field can contain the following values: -.Bl -tag -width XXXEV_ONESHOT -.It EV_ADD +.Bl -tag -width EV_DISPATCH +.It Dv EV_ADD Adds the event to the kqueue. Re-adding an existing event will modify the parameters of the original event, and not result in a duplicate entry. Adding an event automatically enables it, unless overridden by the EV_DISABLE flag. -.It EV_ENABLE +.It Dv EV_ENABLE Permit .Fn kevent to return the event if it is triggered. -.It EV_DISABLE +.It Dv EV_DISABLE Disable the event so .Fn kevent will not return it. The filter itself is not disabled. -.It EV_DISPATCH +.It Dv EV_DISPATCH Disable the event source immediately after delivery of an event. See .Dv EV_DISABLE above. -.It EV_DELETE +.It Dv EV_DELETE Removes the event from the kqueue. Events which are attached to file descriptors are automatically deleted on the last close of the descriptor. -.It EV_RECEIPT +.It Dv EV_RECEIPT This flag is useful for making bulk changes to a kqueue without draining any pending events. When passed as input, it forces @@ -220,20 +220,20 @@ to always be returned. When a filter is successfully added the .Va data field will be zero. -.It EV_ONESHOT +.It Dv EV_ONESHOT Causes the event to return only the first occurrence of the filter being triggered. After the user retrieves the event from the kqueue, it is deleted. -.It EV_CLEAR +.It Dv EV_CLEAR After the event is retrieved by the user, its state is reset. This is useful for filters which report state transitions instead of the current state. Note that some filters may automatically set this flag internally. -.It EV_EOF +.It Dv EV_EOF Filters may set this flag to indicate filter-specific EOF condition. -.It EV_ERROR +.It Dv EV_ERROR See .Sx RETURN VALUES below. @@ -245,8 +245,8 @@ Arguments may be passed to and from the filter via the and .Va data fields in the kevent structure. -.Bl -tag -width EVFILT_PROCDESC -.It EVFILT_READ +.Bl -tag -width "Dv EVFILT_PROCDESC" +.It Dv EVFILT_READ Takes a descriptor as the identifier, and returns whenever there is data available to read. The behavior of the filter is slightly different depending @@ -265,7 +265,7 @@ subject to the value of the socket buffer. This may be overridden with a per-filter low water mark at the time the filter is added by setting the -NOTE_LOWAT +.Dv NOTE_LOWAT flag in .Va fflags , and specifying the new low water mark in @@ -275,7 +275,9 @@ On return, contains the number of bytes of protocol data available to read. .Pp If the read direction of the socket has shutdown, then the filter -also sets EV_EOF in +also sets +.Dv EV_EOF +in .Va flags , and returns the socket error (if any) in .Va fflags . @@ -291,9 +293,13 @@ Returns when the there is data to read; .Va data contains the number of bytes available. .Pp -When the last writer disconnects, the filter will set EV_EOF in +When the last writer disconnects, the filter will set +.Dv EV_EOF +in .Va flags . -This may be cleared by passing in EV_CLEAR, at which point the +This may be cleared by passing in +.Dv EV_CLEAR , +at which point the filter will resume waiting for data to become available before returning. .It "BPF devices" @@ -304,7 +310,7 @@ enabled and there is any data to read; .Va data contains the number of bytes available. .El -.It EVFILT_WRITE +.It Dv EVFILT_WRITE Takes a descriptor as the identifier, and returns whenever it is possible to write to the descriptor. For sockets, pipes @@ -312,23 +318,30 @@ and fifos, .Va data will contain the amount of space remaining in the write buffer. The filter will set EV_EOF when the reader disconnects, and for -the fifo case, this may be cleared by use of EV_CLEAR. +the fifo case, this may be cleared by use of +.Dv EV_CLEAR . Note that this filter is not supported for vnodes or BPF devices. .Pp For sockets, the low water mark and socket error handling is -identical to the EVFILT_READ case. -.It EVFILT_AIO +identical to the +.Dv EVFILT_READ +case. +.It Dv EVFILT_AIO The sigevent portion of the AIO request is filled in, with .Va sigev_notify_kqueue containing the descriptor of the kqueue that the event should be attached to, .Va sigev_notify_kevent_flags -containing the kevent flags which should be EV_ONESHOT, EV_CLEAR or -EV_DISPATCH, +containing the kevent flags which should be +.Dv EV_ONESHOT , +.Dv EV_CLEAR +or +.Dv EV_DISPATCH , .Va sigev_value containing the udata value, and .Va sigev_notify -set to SIGEV_KEVENT. +set to +.Dv SIGEV_KEVENT . When the .Fn aio_* system call is made, the event will be registered @@ -339,29 +352,30 @@ argument set to the returned by the .Fn aio_* system call. -The filter returns under the same conditions as aio_error. -.It EVFILT_VNODE +The filter returns under the same conditions as +.Fn aio_error . +.It Dv EVFILT_VNODE Takes a file descriptor as the identifier and the events to watch for in .Va fflags , and returns when one or more of the requested events occurs on the descriptor. The events to monitor are: -.Bl -tag -width XXNOTE_RENAME -.It NOTE_DELETE +.Bl -tag -width "Dv NOTE_RENAME" +.It Dv NOTE_DELETE The .Fn unlink system call was called on the file referenced by the descriptor. -.It NOTE_WRITE +.It Dv NOTE_WRITE A write occurred on the file referenced by the descriptor. -.It NOTE_EXTEND +.It Dv NOTE_EXTEND The file referenced by the descriptor was extended. -.It NOTE_ATTRIB +.It Dv NOTE_ATTRIB The file referenced by the descriptor had its attributes changed. -.It NOTE_LINK +.It Dv NOTE_LINK The link count on the file changed. -.It NOTE_RENAME +.It Dv NOTE_RENAME The file referenced by the descriptor was renamed. -.It NOTE_REVOKE +.It Dv NOTE_REVOKE Access to the file was revoked via .Xr revoke 2 or the underlying file system was unmounted. @@ -370,26 +384,26 @@ or the underlying file system was unmounted. On return, .Va fflags contains the events which triggered the filter. -.It EVFILT_PROC +.It Dv EVFILT_PROC Takes the process ID to monitor as the identifier and the events to watch for in .Va fflags , and returns when the process performs one or more of the requested events. If a process can normally see another process, it can attach an event to it. The events to monitor are: -.Bl -tag -width XXNOTE_TRACKERR -.It NOTE_EXIT +.Bl -tag -width "Dv NOTE_TRACKERR" +.It Dv NOTE_EXIT The process has exited. The exit status will be stored in .Va data . -.It NOTE_FORK +.It Dv NOTE_FORK The process has called .Fn fork . -.It NOTE_EXEC +.It Dv NOTE_EXEC The process has executed a new process via .Xr execve 2 or a similar call. -.It NOTE_TRACK +.It Dv NOTE_TRACK Follow a process across .Fn fork calls. @@ -397,22 +411,28 @@ The parent process registers a new kevent to monitor the child process using the same .Va fflags as the original event. -The child process will signal an event with NOTE_CHILD set in +The child process will signal an event with +.Dv NOTE_CHILD +set in .Va fflags and the parent PID in .Va data . .Pp If the parent process fails to register a new kevent .Pq usually due to resource limitations , -it will signal an event with NOTE_TRACKERR set in +it will signal an event with +.Dv NOTE_TRACKERR +set in .Va fflags , -and the child process will not signal a NOTE_CHILD event. +and the child process will not signal a +.Dv NOTE_CHILD +event. .El .Pp On return, .Va fflags contains the events which triggered the filter. -.It EVFILT_PROCDESC +.It Dv EVFILT_PROCDESC Takes the process descriptor created by .Xr pdfork 2 to monitor as the identifier and the events to watch for in @@ -420,8 +440,8 @@ to monitor as the identifier and the events to watch for in and returns when the associated process performs one or more of the requested events. The events to monitor are: -.Bl -tag -width XXNOTE_EXIT -.It NOTE_EXIT +.Bl -tag -width "Dv NOTE_EXIT" +.It Dv NOTE_EXIT The process has exited. The exit status will be stored in .Va data . @@ -430,7 +450,7 @@ The exit status will be stored in On return, .Va fflags contains the events which triggered the filter. -.It EVFILT_SIGNAL +.It Dv EVFILT_SIGNAL Takes the signal number to monitor as the identifier and returns when the given signal is delivered to the process. This coexists with the @@ -440,7 +460,9 @@ and facilities, and has a lower precedence. The filter will record all attempts to deliver a signal to a process, even if the signal has -been marked as SIG_IGN, except for the +been marked as +.Dv SIG_IGN , +except for the .Dv SIGCHLD signal, which, if ignored, won't be recorded by the filter. Event notification happens after normal @@ -448,14 +470,18 @@ signal delivery processing. .Va data returns the number of times the signal has occurred since the last call to .Fn kevent . -This filter automatically sets the EV_CLEAR flag internally. -.It EVFILT_TIMER +This filter automatically sets the +.Dv EV_CLEAR +flag internally. +.It Dv EVFILT_TIMER Establishes an arbitrary timer identified by .Va ident . When adding a timer, .Va data specifies the timeout period. -The timer will be periodic unless EV_ONESHOT is specified. +The timer will be periodic unless +.Dv EV_ONESHOT +is specified. On return, .Va data contains the number of times the timeout has expired since the last call to @@ -465,7 +491,7 @@ There is a system wide limit on the number of timers which is controlled by the .Va kern.kq_calloutmax sysctl. -.Bl -tag -width XXNOTE_USECONDS +.Bl -tag -width "Dv NOTE_USECONDS" .It Dv NOTE_SECONDS .Va data is in seconds. @@ -493,7 +519,7 @@ user level code. The lower 24 bits of the .Va fflags may be used for user defined flags and manipulated using the following: -.Bl -tag -width XXNOTE_FFLAGSMASK +.Bl -tag -width "Dv NOTE_FFLAGSMASK" .It Dv NOTE_FFNOP Ignore the input .Va fflags . @@ -515,7 +541,7 @@ User defined flag mask for .El .Pp A user event is triggered for output with the following: -.Bl -tag -width XXNOTE_FFLAGSMASK +.Bl -tag -width "Dv NOTE_FFLAGSMASK" .It Dv NOTE_TRIGGER Cause the event to be triggered. .El From 5ad25ceb41ef72e78cf65f3ce8495b54f23c687e Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 15 Dec 2014 17:52:08 +0000 Subject: [PATCH 19/64] Check for SS_NBIO in so->so_state instead of sb->sb_flags in soreceive_stream(). Differential Revision: https://reviews.freebsd.org/D1299 Reviewed by: bz, gnn MFC after: 1 week --- sys/dev/cxgbe/tom/t4_ddp.c | 2 +- sys/kern/uipc_socket.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/cxgbe/tom/t4_ddp.c b/sys/dev/cxgbe/tom/t4_ddp.c index 17eb071b3cb..08c3224e213 100644 --- a/sys/dev/cxgbe/tom/t4_ddp.c +++ b/sys/dev/cxgbe/tom/t4_ddp.c @@ -1173,7 +1173,7 @@ restart: /* Socket buffer got some data that we shall deliver now. */ if (sbused(sb) && !(flags & MSG_WAITALL) && - ((sb->sb_flags & SS_NBIO) || + ((so->so_state & SS_NBIO) || (flags & (MSG_DONTWAIT|MSG_NBIO)) || sbused(sb) >= sb->sb_lowat || sbused(sb) >= uio->uio_resid || diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index b2091ea2841..f08036d6336 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -2002,7 +2002,7 @@ restart: /* Socket buffer got some data that we shall deliver now. */ if (sbavail(sb) > 0 && !(flags & MSG_WAITALL) && - ((sb->sb_flags & SS_NBIO) || + ((so->so_state & SS_NBIO) || (flags & (MSG_DONTWAIT|MSG_NBIO)) || sbavail(sb) >= sb->sb_lowat || sbavail(sb) >= uio->uio_resid || From 30568ad37ebd7a2afd7e00e091c1b5971a735679 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Mon, 15 Dec 2014 18:18:57 +0000 Subject: [PATCH 20/64] Correct elftoolchain strip(1) memory size calculation Calculate the segment's memory size (p_memsz) using the virtual addresses, not the file offsets. Otherwise padding preceeding SHT_NOBITS sections may be excluded from the calculation, resulting in a segment that is too small. PR: 195653 Sponsored by: The FreeBSD Foundation --- contrib/elftoolchain/elfcopy/segments.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/elftoolchain/elfcopy/segments.c b/contrib/elftoolchain/elfcopy/segments.c index 853c728e8f3..d358e5c3695 100644 --- a/contrib/elftoolchain/elfcopy/segments.c +++ b/contrib/elftoolchain/elfcopy/segments.c @@ -439,7 +439,7 @@ copy_phdr(struct elfcopy *ecp) seg->fsz = seg->msz = 0; for (i = 0; i < seg->nsec; i++) { s = seg->v_sec[i]; - seg->msz = s->off + s->sz - seg->off; + seg->msz = s->vma + s->sz - seg->addr; if (s->type != SHT_NOBITS) seg->fsz = seg->msz; } From 9972df7d1366b8ca0f2a3fcfec59ad7862f8c999 Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Mon, 15 Dec 2014 20:48:06 +0000 Subject: [PATCH 21/64] Properly sort Xr to silence mandoc warnings. Differential Revision: https://reviews.freebsd.org/D1314 Reviewed by: wblock MFC after: 1 Month --- share/man/man9/rmlock.9 | 2 +- share/man/man9/sx.9 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/share/man/man9/rmlock.9 b/share/man/man9/rmlock.9 index da8234b0cdd..ee033a6bc6b 100644 --- a/share/man/man9/rmlock.9 +++ b/share/man/man9/rmlock.9 @@ -289,8 +289,8 @@ Assert that the current thread does not hold a recursive lock of .Xr mutex 9 , .Xr panic 9 , .Xr rwlock 9 , -.Xr sleep 9 , .Xr sema 9 , +.Xr sleep 9 , .Xr sx 9 .Sh HISTORY These diff --git a/share/man/man9/sx.9 b/share/man/man9/sx.9 index 01fffaae7e1..49a064e3989 100644 --- a/share/man/man9/sx.9 +++ b/share/man/man9/sx.9 @@ -315,8 +315,8 @@ lock while another thread blocked on the same lock after acquiring a mutex, then the second thread would effectively end up sleeping while holding a mutex, which is not allowed. .Sh SEE ALSO -.Xr locking 9 , .Xr lock 9 , +.Xr locking 9 , .Xr mutex 9 , .Xr panic 9 , .Xr rwlock 9 , From 55629a87ab4f48eed4839de2283b3db98fe0103c Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Mon, 15 Dec 2014 22:20:14 +0000 Subject: [PATCH 22/64] Use standard BSD license disclaimer text Approved by: benno, nwhitehorn --- sys/dev/ofw/ofw_cpu.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/sys/dev/ofw/ofw_cpu.c b/sys/dev/ofw/ofw_cpu.c index e830e3e9b3a..226514059d5 100644 --- a/sys/dev/ofw/ofw_cpu.c +++ b/sys/dev/ofw/ofw_cpu.c @@ -11,16 +11,17 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #include From e01343ccd72bf1a09cee54dc2bf805fc14a24023 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Tue, 16 Dec 2014 06:13:30 +0000 Subject: [PATCH 23/64] Fix a bug introdiced in r217548. According to NS DP83815 data sheet, RX filter should be disabled before programming. Previously it was clearing wrong bits so RX filter was not disabled in RX filter configuration. Reported by: brad@OpenBSD.org --- sys/dev/sis/if_sis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/sis/if_sis.c b/sys/dev/sis/if_sis.c index f7e6f3ba444..520642f13ba 100644 --- a/sys/dev/sis/if_sis.c +++ b/sys/dev/sis/if_sis.c @@ -780,7 +780,7 @@ sis_rxfilter_sis(struct sis_softc *sc) filter = CSR_READ_4(sc, SIS_RXFILT_CTL); if (filter & SIS_RXFILTCTL_ENABLE) { - CSR_WRITE_4(sc, SIS_RXFILT_CTL, filter & ~SIS_RXFILT_CTL); + CSR_WRITE_4(sc, SIS_RXFILT_CTL, filter & ~SIS_RXFILTCTL_ENABLE); CSR_READ_4(sc, SIS_RXFILT_CTL); } filter &= ~(SIS_RXFILTCTL_ALLPHYS | SIS_RXFILTCTL_BROAD | From 09eced2549e92b5fbc11d825804aa2e16ce72059 Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Tue, 16 Dec 2014 06:33:57 +0000 Subject: [PATCH 24/64] For level triggered interrupts clear the PIC IRR bit when the interrupt pin is deasserted. Prior to this change each assertion on a level triggered irq pin resulted in two interrupts being delivered to the CPU. Differential Revision: https://reviews.freebsd.org/D1310 Reviewed by: tychon MFC after: 1 week --- sys/amd64/vmm/io/vatpic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/amd64/vmm/io/vatpic.c b/sys/amd64/vmm/io/vatpic.c index 54d8155611c..deef5a2ccbe 100644 --- a/sys/amd64/vmm/io/vatpic.c +++ b/sys/amd64/vmm/io/vatpic.c @@ -388,6 +388,8 @@ vatpic_set_pinstate(struct vatpic *vatpic, int pin, bool newstate) } else if (oldcnt == 1 && newcnt == 0) { /* falling edge */ VATPIC_CTR1(vatpic, "atpic pin%d: deasserted", pin); + if (level) + atpic->request &= ~(1 << (pin & 0x7)); } else { VATPIC_CTR3(vatpic, "atpic pin%d: %s, ignored, acnt %d", pin, newstate ? "asserted" : "deasserted", newcnt); From c7d73a4d23fe6884a49b0a4eb8734aa8a153bef4 Mon Sep 17 00:00:00 2001 From: Gleb Kurtsou Date: Tue, 16 Dec 2014 08:29:02 +0000 Subject: [PATCH 25/64] sbin/shutdown: Support time units as in 'shutdown -r +5sec' Units supported: s, sec, m, min, h, hour. Differential Revision: https://reviews.freebsd.org/D1272 --- sbin/shutdown/shutdown.8 | 11 ++++++++++- sbin/shutdown/shutdown.c | 24 ++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/sbin/shutdown/shutdown.8 b/sbin/shutdown/shutdown.8 index 871efbed8b0..4145ba5b64d 100644 --- a/sbin/shutdown/shutdown.8 +++ b/sbin/shutdown/shutdown.8 @@ -28,7 +28,7 @@ .\" @(#)shutdown.8 8.2 (Berkeley) 4/27/95 .\" $FreeBSD$ .\" -.Dd March 19, 2013 +.Dd December 15, 2014 .Dt SHUTDOWN 8 .Os .Sh NAME @@ -118,6 +118,15 @@ to the current system values. The first form brings the system down in .Ar number minutes and the second at the absolute time specified. +.Ar +number +may be specified in units other than minutes by appending the corresponding +suffix: +.Dq Li s , +.Dq Li sec , +.Dq Li m , +.Dq Li min . +.Dq Li h , +.Dq Li hour . .It Ar warning-message Any other arguments comprise the warning message that is broadcast to users currently logged into the system. diff --git a/sbin/shutdown/shutdown.c b/sbin/shutdown/shutdown.c index f53b3d8c98f..b04e0bd87de 100644 --- a/sbin/shutdown/shutdown.c +++ b/sbin/shutdown/shutdown.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -322,7 +323,8 @@ timewarn(int timeleft) (void)fprintf(pf, "System going down in %d minute%s\n\n", timeleft / 60, (timeleft > 60) ? "s" : ""); else if (timeleft) - (void)fprintf(pf, "System going down in 30 seconds\n\n"); + (void)fprintf(pf, "System going down in %s30 seconds\n\n", + (offset > 0 && offset < 30 ? "less than " : "")); else (void)fprintf(pf, "System going down IMMEDIATELY\n\n"); @@ -415,6 +417,7 @@ getoffset(char *timearg) char *p; time_t now; int this_year; + char *timeunit; (void)time(&now); @@ -427,8 +430,25 @@ getoffset(char *timearg) if (*timearg == '+') { /* +minutes */ if (!isdigit(*++timearg)) badtime(); - if ((offset = atoi(timearg) * 60) < 0) + errno = 0; + offset = strtol(timearg, &timeunit, 10); + if (offset < 0 || offset == LONG_MAX || errno != 0) badtime(); + if (timeunit[0] == '\0' || strcasecmp(timeunit, "m") == 0 || + strcasecmp(timeunit, "min") == 0 || + strcasecmp(timeunit, "mins") == 0) { + offset *= 60; + } else if (strcasecmp(timeunit, "h") == 0 || + strcasecmp(timeunit, "hour") == 0 || + strcasecmp(timeunit, "hours") == 0) { + offset *= 60 * 60; + } else if (strcasecmp(timeunit, "s") == 0 || + strcasecmp(timeunit, "sec") == 0 || + strcasecmp(timeunit, "secs") == 0) { + offset *= 1; + } else { + badtime(); + } shuttime = now + offset; return; } From 2cec876a59a7c5396e3df7e21e82091cd461a94a Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Tue, 16 Dec 2014 09:21:56 +0000 Subject: [PATCH 26/64] Rename cpack*() to CMPLX*(). The C11 standard introduced a set of macros (CMPLX, CMPLXF, CMPLXL) that can be used to construct complex numbers from a pair of real and imaginary numbers. Unfortunately, they require some compiler support, which is why we only define them for Clang and GCC>=4.7. The cpack() function in libm performs the same task as CMPLX(), but cannot be used to generate compile-time constants. This means that all invocations of cpack() can safely be replaced by C11's CMPLX(). To keep the code building with GCC 4.2, provide copies of CMPLX() that can at least be used to generate run-time complex numbers. This makes it easier to build some of the functions outside of libm. --- lib/msun/ld128/k_expl.h | 2 +- lib/msun/ld80/k_expl.h | 2 +- lib/msun/src/catrig.c | 64 ++++++++++++++++++------------------- lib/msun/src/catrigf.c | 64 ++++++++++++++++++------------------- lib/msun/src/k_exp.c | 2 +- lib/msun/src/k_expf.c | 2 +- lib/msun/src/math_private.h | 19 +++++++++-- lib/msun/src/s_ccosh.c | 28 ++++++++-------- lib/msun/src/s_ccoshf.c | 28 ++++++++-------- lib/msun/src/s_cexp.c | 12 +++---- lib/msun/src/s_cexpf.c | 12 +++---- lib/msun/src/s_conj.c | 2 +- lib/msun/src/s_conjf.c | 2 +- lib/msun/src/s_conjl.c | 2 +- lib/msun/src/s_cproj.c | 2 +- lib/msun/src/s_cprojf.c | 2 +- lib/msun/src/s_cprojl.c | 2 +- lib/msun/src/s_csinh.c | 30 ++++++++--------- lib/msun/src/s_csinhf.c | 30 ++++++++--------- lib/msun/src/s_csqrt.c | 14 ++++---- lib/msun/src/s_csqrtf.c | 14 ++++---- lib/msun/src/s_csqrtl.c | 14 ++++---- lib/msun/src/s_ctanh.c | 14 ++++---- lib/msun/src/s_ctanhf.c | 14 ++++---- 24 files changed, 195 insertions(+), 182 deletions(-) diff --git a/lib/msun/ld128/k_expl.h b/lib/msun/ld128/k_expl.h index a5668fd47c5..e0a48fc2093 100644 --- a/lib/msun/ld128/k_expl.h +++ b/lib/msun/ld128/k_expl.h @@ -322,7 +322,7 @@ __ldexp_cexpl(long double complex z, int expt) scale2 = 1; SET_LDBL_EXPSIGN(scale1, BIAS + expt - half_expt); - return (cpackl(cos(y) * exp_x * scale1 * scale2, + return (CMPLXL(cos(y) * exp_x * scale1 * scale2, sinl(y) * exp_x * scale1 * scale2)); } #endif /* _COMPLEX_H */ diff --git a/lib/msun/ld80/k_expl.h b/lib/msun/ld80/k_expl.h index ebfb9a8749d..9b081faf033 100644 --- a/lib/msun/ld80/k_expl.h +++ b/lib/msun/ld80/k_expl.h @@ -299,7 +299,7 @@ __ldexp_cexpl(long double complex z, int expt) scale2 = 1; SET_LDBL_EXPSIGN(scale1, BIAS + expt - half_expt); - return (cpackl(cos(y) * exp_x * scale1 * scale2, + return (CMPLXL(cos(y) * exp_x * scale1 * scale2, sinl(y) * exp_x * scale1 * scale2)); } #endif /* _COMPLEX_H */ diff --git a/lib/msun/src/catrig.c b/lib/msun/src/catrig.c index 200977c0af4..c0f5f55079f 100644 --- a/lib/msun/src/catrig.c +++ b/lib/msun/src/catrig.c @@ -286,19 +286,19 @@ casinh(double complex z) if (isnan(x) || isnan(y)) { /* casinh(+-Inf + I*NaN) = +-Inf + I*NaN */ if (isinf(x)) - return (cpack(x, y + y)); + return (CMPLX(x, y + y)); /* casinh(NaN + I*+-Inf) = opt(+-)Inf + I*NaN */ if (isinf(y)) - return (cpack(y, x + x)); + return (CMPLX(y, x + x)); /* casinh(NaN + I*0) = NaN + I*0 */ if (y == 0) - return (cpack(x + x, y)); + return (CMPLX(x + x, y)); /* * All other cases involving NaN return NaN + I*NaN. * C99 leaves it optional whether to raise invalid if one of * the arguments is not NaN, so we opt not to raise it. */ - return (cpack(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); + return (CMPLX(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); } if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) { @@ -307,7 +307,7 @@ casinh(double complex z) w = clog_for_large_values(z) + m_ln2; else w = clog_for_large_values(-z) + m_ln2; - return (cpack(copysign(creal(w), x), copysign(cimag(w), y))); + return (CMPLX(copysign(creal(w), x), copysign(cimag(w), y))); } /* Avoid spuriously raising inexact for z = 0. */ @@ -325,7 +325,7 @@ casinh(double complex z) ry = asin(B); else ry = atan2(new_y, sqrt_A2my2); - return (cpack(copysign(rx, x), copysign(ry, y))); + return (CMPLX(copysign(rx, x), copysign(ry, y))); } /* @@ -335,9 +335,9 @@ casinh(double complex z) double complex casin(double complex z) { - double complex w = casinh(cpack(cimag(z), creal(z))); + double complex w = casinh(CMPLX(cimag(z), creal(z))); - return (cpack(cimag(w), creal(w))); + return (CMPLX(cimag(w), creal(w))); } /* @@ -370,19 +370,19 @@ cacos(double complex z) if (isnan(x) || isnan(y)) { /* cacos(+-Inf + I*NaN) = NaN + I*opt(-)Inf */ if (isinf(x)) - return (cpack(y + y, -INFINITY)); + return (CMPLX(y + y, -INFINITY)); /* cacos(NaN + I*+-Inf) = NaN + I*-+Inf */ if (isinf(y)) - return (cpack(x + x, -y)); + return (CMPLX(x + x, -y)); /* cacos(0 + I*NaN) = PI/2 + I*NaN with inexact */ if (x == 0) - return (cpack(pio2_hi + pio2_lo, y + y)); + return (CMPLX(pio2_hi + pio2_lo, y + y)); /* * All other cases involving NaN return NaN + I*NaN. * C99 leaves it optional whether to raise invalid if one of * the arguments is not NaN, so we opt not to raise it. */ - return (cpack(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); + return (CMPLX(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); } if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) { @@ -392,18 +392,18 @@ cacos(double complex z) ry = creal(w) + m_ln2; if (sy == 0) ry = -ry; - return (cpack(rx, ry)); + return (CMPLX(rx, ry)); } /* Avoid spuriously raising inexact for z = 1. */ if (x == 1 && y == 0) - return (cpack(0, -y)); + return (CMPLX(0, -y)); /* All remaining cases are inexact. */ raise_inexact(); if (ax < SQRT_6_EPSILON / 4 && ay < SQRT_6_EPSILON / 4) - return (cpack(pio2_hi - (x - pio2_lo), -y)); + return (CMPLX(pio2_hi - (x - pio2_lo), -y)); do_hard_work(ay, ax, &ry, &B_is_usable, &B, &sqrt_A2mx2, &new_x); if (B_is_usable) { @@ -419,7 +419,7 @@ cacos(double complex z) } if (sy == 0) ry = -ry; - return (cpack(rx, ry)); + return (CMPLX(rx, ry)); } /* @@ -437,15 +437,15 @@ cacosh(double complex z) ry = cimag(w); /* cacosh(NaN + I*NaN) = NaN + I*NaN */ if (isnan(rx) && isnan(ry)) - return (cpack(ry, rx)); + return (CMPLX(ry, rx)); /* cacosh(NaN + I*+-Inf) = +Inf + I*NaN */ /* cacosh(+-Inf + I*NaN) = +Inf + I*NaN */ if (isnan(rx)) - return (cpack(fabs(ry), rx)); + return (CMPLX(fabs(ry), rx)); /* cacosh(0 + I*NaN) = NaN + I*NaN */ if (isnan(ry)) - return (cpack(ry, ry)); - return (cpack(fabs(ry), copysign(rx, cimag(z)))); + return (CMPLX(ry, ry)); + return (CMPLX(fabs(ry), copysign(rx, cimag(z)))); } /* @@ -475,16 +475,16 @@ clog_for_large_values(double complex z) * this method is still poor since it is uneccessarily slow. */ if (ax > DBL_MAX / 2) - return (cpack(log(hypot(x / m_e, y / m_e)) + 1, atan2(y, x))); + return (CMPLX(log(hypot(x / m_e, y / m_e)) + 1, atan2(y, x))); /* * Avoid overflow when x or y is large. Avoid underflow when x or * y is small. */ if (ax > QUARTER_SQRT_MAX || ay < SQRT_MIN) - return (cpack(log(hypot(x, y)), atan2(y, x))); + return (CMPLX(log(hypot(x, y)), atan2(y, x))); - return (cpack(log(ax * ax + ay * ay) / 2, atan2(y, x))); + return (CMPLX(log(ax * ax + ay * ay) / 2, atan2(y, x))); } /* @@ -575,30 +575,30 @@ catanh(double complex z) /* This helps handle many cases. */ if (y == 0 && ax <= 1) - return (cpack(atanh(x), y)); + return (CMPLX(atanh(x), y)); /* To ensure the same accuracy as atan(), and to filter out z = 0. */ if (x == 0) - return (cpack(x, atan(y))); + return (CMPLX(x, atan(y))); if (isnan(x) || isnan(y)) { /* catanh(+-Inf + I*NaN) = +-0 + I*NaN */ if (isinf(x)) - return (cpack(copysign(0, x), y + y)); + return (CMPLX(copysign(0, x), y + y)); /* catanh(NaN + I*+-Inf) = sign(NaN)0 + I*+-PI/2 */ if (isinf(y)) - return (cpack(copysign(0, x), + return (CMPLX(copysign(0, x), copysign(pio2_hi + pio2_lo, y))); /* * All other cases involving NaN return NaN + I*NaN. * C99 leaves it optional whether to raise invalid if one of * the arguments is not NaN, so we opt not to raise it. */ - return (cpack(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); + return (CMPLX(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); } if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) - return (cpack(real_part_reciprocal(x, y), + return (CMPLX(real_part_reciprocal(x, y), copysign(pio2_hi + pio2_lo, y))); if (ax < SQRT_3_EPSILON / 2 && ay < SQRT_3_EPSILON / 2) { @@ -623,7 +623,7 @@ catanh(double complex z) else ry = atan2(2 * ay, (1 - ax) * (1 + ax) - ay * ay) / 2; - return (cpack(copysign(rx, x), copysign(ry, y))); + return (CMPLX(copysign(rx, x), copysign(ry, y))); } /* @@ -633,7 +633,7 @@ catanh(double complex z) double complex catan(double complex z) { - double complex w = catanh(cpack(cimag(z), creal(z))); + double complex w = catanh(CMPLX(cimag(z), creal(z))); - return (cpack(cimag(w), creal(w))); + return (CMPLX(cimag(w), creal(w))); } diff --git a/lib/msun/src/catrigf.c b/lib/msun/src/catrigf.c index 08ebef78366..ca84ce2a99a 100644 --- a/lib/msun/src/catrigf.c +++ b/lib/msun/src/catrigf.c @@ -156,12 +156,12 @@ casinhf(float complex z) if (isnan(x) || isnan(y)) { if (isinf(x)) - return (cpackf(x, y + y)); + return (CMPLXF(x, y + y)); if (isinf(y)) - return (cpackf(y, x + x)); + return (CMPLXF(y, x + x)); if (y == 0) - return (cpackf(x + x, y)); - return (cpackf(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); + return (CMPLXF(x + x, y)); + return (CMPLXF(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); } if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) { @@ -169,7 +169,7 @@ casinhf(float complex z) w = clog_for_large_values(z) + m_ln2; else w = clog_for_large_values(-z) + m_ln2; - return (cpackf(copysignf(crealf(w), x), + return (CMPLXF(copysignf(crealf(w), x), copysignf(cimagf(w), y))); } @@ -186,15 +186,15 @@ casinhf(float complex z) ry = asinf(B); else ry = atan2f(new_y, sqrt_A2my2); - return (cpackf(copysignf(rx, x), copysignf(ry, y))); + return (CMPLXF(copysignf(rx, x), copysignf(ry, y))); } float complex casinf(float complex z) { - float complex w = casinhf(cpackf(cimagf(z), crealf(z))); + float complex w = casinhf(CMPLXF(cimagf(z), crealf(z))); - return (cpackf(cimagf(w), crealf(w))); + return (CMPLXF(cimagf(w), crealf(w))); } float complex @@ -214,12 +214,12 @@ cacosf(float complex z) if (isnan(x) || isnan(y)) { if (isinf(x)) - return (cpackf(y + y, -INFINITY)); + return (CMPLXF(y + y, -INFINITY)); if (isinf(y)) - return (cpackf(x + x, -y)); + return (CMPLXF(x + x, -y)); if (x == 0) - return (cpackf(pio2_hi + pio2_lo, y + y)); - return (cpackf(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); + return (CMPLXF(pio2_hi + pio2_lo, y + y)); + return (CMPLXF(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); } if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) { @@ -228,16 +228,16 @@ cacosf(float complex z) ry = crealf(w) + m_ln2; if (sy == 0) ry = -ry; - return (cpackf(rx, ry)); + return (CMPLXF(rx, ry)); } if (x == 1 && y == 0) - return (cpackf(0, -y)); + return (CMPLXF(0, -y)); raise_inexact(); if (ax < SQRT_6_EPSILON / 4 && ay < SQRT_6_EPSILON / 4) - return (cpackf(pio2_hi - (x - pio2_lo), -y)); + return (CMPLXF(pio2_hi - (x - pio2_lo), -y)); do_hard_work(ay, ax, &ry, &B_is_usable, &B, &sqrt_A2mx2, &new_x); if (B_is_usable) { @@ -253,7 +253,7 @@ cacosf(float complex z) } if (sy == 0) ry = -ry; - return (cpackf(rx, ry)); + return (CMPLXF(rx, ry)); } float complex @@ -266,12 +266,12 @@ cacoshf(float complex z) rx = crealf(w); ry = cimagf(w); if (isnan(rx) && isnan(ry)) - return (cpackf(ry, rx)); + return (CMPLXF(ry, rx)); if (isnan(rx)) - return (cpackf(fabsf(ry), rx)); + return (CMPLXF(fabsf(ry), rx)); if (isnan(ry)) - return (cpackf(ry, ry)); - return (cpackf(fabsf(ry), copysignf(rx, cimagf(z)))); + return (CMPLXF(ry, ry)); + return (CMPLXF(fabsf(ry), copysignf(rx, cimagf(z)))); } static float complex @@ -291,13 +291,13 @@ clog_for_large_values(float complex z) } if (ax > FLT_MAX / 2) - return (cpackf(logf(hypotf(x / m_e, y / m_e)) + 1, + return (CMPLXF(logf(hypotf(x / m_e, y / m_e)) + 1, atan2f(y, x))); if (ax > QUARTER_SQRT_MAX || ay < SQRT_MIN) - return (cpackf(logf(hypotf(x, y)), atan2f(y, x))); + return (CMPLXF(logf(hypotf(x, y)), atan2f(y, x))); - return (cpackf(logf(ax * ax + ay * ay) / 2, atan2f(y, x))); + return (CMPLXF(logf(ax * ax + ay * ay) / 2, atan2f(y, x))); } static inline float @@ -346,22 +346,22 @@ catanhf(float complex z) ay = fabsf(y); if (y == 0 && ax <= 1) - return (cpackf(atanhf(x), y)); + return (CMPLXF(atanhf(x), y)); if (x == 0) - return (cpackf(x, atanf(y))); + return (CMPLXF(x, atanf(y))); if (isnan(x) || isnan(y)) { if (isinf(x)) - return (cpackf(copysignf(0, x), y + y)); + return (CMPLXF(copysignf(0, x), y + y)); if (isinf(y)) - return (cpackf(copysignf(0, x), + return (CMPLXF(copysignf(0, x), copysignf(pio2_hi + pio2_lo, y))); - return (cpackf(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); + return (CMPLXF(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); } if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) - return (cpackf(real_part_reciprocal(x, y), + return (CMPLXF(real_part_reciprocal(x, y), copysignf(pio2_hi + pio2_lo, y))); if (ax < SQRT_3_EPSILON / 2 && ay < SQRT_3_EPSILON / 2) { @@ -381,13 +381,13 @@ catanhf(float complex z) else ry = atan2f(2 * ay, (1 - ax) * (1 + ax) - ay * ay) / 2; - return (cpackf(copysignf(rx, x), copysignf(ry, y))); + return (CMPLXF(copysignf(rx, x), copysignf(ry, y))); } float complex catanf(float complex z) { - float complex w = catanhf(cpackf(cimagf(z), crealf(z))); + float complex w = catanhf(CMPLXF(cimagf(z), crealf(z))); - return (cpackf(cimagf(w), crealf(w))); + return (CMPLXF(cimagf(w), crealf(w))); } diff --git a/lib/msun/src/k_exp.c b/lib/msun/src/k_exp.c index f592f69aa00..ecef54c0f3c 100644 --- a/lib/msun/src/k_exp.c +++ b/lib/msun/src/k_exp.c @@ -103,6 +103,6 @@ __ldexp_cexp(double complex z, int expt) half_expt = expt - half_expt; INSERT_WORDS(scale2, (0x3ff + half_expt) << 20, 0); - return (cpack(cos(y) * exp_x * scale1 * scale2, + return (CMPLX(cos(y) * exp_x * scale1 * scale2, sin(y) * exp_x * scale1 * scale2)); } diff --git a/lib/msun/src/k_expf.c b/lib/msun/src/k_expf.c index 548a008f86b..f8c254d1d5b 100644 --- a/lib/msun/src/k_expf.c +++ b/lib/msun/src/k_expf.c @@ -82,6 +82,6 @@ __ldexp_cexpf(float complex z, int expt) half_expt = expt - half_expt; SET_FLOAT_WORD(scale2, (0x7f + half_expt) << 23); - return (cpackf(cosf(y) * exp_x * scale1 * scale2, + return (CMPLXF(cosf(y) * exp_x * scale1 * scale2, sinf(y) * exp_x * scale1 * scale2)); } diff --git a/lib/msun/src/math_private.h b/lib/msun/src/math_private.h index 8af2c650e77..083197e1b94 100644 --- a/lib/msun/src/math_private.h +++ b/lib/msun/src/math_private.h @@ -454,9 +454,16 @@ typedef union { * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product. * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted * to -0.0+I*0.0. + * + * The C11 standard introduced the macros CMPLX(), CMPLXF() and CMPLXL() + * to construct complex values. The functions below are modelled after + * these macros, with the exception that they cannot be used to + * construct compile-time complex values. */ + +#ifndef CMPLXF static __inline float complex -cpackf(float x, float y) +CMPLXF(float x, float y) { float_complex z; @@ -464,9 +471,11 @@ cpackf(float x, float y) IMAGPART(z) = y; return (z.f); } +#endif +#ifndef CMPLX static __inline double complex -cpack(double x, double y) +CMPLX(double x, double y) { double_complex z; @@ -474,9 +483,11 @@ cpack(double x, double y) IMAGPART(z) = y; return (z.f); } +#endif +#ifndef CMPLXL static __inline long double complex -cpackl(long double x, long double y) +CMPLXL(long double x, long double y) { long_double_complex z; @@ -484,6 +495,8 @@ cpackl(long double x, long double y) IMAGPART(z) = y; return (z.f); } +#endif + #endif /* _COMPLEX_H */ #ifdef __GNUCLIKE_ASM diff --git a/lib/msun/src/s_ccosh.c b/lib/msun/src/s_ccosh.c index 9ea962b4818..fbe15fc9c87 100644 --- a/lib/msun/src/s_ccosh.c +++ b/lib/msun/src/s_ccosh.c @@ -62,23 +62,23 @@ ccosh(double complex z) /* Handle the nearly-non-exceptional cases where x and y are finite. */ if (ix < 0x7ff00000 && iy < 0x7ff00000) { if ((iy | ly) == 0) - return (cpack(cosh(x), x * y)); + return (CMPLX(cosh(x), x * y)); if (ix < 0x40360000) /* small x: normal case */ - return (cpack(cosh(x) * cos(y), sinh(x) * sin(y))); + return (CMPLX(cosh(x) * cos(y), sinh(x) * sin(y))); /* |x| >= 22, so cosh(x) ~= exp(|x|) */ if (ix < 0x40862e42) { /* x < 710: exp(|x|) won't overflow */ h = exp(fabs(x)) * 0.5; - return (cpack(h * cos(y), copysign(h, x) * sin(y))); + return (CMPLX(h * cos(y), copysign(h, x) * sin(y))); } else if (ix < 0x4096bbaa) { /* x < 1455: scale to avoid overflow */ - z = __ldexp_cexp(cpack(fabs(x), y), -1); - return (cpack(creal(z), cimag(z) * copysign(1, x))); + z = __ldexp_cexp(CMPLX(fabs(x), y), -1); + return (CMPLX(creal(z), cimag(z) * copysign(1, x))); } else { /* x >= 1455: the result always overflows */ h = huge * x; - return (cpack(h * h * cos(y), h * sin(y))); + return (CMPLX(h * h * cos(y), h * sin(y))); } } @@ -92,7 +92,7 @@ ccosh(double complex z) * the same as d(NaN). */ if ((ix | lx) == 0 && iy >= 0x7ff00000) - return (cpack(y - y, copysign(0, x * (y - y)))); + return (CMPLX(y - y, copysign(0, x * (y - y)))); /* * cosh(+-Inf +- I 0) = +Inf + I (+-)(+-)0. @@ -102,8 +102,8 @@ ccosh(double complex z) */ if ((iy | ly) == 0 && ix >= 0x7ff00000) { if (((hx & 0xfffff) | lx) == 0) - return (cpack(x * x, copysign(0, x) * y)); - return (cpack(x * x, copysign(0, (x + x) * y))); + return (CMPLX(x * x, copysign(0, x) * y)); + return (CMPLX(x * x, copysign(0, (x + x) * y))); } /* @@ -115,7 +115,7 @@ ccosh(double complex z) * nonzero x. Choice = don't raise (except for signaling NaNs). */ if (ix < 0x7ff00000 && iy >= 0x7ff00000) - return (cpack(y - y, x * (y - y))); + return (CMPLX(y - y, x * (y - y))); /* * cosh(+-Inf + I NaN) = +Inf + I d(NaN). @@ -128,8 +128,8 @@ ccosh(double complex z) */ if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) { if (iy >= 0x7ff00000) - return (cpack(x * x, x * (y - y))); - return (cpack((x * x) * cos(y), x * sin(y))); + return (CMPLX(x * x, x * (y - y))); + return (CMPLX((x * x) * cos(y), x * sin(y))); } /* @@ -143,7 +143,7 @@ ccosh(double complex z) * Optionally raises the invalid floating-point exception for finite * nonzero y. Choice = don't raise (except for signaling NaNs). */ - return (cpack((x * x) * (y - y), (x + x) * (y - y))); + return (CMPLX((x * x) * (y - y), (x + x) * (y - y))); } double complex @@ -151,5 +151,5 @@ ccos(double complex z) { /* ccos(z) = ccosh(I * z) */ - return (ccosh(cpack(-cimag(z), creal(z)))); + return (ccosh(CMPLX(-cimag(z), creal(z)))); } diff --git a/lib/msun/src/s_ccoshf.c b/lib/msun/src/s_ccoshf.c index 1de9ad44377..fe8cf89c415 100644 --- a/lib/msun/src/s_ccoshf.c +++ b/lib/msun/src/s_ccoshf.c @@ -55,50 +55,50 @@ ccoshf(float complex z) if (ix < 0x7f800000 && iy < 0x7f800000) { if (iy == 0) - return (cpackf(coshf(x), x * y)); + return (CMPLXF(coshf(x), x * y)); if (ix < 0x41100000) /* small x: normal case */ - return (cpackf(coshf(x) * cosf(y), sinhf(x) * sinf(y))); + return (CMPLXF(coshf(x) * cosf(y), sinhf(x) * sinf(y))); /* |x| >= 9, so cosh(x) ~= exp(|x|) */ if (ix < 0x42b17218) { /* x < 88.7: expf(|x|) won't overflow */ h = expf(fabsf(x)) * 0.5f; - return (cpackf(h * cosf(y), copysignf(h, x) * sinf(y))); + return (CMPLXF(h * cosf(y), copysignf(h, x) * sinf(y))); } else if (ix < 0x4340b1e7) { /* x < 192.7: scale to avoid overflow */ - z = __ldexp_cexpf(cpackf(fabsf(x), y), -1); - return (cpackf(crealf(z), cimagf(z) * copysignf(1, x))); + z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1); + return (CMPLXF(crealf(z), cimagf(z) * copysignf(1, x))); } else { /* x >= 192.7: the result always overflows */ h = huge * x; - return (cpackf(h * h * cosf(y), h * sinf(y))); + return (CMPLXF(h * h * cosf(y), h * sinf(y))); } } if (ix == 0 && iy >= 0x7f800000) - return (cpackf(y - y, copysignf(0, x * (y - y)))); + return (CMPLXF(y - y, copysignf(0, x * (y - y)))); if (iy == 0 && ix >= 0x7f800000) { if ((hx & 0x7fffff) == 0) - return (cpackf(x * x, copysignf(0, x) * y)); - return (cpackf(x * x, copysignf(0, (x + x) * y))); + return (CMPLXF(x * x, copysignf(0, x) * y)); + return (CMPLXF(x * x, copysignf(0, (x + x) * y))); } if (ix < 0x7f800000 && iy >= 0x7f800000) - return (cpackf(y - y, x * (y - y))); + return (CMPLXF(y - y, x * (y - y))); if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) { if (iy >= 0x7f800000) - return (cpackf(x * x, x * (y - y))); - return (cpackf((x * x) * cosf(y), x * sinf(y))); + return (CMPLXF(x * x, x * (y - y))); + return (CMPLXF((x * x) * cosf(y), x * sinf(y))); } - return (cpackf((x * x) * (y - y), (x + x) * (y - y))); + return (CMPLXF((x * x) * (y - y), (x + x) * (y - y))); } float complex ccosf(float complex z) { - return (ccoshf(cpackf(-cimagf(z), crealf(z)))); + return (ccoshf(CMPLXF(-cimagf(z), crealf(z)))); } diff --git a/lib/msun/src/s_cexp.c b/lib/msun/src/s_cexp.c index abe178f3169..9e11d515a68 100644 --- a/lib/msun/src/s_cexp.c +++ b/lib/msun/src/s_cexp.c @@ -50,22 +50,22 @@ cexp(double complex z) /* cexp(x + I 0) = exp(x) + I 0 */ if ((hy | ly) == 0) - return (cpack(exp(x), y)); + return (CMPLX(exp(x), y)); EXTRACT_WORDS(hx, lx, x); /* cexp(0 + I y) = cos(y) + I sin(y) */ if (((hx & 0x7fffffff) | lx) == 0) - return (cpack(cos(y), sin(y))); + return (CMPLX(cos(y), sin(y))); if (hy >= 0x7ff00000) { if (lx != 0 || (hx & 0x7fffffff) != 0x7ff00000) { /* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */ - return (cpack(y - y, y - y)); + return (CMPLX(y - y, y - y)); } else if (hx & 0x80000000) { /* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */ - return (cpack(0.0, 0.0)); + return (CMPLX(0.0, 0.0)); } else { /* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */ - return (cpack(x, y - y)); + return (CMPLX(x, y - y)); } } @@ -84,6 +84,6 @@ cexp(double complex z) * - x = NaN (spurious inexact exception from y) */ exp_x = exp(x); - return (cpack(exp_x * cos(y), exp_x * sin(y))); + return (CMPLX(exp_x * cos(y), exp_x * sin(y))); } } diff --git a/lib/msun/src/s_cexpf.c b/lib/msun/src/s_cexpf.c index 0e30d08c80d..0138cd1e83f 100644 --- a/lib/msun/src/s_cexpf.c +++ b/lib/msun/src/s_cexpf.c @@ -50,22 +50,22 @@ cexpf(float complex z) /* cexp(x + I 0) = exp(x) + I 0 */ if (hy == 0) - return (cpackf(expf(x), y)); + return (CMPLXF(expf(x), y)); GET_FLOAT_WORD(hx, x); /* cexp(0 + I y) = cos(y) + I sin(y) */ if ((hx & 0x7fffffff) == 0) - return (cpackf(cosf(y), sinf(y))); + return (CMPLXF(cosf(y), sinf(y))); if (hy >= 0x7f800000) { if ((hx & 0x7fffffff) != 0x7f800000) { /* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */ - return (cpackf(y - y, y - y)); + return (CMPLXF(y - y, y - y)); } else if (hx & 0x80000000) { /* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */ - return (cpackf(0.0, 0.0)); + return (CMPLXF(0.0, 0.0)); } else { /* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */ - return (cpackf(x, y - y)); + return (CMPLXF(x, y - y)); } } @@ -84,6 +84,6 @@ cexpf(float complex z) * - x = NaN (spurious inexact exception from y) */ exp_x = expf(x); - return (cpackf(exp_x * cosf(y), exp_x * sinf(y))); + return (CMPLXF(exp_x * cosf(y), exp_x * sinf(y))); } } diff --git a/lib/msun/src/s_conj.c b/lib/msun/src/s_conj.c index 5770c29462e..d0dd05133f2 100644 --- a/lib/msun/src/s_conj.c +++ b/lib/msun/src/s_conj.c @@ -34,5 +34,5 @@ double complex conj(double complex z) { - return (cpack(creal(z), -cimag(z))); + return (CMPLX(creal(z), -cimag(z))); } diff --git a/lib/msun/src/s_conjf.c b/lib/msun/src/s_conjf.c index b09076039cc..c4cf127f8c2 100644 --- a/lib/msun/src/s_conjf.c +++ b/lib/msun/src/s_conjf.c @@ -34,5 +34,5 @@ float complex conjf(float complex z) { - return (cpackf(crealf(z), -cimagf(z))); + return (CMPLXF(crealf(z), -cimagf(z))); } diff --git a/lib/msun/src/s_conjl.c b/lib/msun/src/s_conjl.c index 0e431efa01a..a4604b6fd16 100644 --- a/lib/msun/src/s_conjl.c +++ b/lib/msun/src/s_conjl.c @@ -34,5 +34,5 @@ long double complex conjl(long double complex z) { - return (cpackl(creall(z), -cimagl(z))); + return (CMPLXL(creall(z), -cimagl(z))); } diff --git a/lib/msun/src/s_cproj.c b/lib/msun/src/s_cproj.c index 8e9404c297d..2f0db6e6151 100644 --- a/lib/msun/src/s_cproj.c +++ b/lib/msun/src/s_cproj.c @@ -39,7 +39,7 @@ cproj(double complex z) if (!isinf(creal(z)) && !isinf(cimag(z))) return (z); else - return (cpack(INFINITY, copysign(0.0, cimag(z)))); + return (CMPLX(INFINITY, copysign(0.0, cimag(z)))); } #if LDBL_MANT_DIG == 53 diff --git a/lib/msun/src/s_cprojf.c b/lib/msun/src/s_cprojf.c index 68ea77b80d8..bd27bdcb0b5 100644 --- a/lib/msun/src/s_cprojf.c +++ b/lib/msun/src/s_cprojf.c @@ -39,5 +39,5 @@ cprojf(float complex z) if (!isinf(crealf(z)) && !isinf(cimagf(z))) return (z); else - return (cpackf(INFINITY, copysignf(0.0, cimagf(z)))); + return (CMPLXF(INFINITY, copysignf(0.0, cimagf(z)))); } diff --git a/lib/msun/src/s_cprojl.c b/lib/msun/src/s_cprojl.c index 07385bcc626..5cccc917081 100644 --- a/lib/msun/src/s_cprojl.c +++ b/lib/msun/src/s_cprojl.c @@ -39,5 +39,5 @@ cprojl(long double complex z) if (!isinf(creall(z)) && !isinf(cimagl(z))) return (z); else - return (cpackl(INFINITY, copysignl(0.0, cimagl(z)))); + return (CMPLXL(INFINITY, copysignl(0.0, cimagl(z)))); } diff --git a/lib/msun/src/s_csinh.c b/lib/msun/src/s_csinh.c index c192f30308e..37f46da226d 100644 --- a/lib/msun/src/s_csinh.c +++ b/lib/msun/src/s_csinh.c @@ -62,23 +62,23 @@ csinh(double complex z) /* Handle the nearly-non-exceptional cases where x and y are finite. */ if (ix < 0x7ff00000 && iy < 0x7ff00000) { if ((iy | ly) == 0) - return (cpack(sinh(x), y)); + return (CMPLX(sinh(x), y)); if (ix < 0x40360000) /* small x: normal case */ - return (cpack(sinh(x) * cos(y), cosh(x) * sin(y))); + return (CMPLX(sinh(x) * cos(y), cosh(x) * sin(y))); /* |x| >= 22, so cosh(x) ~= exp(|x|) */ if (ix < 0x40862e42) { /* x < 710: exp(|x|) won't overflow */ h = exp(fabs(x)) * 0.5; - return (cpack(copysign(h, x) * cos(y), h * sin(y))); + return (CMPLX(copysign(h, x) * cos(y), h * sin(y))); } else if (ix < 0x4096bbaa) { /* x < 1455: scale to avoid overflow */ - z = __ldexp_cexp(cpack(fabs(x), y), -1); - return (cpack(creal(z) * copysign(1, x), cimag(z))); + z = __ldexp_cexp(CMPLX(fabs(x), y), -1); + return (CMPLX(creal(z) * copysign(1, x), cimag(z))); } else { /* x >= 1455: the result always overflows */ h = huge * x; - return (cpack(h * cos(y), h * h * sin(y))); + return (CMPLX(h * cos(y), h * h * sin(y))); } } @@ -92,7 +92,7 @@ csinh(double complex z) * the same as d(NaN). */ if ((ix | lx) == 0 && iy >= 0x7ff00000) - return (cpack(copysign(0, x * (y - y)), y - y)); + return (CMPLX(copysign(0, x * (y - y)), y - y)); /* * sinh(+-Inf +- I 0) = +-Inf + I +-0. @@ -101,8 +101,8 @@ csinh(double complex z) */ if ((iy | ly) == 0 && ix >= 0x7ff00000) { if (((hx & 0xfffff) | lx) == 0) - return (cpack(x, y)); - return (cpack(x, copysign(0, y))); + return (CMPLX(x, y)); + return (CMPLX(x, copysign(0, y))); } /* @@ -114,7 +114,7 @@ csinh(double complex z) * nonzero x. Choice = don't raise (except for signaling NaNs). */ if (ix < 0x7ff00000 && iy >= 0x7ff00000) - return (cpack(y - y, x * (y - y))); + return (CMPLX(y - y, x * (y - y))); /* * sinh(+-Inf + I NaN) = +-Inf + I d(NaN). @@ -129,8 +129,8 @@ csinh(double complex z) */ if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) { if (iy >= 0x7ff00000) - return (cpack(x * x, x * (y - y))); - return (cpack(x * cos(y), INFINITY * sin(y))); + return (CMPLX(x * x, x * (y - y))); + return (CMPLX(x * cos(y), INFINITY * sin(y))); } /* @@ -144,7 +144,7 @@ csinh(double complex z) * Optionally raises the invalid floating-point exception for finite * nonzero y. Choice = don't raise (except for signaling NaNs). */ - return (cpack((x * x) * (y - y), (x + x) * (y - y))); + return (CMPLX((x * x) * (y - y), (x + x) * (y - y))); } double complex @@ -152,6 +152,6 @@ csin(double complex z) { /* csin(z) = -I * csinh(I * z) */ - z = csinh(cpack(-cimag(z), creal(z))); - return (cpack(cimag(z), -creal(z))); + z = csinh(CMPLX(-cimag(z), creal(z))); + return (CMPLX(cimag(z), -creal(z))); } diff --git a/lib/msun/src/s_csinhf.c b/lib/msun/src/s_csinhf.c index c5231251fad..63482723ad9 100644 --- a/lib/msun/src/s_csinhf.c +++ b/lib/msun/src/s_csinhf.c @@ -55,51 +55,51 @@ csinhf(float complex z) if (ix < 0x7f800000 && iy < 0x7f800000) { if (iy == 0) - return (cpackf(sinhf(x), y)); + return (CMPLXF(sinhf(x), y)); if (ix < 0x41100000) /* small x: normal case */ - return (cpackf(sinhf(x) * cosf(y), coshf(x) * sinf(y))); + return (CMPLXF(sinhf(x) * cosf(y), coshf(x) * sinf(y))); /* |x| >= 9, so cosh(x) ~= exp(|x|) */ if (ix < 0x42b17218) { /* x < 88.7: expf(|x|) won't overflow */ h = expf(fabsf(x)) * 0.5f; - return (cpackf(copysignf(h, x) * cosf(y), h * sinf(y))); + return (CMPLXF(copysignf(h, x) * cosf(y), h * sinf(y))); } else if (ix < 0x4340b1e7) { /* x < 192.7: scale to avoid overflow */ - z = __ldexp_cexpf(cpackf(fabsf(x), y), -1); - return (cpackf(crealf(z) * copysignf(1, x), cimagf(z))); + z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1); + return (CMPLXF(crealf(z) * copysignf(1, x), cimagf(z))); } else { /* x >= 192.7: the result always overflows */ h = huge * x; - return (cpackf(h * cosf(y), h * h * sinf(y))); + return (CMPLXF(h * cosf(y), h * h * sinf(y))); } } if (ix == 0 && iy >= 0x7f800000) - return (cpackf(copysignf(0, x * (y - y)), y - y)); + return (CMPLXF(copysignf(0, x * (y - y)), y - y)); if (iy == 0 && ix >= 0x7f800000) { if ((hx & 0x7fffff) == 0) - return (cpackf(x, y)); - return (cpackf(x, copysignf(0, y))); + return (CMPLXF(x, y)); + return (CMPLXF(x, copysignf(0, y))); } if (ix < 0x7f800000 && iy >= 0x7f800000) - return (cpackf(y - y, x * (y - y))); + return (CMPLXF(y - y, x * (y - y))); if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) { if (iy >= 0x7f800000) - return (cpackf(x * x, x * (y - y))); - return (cpackf(x * cosf(y), INFINITY * sinf(y))); + return (CMPLXF(x * x, x * (y - y))); + return (CMPLXF(x * cosf(y), INFINITY * sinf(y))); } - return (cpackf((x * x) * (y - y), (x + x) * (y - y))); + return (CMPLXF((x * x) * (y - y), (x + x) * (y - y))); } float complex csinf(float complex z) { - z = csinhf(cpackf(-cimagf(z), crealf(z))); - return (cpackf(cimagf(z), -crealf(z))); + z = csinhf(CMPLXF(-cimagf(z), crealf(z))); + return (CMPLXF(cimagf(z), -crealf(z))); } diff --git a/lib/msun/src/s_csqrt.c b/lib/msun/src/s_csqrt.c index 18a7ae3e714..75e12d8a494 100644 --- a/lib/msun/src/s_csqrt.c +++ b/lib/msun/src/s_csqrt.c @@ -58,12 +58,12 @@ csqrt(double complex z) /* Handle special cases. */ if (z == 0) - return (cpack(0, b)); + return (CMPLX(0, b)); if (isinf(b)) - return (cpack(INFINITY, b)); + return (CMPLX(INFINITY, b)); if (isnan(a)) { t = (b - b) / (b - b); /* raise invalid if b is not a NaN */ - return (cpack(a, t)); /* return NaN + NaN i */ + return (CMPLX(a, t)); /* return NaN + NaN i */ } if (isinf(a)) { /* @@ -73,9 +73,9 @@ csqrt(double complex z) * csqrt(-inf + y i) = 0 + inf i */ if (signbit(a)) - return (cpack(fabs(b - b), copysign(a, b))); + return (CMPLX(fabs(b - b), copysign(a, b))); else - return (cpack(a, copysign(b - b, b))); + return (CMPLX(a, copysign(b - b, b))); } /* * The remaining special case (b is NaN) is handled just fine by @@ -94,10 +94,10 @@ csqrt(double complex z) /* Algorithm 312, CACM vol 10, Oct 1967. */ if (a >= 0) { t = sqrt((a + hypot(a, b)) * 0.5); - result = cpack(t, b / (2 * t)); + result = CMPLX(t, b / (2 * t)); } else { t = sqrt((-a + hypot(a, b)) * 0.5); - result = cpack(fabs(b) / (2 * t), copysign(t, b)); + result = CMPLX(fabs(b) / (2 * t), copysign(t, b)); } /* Rescale. */ diff --git a/lib/msun/src/s_csqrtf.c b/lib/msun/src/s_csqrtf.c index da7fe184709..7ee513f2d76 100644 --- a/lib/msun/src/s_csqrtf.c +++ b/lib/msun/src/s_csqrtf.c @@ -49,12 +49,12 @@ csqrtf(float complex z) /* Handle special cases. */ if (z == 0) - return (cpackf(0, b)); + return (CMPLXF(0, b)); if (isinf(b)) - return (cpackf(INFINITY, b)); + return (CMPLXF(INFINITY, b)); if (isnan(a)) { t = (b - b) / (b - b); /* raise invalid if b is not a NaN */ - return (cpackf(a, t)); /* return NaN + NaN i */ + return (CMPLXF(a, t)); /* return NaN + NaN i */ } if (isinf(a)) { /* @@ -64,9 +64,9 @@ csqrtf(float complex z) * csqrtf(-inf + y i) = 0 + inf i */ if (signbit(a)) - return (cpackf(fabsf(b - b), copysignf(a, b))); + return (CMPLXF(fabsf(b - b), copysignf(a, b))); else - return (cpackf(a, copysignf(b - b, b))); + return (CMPLXF(a, copysignf(b - b, b))); } /* * The remaining special case (b is NaN) is handled just fine by @@ -80,9 +80,9 @@ csqrtf(float complex z) */ if (a >= 0) { t = sqrt((a + hypot(a, b)) * 0.5); - return (cpackf(t, b / (2.0 * t))); + return (CMPLXF(t, b / (2.0 * t))); } else { t = sqrt((-a + hypot(a, b)) * 0.5); - return (cpackf(fabsf(b) / (2.0 * t), copysignf(t, b))); + return (CMPLXF(fabsf(b) / (2.0 * t), copysignf(t, b))); } } diff --git a/lib/msun/src/s_csqrtl.c b/lib/msun/src/s_csqrtl.c index dd18e1ef38e..ea2ef27b508 100644 --- a/lib/msun/src/s_csqrtl.c +++ b/lib/msun/src/s_csqrtl.c @@ -58,12 +58,12 @@ csqrtl(long double complex z) /* Handle special cases. */ if (z == 0) - return (cpackl(0, b)); + return (CMPLXL(0, b)); if (isinf(b)) - return (cpackl(INFINITY, b)); + return (CMPLXL(INFINITY, b)); if (isnan(a)) { t = (b - b) / (b - b); /* raise invalid if b is not a NaN */ - return (cpackl(a, t)); /* return NaN + NaN i */ + return (CMPLXL(a, t)); /* return NaN + NaN i */ } if (isinf(a)) { /* @@ -73,9 +73,9 @@ csqrtl(long double complex z) * csqrt(-inf + y i) = 0 + inf i */ if (signbit(a)) - return (cpackl(fabsl(b - b), copysignl(a, b))); + return (CMPLXL(fabsl(b - b), copysignl(a, b))); else - return (cpackl(a, copysignl(b - b, b))); + return (CMPLXL(a, copysignl(b - b, b))); } /* * The remaining special case (b is NaN) is handled just fine by @@ -94,10 +94,10 @@ csqrtl(long double complex z) /* Algorithm 312, CACM vol 10, Oct 1967. */ if (a >= 0) { t = sqrtl((a + hypotl(a, b)) * 0.5); - result = cpackl(t, b / (2 * t)); + result = CMPLXL(t, b / (2 * t)); } else { t = sqrtl((-a + hypotl(a, b)) * 0.5); - result = cpackl(fabsl(b) / (2 * t), copysignl(t, b)); + result = CMPLXL(fabsl(b) / (2 * t), copysignl(t, b)); } /* Rescale. */ diff --git a/lib/msun/src/s_ctanh.c b/lib/msun/src/s_ctanh.c index d427e28d728..b15c8146954 100644 --- a/lib/msun/src/s_ctanh.c +++ b/lib/msun/src/s_ctanh.c @@ -102,9 +102,9 @@ ctanh(double complex z) */ if (ix >= 0x7ff00000) { if ((ix & 0xfffff) | lx) /* x is NaN */ - return (cpack(x, (y == 0 ? y : x * y))); + return (CMPLX(x, (y == 0 ? y : x * y))); SET_HIGH_WORD(x, hx - 0x40000000); /* x = copysign(1, x) */ - return (cpack(x, copysign(0, isinf(y) ? y : sin(y) * cos(y)))); + return (CMPLX(x, copysign(0, isinf(y) ? y : sin(y) * cos(y)))); } /* @@ -112,7 +112,7 @@ ctanh(double complex z) * ctanh(x +- i Inf) = NaN + i NaN */ if (!isfinite(y)) - return (cpack(y - y, y - y)); + return (CMPLX(y - y, y - y)); /* * ctanh(+-huge + i +-y) ~= +-1 +- i 2sin(2y)/exp(2x), using the @@ -121,7 +121,7 @@ ctanh(double complex z) */ if (ix >= 0x40360000) { /* x >= 22 */ double exp_mx = exp(-fabs(x)); - return (cpack(copysign(1, x), + return (CMPLX(copysign(1, x), 4 * sin(y) * cos(y) * exp_mx * exp_mx)); } @@ -131,7 +131,7 @@ ctanh(double complex z) s = sinh(x); rho = sqrt(1 + s * s); /* = cosh(x) */ denom = 1 + beta * s * s; - return (cpack((beta * rho * s) / denom, t / denom)); + return (CMPLX((beta * rho * s) / denom, t / denom)); } double complex @@ -139,6 +139,6 @@ ctan(double complex z) { /* ctan(z) = -I * ctanh(I * z) */ - z = ctanh(cpack(-cimag(z), creal(z))); - return (cpack(cimag(z), -creal(z))); + z = ctanh(CMPLX(-cimag(z), creal(z))); + return (CMPLX(cimag(z), -creal(z))); } diff --git a/lib/msun/src/s_ctanhf.c b/lib/msun/src/s_ctanhf.c index 4be28d8526d..9b0cda1600f 100644 --- a/lib/msun/src/s_ctanhf.c +++ b/lib/msun/src/s_ctanhf.c @@ -51,18 +51,18 @@ ctanhf(float complex z) if (ix >= 0x7f800000) { if (ix & 0x7fffff) - return (cpackf(x, (y == 0 ? y : x * y))); + return (CMPLXF(x, (y == 0 ? y : x * y))); SET_FLOAT_WORD(x, hx - 0x40000000); - return (cpackf(x, + return (CMPLXF(x, copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)))); } if (!isfinite(y)) - return (cpackf(y - y, y - y)); + return (CMPLXF(y - y, y - y)); if (ix >= 0x41300000) { /* x >= 11 */ float exp_mx = expf(-fabsf(x)); - return (cpackf(copysignf(1, x), + return (CMPLXF(copysignf(1, x), 4 * sinf(y) * cosf(y) * exp_mx * exp_mx)); } @@ -71,14 +71,14 @@ ctanhf(float complex z) s = sinhf(x); rho = sqrtf(1 + s * s); denom = 1 + beta * s * s; - return (cpackf((beta * rho * s) / denom, t / denom)); + return (CMPLXF((beta * rho * s) / denom, t / denom)); } float complex ctanf(float complex z) { - z = ctanhf(cpackf(-cimagf(z), crealf(z))); - return (cpackf(cimagf(z), -crealf(z))); + z = ctanhf(CMPLXF(-cimagf(z), crealf(z))); + return (CMPLXF(cimagf(z), -crealf(z))); } From 917dd390846304a11ce07d69365cb81ad31daac3 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 16 Dec 2014 09:48:23 +0000 Subject: [PATCH 27/64] Add missed break. CID: 1258586 Sponsored by: The FreeBSD Foundation MFC after: 4 days --- sys/kern/kern_thread.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 0ede6551fda..2d0b0d278a5 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -618,6 +618,7 @@ weed_inhib(int mode, struct thread *td2, struct proc *p) wakeup_swapper |= thread_unsuspend_one(td2, p); if (TD_ON_SLEEPQ(td2) && (td2->td_flags & TDF_SINTR) != 0) wakeup_swapper |= sleepq_abort(td2, ERESTART); + break; case SINGLE_ALLPROC: /* * ALLPROC suspend tries to avoid spurious EINTR for From 5b73811febfc624fdccc5ae627d507bc3585a457 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 16 Dec 2014 09:49:07 +0000 Subject: [PATCH 28/64] Add missed break. CID: 1258587 Sponsored by: The FreeBSD Foundation MFC after: 20 days --- sys/kern/kern_procctl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c index 5ee2953a169..9b0d14aea35 100644 --- a/sys/kern/kern_procctl.c +++ b/sys/kern/kern_procctl.c @@ -336,6 +336,7 @@ sys_procctl(struct thread *td, struct procctl_args *uap) case PROC_REAP_STATUS: if (error == 0) error = copyout(&x.rs, uap->data, sizeof(x.rs)); + break; case PROC_REAP_KILL: error1 = copyout(&x.rk, uap->data, sizeof(x.rk)); if (error == 0) From d03f0c51998c3a95d200f818e04529769165883e Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 16 Dec 2014 14:50:33 +0000 Subject: [PATCH 29/64] Add tests for pw -N PR: 150449 Submitted by: Robert O'Neil Approved by: will --- usr.sbin/pw/tests/pw_useradd.sh | 33 +++++++++++++++++++ usr.sbin/pw/tests/pw_usermod.sh | 56 +++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/usr.sbin/pw/tests/pw_useradd.sh b/usr.sbin/pw/tests/pw_useradd.sh index fb2e33f954c..2930c41b064 100755 --- a/usr.sbin/pw/tests/pw_useradd.sh +++ b/usr.sbin/pw/tests/pw_useradd.sh @@ -13,7 +13,16 @@ user_add_body() { grep "^test:.*" $HOME/master.passwd } +# Test add user with option -N +atf_test_case user_add_noupdate +user_add_noupdate_body() { + populate_etc_skel + atf_check -s exit:0 -o match:"^test:.*" ${PW} useradd test -N + atf_check -s exit:1 -o empty grep "^test:.*" $HOME/master.passwd +} + +# Test add user with comments atf_test_case user_add_comments user_add_comments_body() { populate_etc_skel @@ -23,6 +32,17 @@ user_add_comments_body() { grep "^test:.*:Test User,work,123,456:" $HOME/master.passwd } +# Test add user with comments and option -N +atf_test_case user_add_comments_noupdate +user_add_comments_noupdate_body() { + populate_etc_skel + + atf_check -s exit:0 -o match:"^test:.*:Test User,work,123,456:" \ + ${PW} useradd test -c "Test User,work,123,456" -N + atf_check -s exit:1 -o empty grep "^test:.*" $HOME/master.passwd +} + +# Test add user with invalid comments atf_test_case user_add_comments_invalid user_add_comments_invalid_body() { populate_etc_skel @@ -33,8 +53,21 @@ user_add_comments_invalid_body() { grep "^test:.*:Test User,work,123:456,456:" $HOME/master.passwd } +# Test add user with invalid comments and option -N +atf_test_case user_add_comments_invalid_noupdate +user_add_comments_invalid_noupdate_body() { + populate_etc_skel + + atf_check -s exit:65 -e match:"invalid character" \ + ${PW} useradd test -c "Test User,work,123:456,456" -N + atf_check -s exit:1 -o empty grep "^test:.*" $HOME/master.passwd +} + atf_init_test_cases() { atf_add_test_case user_add + atf_add_test_case user_add_noupdate atf_add_test_case user_add_comments + atf_add_test_case user_add_comments_noupdate atf_add_test_case user_add_comments_invalid + atf_add_test_case user_add_comments_invalid_noupdate } diff --git a/usr.sbin/pw/tests/pw_usermod.sh b/usr.sbin/pw/tests/pw_usermod.sh index f5bac78aed3..88bd3163a62 100755 --- a/usr.sbin/pw/tests/pw_usermod.sh +++ b/usr.sbin/pw/tests/pw_usermod.sh @@ -15,6 +15,18 @@ user_mod_body() { grep "^test:.*" $HOME/master.passwd } +# Test modifying a user with option -N +atf_test_case user_mod_noupdate +user_mod_noupdate_body() { + populate_etc_skel + + atf_check -s exit:67 -e match:"no such user" ${PW} usermod test -N + atf_check -s exit:0 ${PW} useradd test + atf_check -s exit:0 -o match:"^test:.*" ${PW} usermod test -N + atf_check -s exit:0 -o match:"^test:.*" \ + grep "^test:.*" $HOME/master.passwd +} + # Test modifying a user with comments atf_test_case user_mod_comments user_mod_comments_body() { @@ -26,6 +38,18 @@ user_mod_comments_body() { grep "^test:.*:Test User,work,123,456:" $HOME/master.passwd } +# Test modifying a user with comments with option -N +atf_test_case user_mod_comments_noupdate +user_mod_comments_noupdate_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd test -c "Test User,home,123,456" + atf_check -s exit:0 -o match:"^test:.*:Test User,work,123,456:" \ + ${PW} usermod test -c "Test User,work,123,456" -N + atf_check -s exit:0 -o match:"^test:.*:Test User,home,123,456:" \ + grep "^test:.*:Test User,home,123,456:" $HOME/master.passwd +} + # Test modifying a user with invalid comments atf_test_case user_mod_comments_invalid user_mod_comments_invalid_body() { @@ -36,6 +60,22 @@ user_mod_comments_invalid_body() { ${PW} usermod test -c "Test User,work,123:456,456" atf_check -s exit:1 -o empty \ grep "^test:.*:Test User,work,123:456,456:" $HOME/master.passwd + atf_check -s exit:0 -o match:"^test:\*" \ + grep "^test:\*" $HOME/master.passwd +} + +# Test modifying a user with invalid comments with option -N +atf_test_case user_mod_comments_invalid_noupdate +user_mod_comments_invalid_noupdate_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd test + atf_check -s exit:65 -e match:"invalid character" \ + ${PW} usermod test -c "Test User,work,123:456,456" -N + atf_check -s exit:1 -o empty \ + grep "^test:.*:Test User,work,123:456,456:" $HOME/master.passwd + atf_check -s exit:0 -o match:"^test:\*" \ + grep "^test:\*" $HOME/master.passwd } # Test modifying a user name with -l @@ -48,9 +88,25 @@ user_mod_name_body() { atf_check -s exit:0 -o match:"^bar:.*" \ grep "^bar:.*" $HOME/master.passwd } + +# Test modifying a user name with -l with option -N +atf_test_case user_mod_name_noupdate +user_mod_name_noupdate_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd foo + atf_check -s exit:0 -o match:"^bar:.*" ${PW} usermod foo -l "bar" -N + atf_check -s exit:0 -o match:"^foo:.*" \ + grep "^foo:.*" $HOME/master.passwd +} + atf_init_test_cases() { atf_add_test_case user_mod + atf_add_test_case user_mod_noupdate atf_add_test_case user_mod_comments + atf_add_test_case user_mod_comments_noupdate atf_add_test_case user_mod_comments_invalid + atf_add_test_case user_mod_comments_invalid_noupdate atf_add_test_case user_mod_name + atf_add_test_case user_mod_name_noupdate } From 8150c3ec36a3d280725daa656a1ca79b0b035c9d Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Tue, 16 Dec 2014 14:59:20 +0000 Subject: [PATCH 30/64] Add ability to not specify a zone identifier twice, when both source and destination addresses are specified. For example: # ping6 -S fe80::1%ix0 ff02::1 or # ping6 -S fe80::1 fe80::2%ix0 Obtained from: Yandex LLC Sponsored by: Yandex LLC --- sbin/ping6/ping6.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/sbin/ping6/ping6.c b/sbin/ping6/ping6.c index fa314f6cb5c..d71c021ad45 100644 --- a/sbin/ping6/ping6.c +++ b/sbin/ping6/ping6.c @@ -648,11 +648,20 @@ main(int argc, char *argv[]) err(1, "socket"); /* set the source address if specified. */ - if ((options & F_SRCADDR) && - bind(s, (struct sockaddr *)&src, srclen) != 0) { - err(1, "bind"); + if ((options & F_SRCADDR) != 0) { + /* properly fill sin6_scope_id */ + if (IN6_IS_ADDR_LINKLOCAL(&src.sin6_addr) && ( + IN6_IS_ADDR_LINKLOCAL(&dst.sin6_addr) || + IN6_IS_ADDR_MC_LINKLOCAL(&dst.sin6_addr) || + IN6_IS_ADDR_MC_NODELOCAL(&dst.sin6_addr))) { + if (src.sin6_scope_id == 0) + src.sin6_scope_id = dst.sin6_scope_id; + if (dst.sin6_scope_id == 0) + dst.sin6_scope_id = src.sin6_scope_id; + } + if (bind(s, (struct sockaddr *)&src, srclen) != 0) + err(1, "bind"); } - /* set the gateway (next hop) if specified */ if (gateway) { memset(&hints, 0, sizeof(hints)); From 6b8c8dee3c4d62838f2a6771b705daaac3998d6c Mon Sep 17 00:00:00 2001 From: Will Andrews Date: Tue, 16 Dec 2014 17:59:05 +0000 Subject: [PATCH 31/64] Make NanoBSD source-able from other scripts. Summary: This change converts NanoBSD into a two-script bundle. - defaults.sh contains all non-CLI code. Most NanoBSD code is moved into this file. - nanobsd.sh now consists just of a command line interface that calls into functions in defaults.sh. Test Plan: Run NanoBSD using a previously-working configuration. Reviewers: imp Reviewed By: imp Differential Revision: https://reviews.freebsd.org/D1321 --- tools/tools/nanobsd/defaults.sh | 983 ++++++++++++++++++++++++++++++++ tools/tools/nanobsd/nanobsd.sh | 955 +------------------------------ 2 files changed, 989 insertions(+), 949 deletions(-) create mode 100755 tools/tools/nanobsd/defaults.sh diff --git a/tools/tools/nanobsd/defaults.sh b/tools/tools/nanobsd/defaults.sh new file mode 100755 index 00000000000..a556e1b9622 --- /dev/null +++ b/tools/tools/nanobsd/defaults.sh @@ -0,0 +1,983 @@ +#!/bin/sh +# +# Copyright (c) 2005 Poul-Henning Kamp. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +set -e + +####################################################################### +# +# Setup default values for all controlling variables. +# These values can be overridden from the config file(s) +# +####################################################################### + +# Name of this NanoBSD build. (Used to construct workdir names) +NANO_NAME=full + +# Source tree directory +NANO_SRC=/usr/src + +# Where nanobsd additional files live under the source tree +NANO_TOOLS=tools/tools/nanobsd + +# Where cust_pkg() finds packages to install +NANO_PACKAGE_DIR=${NANO_SRC}/${NANO_TOOLS}/Pkg +NANO_PACKAGE_LIST="*" + +# where package metadata gets placed +NANO_PKG_META_BASE=/var/db + +# Object tree directory +# default is subdir of /usr/obj +#NANO_OBJ="" + +# The directory to put the final images +# default is ${NANO_OBJ} +#NANO_DISKIMGDIR="" + +# Make & parallel Make +NANO_MAKE="make" +NANO_PMAKE="make -j 3" + +# The default name for any image we create. +NANO_IMGNAME="_.disk.full" + +# Options to put in make.conf during buildworld only +CONF_BUILD=' ' + +# Options to put in make.conf during installworld only +CONF_INSTALL=' ' + +# Options to put in make.conf during both build- & installworld. +CONF_WORLD=' ' + +# Kernel config file to use +NANO_KERNEL=GENERIC + +# Kernel modules to install. If empty, no modules are installed. +# Use "default" to install all built modules. +NANO_MODULES= + +# Customize commands. +NANO_CUSTOMIZE="" + +# Late customize commands. +NANO_LATE_CUSTOMIZE="" + +# Newfs paramters to use +NANO_NEWFS="-b 4096 -f 512 -i 8192 -U" + +# The drive name of the media at runtime +NANO_DRIVE=ad0 + +# Target media size in 512 bytes sectors +NANO_MEDIASIZE=2000000 + +# Number of code images on media (1 or 2) +NANO_IMAGES=2 + +# 0 -> Leave second image all zeroes so it compresses better. +# 1 -> Initialize second image with a copy of the first +NANO_INIT_IMG2=1 + +# Size of code file system in 512 bytes sectors +# If zero, size will be as large as possible. +NANO_CODESIZE=0 + +# Size of configuration file system in 512 bytes sectors +# Cannot be zero. +NANO_CONFSIZE=2048 + +# Size of data file system in 512 bytes sectors +# If zero: no partition configured. +# If negative: max size possible +NANO_DATASIZE=0 + +# Size of the /etc ramdisk in 512 bytes sectors +NANO_RAM_ETCSIZE=10240 + +# Size of the /tmp+/var ramdisk in 512 bytes sectors +NANO_RAM_TMPVARSIZE=10240 + +# Media geometry, only relevant if bios doesn't understand LBA. +NANO_SECTS=63 +NANO_HEADS=16 + +# boot0 flags/options and configuration +NANO_BOOT0CFG="-o packet -s 1 -m 3" +NANO_BOOTLOADER="boot/boot0sio" + +# boot2 flags/options +# default force serial console +NANO_BOOT2CFG="-h" + +# Backing type of md(4) device +# Can be "file" or "swap" +NANO_MD_BACKING="file" + +# for swap type md(4) backing, write out the mbr only +NANO_IMAGE_MBRONLY=true + +# Progress Print level +PPLEVEL=3 + +# Set NANO_LABEL to non-blank to form the basis for using /dev/ufs/label +# in preference to /dev/${NANO_DRIVE} +# Root partition will be ${NANO_LABEL}s{1,2} +# /cfg partition will be ${NANO_LABEL}s3 +# /data partition will be ${NANO_LABEL}s4 +NANO_LABEL="" + +####################################################################### +# Architecture to build. Corresponds to TARGET_ARCH in a buildworld. +# Unfortunately, there's no way to set TARGET at this time, and it +# conflates the two, so architectures where TARGET != TARGET_ARCH do +# not work. This defaults to the arch of the current machine. + +NANO_ARCH=`uname -p` + +# Directory to populate /cfg from +NANO_CFGDIR="" + +# Directory to populate /data from +NANO_DATADIR="" + +# src.conf to use when building the image. Defaults to /dev/null for the sake +# of determinism. +SRCCONF=${SRCCONF:=/dev/null} + +####################################################################### +# +# The functions which do the real work. +# Can be overridden from the config file(s) +# +####################################################################### + +# rm doesn't know -x prior to FreeBSD 10, so cope with a variety of build +# hosts for now. +nano_rm ( ) { + case $(uname -r) in + 7*|8*|9*) rm $* ;; + *) rm -x $* ;; + esac +} + +# run in the world chroot, errors fatal +CR() +{ + chroot ${NANO_WORLDDIR} /bin/sh -exc "$*" +} + +# run in the world chroot, errors not fatal +CR0() +{ + chroot ${NANO_WORLDDIR} /bin/sh -c "$*" || true +} + +nano_cleanup ( ) ( + if [ $? -ne 0 ]; then + echo "Error encountered. Check for errors in last log file." 1>&2 + fi + exit $? +) + +clean_build ( ) ( + pprint 2 "Clean and create object directory (${MAKEOBJDIRPREFIX})" + + if ! nano_rm -rf ${MAKEOBJDIRPREFIX}/ > /dev/null 2>&1 ; then + chflags -R noschg ${MAKEOBJDIRPREFIX}/ + nano_rm -r ${MAKEOBJDIRPREFIX}/ + fi +) + +make_conf_build ( ) ( + pprint 2 "Construct build make.conf ($NANO_MAKE_CONF_BUILD)" + + mkdir -p ${MAKEOBJDIRPREFIX} + printenv > ${MAKEOBJDIRPREFIX}/_.env + + echo "${CONF_WORLD}" > ${NANO_MAKE_CONF_BUILD} + echo "${CONF_BUILD}" >> ${NANO_MAKE_CONF_BUILD} +) + +build_world ( ) ( + pprint 2 "run buildworld" + pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.bw" + + cd ${NANO_SRC} + env TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} \ + SRCCONF=${SRCCONF} \ + __MAKE_CONF=${NANO_MAKE_CONF_BUILD} buildworld \ + > ${MAKEOBJDIRPREFIX}/_.bw 2>&1 +) + +build_kernel ( ) ( + local extra + + pprint 2 "build kernel ($NANO_KERNEL)" + pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.bk" + + ( + if [ -f ${NANO_KERNEL} ] ; then + kernconfdir_arg="KERNCONFDIR='$(realpath $(dirname ${NANO_KERNEL}))'" + kernconf=$(basename ${NANO_KERNEL}) + else + kernconf=${NANO_KERNEL} + fi + + cd ${NANO_SRC}; + # unset these just in case to avoid compiler complaints + # when cross-building + unset TARGET_CPUTYPE + # Note: We intentionally build all modules, not only the ones in + # NANO_MODULES so the built world can be reused by multiple images. + eval "TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} buildkernel \ + SRCCONF='${SRCCONF}' \ + __MAKE_CONF='${NANO_MAKE_CONF_BUILD}' \ + ${kernconfdir_arg} KERNCONF=${kernconf}" + ) > ${MAKEOBJDIRPREFIX}/_.bk 2>&1 +) + +clean_world ( ) ( + if [ "${NANO_OBJ}" != "${MAKEOBJDIRPREFIX}" ]; then + pprint 2 "Clean and create object directory (${NANO_OBJ})" + if ! nano_rm -rf ${NANO_OBJ}/ > /dev/null 2>&1 ; then + chflags -R noschg ${NANO_OBJ} + nano_rm -r ${NANO_OBJ}/ + fi + mkdir -p ${NANO_OBJ} ${NANO_WORLDDIR} + printenv > ${NANO_OBJ}/_.env + else + pprint 2 "Clean and create world directory (${NANO_WORLDDIR})" + if ! nano_rm -rf ${NANO_WORLDDIR}/ > /dev/null 2>&1 ; then + chflags -R noschg ${NANO_WORLDDIR} + nano_rm -rf ${NANO_WORLDDIR}/ + fi + mkdir -p ${NANO_WORLDDIR} + fi +) + +make_conf_install ( ) ( + pprint 2 "Construct install make.conf ($NANO_MAKE_CONF_INSTALL)" + + echo "${CONF_WORLD}" > ${NANO_MAKE_CONF_INSTALL} + echo "${CONF_INSTALL}" >> ${NANO_MAKE_CONF_INSTALL} +) + +install_world ( ) ( + pprint 2 "installworld" + pprint 3 "log: ${NANO_OBJ}/_.iw" + + cd ${NANO_SRC} + env TARGET_ARCH=${NANO_ARCH} \ + ${NANO_MAKE} SRCCONF=${SRCCONF} \ + __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} installworld \ + DESTDIR=${NANO_WORLDDIR} \ + > ${NANO_OBJ}/_.iw 2>&1 + chflags -R noschg ${NANO_WORLDDIR} +) + +install_etc ( ) ( + + pprint 2 "install /etc" + pprint 3 "log: ${NANO_OBJ}/_.etc" + + cd ${NANO_SRC} + env TARGET_ARCH=${NANO_ARCH} \ + ${NANO_MAKE} SRCCONF=${SRCCONF} \ + __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} distribution \ + DESTDIR=${NANO_WORLDDIR} \ + > ${NANO_OBJ}/_.etc 2>&1 + # make.conf doesn't get created by default, but some ports need it + # so they can spam it. + cp /dev/null ${NANO_WORLDDIR}/etc/make.conf +) + +install_kernel ( ) ( + local extra + + pprint 2 "install kernel ($NANO_KERNEL)" + pprint 3 "log: ${NANO_OBJ}/_.ik" + + ( + if [ -f ${NANO_KERNEL} ] ; then + kernconfdir_arg="KERNCONFDIR='$(realpath $(dirname ${NANO_KERNEL}))'" + kernconf=$(basename ${NANO_KERNEL}) + else + kernconf=${NANO_KERNEL} + fi + + # Install all built modules if NANO_MODULES=default, + # else install only listed modules (none if NANO_MODULES is empty). + if [ "${NANO_MODULES}" != "default" ]; then + modules_override_arg="MODULES_OVERRIDE='${NANO_MODULES}'" + fi + + cd ${NANO_SRC} + eval "TARGET_ARCH=${NANO_ARCH} ${NANO_MAKE} installkernel \ + DESTDIR='${NANO_WORLDDIR}' \ + SRCCONF='${SRCCONF}' \ + __MAKE_CONF='${NANO_MAKE_CONF_INSTALL}' \ + ${kernconfdir_arg} KERNCONF=${kernconf} \ + ${modules_override_arg}" + ) > ${NANO_OBJ}/_.ik 2>&1 +) + +native_xtools ( ) ( + print 2 "Installing the optimized native build tools for cross env" + pprint 3 "log: ${NANO_OBJ}/_.native_xtools" + + cd ${NANO_SRC} + env TARGET_ARCH=${NANO_ARCH} \ + ${NANO_MAKE} SRCCONF=${SRCCONF} \ + __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} native-xtools \ + DESTDIR=${NANO_WORLDDIR} \ + > ${NANO_OBJ}/_.native_xtools 2>&1 +) + +run_customize() ( + + pprint 2 "run customize scripts" + for c in $NANO_CUSTOMIZE + do + pprint 2 "customize \"$c\"" + pprint 3 "log: ${NANO_OBJ}/_.cust.$c" + pprint 4 "`type $c`" + ( set -x ; $c ) > ${NANO_OBJ}/_.cust.$c 2>&1 + done +) + +run_late_customize() ( + + pprint 2 "run late customize scripts" + for c in $NANO_LATE_CUSTOMIZE + do + pprint 2 "late customize \"$c\"" + pprint 3 "log: ${NANO_OBJ}/_.late_cust.$c" + pprint 4 "`type $c`" + ( set -x ; $c ) > ${NANO_OBJ}/_.late_cust.$c 2>&1 + done +) + +setup_nanobsd ( ) ( + pprint 2 "configure nanobsd setup" + pprint 3 "log: ${NANO_OBJ}/_.dl" + + ( + cd ${NANO_WORLDDIR} + + # Move /usr/local/etc to /etc/local so that the /cfg stuff + # can stomp on it. Otherwise packages like ipsec-tools which + # have hardcoded paths under ${prefix}/etc are not tweakable. + if [ -d usr/local/etc ] ; then + ( + mkdir -p etc/local + cd usr/local/etc + find . -print | cpio -dumpl ../../../etc/local + cd .. + nano_rm -rf etc + ln -s ../../etc/local etc + ) + fi + + for d in var etc + do + # link /$d under /conf + # we use hard links so we have them both places. + # the files in /$d will be hidden by the mount. + # XXX: configure /$d ramdisk size + mkdir -p conf/base/$d conf/default/$d + find $d -print | cpio -dumpl conf/base/ + done + + echo "$NANO_RAM_ETCSIZE" > conf/base/etc/md_size + echo "$NANO_RAM_TMPVARSIZE" > conf/base/var/md_size + + # pick up config files from the special partition + echo "mount -o ro /dev/${NANO_DRIVE}s3" > conf/default/etc/remount + + # Put /tmp on the /var ramdisk (could be symlink already) + nano_rm -rf tmp + ln -s var/tmp tmp + + ) > ${NANO_OBJ}/_.dl 2>&1 +) + +setup_nanobsd_etc ( ) ( + pprint 2 "configure nanobsd /etc" + + ( + cd ${NANO_WORLDDIR} + + # create diskless marker file + touch etc/diskless + + # Make root filesystem R/O by default + echo "root_rw_mount=NO" >> etc/defaults/rc.conf + + # save config file for scripts + echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf + + echo "/dev/${NANO_DRIVE}s1a / ufs ro 1 1" > etc/fstab + echo "/dev/${NANO_DRIVE}s3 /cfg ufs rw,noauto 2 2" >> etc/fstab + mkdir -p cfg + ) +) + +prune_usr() ( + + # Remove all empty directories in /usr + find ${NANO_WORLDDIR}/usr -type d -depth -print | + while read d + do + rmdir $d > /dev/null 2>&1 || true + done +) + +newfs_part ( ) ( + local dev mnt lbl + dev=$1 + mnt=$2 + lbl=$3 + echo newfs ${NANO_NEWFS} ${NANO_LABEL:+-L${NANO_LABEL}${lbl}} ${dev} + newfs ${NANO_NEWFS} ${NANO_LABEL:+-L${NANO_LABEL}${lbl}} ${dev} + mount -o async ${dev} ${mnt} +) + +# Convenient spot to work around any umount issues that your build environment +# hits by overriding this method. +nano_umount () ( + umount ${1} +) + +populate_slice ( ) ( + local dev dir mnt lbl + dev=$1 + dir=$2 + mnt=$3 + lbl=$4 + echo "Creating ${dev} (mounting on ${mnt})" + newfs_part ${dev} ${mnt} ${lbl} + if [ -n "${dir}" -a -d "${dir}" ]; then + echo "Populating ${lbl} from ${dir}" + cd ${dir} + find . -print | grep -Ev '/(CVS|\.svn|\.hg|\.git)' | cpio -dumpv ${mnt} + fi + df -i ${mnt} + nano_umount ${mnt} +) + +populate_cfg_slice ( ) ( + populate_slice "$1" "$2" "$3" "$4" +) + +populate_data_slice ( ) ( + populate_slice "$1" "$2" "$3" "$4" +) + +create_diskimage ( ) ( + pprint 2 "build diskimage" + pprint 3 "log: ${NANO_OBJ}/_.di" + + ( + echo $NANO_MEDIASIZE $NANO_IMAGES \ + $NANO_SECTS $NANO_HEADS \ + $NANO_CODESIZE $NANO_CONFSIZE $NANO_DATASIZE | + awk ' + { + printf "# %s\n", $0 + + # size of cylinder in sectors + cs = $3 * $4 + + # number of full cylinders on media + cyl = int ($1 / cs) + + # output fdisk geometry spec, truncate cyls to 1023 + if (cyl <= 1023) + print "g c" cyl " h" $4 " s" $3 + else + print "g c" 1023 " h" $4 " s" $3 + + if ($7 > 0) { + # size of data partition in full cylinders + dsl = int (($7 + cs - 1) / cs) + } else { + dsl = 0; + } + + # size of config partition in full cylinders + csl = int (($6 + cs - 1) / cs) + + if ($5 == 0) { + # size of image partition(s) in full cylinders + isl = int ((cyl - dsl - csl) / $2) + } else { + isl = int (($5 + cs - 1) / cs) + } + + # First image partition start at second track + print "p 1 165 " $3, isl * cs - $3 + c = isl * cs; + + # Second image partition (if any) also starts offset one + # track to keep them identical. + if ($2 > 1) { + print "p 2 165 " $3 + c, isl * cs - $3 + c += isl * cs; + } + + # Config partition starts at cylinder boundary. + print "p 3 165 " c, csl * cs + c += csl * cs + + # Data partition (if any) starts at cylinder boundary. + if ($7 > 0) { + print "p 4 165 " c, dsl * cs + } else if ($7 < 0 && $1 > c) { + print "p 4 165 " c, $1 - c + } else if ($1 < c) { + print "Disk space overcommitted by", \ + c - $1, "sectors" > "/dev/stderr" + exit 2 + } + + # Force slice 1 to be marked active. This is necessary + # for booting the image from a USB device to work. + print "a 1" + } + ' > ${NANO_OBJ}/_.fdisk + + IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME} + MNT=${NANO_OBJ}/_.mnt + mkdir -p ${MNT} + + if [ "${NANO_MD_BACKING}" = "swap" ] ; then + MD=`mdconfig -a -t swap -s ${NANO_MEDIASIZE} -x ${NANO_SECTS} \ + -y ${NANO_HEADS}` + else + echo "Creating md backing file..." + nano_rm -f ${IMG} + dd if=/dev/zero of=${IMG} seek=${NANO_MEDIASIZE} count=0 + MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} \ + -y ${NANO_HEADS}` + fi + + trap "echo 'Running exit trap code' ; df -i ${MNT} ; nano_umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT + + fdisk -i -f ${NANO_OBJ}/_.fdisk ${MD} + fdisk ${MD} + # XXX: params + # XXX: pick up cached boot* files, they may not be in image anymore. + if [ -f ${NANO_WORLDDIR}/${NANO_BOOTLOADER} ]; then + boot0cfg -B -b ${NANO_WORLDDIR}/${NANO_BOOTLOADER} ${NANO_BOOT0CFG} ${MD} + fi + if [ -f ${NANO_WORLDDIR}/boot/boot ]; then + bsdlabel -w -B -b ${NANO_WORLDDIR}/boot/boot ${MD}s1 + else + bsdlabel -w ${MD}s1 + fi + bsdlabel ${MD}s1 + + # Create first image + populate_slice /dev/${MD}s1a ${NANO_WORLDDIR} ${MNT} "s1a" + mount /dev/${MD}s1a ${MNT} + echo "Generating mtree..." + ( cd ${MNT} && mtree -c ) > ${NANO_OBJ}/_.mtree + ( cd ${MNT} && du -k ) > ${NANO_OBJ}/_.du + nano_umount ${MNT} + + if [ $NANO_IMAGES -gt 1 -a $NANO_INIT_IMG2 -gt 0 ] ; then + # Duplicate to second image (if present) + echo "Duplicating to second image..." + dd conv=sparse if=/dev/${MD}s1 of=/dev/${MD}s2 bs=64k + mount /dev/${MD}s2a ${MNT} + for f in ${MNT}/etc/fstab ${MNT}/conf/base/etc/fstab + do + sed -i "" "s=${NANO_DRIVE}s1=${NANO_DRIVE}s2=g" $f + done + nano_umount ${MNT} + # Override the label from the first partition so we + # don't confuse glabel with duplicates. + if [ ! -z ${NANO_LABEL} ]; then + tunefs -L ${NANO_LABEL}"s2a" /dev/${MD}s2a + fi + fi + + # Create Config slice + populate_cfg_slice /dev/${MD}s3 "${NANO_CFGDIR}" ${MNT} "s3" + + # Create Data slice, if any. + if [ $NANO_DATASIZE -ne 0 ] ; then + populate_data_slice /dev/${MD}s4 "${NANO_DATADIR}" ${MNT} "s4" + fi + + if [ "${NANO_MD_BACKING}" = "swap" ] ; then + if [ ${NANO_IMAGE_MBRONLY} ]; then + echo "Writing out _.disk.mbr..." + dd if=/dev/${MD} of=${NANO_DISKIMGDIR}/_.disk.mbr bs=512 count=1 + else + echo "Writing out ${NANO_IMGNAME}..." + dd if=/dev/${MD} of=${IMG} bs=64k + fi + + echo "Writing out ${NANO_IMGNAME}..." + dd conv=sparse if=/dev/${MD} of=${IMG} bs=64k + fi + + if ${do_copyout_partition} ; then + echo "Writing out _.disk.image..." + dd conv=sparse if=/dev/${MD}s1 of=${NANO_DISKIMGDIR}/_.disk.image bs=64k + fi + mdconfig -d -u $MD + + trap - 1 2 15 + trap nano_cleanup EXIT + + ) > ${NANO_OBJ}/_.di 2>&1 +) + +last_orders () ( + # Redefine this function with any last orders you may have + # after the build completed, for instance to copy the finished + # image to a more convenient place: + # cp ${NANO_DISKIMGDIR}/_.disk.image /home/ftp/pub/nanobsd.disk + true +) + +####################################################################### +# +# Optional convenience functions. +# +####################################################################### + +####################################################################### +# Common Flash device geometries +# + +FlashDevice () { + if [ -d ${NANO_TOOLS} ] ; then + . ${NANO_TOOLS}/FlashDevice.sub + else + . ${NANO_SRC}/${NANO_TOOLS}/FlashDevice.sub + fi + sub_FlashDevice $1 $2 +} + +####################################################################### +# USB device geometries +# +# Usage: +# UsbDevice Generic 1000 # a generic flash key sold as having 1GB +# +# This function will set NANO_MEDIASIZE, NANO_HEADS and NANO_SECTS for you. +# +# Note that the capacity of a flash key is usually advertised in MB or +# GB, *not* MiB/GiB. As such, the precise number of cylinders available +# for C/H/S geometry may vary depending on the actual flash geometry. +# +# The following generic device layouts are understood: +# generic An alias for generic-hdd. +# generic-hdd 255H 63S/T xxxxC with no MBR restrictions. +# generic-fdd 64H 32S/T xxxxC with no MBR restrictions. +# +# The generic-hdd device is preferred for flash devices larger than 1GB. +# + +UsbDevice () { + a1=`echo $1 | tr '[:upper:]' '[:lower:]'` + case $a1 in + generic-fdd) + NANO_HEADS=64 + NANO_SECTS=32 + NANO_MEDIASIZE=$(( $2 * 1000 * 1000 / 512 )) + ;; + generic|generic-hdd) + NANO_HEADS=255 + NANO_SECTS=63 + NANO_MEDIASIZE=$(( $2 * 1000 * 1000 / 512 )) + ;; + *) + echo "Unknown USB flash device" + exit 2 + ;; + esac +} + +####################################################################### +# Setup serial console + +cust_comconsole () ( + # Enable getty on console + sed -i "" -e /tty[du]0/s/off/on/ ${NANO_WORLDDIR}/etc/ttys + + # Disable getty on syscons devices + sed -i "" -e '/^ttyv[0-8]/s/ on/ off/' ${NANO_WORLDDIR}/etc/ttys + + # Tell loader to use serial console early. + echo "${NANO_BOOT2CFG}" > ${NANO_WORLDDIR}/boot.config +) + +####################################################################### +# Allow root login via ssh + +cust_allow_ssh_root () ( + sed -i "" -e '/PermitRootLogin/s/.*/PermitRootLogin yes/' \ + ${NANO_WORLDDIR}/etc/ssh/sshd_config +) + +####################################################################### +# Install the stuff under ./Files + +cust_install_files () ( + cd ${NANO_TOOLS}/Files + find . -print | grep -Ev '/(CVS|\.svn|\.hg|\.git)' | cpio -Ldumpv ${NANO_WORLDDIR} +) + +####################################################################### +# Install packages from ${NANO_PACKAGE_DIR} + +cust_pkg () ( + + # If the package directory doesn't exist, we're done. + if [ ! -d ${NANO_PACKAGE_DIR} ]; then + echo "DONE 0 packages" + return 0 + fi + + # Copy packages into chroot + mkdir -p ${NANO_WORLDDIR}/Pkg ${NANO_WORLDDIR}/${NANO_PKG_META_BASE}/pkg + ( + cd ${NANO_PACKAGE_DIR} + find ${NANO_PACKAGE_LIST} -print | + cpio -Ldumpv ${NANO_WORLDDIR}/Pkg + ) + + # Count & report how many we have to install + todo=`ls ${NANO_WORLDDIR}/Pkg | wc -l` + echo "=== TODO: $todo" + ls ${NANO_WORLDDIR}/Pkg + echo "===" + while true + do + # Record how many we have now + have=`ls ${NANO_WORLDDIR}/${NANO_PKG_META_BASE}/pkg | wc -l` + + # Attempt to install more packages + # ...but no more than 200 at a time due to pkg_add's internal + # limitations. + CR0 'ls Pkg/*tbz | xargs -n 200 env PKG_DBDIR='${NANO_PKG_META_BASE}'/pkg pkg_add -v -F' + + # See what that got us + now=`ls ${NANO_WORLDDIR}/${NANO_PKG_META_BASE}/pkg | wc -l` + echo "=== NOW $now" + ls ${NANO_WORLDDIR}/${NANO_PKG_META_BASE}/pkg + echo "===" + + + if [ $now -eq $todo ] ; then + echo "DONE $now packages" + break + elif [ $now -eq $have ] ; then + echo "FAILED: Nothing happened on this pass" + exit 2 + fi + done + nano_rm -rf ${NANO_WORLDDIR}/Pkg +) + +cust_pkgng () ( + + # If the package directory doesn't exist, we're done. + if [ ! -d ${NANO_PACKAGE_DIR} ]; then + echo "DONE 0 packages" + return 0 + fi + + # Find a pkg-* package + for x in `find -s ${NANO_PACKAGE_DIR} -iname 'pkg-*'`; do + _NANO_PKG_PACKAGE=`basename "$x"` + done + if [ -z "${_NANO_PKG_PACKAGE}" -o ! -f "${NANO_PACKAGE_DIR}/${_NANO_PKG_PACKAGE}" ]; then + echo "FAILED: need a pkg/ package for bootstrapping" + exit 2 + fi + + # Copy packages into chroot + mkdir -p ${NANO_WORLDDIR}/Pkg + ( + cd ${NANO_PACKAGE_DIR} + find ${NANO_PACKAGE_LIST} -print | + cpio -Ldumpv ${NANO_WORLDDIR}/Pkg + ) + + #Bootstrap pkg + CR env ASSUME_ALWAYS_YES=YES SIGNATURE_TYPE=none /usr/sbin/pkg add /Pkg/${_NANO_PKG_PACKAGE} + CR pkg -N >/dev/null 2>&1 + if [ "$?" -ne "0" ]; then + echo "FAILED: pkg bootstrapping faied" + exit 2 + fi + nano_rm -f ${NANO_WORLDDIR}/Pkg/pkg-* + + # Count & report how many we have to install + todo=`ls ${NANO_WORLDDIR}/Pkg | /usr/bin/wc -l` + todo=$(expr $todo + 1) # add one for pkg since it is installed already + echo "=== TODO: $todo" + ls ${NANO_WORLDDIR}/Pkg + echo "===" + while true + do + # Record how many we have now + have=$(CR env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg info | /usr/bin/wc -l) + + # Attempt to install more packages + CR0 'ls 'Pkg/*txz' | xargs env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg add' + + # See what that got us + now=$(CR env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg info | /usr/bin/wc -l) + echo "=== NOW $now" + CR env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg info + echo "===" + if [ $now -eq $todo ] ; then + echo "DONE $now packages" + break + elif [ $now -eq $have ] ; then + echo "FAILED: Nothing happened on this pass" + exit 2 + fi + done + nano_rm -rf ${NANO_WORLDDIR}/Pkg +) + +####################################################################### +# Convenience function: +# Register all args as customize function. + +customize_cmd () { + NANO_CUSTOMIZE="$NANO_CUSTOMIZE $*" +} + +####################################################################### +# Convenience function: +# Register all args as late customize function to run just before +# image creation. + +late_customize_cmd () { + NANO_LATE_CUSTOMIZE="$NANO_LATE_CUSTOMIZE $*" +} + +####################################################################### +# +# All set up to go... +# +####################################################################### + +# Progress Print +# Print $2 at level $1. +pprint() ( + if [ "$1" -le $PPLEVEL ]; then + runtime=$(( `date +%s` - $NANO_STARTTIME )) + printf "%s %.${1}s %s\n" "`date -u -r $runtime +%H:%M:%S`" "#####" "$2" 1>&3 + fi +) + +usage () { + ( + echo "Usage: $0 [-bfiKknqvw] [-c config_file]" + echo " -b suppress builds (both kernel and world)" + echo " -c specify config file" + echo " -f suppress code slice extraction" + echo " -i suppress disk image build" + echo " -K suppress installkernel" + echo " -k suppress buildkernel" + echo " -n add -DNO_CLEAN to buildworld, buildkernel, etc" + echo " -q make output more quiet" + echo " -v make output more verbose" + echo " -w suppress buildworld" + ) 1>&2 + exit 2 +} + +####################################################################### +# Setup and Export Internal variables +# + +export_var() { + var=$1 + # Lookup value of the variable. + eval val=\$$var + pprint 3 "Setting variable: $var=\"$val\"" + export $1 +} + +# Call this function to set defaults _after_ parsing options. +set_defaults_and_export() { + test -n "${NANO_OBJ}" || NANO_OBJ=/usr/obj/nanobsd.${NANO_NAME} + test -n "${MAKEOBJDIRPREFIX}" || MAKEOBJDIRPREFIX=${NANO_OBJ} + test -n "${NANO_DISKIMGDIR}" || NANO_DISKIMGDIR=${NANO_OBJ} + NANO_WORLDDIR=${NANO_OBJ}/_.w + NANO_MAKE_CONF_BUILD=${MAKEOBJDIRPREFIX}/make.conf.build + NANO_MAKE_CONF_INSTALL=${NANO_OBJ}/make.conf.install + + # Override user's NANO_DRIVE if they specified a NANO_LABEL + [ ! -z "${NANO_LABEL}" ] && NANO_DRIVE="ufs/${NANO_LABEL}" + + # Set a default NANO_TOOLS to NANO_SRC/NANO_TOOLS if it exists. + [ ! -d "${NANO_TOOLS}" ] && [ -d "${NANO_SRC}/${NANO_TOOLS}" ] && \ + NANO_TOOLS="${NANO_SRC}/${NANO_TOOLS}" + + NANO_STARTTIME=`date +%s` + pprint 3 "Exporting NanoBSD variables" + export_var MAKEOBJDIRPREFIX + export_var NANO_ARCH + export_var NANO_CODESIZE + export_var NANO_CONFSIZE + export_var NANO_CUSTOMIZE + export_var NANO_DATASIZE + export_var NANO_DRIVE + export_var NANO_HEADS + export_var NANO_IMAGES + export_var NANO_IMGNAME + export_var NANO_MAKE + export_var NANO_MAKE_CONF_BUILD + export_var NANO_MAKE_CONF_INSTALL + export_var NANO_MEDIASIZE + export_var NANO_NAME + export_var NANO_NEWFS + export_var NANO_OBJ + export_var NANO_PMAKE + export_var NANO_SECTS + export_var NANO_SRC + export_var NANO_TOOLS + export_var NANO_WORLDDIR + export_var NANO_BOOT0CFG + export_var NANO_BOOTLOADER + export_var NANO_LABEL + export_var NANO_MODULES +} diff --git a/tools/tools/nanobsd/nanobsd.sh b/tools/tools/nanobsd/nanobsd.sh index 7789ef0999b..a4464e0caf5 100644 --- a/tools/tools/nanobsd/nanobsd.sh +++ b/tools/tools/nanobsd/nanobsd.sh @@ -29,900 +29,9 @@ set -e -####################################################################### -# -# Setup default values for all controlling variables. -# These values can be overridden from the config file(s) -# -####################################################################### - -# Name of this NanoBSD build. (Used to construct workdir names) -NANO_NAME=full - -# Source tree directory -NANO_SRC=/usr/src - -# Where nanobsd additional files live under the source tree -NANO_TOOLS=tools/tools/nanobsd - -# Where cust_pkg() finds packages to install -NANO_PACKAGE_DIR=${NANO_SRC}/${NANO_TOOLS}/Pkg -NANO_PACKAGE_LIST="*" - -# where package metadata gets placed -NANO_PKG_META_BASE=/var/db - -# Object tree directory -# default is subdir of /usr/obj -#NANO_OBJ="" - -# The directory to put the final images -# default is ${NANO_OBJ} -#NANO_DISKIMGDIR="" - -# Make & parallel Make -NANO_MAKE="make" -NANO_PMAKE="make -j 3" - -# The default name for any image we create. -NANO_IMGNAME="_.disk.full" - -# Options to put in make.conf during buildworld only -CONF_BUILD=' ' - -# Options to put in make.conf during installworld only -CONF_INSTALL=' ' - -# Options to put in make.conf during both build- & installworld. -CONF_WORLD=' ' - -# Kernel config file to use -NANO_KERNEL=GENERIC - -# Kernel modules to install. If empty, no modules are installed. -# Use "default" to install all built modules. -NANO_MODULES= - -# Customize commands. -NANO_CUSTOMIZE="" - -# Late customize commands. -NANO_LATE_CUSTOMIZE="" - -# Newfs paramters to use -NANO_NEWFS="-b 4096 -f 512 -i 8192 -U" - -# The drive name of the media at runtime -NANO_DRIVE=ad0 - -# Target media size in 512 bytes sectors -NANO_MEDIASIZE=2000000 - -# Number of code images on media (1 or 2) -NANO_IMAGES=2 - -# 0 -> Leave second image all zeroes so it compresses better. -# 1 -> Initialize second image with a copy of the first -NANO_INIT_IMG2=1 - -# Size of code file system in 512 bytes sectors -# If zero, size will be as large as possible. -NANO_CODESIZE=0 - -# Size of configuration file system in 512 bytes sectors -# Cannot be zero. -NANO_CONFSIZE=2048 - -# Size of data file system in 512 bytes sectors -# If zero: no partition configured. -# If negative: max size possible -NANO_DATASIZE=0 - -# Size of the /etc ramdisk in 512 bytes sectors -NANO_RAM_ETCSIZE=10240 - -# Size of the /tmp+/var ramdisk in 512 bytes sectors -NANO_RAM_TMPVARSIZE=10240 - -# Media geometry, only relevant if bios doesn't understand LBA. -NANO_SECTS=63 -NANO_HEADS=16 - -# boot0 flags/options and configuration -NANO_BOOT0CFG="-o packet -s 1 -m 3" -NANO_BOOTLOADER="boot/boot0sio" - -# boot2 flags/options -# default force serial console -NANO_BOOT2CFG="-h" - -# Backing type of md(4) device -# Can be "file" or "swap" -NANO_MD_BACKING="file" - -# for swap type md(4) backing, write out the mbr only -NANO_IMAGE_MBRONLY=true - -# Progress Print level -PPLEVEL=3 - -# Set NANO_LABEL to non-blank to form the basis for using /dev/ufs/label -# in preference to /dev/${NANO_DRIVE} -# Root partition will be ${NANO_LABEL}s{1,2} -# /cfg partition will be ${NANO_LABEL}s3 -# /data partition will be ${NANO_LABEL}s4 -NANO_LABEL="" - -####################################################################### -# Architecture to build. Corresponds to TARGET_ARCH in a buildworld. -# Unfortunately, there's no way to set TARGET at this time, and it -# conflates the two, so architectures where TARGET != TARGET_ARCH do -# not work. This defaults to the arch of the current machine. - -NANO_ARCH=`uname -p` - -# Directory to populate /cfg from -NANO_CFGDIR="" - -# Directory to populate /data from -NANO_DATADIR="" - -# src.conf to use when building the image. Defaults to /dev/null for the sake -# of determinism. -SRCCONF=${SRCCONF:=/dev/null} - -####################################################################### -# -# The functions which do the real work. -# Can be overridden from the config file(s) -# -####################################################################### - -# rm doesn't know -x prior to FreeBSD 10, so cope with a variety of build -# hosts for now. -nano_rm ( ) { - case $(uname -r) in - 7*|8*|9*) rm $* ;; - *) rm -x $* ;; - esac -} - -# run in the world chroot, errors fatal -CR() -{ - chroot ${NANO_WORLDDIR} /bin/sh -exc "$*" -} - -# run in the world chroot, errors not fatal -CR0() -{ - chroot ${NANO_WORLDDIR} /bin/sh -c "$*" || true -} - -nano_cleanup ( ) ( - if [ $? -ne 0 ]; then - echo "Error encountered. Check for errors in last log file." 1>&2 - fi - exit $? -) - -clean_build ( ) ( - pprint 2 "Clean and create object directory (${MAKEOBJDIRPREFIX})" - - if ! nano_rm -rf ${MAKEOBJDIRPREFIX}/ > /dev/null 2>&1 ; then - chflags -R noschg ${MAKEOBJDIRPREFIX}/ - nano_rm -r ${MAKEOBJDIRPREFIX}/ - fi -) - -make_conf_build ( ) ( - pprint 2 "Construct build make.conf ($NANO_MAKE_CONF_BUILD)" - - mkdir -p ${MAKEOBJDIRPREFIX} - printenv > ${MAKEOBJDIRPREFIX}/_.env - - echo "${CONF_WORLD}" > ${NANO_MAKE_CONF_BUILD} - echo "${CONF_BUILD}" >> ${NANO_MAKE_CONF_BUILD} -) - -build_world ( ) ( - pprint 2 "run buildworld" - pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.bw" - - cd ${NANO_SRC} - env TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} \ - SRCCONF=${SRCCONF} \ - __MAKE_CONF=${NANO_MAKE_CONF_BUILD} buildworld \ - > ${MAKEOBJDIRPREFIX}/_.bw 2>&1 -) - -build_kernel ( ) ( - local extra - - pprint 2 "build kernel ($NANO_KERNEL)" - pprint 3 "log: ${MAKEOBJDIRPREFIX}/_.bk" - - ( - if [ -f ${NANO_KERNEL} ] ; then - kernconfdir_arg="KERNCONFDIR='$(realpath $(dirname ${NANO_KERNEL}))'" - kernconf=$(basename ${NANO_KERNEL}) - else - kernconf=${NANO_KERNEL} - fi - - cd ${NANO_SRC}; - # unset these just in case to avoid compiler complaints - # when cross-building - unset TARGET_CPUTYPE - # Note: We intentionally build all modules, not only the ones in - # NANO_MODULES so the built world can be reused by multiple images. - eval "TARGET_ARCH=${NANO_ARCH} ${NANO_PMAKE} buildkernel \ - SRCCONF='${SRCCONF}' \ - __MAKE_CONF='${NANO_MAKE_CONF_BUILD}' \ - ${kernconfdir_arg} KERNCONF=${kernconf}" - ) > ${MAKEOBJDIRPREFIX}/_.bk 2>&1 -) - -clean_world ( ) ( - if [ "${NANO_OBJ}" != "${MAKEOBJDIRPREFIX}" ]; then - pprint 2 "Clean and create object directory (${NANO_OBJ})" - if ! nano_rm -rf ${NANO_OBJ}/ > /dev/null 2>&1 ; then - chflags -R noschg ${NANO_OBJ} - nano_rm -r ${NANO_OBJ}/ - fi - mkdir -p ${NANO_OBJ} ${NANO_WORLDDIR} - printenv > ${NANO_OBJ}/_.env - else - pprint 2 "Clean and create world directory (${NANO_WORLDDIR})" - if ! nano_rm -rf ${NANO_WORLDDIR}/ > /dev/null 2>&1 ; then - chflags -R noschg ${NANO_WORLDDIR} - nano_rm -rf ${NANO_WORLDDIR}/ - fi - mkdir -p ${NANO_WORLDDIR} - fi -) - -make_conf_install ( ) ( - pprint 2 "Construct install make.conf ($NANO_MAKE_CONF_INSTALL)" - - echo "${CONF_WORLD}" > ${NANO_MAKE_CONF_INSTALL} - echo "${CONF_INSTALL}" >> ${NANO_MAKE_CONF_INSTALL} -) - -install_world ( ) ( - pprint 2 "installworld" - pprint 3 "log: ${NANO_OBJ}/_.iw" - - cd ${NANO_SRC} - env TARGET_ARCH=${NANO_ARCH} \ - ${NANO_MAKE} SRCCONF=${SRCCONF} \ - __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} installworld \ - DESTDIR=${NANO_WORLDDIR} \ - > ${NANO_OBJ}/_.iw 2>&1 - chflags -R noschg ${NANO_WORLDDIR} -) - -install_etc ( ) ( - - pprint 2 "install /etc" - pprint 3 "log: ${NANO_OBJ}/_.etc" - - cd ${NANO_SRC} - env TARGET_ARCH=${NANO_ARCH} \ - ${NANO_MAKE} SRCCONF=${SRCCONF} \ - __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} distribution \ - DESTDIR=${NANO_WORLDDIR} \ - > ${NANO_OBJ}/_.etc 2>&1 - # make.conf doesn't get created by default, but some ports need it - # so they can spam it. - cp /dev/null ${NANO_WORLDDIR}/etc/make.conf -) - -install_kernel ( ) ( - local extra - - pprint 2 "install kernel ($NANO_KERNEL)" - pprint 3 "log: ${NANO_OBJ}/_.ik" - - ( - if [ -f ${NANO_KERNEL} ] ; then - kernconfdir_arg="KERNCONFDIR='$(realpath $(dirname ${NANO_KERNEL}))'" - kernconf=$(basename ${NANO_KERNEL}) - else - kernconf=${NANO_KERNEL} - fi - - # Install all built modules if NANO_MODULES=default, - # else install only listed modules (none if NANO_MODULES is empty). - if [ "${NANO_MODULES}" != "default" ]; then - modules_override_arg="MODULES_OVERRIDE='${NANO_MODULES}'" - fi - - cd ${NANO_SRC} - eval "TARGET_ARCH=${NANO_ARCH} ${NANO_MAKE} installkernel \ - DESTDIR='${NANO_WORLDDIR}' \ - SRCCONF='${SRCCONF}' \ - __MAKE_CONF='${NANO_MAKE_CONF_INSTALL}' \ - ${kernconfdir_arg} KERNCONF=${kernconf} \ - ${modules_override_arg}" - ) > ${NANO_OBJ}/_.ik 2>&1 -) - -native_xtools ( ) ( - print 2 "Installing the optimized native build tools for cross env" - pprint 3 "log: ${NANO_OBJ}/_.native_xtools" - - cd ${NANO_SRC} - env TARGET_ARCH=${NANO_ARCH} \ - ${NANO_MAKE} SRCCONF=${SRCCONF} \ - __MAKE_CONF=${NANO_MAKE_CONF_INSTALL} native-xtools \ - DESTDIR=${NANO_WORLDDIR} \ - > ${NANO_OBJ}/_.native_xtools 2>&1 -) - -run_customize() ( - - pprint 2 "run customize scripts" - for c in $NANO_CUSTOMIZE - do - pprint 2 "customize \"$c\"" - pprint 3 "log: ${NANO_OBJ}/_.cust.$c" - pprint 4 "`type $c`" - ( set -x ; $c ) > ${NANO_OBJ}/_.cust.$c 2>&1 - done -) - -run_late_customize() ( - - pprint 2 "run late customize scripts" - for c in $NANO_LATE_CUSTOMIZE - do - pprint 2 "late customize \"$c\"" - pprint 3 "log: ${NANO_OBJ}/_.late_cust.$c" - pprint 4 "`type $c`" - ( set -x ; $c ) > ${NANO_OBJ}/_.late_cust.$c 2>&1 - done -) - -setup_nanobsd ( ) ( - pprint 2 "configure nanobsd setup" - pprint 3 "log: ${NANO_OBJ}/_.dl" - - ( - cd ${NANO_WORLDDIR} - - # Move /usr/local/etc to /etc/local so that the /cfg stuff - # can stomp on it. Otherwise packages like ipsec-tools which - # have hardcoded paths under ${prefix}/etc are not tweakable. - if [ -d usr/local/etc ] ; then - ( - mkdir -p etc/local - cd usr/local/etc - find . -print | cpio -dumpl ../../../etc/local - cd .. - nano_rm -rf etc - ln -s ../../etc/local etc - ) - fi - - for d in var etc - do - # link /$d under /conf - # we use hard links so we have them both places. - # the files in /$d will be hidden by the mount. - # XXX: configure /$d ramdisk size - mkdir -p conf/base/$d conf/default/$d - find $d -print | cpio -dumpl conf/base/ - done - - echo "$NANO_RAM_ETCSIZE" > conf/base/etc/md_size - echo "$NANO_RAM_TMPVARSIZE" > conf/base/var/md_size - - # pick up config files from the special partition - echo "mount -o ro /dev/${NANO_DRIVE}s3" > conf/default/etc/remount - - # Put /tmp on the /var ramdisk (could be symlink already) - nano_rm -rf tmp - ln -s var/tmp tmp - - ) > ${NANO_OBJ}/_.dl 2>&1 -) - -setup_nanobsd_etc ( ) ( - pprint 2 "configure nanobsd /etc" - - ( - cd ${NANO_WORLDDIR} - - # create diskless marker file - touch etc/diskless - - # Make root filesystem R/O by default - echo "root_rw_mount=NO" >> etc/defaults/rc.conf - - # save config file for scripts - echo "NANO_DRIVE=${NANO_DRIVE}" > etc/nanobsd.conf - - echo "/dev/${NANO_DRIVE}s1a / ufs ro 1 1" > etc/fstab - echo "/dev/${NANO_DRIVE}s3 /cfg ufs rw,noauto 2 2" >> etc/fstab - mkdir -p cfg - ) -) - -prune_usr() ( - - # Remove all empty directories in /usr - find ${NANO_WORLDDIR}/usr -type d -depth -print | - while read d - do - rmdir $d > /dev/null 2>&1 || true - done -) - -newfs_part ( ) ( - local dev mnt lbl - dev=$1 - mnt=$2 - lbl=$3 - echo newfs ${NANO_NEWFS} ${NANO_LABEL:+-L${NANO_LABEL}${lbl}} ${dev} - newfs ${NANO_NEWFS} ${NANO_LABEL:+-L${NANO_LABEL}${lbl}} ${dev} - mount -o async ${dev} ${mnt} -) - -# Convenient spot to work around any umount issues that your build environment -# hits by overriding this method. -nano_umount () ( - umount ${1} -) - -populate_slice ( ) ( - local dev dir mnt lbl - dev=$1 - dir=$2 - mnt=$3 - lbl=$4 - echo "Creating ${dev} (mounting on ${mnt})" - newfs_part ${dev} ${mnt} ${lbl} - if [ -n "${dir}" -a -d "${dir}" ]; then - echo "Populating ${lbl} from ${dir}" - cd ${dir} - find . -print | grep -Ev '/(CVS|\.svn|\.hg|\.git)' | cpio -dumpv ${mnt} - fi - df -i ${mnt} - nano_umount ${mnt} -) - -populate_cfg_slice ( ) ( - populate_slice "$1" "$2" "$3" "$4" -) - -populate_data_slice ( ) ( - populate_slice "$1" "$2" "$3" "$4" -) - -create_diskimage ( ) ( - pprint 2 "build diskimage" - pprint 3 "log: ${NANO_OBJ}/_.di" - - ( - echo $NANO_MEDIASIZE $NANO_IMAGES \ - $NANO_SECTS $NANO_HEADS \ - $NANO_CODESIZE $NANO_CONFSIZE $NANO_DATASIZE | - awk ' - { - printf "# %s\n", $0 - - # size of cylinder in sectors - cs = $3 * $4 - - # number of full cylinders on media - cyl = int ($1 / cs) - - # output fdisk geometry spec, truncate cyls to 1023 - if (cyl <= 1023) - print "g c" cyl " h" $4 " s" $3 - else - print "g c" 1023 " h" $4 " s" $3 - - if ($7 > 0) { - # size of data partition in full cylinders - dsl = int (($7 + cs - 1) / cs) - } else { - dsl = 0; - } - - # size of config partition in full cylinders - csl = int (($6 + cs - 1) / cs) - - if ($5 == 0) { - # size of image partition(s) in full cylinders - isl = int ((cyl - dsl - csl) / $2) - } else { - isl = int (($5 + cs - 1) / cs) - } - - # First image partition start at second track - print "p 1 165 " $3, isl * cs - $3 - c = isl * cs; - - # Second image partition (if any) also starts offset one - # track to keep them identical. - if ($2 > 1) { - print "p 2 165 " $3 + c, isl * cs - $3 - c += isl * cs; - } - - # Config partition starts at cylinder boundary. - print "p 3 165 " c, csl * cs - c += csl * cs - - # Data partition (if any) starts at cylinder boundary. - if ($7 > 0) { - print "p 4 165 " c, dsl * cs - } else if ($7 < 0 && $1 > c) { - print "p 4 165 " c, $1 - c - } else if ($1 < c) { - print "Disk space overcommitted by", \ - c - $1, "sectors" > "/dev/stderr" - exit 2 - } - - # Force slice 1 to be marked active. This is necessary - # for booting the image from a USB device to work. - print "a 1" - } - ' > ${NANO_OBJ}/_.fdisk - - IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME} - MNT=${NANO_OBJ}/_.mnt - mkdir -p ${MNT} - - if [ "${NANO_MD_BACKING}" = "swap" ] ; then - MD=`mdconfig -a -t swap -s ${NANO_MEDIASIZE} -x ${NANO_SECTS} \ - -y ${NANO_HEADS}` - else - echo "Creating md backing file..." - nano_rm -f ${IMG} - dd if=/dev/zero of=${IMG} seek=${NANO_MEDIASIZE} count=0 - MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} \ - -y ${NANO_HEADS}` - fi - - trap "echo 'Running exit trap code' ; df -i ${MNT} ; nano_umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT - - fdisk -i -f ${NANO_OBJ}/_.fdisk ${MD} - fdisk ${MD} - # XXX: params - # XXX: pick up cached boot* files, they may not be in image anymore. - if [ -f ${NANO_WORLDDIR}/${NANO_BOOTLOADER} ]; then - boot0cfg -B -b ${NANO_WORLDDIR}/${NANO_BOOTLOADER} ${NANO_BOOT0CFG} ${MD} - fi - if [ -f ${NANO_WORLDDIR}/boot/boot ]; then - bsdlabel -w -B -b ${NANO_WORLDDIR}/boot/boot ${MD}s1 - else - bsdlabel -w ${MD}s1 - fi - bsdlabel ${MD}s1 - - # Create first image - populate_slice /dev/${MD}s1a ${NANO_WORLDDIR} ${MNT} "s1a" - mount /dev/${MD}s1a ${MNT} - echo "Generating mtree..." - ( cd ${MNT} && mtree -c ) > ${NANO_OBJ}/_.mtree - ( cd ${MNT} && du -k ) > ${NANO_OBJ}/_.du - nano_umount ${MNT} - - if [ $NANO_IMAGES -gt 1 -a $NANO_INIT_IMG2 -gt 0 ] ; then - # Duplicate to second image (if present) - echo "Duplicating to second image..." - dd conv=sparse if=/dev/${MD}s1 of=/dev/${MD}s2 bs=64k - mount /dev/${MD}s2a ${MNT} - for f in ${MNT}/etc/fstab ${MNT}/conf/base/etc/fstab - do - sed -i "" "s=${NANO_DRIVE}s1=${NANO_DRIVE}s2=g" $f - done - nano_umount ${MNT} - # Override the label from the first partition so we - # don't confuse glabel with duplicates. - if [ ! -z ${NANO_LABEL} ]; then - tunefs -L ${NANO_LABEL}"s2a" /dev/${MD}s2a - fi - fi - - # Create Config slice - populate_cfg_slice /dev/${MD}s3 "${NANO_CFGDIR}" ${MNT} "s3" - - # Create Data slice, if any. - if [ $NANO_DATASIZE -ne 0 ] ; then - populate_data_slice /dev/${MD}s4 "${NANO_DATADIR}" ${MNT} "s4" - fi - - if [ "${NANO_MD_BACKING}" = "swap" ] ; then - if [ ${NANO_IMAGE_MBRONLY} ]; then - echo "Writing out _.disk.mbr..." - dd if=/dev/${MD} of=${NANO_DISKIMGDIR}/_.disk.mbr bs=512 count=1 - else - echo "Writing out ${NANO_IMGNAME}..." - dd if=/dev/${MD} of=${IMG} bs=64k - fi - - echo "Writing out ${NANO_IMGNAME}..." - dd conv=sparse if=/dev/${MD} of=${IMG} bs=64k - fi - - if ${do_copyout_partition} ; then - echo "Writing out _.disk.image..." - dd conv=sparse if=/dev/${MD}s1 of=${NANO_DISKIMGDIR}/_.disk.image bs=64k - fi - mdconfig -d -u $MD - - trap - 1 2 15 - trap nano_cleanup EXIT - - ) > ${NANO_OBJ}/_.di 2>&1 -) - -last_orders () ( - # Redefine this function with any last orders you may have - # after the build completed, for instance to copy the finished - # image to a more convenient place: - # cp ${NANO_DISKIMGDIR}/_.disk.image /home/ftp/pub/nanobsd.disk - true -) - -####################################################################### -# -# Optional convenience functions. -# -####################################################################### - -####################################################################### -# Common Flash device geometries -# - -FlashDevice () { - if [ -d ${NANO_TOOLS} ] ; then - . ${NANO_TOOLS}/FlashDevice.sub - else - . ${NANO_SRC}/${NANO_TOOLS}/FlashDevice.sub - fi - sub_FlashDevice $1 $2 -} - -####################################################################### -# USB device geometries -# -# Usage: -# UsbDevice Generic 1000 # a generic flash key sold as having 1GB -# -# This function will set NANO_MEDIASIZE, NANO_HEADS and NANO_SECTS for you. -# -# Note that the capacity of a flash key is usually advertised in MB or -# GB, *not* MiB/GiB. As such, the precise number of cylinders available -# for C/H/S geometry may vary depending on the actual flash geometry. -# -# The following generic device layouts are understood: -# generic An alias for generic-hdd. -# generic-hdd 255H 63S/T xxxxC with no MBR restrictions. -# generic-fdd 64H 32S/T xxxxC with no MBR restrictions. -# -# The generic-hdd device is preferred for flash devices larger than 1GB. -# - -UsbDevice () { - a1=`echo $1 | tr '[:upper:]' '[:lower:]'` - case $a1 in - generic-fdd) - NANO_HEADS=64 - NANO_SECTS=32 - NANO_MEDIASIZE=$(( $2 * 1000 * 1000 / 512 )) - ;; - generic|generic-hdd) - NANO_HEADS=255 - NANO_SECTS=63 - NANO_MEDIASIZE=$(( $2 * 1000 * 1000 / 512 )) - ;; - *) - echo "Unknown USB flash device" - exit 2 - ;; - esac -} - -####################################################################### -# Setup serial console - -cust_comconsole () ( - # Enable getty on console - sed -i "" -e /tty[du]0/s/off/on/ ${NANO_WORLDDIR}/etc/ttys - - # Disable getty on syscons devices - sed -i "" -e '/^ttyv[0-8]/s/ on/ off/' ${NANO_WORLDDIR}/etc/ttys - - # Tell loader to use serial console early. - echo "${NANO_BOOT2CFG}" > ${NANO_WORLDDIR}/boot.config -) - -####################################################################### -# Allow root login via ssh - -cust_allow_ssh_root () ( - sed -i "" -e '/PermitRootLogin/s/.*/PermitRootLogin yes/' \ - ${NANO_WORLDDIR}/etc/ssh/sshd_config -) - -####################################################################### -# Install the stuff under ./Files - -cust_install_files () ( - cd ${NANO_TOOLS}/Files - find . -print | grep -Ev '/(CVS|\.svn|\.hg|\.git)' | cpio -Ldumpv ${NANO_WORLDDIR} -) - -####################################################################### -# Install packages from ${NANO_PACKAGE_DIR} - -cust_pkg () ( - - # If the package directory doesn't exist, we're done. - if [ ! -d ${NANO_PACKAGE_DIR} ]; then - echo "DONE 0 packages" - return 0 - fi - - # Copy packages into chroot - mkdir -p ${NANO_WORLDDIR}/Pkg ${NANO_WORLDDIR}/${NANO_PKG_META_BASE}/pkg - ( - cd ${NANO_PACKAGE_DIR} - find ${NANO_PACKAGE_LIST} -print | - cpio -Ldumpv ${NANO_WORLDDIR}/Pkg - ) - - # Count & report how many we have to install - todo=`ls ${NANO_WORLDDIR}/Pkg | wc -l` - echo "=== TODO: $todo" - ls ${NANO_WORLDDIR}/Pkg - echo "===" - while true - do - # Record how many we have now - have=`ls ${NANO_WORLDDIR}/${NANO_PKG_META_BASE}/pkg | wc -l` - - # Attempt to install more packages - # ...but no more than 200 at a time due to pkg_add's internal - # limitations. - CR0 'ls Pkg/*tbz | xargs -n 200 env PKG_DBDIR='${NANO_PKG_META_BASE}'/pkg pkg_add -v -F' - - # See what that got us - now=`ls ${NANO_WORLDDIR}/${NANO_PKG_META_BASE}/pkg | wc -l` - echo "=== NOW $now" - ls ${NANO_WORLDDIR}/${NANO_PKG_META_BASE}/pkg - echo "===" - - - if [ $now -eq $todo ] ; then - echo "DONE $now packages" - break - elif [ $now -eq $have ] ; then - echo "FAILED: Nothing happened on this pass" - exit 2 - fi - done - nano_rm -rf ${NANO_WORLDDIR}/Pkg -) - -cust_pkgng () ( - - # If the package directory doesn't exist, we're done. - if [ ! -d ${NANO_PACKAGE_DIR} ]; then - echo "DONE 0 packages" - return 0 - fi - - # Find a pkg-* package - for x in `find -s ${NANO_PACKAGE_DIR} -iname 'pkg-*'`; do - _NANO_PKG_PACKAGE=`basename "$x"` - done - if [ -z "${_NANO_PKG_PACKAGE}" -o ! -f "${NANO_PACKAGE_DIR}/${_NANO_PKG_PACKAGE}" ]; then - echo "FAILED: need a pkg/ package for bootstrapping" - exit 2 - fi - - # Copy packages into chroot - mkdir -p ${NANO_WORLDDIR}/Pkg - ( - cd ${NANO_PACKAGE_DIR} - find ${NANO_PACKAGE_LIST} -print | - cpio -Ldumpv ${NANO_WORLDDIR}/Pkg - ) - - #Bootstrap pkg - CR env ASSUME_ALWAYS_YES=YES SIGNATURE_TYPE=none /usr/sbin/pkg add /Pkg/${_NANO_PKG_PACKAGE} - CR pkg -N >/dev/null 2>&1 - if [ "$?" -ne "0" ]; then - echo "FAILED: pkg bootstrapping faied" - exit 2 - fi - nano_rm -f ${NANO_WORLDDIR}/Pkg/pkg-* - - # Count & report how many we have to install - todo=`ls ${NANO_WORLDDIR}/Pkg | /usr/bin/wc -l` - todo=$(expr $todo + 1) # add one for pkg since it is installed already - echo "=== TODO: $todo" - ls ${NANO_WORLDDIR}/Pkg - echo "===" - while true - do - # Record how many we have now - have=$(CR env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg info | /usr/bin/wc -l) - - # Attempt to install more packages - CR0 'ls 'Pkg/*txz' | xargs env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg add' - - # See what that got us - now=$(CR env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg info | /usr/bin/wc -l) - echo "=== NOW $now" - CR env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg info - echo "===" - if [ $now -eq $todo ] ; then - echo "DONE $now packages" - break - elif [ $now -eq $have ] ; then - echo "FAILED: Nothing happened on this pass" - exit 2 - fi - done - nano_rm -rf ${NANO_WORLDDIR}/Pkg -) - -####################################################################### -# Convenience function: -# Register all args as customize function. - -customize_cmd () { - NANO_CUSTOMIZE="$NANO_CUSTOMIZE $*" -} - -####################################################################### -# Convenience function: -# Register all args as late customize function to run just before -# image creation. - -late_customize_cmd () { - NANO_LATE_CUSTOMIZE="$NANO_LATE_CUSTOMIZE $*" -} - -####################################################################### -# -# All set up to go... -# -####################################################################### - -# Progress Print -# Print $2 at level $1. -pprint() ( - if [ "$1" -le $PPLEVEL ]; then - runtime=$(( `date +%s` - $NANO_STARTTIME )) - printf "%s %.${1}s %s\n" "`date -u -r $runtime +%H:%M:%S`" "#####" "$2" 1>&3 - fi -) - -usage () { - ( - echo "Usage: $0 [-bfiKknqvw] [-c config_file]" - echo " -b suppress builds (both kernel and world)" - echo " -c specify config file" - echo " -f suppress code slice extraction" - echo " -i suppress disk image build" - echo " -K suppress installkernel" - echo " -k suppress buildkernel" - echo " -n add -DNO_CLEAN to buildworld, buildkernel, etc" - echo " -q make output more quiet" - echo " -v make output more verbose" - echo " -w suppress buildworld" - ) 1>&2 - exit 2 -} +nanobsd_sh=`realpath $0` +topdir=`dirname ${nanobsd_sh}` +. "${topdir}/defaults.sh" ####################################################################### # Parse arguments @@ -1012,74 +121,22 @@ if [ $# -gt 0 ] ; then usage fi -trap nano_cleanup EXIT - -####################################################################### -# Setup and Export Internal variables -# -test -n "${NANO_OBJ}" || NANO_OBJ=/usr/obj/nanobsd.${NANO_NAME} -test -n "${MAKEOBJDIRPREFIX}" || MAKEOBJDIRPREFIX=${NANO_OBJ} -test -n "${NANO_DISKIMGDIR}" || NANO_DISKIMGDIR=${NANO_OBJ} - -NANO_WORLDDIR=${NANO_OBJ}/_.w -NANO_MAKE_CONF_BUILD=${MAKEOBJDIRPREFIX}/make.conf.build -NANO_MAKE_CONF_INSTALL=${NANO_OBJ}/make.conf.install - -if [ -d ${NANO_TOOLS} ] ; then - true -elif [ -d ${NANO_SRC}/${NANO_TOOLS} ] ; then - NANO_TOOLS=${NANO_SRC}/${NANO_TOOLS} -else +if [ ! -d "${NANO_TOOLS}" ]; then echo "NANO_TOOLS directory does not exist" 1>&2 exit 1 fi -if $do_clean ; then - true -else - NANO_MAKE="${NANO_MAKE} -DNO_CLEAN" +if ! $do_clean; then NANO_PMAKE="${NANO_PMAKE} -DNO_CLEAN" fi -# Override user's NANO_DRIVE if they specified a NANO_LABEL -if [ ! -z "${NANO_LABEL}" ]; then - NANO_DRIVE=ufs/${NANO_LABEL} -fi - -export MAKEOBJDIRPREFIX - -export NANO_ARCH -export NANO_CODESIZE -export NANO_CONFSIZE -export NANO_CUSTOMIZE -export NANO_DATASIZE -export NANO_DRIVE -export NANO_HEADS -export NANO_IMAGES -export NANO_IMGNAME -export NANO_MAKE -export NANO_MAKE_CONF_BUILD -export NANO_MAKE_CONF_INSTALL -export NANO_MEDIASIZE -export NANO_NAME -export NANO_NEWFS -export NANO_OBJ -export NANO_PMAKE -export NANO_SECTS -export NANO_SRC -export NANO_TOOLS -export NANO_WORLDDIR -export NANO_BOOT0CFG -export NANO_BOOTLOADER -export NANO_LABEL - ####################################################################### # And then it is as simple as that... # File descriptor 3 is used for logging output, see pprint exec 3>&1 +set_defaults_and_export -NANO_STARTTIME=`date +%s` pprint 1 "NanoBSD image ${NANO_NAME} build starting" if $do_world ; then From 2d45c2d52dfd81603621506119de8acbfbb21831 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 16 Dec 2014 18:28:33 +0000 Subject: [PATCH 32/64] The iret instruction may generate #np and #ss fault, besides #gp. When returning to usermode, the handler for that exceptions is also executed with wrong gs base. Handle all three possible faults in the same way, checking for iret fault, and performing full iret. Sponsored by: The FreeBSD Foundation MFC after: 3 days --- sys/amd64/amd64/exception.S | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S index 2a908a980f8..71f16746e64 100644 --- a/sys/amd64/amd64/exception.S +++ b/sys/amd64/amd64/exception.S @@ -153,9 +153,13 @@ IDTVEC(xmm) IDTVEC(tss) TRAP_ERR(T_TSSFLT) IDTVEC(missing) - TRAP_ERR(T_SEGNPFLT) + subq $TF_ERR,%rsp + movl $T_SEGNPFLT,TF_TRAPNO(%rsp) + jmp prot_addrf IDTVEC(stk) - TRAP_ERR(T_STKFLT) + subq $TF_ERR,%rsp + movl $T_STKFLT,TF_TRAPNO(%rsp) + jmp prot_addrf IDTVEC(align) TRAP_ERR(T_ALIGNFLT) @@ -318,6 +322,7 @@ IDTVEC(page) IDTVEC(prot) subq $TF_ERR,%rsp movl $T_PROTFLT,TF_TRAPNO(%rsp) +prot_addrf: movq $0,TF_ADDR(%rsp) movq %rdi,TF_RDI(%rsp) /* free up a GP register */ leaq doreti_iret(%rip),%rdi From a34b42e43c16c2d2ba96666b845971ba9a4481a0 Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Tue, 16 Dec 2014 20:26:11 +0000 Subject: [PATCH 33/64] sed: Bounds check the file path used in the 'w' command. Modified version of a diff from Sebastien Marie to prevent a crash found with the afl fuzzer. Obtained from: OpenBSD (CVS Rev. 1.37) MFC after: 1 week --- usr.bin/sed/compile.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/usr.bin/sed/compile.c b/usr.bin/sed/compile.c index e14666883d0..c7fbe21f9d2 100644 --- a/usr.bin/sed/compile.c +++ b/usr.bin/sed/compile.c @@ -558,7 +558,7 @@ compile_flags(char *p, struct s_subst *s) { int gn; /* True if we have seen g or n */ unsigned long nval; - char wfile[_POSIX2_LINE_MAX + 1], *q; + char wfile[_POSIX2_LINE_MAX + 1], *q, *eq; s->n = 1; /* Default */ s->p = 0; @@ -611,9 +611,12 @@ compile_flags(char *p, struct s_subst *s) #endif EATSPACE(); q = wfile; + eq = wfile + sizeof(wfile) - 1; while (*p) { if (*p == '\n') break; + if (q >= eq) + err(1, "wfile too long"); *q++ = *p++; } *q = '\0'; From 5f25ee9cef214e9fc8253d16401ed25836ab6617 Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Tue, 16 Dec 2014 20:45:17 +0000 Subject: [PATCH 34/64] Add an UPDATING entry and warning about the change in r274807 to help users transition to the new behavior. Discussed with: jmallett Sponsored by: DARPA, AFRL --- Makefile.inc1 | 2 ++ UPDATING | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/Makefile.inc1 b/Makefile.inc1 index c07cd5167ce..c7cb8ef0182 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -113,6 +113,8 @@ _REDUNDENT_LIB_DIRS+= ${LOCAL_LIB_DIRS:M${_DIR}*} .for _DIR in ${LOCAL_LIB_DIRS} .if empty(_REDUNDENT_LIB_DIRS:M${_DIR}) && exists(${.CURDIR}/${_DIR}/Makefile) SUBDIR+= ${_DIR} +.else +.warning ${_DIR} not added to SUBDIR list. See UPDATING 20141121. .endif .endfor .endif diff --git a/UPDATING b/UPDATING index b9a7b3552fb..89a2de7deb1 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20141121: + The handling of LOCAL_LIB_DIRS has been altered to skip addition of + directories to top level SUBDIR variable when their parent + directory is included in LOCAL_DIRS. Users with build systems with + such hierarchies and without SUBDIR entries in the parent + directory Makefiles should add them or add the directories to + LOCAL_DIRS. + 20141109: faith(4) and faithd(8) has been removed from base system. It has been obsolete for a very long time. From cb7430346d546572e2f0163ab36e13e9eb678614 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 16 Dec 2014 21:51:21 +0000 Subject: [PATCH 35/64] Do not count RCTD bit set as an error. We can not really implement it, but specification tells that it "shall" work, so it can be safely ignored. MFC after: 1 week --- sys/cam/ctl/ctl_cmd_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/cam/ctl/ctl_cmd_table.c b/sys/cam/ctl/ctl_cmd_table.c index 24c0091d614..b07ea935570 100644 --- a/sys/cam/ctl/ctl_cmd_table.c +++ b/sys/cam/ctl/ctl_cmd_table.c @@ -513,7 +513,7 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] = CTL_FLAG_DATA_IN | CTL_CMD_FLAG_ALLOW_ON_PR_RESV, CTL_LUN_PAT_NONE, - 12, {0x0c, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, + 12, {0x0c, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, /* 0D REPORT SUPPORTED_TASK MANAGEMENT FUNCTIONS */ {ctl_report_supported_tmf, CTL_SERIDX_INQ, CTL_CMD_FLAG_OK_ON_BOTH | From c40c0dcc50043c1f440bca54c9d731eeec13678a Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 16 Dec 2014 23:25:12 +0000 Subject: [PATCH 36/64] Bring in unbound fixes for CVE-2014-8602 to ease future code import. --- iterator/iterator.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ iterator/iterator.h | 6 ++++++ 2 files changed, 50 insertions(+) diff --git a/iterator/iterator.c b/iterator/iterator.c index 87fac81f38c..dc93443e88f 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -120,6 +120,7 @@ iter_new(struct module_qstate* qstate, int id) iq->query_restart_count = 0; iq->referral_count = 0; iq->sent_count = 0; + iq->target_count = NULL; iq->wait_priming_stub = 0; iq->refetch_glue = 0; iq->dnssec_expected = 0; @@ -445,6 +446,26 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq, return 1; } +/** create target count structure for this query */ +static void +target_count_create(struct iter_qstate* iq) +{ + if(!iq->target_count) { + iq->target_count = (int*)calloc(2, sizeof(int)); + /* if calloc fails we simply do not track this number */ + if(iq->target_count) + iq->target_count[0] = 1; + } +} + +static void +target_count_increase(struct iter_qstate* iq, int num) +{ + target_count_create(iq); + if(iq->target_count) + iq->target_count[1] += num; +} + /** * Generate a subrequest. * Generate a local request event. Local events are tied to this module, and @@ -516,6 +537,10 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, subiq = (struct iter_qstate*)subq->minfo[id]; memset(subiq, 0, sizeof(*subiq)); subiq->num_target_queries = 0; + target_count_create(iq); + subiq->target_count = iq->target_count; + if(iq->target_count) + iq->target_count[0] ++; /* extra reference */ subiq->num_current_queries = 0; subiq->depth = iq->depth+1; outbound_list_init(&subiq->outlist); @@ -1342,6 +1367,12 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq, if(iq->depth == ie->max_dependency_depth) return 0; + if(iq->depth > 0 && iq->target_count && + iq->target_count[1] > MAX_TARGET_COUNT) { + verbose(VERB_QUERY, "request has exceeded the maximum " + "number of glue fetches %d", iq->target_count[1]); + return 0; + } iter_mark_cycle_targets(qstate, iq->dp); missing = (int)delegpt_count_missing_targets(iq->dp); @@ -1524,6 +1555,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, return error_response(qstate, id, LDNS_RCODE_SERVFAIL); } iq->num_target_queries += qs; + target_count_increase(iq, qs); if(qs != 0) { qstate->ext_state[id] = module_wait_subquery; return 0; /* and wait for them */ @@ -1533,6 +1565,12 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, verbose(VERB_QUERY, "maxdepth and need more nameservers, fail"); return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); } + if(iq->depth > 0 && iq->target_count && + iq->target_count[1] > MAX_TARGET_COUNT) { + verbose(VERB_QUERY, "request has exceeded the maximum " + "number of glue fetches %d", iq->target_count[1]); + return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); + } /* mark cycle targets for parent-side lookups */ iter_mark_pside_cycle_targets(qstate, iq->dp); /* see if we can issue queries to get nameserver addresses */ @@ -1562,6 +1600,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, if(query_count != 0) { /* suspend to await results */ verbose(VERB_ALGO, "try parent-side glue lookup"); iq->num_target_queries += query_count; + target_count_increase(iq, query_count); qstate->ext_state[id] = module_wait_subquery; return 0; } @@ -1717,6 +1756,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, return error_response(qstate, id, LDNS_RCODE_SERVFAIL); } iq->num_target_queries += extra; + target_count_increase(iq, extra); if(iq->num_target_queries > 0) { /* wait to get all targets, we want to try em */ verbose(VERB_ALGO, "wait for all targets for fallback"); @@ -1757,6 +1797,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, /* errors ignored, these targets are not strictly necessary for * this result, we do not have to reply with SERVFAIL */ iq->num_target_queries += extra; + target_count_increase(iq, extra); } /* Add the current set of unused targets to our queue. */ @@ -1802,6 +1843,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, return 1; } iq->num_target_queries += qs; + target_count_increase(iq, qs); } /* Since a target query might have been made, we * need to check again. */ @@ -2894,6 +2936,8 @@ iter_clear(struct module_qstate* qstate, int id) iq = (struct iter_qstate*)qstate->minfo[id]; if(iq) { outbound_list_clear(&iq->outlist); + if(iq->target_count && --iq->target_count[0] == 0) + free(iq->target_count); iq->num_current_queries = 0; } qstate->minfo[id] = NULL; diff --git a/iterator/iterator.h b/iterator/iterator.h index 1816d12cd03..f6aee34a65a 100644 --- a/iterator/iterator.h +++ b/iterator/iterator.h @@ -52,6 +52,8 @@ struct iter_donotq; struct iter_prep_list; struct iter_priv; +/** max number of targets spawned for a query and its subqueries */ +#define MAX_TARGET_COUNT 32 /** max number of query restarts. Determines max number of CNAME chain. */ #define MAX_RESTART_COUNT 8 /** max number of referrals. Makes sure resolver does not run away */ @@ -254,6 +256,10 @@ struct iter_qstate { /** number of queries fired off */ int sent_count; + + /** number of target queries spawned in [1], for this query and its + * subqueries, the malloced-array is shared, [0] refcount. */ + int* target_count; /** * The query must store NS records from referrals as parentside RRs From 9ad184a98ca85fb8de404938a8b65f79d8bff237 Mon Sep 17 00:00:00 2001 From: Will Andrews Date: Wed, 17 Dec 2014 00:22:41 +0000 Subject: [PATCH 37/64] Initialize an argument to NULL instead of expecting dlinfo() to do it. dlinfo() is a weak reference that may not be initialized at the time of execution. The default implementation (in lib/libc/gen/dlfcn.c) neither modifies the address pointed to by the third argument nor returns an error. Differential Revision: https://reviews.freebsd.org/D1326 Reviewed by: markj MFC after: 1 week --- cddl/contrib/opensolaris/lib/libdtrace/common/drti.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c index ccd4f9b7fb8..fc86eb79522 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c @@ -110,7 +110,7 @@ dtrace_dof_init(void) Elf32_Ehdr *elf; #endif dof_helper_t dh; - Link_map *lmp; + Link_map *lmp = NULL; #if defined(sun) Lmid_t lmid; #else From 27ae6f4af7fb2f63316b4c7668041543de5af11b Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Wed, 17 Dec 2014 01:32:27 +0000 Subject: [PATCH 38/64] Add some additional clarification and fix a few gammer nits. Reviewed by: kib MFC after: 3 weeks --- lib/libc/sys/procctl.2 | 124 ++++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 58 deletions(-) diff --git a/lib/libc/sys/procctl.2 b/lib/libc/sys/procctl.2 index a5d3d899031..b88aa330cec 100644 --- a/lib/libc/sys/procctl.2 +++ b/lib/libc/sys/procctl.2 @@ -101,25 +101,25 @@ Future child processes will also mark all of their future child processes. .El .It Dv PROC_REAP_ACQUIRE Acquires the reaper status for the current process. -The status means that orphaned children by the reaper descendants, -forked after the acquisition of the status, are reparented to the +The status means that children orphaned by the reaper's descendants +that were forked after the acquisition of the status are reparented to the reaper. After the system initialization, .Xr init 8 is the default reaper. .Pp .It Dv PROC_REAP_RELEASE -Releases the reaper state fpr the current process. +Releases the reaper state for the current process. The reaper of the current process becomes the new reaper of the -current process descendants. +current process's descendants. .It Dv PROC_REAP_STATUS Provides the information about the reaper of the specified process, -or the process itself, in case it is a reaper. +or the process itself when it is a reaper. The .Fa data -argument must point to the -.Vt "struct procctl_reaper_status" , -which if filled by the syscall on successfull return. +argument must point to a +.Vt procctl_reaper_status +structure which is filled in by the syscall on successful return. .Bd -literal struct procctl_reaper_status { u_int rs_flags; @@ -134,57 +134,62 @@ The may have the following flags returned: .Bl -tag -width "Dv REAPER_STATUS_REALINIT" .It Dv REAPER_STATUS_OWNED -The specified process has acquired the reaper status and did not +The specified process has acquired the reaper status and has not released it. -When the flag is returned, the -.Fa id -pid identifies reaper, otherwise the +When the flag is returned, the specified process +.Fa id , +pid, identifies the reaper, otherwise the .Fa rs_reaper -field of the structure is the pid of the reaper for passed process id. +field of the structure is set to the pid of the reaper +for the specified process id. .It Dv REAPER_STATUS_REALINIT The specified process is the root of the reaper tree, i.e. -.Xr init 8. +.Xr init 8 . .El The .Fa rs_children -returns the number of the children of the reaper. +field returns the number of children of the reaper. The .Fa rs_descendants -returns the total number of descendants of the reaper, -not counting descendants of the reapers in the subtree. +field returns the total number of descendants of the reaper(s), +not counting descendants of the reaper in the subtree. The .Fa rs_reaper -returns the reaper pid. +field returns the reaper pid. The .Fa rs_pid -returns pid of some reaper child if there is any descendant. +returns the pid of one reaper child if there are any descendants. .It Dv PROC_REAP_GETPIDS Queries the list of descendants of the reaper of the specified process. -The request takes the pointer to -.Vt "struct procctl_reaper_pids" -as -.Fa data . +The request takes a pointer to a +.Vt procctl_reaper_pids +structure in the +.Fa data +parameter. .Bd -literal struct procctl_reaper_pids { u_int rp_count; struct procctl_reaper_pidinfo *rp_pids; }; .Ed -On call, the +When called, the .Fa rp_pids -must point to the array of +field must point to an array of .Vt procctl_reaper_pidinfo -structures, to be filled on return, +structures, to be filled in on return, and the .Fa rp_count -must specify the size of the array, -no more than rp_count elements is filled by kernel. +field must specify the size of the array, +into which no more than +.Fa rp_count +elements will be filled in by the kernel. .Pp The .Vt "struct procctl_reaper_pidinfo" -structure provides some information about one reaper' descendant. -Note that for the descendant which is not child, it is the subject -of usual race with process exiting and pid reuse. +structure provides some information about one of the reaper's descendants. +Note that for a descendant that is not a child, it may be incorrectly +identified because of a race in which the original child process exited +and the exited process's pid was reused for an unrelated process. .Bd -literal struct procctl_reaper_pidinfo { pid_t pi_pid; @@ -194,33 +199,35 @@ struct procctl_reaper_pidinfo { .Ed The .Fa pi_pid -is the process id of the descendant. +field is the process id of the descendant. The .Fa pi_subtree -provides the pid of the child of the reaper, which is (grand-)parent +field provides the pid of the child of the reaper, which is the (grand-)parent of the process. The .Fa pi_flags -returns the following flags, further describing the descendant: +field returns the following flags, further describing the descendant: .Bl -tag -width "Dv REAPER_PIDINFO_VALID" .It Dv REAPER_PIDINFO_VALID -Set for the +Set to indicate that the .Vt procctl_reaper_pidinfo -structure, which was filled by kernel. +structure was filled in by the kernel. Zero-filling the .Fa rp_pids -array and testing the flag allows the caller to detect the end -of returned array. +array and testing the +.Dv REAPER_PIDINFO_VALID +flag allows the caller to detect the end +of the returned array. .It Dv REAPER_PIDINFO_CHILD The .Fa pi_pid -is the direct child of the reaper. +field identifies the direct child of the reaper. .El .It Dv PROC_REAP_KILL -Request to deliver a signal to some subset of descendants of the reaper. +Request to deliver a signal to some subset of the descendants of the reaper. The .Fa data -must point to +parameter must point to a .Vt procctl_reaper_kill structure, which is used both for parameters and status return. .Bd -literal @@ -234,39 +241,40 @@ struct procctl_reaper_kill { .Ed The .Fa rk_sig -specifies the signal to be delivered. +field specifies the signal to be delivered. Zero is not a valid signal number, unlike .Xr kill 2 . The .Fa rk_flags -further directs the operation. +field further directs the operation. It is or-ed from the following flags: .Bl -tag -width "Dv REAPER_KILL_CHILDREN" .It Dv REAPER_KILL_CHILDREN Deliver the specified signal only to direct children of the reaper. .It Dv REAPER_KILL_SUBTREE -Deliver the specified signal only to descendants which were forked by -the direct child with pid specified in -.Fa rk_subtree . +Deliver the specified signal only to descendants that were forked by +the direct child with pid specified in the +.Fa rk_subtree +field. .El -If no +If neither the .Dv REAPER_KILL_CHILDREN -and +nor the .Dv REAPER_KILL_SUBTREE flags are specified, all current descendants of the reaper are signalled. .Pp -If signal was delivered to any process, the return value from the request +If a signal was delivered to any process, the return value from the request is zero. -In this case, +In this case, the .Fa rk_killed -field is filled with the count of processes signalled. +field identifies the number of processes signalled. The .Fa rk_fpid field is set to the pid of the first process for which signal delivery failed, e.g. due to the permission problems. If no such process exist, the .Fa rk_fpid -is set to -1. +field is set to -1. .El .Sh RETURN VALUES If an error occurs, a value of -1 is returned and @@ -281,7 +289,7 @@ will fail if: .It Bq Er EFAULT The .Fa arg -points outside the process's allocated address space. +parameter points outside the process's allocated address space. .It Bq Er EINVAL The .Fa cmd @@ -317,11 +325,11 @@ or .Dv PROC_REAP_RELEASE requests. .It Bq Er EINVAL -Invalid or undefined flags were passed to +Invalid or undefined flags were passed to a .Dv PROC_REAP_KILL request. .It Bq Er EINVAL -Invalid or zero signal number was requested for +An invalid or zero signal number was requested for a .Dv PROC_REAP_KILL request. .It Bq Er EINVAL @@ -333,8 +341,8 @@ process. .It Bq Er EBUSY The .Dv PROC_REAP_ACQUIRE -request was issued by the process which already acquired reaper status -and did not released it. +request was issued by a process that had already acquired reaper status +and has not yet released it. .El .Sh SEE ALSO .Xr kill 2 , @@ -346,6 +354,6 @@ The .Fn procctl function appeared in .Fx 10.0 . -Reaper facility was created based on the similar feature of Linux and +The reaper facility is based on a similar feature of Linux and DragonflyBSD, and first appeared in .Fx 10.2 . From 4bb90cbe182a382dda8c45b45312d6e23fc01577 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Wed, 17 Dec 2014 01:36:00 +0000 Subject: [PATCH 39/64] Bump Dd for r275846 MFC after: 3 weeks --- lib/libc/sys/procctl.2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/sys/procctl.2 b/lib/libc/sys/procctl.2 index b88aa330cec..70ee276922f 100644 --- a/lib/libc/sys/procctl.2 +++ b/lib/libc/sys/procctl.2 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 15, 2014 +.Dd December 16, 2014 .Dt PROCCTL 2 .Os .Sh NAME From e64c5af3f87fbb9817304d71d5a4824e2f036722 Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Wed, 17 Dec 2014 03:04:43 +0000 Subject: [PATCH 40/64] Fix 8259 IRQ priority resolver. Initialize the 8259 such that IRQ7 is the lowest priority. Reviewed by: tychon Differential Revision: https://reviews.freebsd.org/D1322 MFC after: 1 week --- sys/amd64/vmm/io/vatpic.c | 48 +++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/sys/amd64/vmm/io/vatpic.c b/sys/amd64/vmm/io/vatpic.c index deef5a2ccbe..c6d4590e893 100644 --- a/sys/amd64/vmm/io/vatpic.c +++ b/sys/amd64/vmm/io/vatpic.c @@ -75,7 +75,7 @@ struct atpic { uint8_t mask; /* Interrupt Mask Register (IMR) */ int acnt[8]; /* sum of pin asserts and deasserts */ - int priority; /* current pin priority */ + int lowprio; /* lowest priority irq */ bool intr_raised; }; @@ -102,6 +102,14 @@ struct vatpic { #define VATPIC_CTR4(vatpic, fmt, a1, a2, a3, a4) \ VM_CTR4((vatpic)->vm, fmt, a1, a2, a3, a4) +/* + * Loop over all the pins in priority order from highest to lowest. + */ +#define ATPIC_PIN_FOREACH(pinvar, atpic, tmpvar) \ + for (tmpvar = 0, pinvar = (atpic->lowprio + 1) & 0x7; \ + tmpvar < 8; \ + tmpvar++, pinvar = (pinvar + 1) & 0x7) + static void vatpic_set_pinstate(struct vatpic *vatpic, int pin, bool newstate); static __inline int @@ -110,8 +118,7 @@ vatpic_get_highest_isrpin(struct atpic *atpic) int bit, pin; int i; - for (i = 0; i <= 7; i++) { - pin = ((i + 7 - atpic->priority) & 0x7); + ATPIC_PIN_FOREACH(pin, atpic, i) { bit = (1 << pin); if (atpic->service & bit) @@ -125,8 +132,7 @@ static __inline int vatpic_get_highest_irrpin(struct atpic *atpic) { int serviced; - int bit, pin; - int i, j; + int bit, pin, tmp; /* * In 'Special Fully-Nested Mode' when an interrupt request from @@ -137,17 +143,21 @@ vatpic_get_highest_irrpin(struct atpic *atpic) if (atpic->sfn) serviced &= ~(1 << 2); - for (i = 0; i <= 7; i++) { - pin = ((i + 7 - atpic->priority) & 0x7); - bit = (1 << pin); - if (serviced & bit) - break; - } + ATPIC_PIN_FOREACH(pin, atpic, tmp) { + bit = 1 << pin; - for (j = 0; j < i; j++) { - pin = ((j + 7 - atpic->priority) & 0x7); - bit = (1 << pin); - if (atpic->request & bit && (~atpic->mask & bit)) + /* + * If there is already an interrupt in service at the same + * or higher priority then bail. + */ + if ((serviced & bit) != 0) + break; + + /* + * If an interrupt is asserted and not masked then return + * the corresponding 'pin' to the caller. + */ + if ((atpic->request & bit) != 0 && (atpic->mask & bit) == 0) return (pin); } @@ -238,7 +248,7 @@ vatpic_icw1(struct vatpic *vatpic, struct atpic *atpic, uint8_t val) atpic->icw_num = 1; atpic->mask = 0; - atpic->priority = 0; + atpic->lowprio = 7; atpic->rd_cmd_reg = 0; if ((val & ICW1_SNGL) != 0) { @@ -329,11 +339,11 @@ vatpic_ocw2(struct vatpic *vatpic, struct atpic *atpic, uint8_t val) atpic->service &= ~(1 << isr_bit); if (atpic->rotate) - atpic->priority = isr_bit; + atpic->lowprio = isr_bit; } } else if ((val & OCW2_SL) != 0 && atpic->rotate == true) { /* specific priority */ - atpic->priority = val & 0x7; + atpic->lowprio = val & 0x7; } return (0); @@ -530,7 +540,7 @@ vatpic_pin_accepted(struct atpic *atpic, int pin) if (atpic->aeoi == true) { if (atpic->rotate == true) - atpic->priority = pin; + atpic->lowprio = pin; } else { atpic->service |= (1 << pin); } From c6e32006e19ca3a4b0bddcf8a32ccebb6a7c061f Mon Sep 17 00:00:00 2001 From: Bryan Venteicher Date: Wed, 17 Dec 2014 05:36:34 +0000 Subject: [PATCH 41/64] Prefix all the vxlan ifconfig commands so they are unique And rehook ifvxlan back into the build. --- sbin/ifconfig/Makefile | 2 +- sbin/ifconfig/ifconfig.8 | 30 +++++++++++------------ sbin/ifconfig/ifvxlan.c | 52 ++++++++++++++++++++-------------------- share/man/man4/vxlan.4 | 18 +++++++------- 4 files changed, 51 insertions(+), 51 deletions(-) diff --git a/sbin/ifconfig/Makefile b/sbin/ifconfig/Makefile index 572c0613904..885f8a9922b 100644 --- a/sbin/ifconfig/Makefile +++ b/sbin/ifconfig/Makefile @@ -30,7 +30,7 @@ SRCS+= ifmac.c # MAC support SRCS+= ifmedia.c # SIOC[GS]IFMEDIA support SRCS+= iffib.c # non-default FIB support SRCS+= ifvlan.c # SIOC[GS]ETVLAN support -#SRCS+= ifvxlan.c # VXLAN support +SRCS+= ifvxlan.c # VXLAN support SRCS+= ifgre.c # GRE keys etc SRCS+= ifgif.c # GIF reversed header workaround diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index 064a62d27b8..90c8d7a8c1d 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -28,7 +28,7 @@ .\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94 .\" $FreeBSD$ .\" -.Dd October 20, 2014 +.Dd December 16, 2014 .Dt IFCONFIG 8 .Os .Sh NAME @@ -2544,33 +2544,33 @@ The following parameters are used to configure .Xr vxlan 4 interfaces. .Bl -tag -width indent -.It Cm vni Ar identifier +.It Cm vxlanid Ar identifier This value is a 24-bit VXLAN Network Identifier (VNI) that identifies the virtual network segment membership of the interface. -.It Cm local Ar address +.It Cm vxlanlocal Ar address The source address used in the encapsulating IPv4/IPv6 header. The address should already be assigned to an existing interface. When the interface is configured in unicast mode, the listening socket is bound to this address. -.It Cm remote Ar address +.It Cm vxlanremote Ar address The interface can be configured in a unicast, or point-to-point, mode to create a tunnel between two hosts. This is the IP address of the remote end of the tunnel. -.It Cm group Ar address +.It Cm vxlangroup Ar address The interface can be configured in a multicast mode to create a virtual network of hosts. This is the IP multicast group address the interface will join. -.It Cm localport Ar port +.It Cm vxlanlocalport Ar port The port number the interface will listen on. The default port number is 4789. -.It Cm remoteport Ar port +.It Cm vxlanremoteport Ar port The destination port number used in the encapsulating IPv4/IPv6 header. The remote host should be listening on this port. The default port number is 4789. Note some other implementations, such as Linux, do not default to the IANA assigned port, but instead listen on port 8472. -.It Cm portrange Ar low high +.It Cm vxlanportrange Ar low high The range of source ports used in the encapsulating IPv4/IPv6 header. The port selected within the range is based on a hash of the inner frame. A range is useful to provide entropy within the outer IP header @@ -2581,32 +2581,32 @@ variables .Va net.inet.ip.portrange.first and .Va net.inet.ip.portrange.last -.It Cm timeout Ar timeout +.It Cm vxlantimeout Ar timeout The maximum time, in seconds, before an entry in the forwarding table is pruned. The default is 1200 seconds (20 minutes). -.It Cm maxaddr Ar max +.It Cm vxlanmaxaddr Ar max The maximum number of entries in the forwarding table. The default is 2000. .It Cm vxlandev Ar dev When the interface is configured in multicast mode, the .Cm dev interface is used to transmit IP multicast packets. -.It Cm ttl Ar ttl +.It Cm vxlanttl Ar ttl The TTL used in the encapsulating IPv4/IPv6 header. The default is 64. -.It Cm learn +.It Cm vxlanlearn The source IP address and inner source Ethernet MAC address of received packets are used to dynamically populate the forwarding table. When in multicast mode, an entry in the forwarding table allows the interface to send the frame directly to the remote host instead of broadcasting the frame to the multicast group. This is the default. -.It Fl learn +.It Fl vxlanlearn The forwarding table is not populated by recevied packets. -.It Cm flush +.It Cm vxlanflush Delete all dynamically-learned addresses from the forwarding table. -.It Cm flushall +.It Cm vxlanflushall Delete all addresses, including static addresses, from the forwarding table. .El .Pp diff --git a/sbin/ifconfig/ifvxlan.c b/sbin/ifconfig/ifvxlan.c index 72346675faa..9aa84a29ff2 100644 --- a/sbin/ifconfig/ifvxlan.c +++ b/sbin/ifconfig/ifvxlan.c @@ -595,36 +595,36 @@ setvxlan_flush(const char *val, int d, int s, const struct afswtch *afp) static struct cmd vxlan_cmds[] = { - DEF_CLONE_CMD_ARG("vni", setvxlan_vni), - DEF_CLONE_CMD_ARG("local", setvxlan_local), - DEF_CLONE_CMD_ARG("remote", setvxlan_remote), - DEF_CLONE_CMD_ARG("group", setvxlan_group), - DEF_CLONE_CMD_ARG("localport", setvxlan_local_port), - DEF_CLONE_CMD_ARG("remoteport", setvxlan_remote_port), - DEF_CLONE_CMD_ARG2("portrange", setvxlan_port_range), - DEF_CLONE_CMD_ARG("timeout", setvxlan_timeout), - DEF_CLONE_CMD_ARG("maxaddr", setvxlan_maxaddr), + DEF_CLONE_CMD_ARG("vxlanid", setvxlan_vni), + DEF_CLONE_CMD_ARG("vxlanlocal", setvxlan_local), + DEF_CLONE_CMD_ARG("vxlanremote", setvxlan_remote), + DEF_CLONE_CMD_ARG("vxlangroup", setvxlan_group), + DEF_CLONE_CMD_ARG("vxlanlocalport", setvxlan_local_port), + DEF_CLONE_CMD_ARG("vxlanremoteport", setvxlan_remote_port), + DEF_CLONE_CMD_ARG2("vxlanportrange", setvxlan_port_range), + DEF_CLONE_CMD_ARG("vxlantimeout", setvxlan_timeout), + DEF_CLONE_CMD_ARG("vxlanmaxaddr", setvxlan_maxaddr), DEF_CLONE_CMD_ARG("vxlandev", setvxlan_dev), - DEF_CLONE_CMD_ARG("ttl", setvxlan_ttl), - DEF_CLONE_CMD("learn", 1, setvxlan_learn), - DEF_CLONE_CMD("-learn", 0, setvxlan_learn), + DEF_CLONE_CMD_ARG("vxlanttl", setvxlan_ttl), + DEF_CLONE_CMD("vxlanlearn", 1, setvxlan_learn), + DEF_CLONE_CMD("-vxlanlearn", 0, setvxlan_learn), - DEF_CMD_ARG("vni", setvxlan_vni), - DEF_CMD_ARG("local", setvxlan_local), - DEF_CMD_ARG("remote", setvxlan_remote), - DEF_CMD_ARG("group", setvxlan_group), - DEF_CMD_ARG("localport", setvxlan_local_port), - DEF_CMD_ARG("remoteport", setvxlan_remote_port), - DEF_CMD_ARG2("portrange", setvxlan_port_range), - DEF_CMD_ARG("timeout", setvxlan_timeout), - DEF_CMD_ARG("maxaddr", setvxlan_maxaddr), + DEF_CMD_ARG("vxlanvni", setvxlan_vni), + DEF_CMD_ARG("vxlanlocal", setvxlan_local), + DEF_CMD_ARG("vxlanremote", setvxlan_remote), + DEF_CMD_ARG("vxlangroup", setvxlan_group), + DEF_CMD_ARG("vxlanlocalport", setvxlan_local_port), + DEF_CMD_ARG("vxlanremoteport", setvxlan_remote_port), + DEF_CMD_ARG2("vxlanportrange", setvxlan_port_range), + DEF_CMD_ARG("vxlantimeout", setvxlan_timeout), + DEF_CMD_ARG("vxlanmaxaddr", setvxlan_maxaddr), DEF_CMD_ARG("vxlandev", setvxlan_dev), - DEF_CMD_ARG("ttl", setvxlan_ttl), - DEF_CMD("learn", 1, setvxlan_learn), - DEF_CMD("-learn", 0, setvxlan_learn), + DEF_CMD_ARG("vxlanttl", setvxlan_ttl), + DEF_CMD("vxlanlearn", 1, setvxlan_learn), + DEF_CMD("-vxlanlearn", 0, setvxlan_learn), - DEF_CMD("flush", 0, setvxlan_flush), - DEF_CMD("flushall", 1, setvxlan_flush), + DEF_CMD("vxlanflush", 0, setvxlan_flush), + DEF_CMD("vxlanflushall", 1, setvxlan_flush), }; static struct afswtch af_vxlan = { diff --git a/share/man/man4/vxlan.4 b/share/man/man4/vxlan.4 index 1e68c0845db..ec95db1d9cf 100644 --- a/share/man/man4/vxlan.4 +++ b/share/man/man4/vxlan.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 20, 2014 +.Dd December 16, 2014 .Dt VXLAN 4 .Os .Sh NAME @@ -140,7 +140,7 @@ or VNI. .Pp When configured with the .Xr ifconfig 8 -.Cm learn +.Cm vxlanlearn parameter, the interface dynamically creates forwarding table entries from received packets. An entry in the forwarding table maps the inner source MAC address @@ -153,16 +153,16 @@ Otherwise, when configured in multicast mode, the interface must flood the frame to all hosts in the group. The maximum number of entries in the table is configurable with the .Xr ifconfig 8 -.Cm maxaddr +.Cm vxlanmaxaddr command. Stale entries in the table periodically pruned. The timeout is configurable with the .Xr ifconfig 8 -.Cm timeout +.Cm vxlantimeout command. The table may be viewed with the .Xr sysctl 8 -.Cm net.link.vlxan.N.ftable.dump +.Cm net.link.vxlan.N.ftable.dump command. .Sh MTU Since the @@ -187,13 +187,13 @@ Create a .Nm interface in unicast mode with the -.Cm local +.Cm vxlanlocal tunnel address of 192.168.100.1, and the -.Cm remote +.Cm vxlanremote tunnel address of 192.168.100.2. .Bd -literal -offset indent -ifconfig vxlan create vni 108 local 192.168.100.1 remote 192.168.100.2 +ifconfig vxlan create vxlanid 108 vxlanlocal 192.168.100.1 vxlanremote 192.168.100.2 .Ed .Pp Create a @@ -207,7 +207,7 @@ and the address of 224.0.2.6. The em0 interface will be used to transmit multicast packets. .Bd -literal -offset indent -ifconfig vxlan create vni 42 local 192.168.10.95 group 224.0.2.6 vxlandev em0 +ifconfig vxlan create vxlanid 42 vxlanlocal 192.168.10.95 vxlangroup 224.0.2.6 vxlandev em0 .Ed .Pp Once created, the From 9b3370541180604458bbc768f3fa6839ed4d938e Mon Sep 17 00:00:00 2001 From: Gleb Kurtsou Date: Wed, 17 Dec 2014 07:10:48 +0000 Subject: [PATCH 42/64] Adjust printf format specifiers for dev_t and ino_t in user space. ino_t and dev_t are about to become uint64_t. Reviewed by: kib, mckusick --- sbin/ffsinfo/ffsinfo.c | 46 +++++++++++++++++++++++---------------- usr.bin/id/id.c | 9 ++++---- usr.bin/killall/killall.c | 8 ++++--- usr.sbin/lpr/lpr/lpr.c | 4 ++-- 4 files changed, 39 insertions(+), 28 deletions(-) diff --git a/sbin/ffsinfo/ffsinfo.c b/sbin/ffsinfo/ffsinfo.c index 881fc1e1e1d..c1e7c87c1b4 100644 --- a/sbin/ffsinfo/ffsinfo.c +++ b/sbin/ffsinfo/ffsinfo.c @@ -67,6 +67,7 @@ static const char rcsid[] = #include #include #include +#include #include #include #include @@ -361,7 +362,7 @@ dump_whole_ufs1_inode(ino_t inode, int level) /* * Dump the main inode structure. */ - snprintf(comment, sizeof(comment), "Inode 0x%08x", inode); + snprintf(comment, sizeof(comment), "Inode 0x%08jx", (uintmax_t)inode); if (level & 0x100) { DBG_DUMP_INO(&sblock, comment, @@ -385,8 +386,8 @@ dump_whole_ufs1_inode(ino_t inode, int level) (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } - snprintf(comment, sizeof(comment), "Inode 0x%08x: indirect 0", - inode); + snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 0", + (uintmax_t)inode); DBG_DUMP_IBLK(&sblock, comment, i1blk, @@ -401,8 +402,8 @@ dump_whole_ufs1_inode(ino_t inode, int level) (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } - snprintf(comment, sizeof(comment), "Inode 0x%08x: indirect 1", - inode); + snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 1", + (uintmax_t)inode); DBG_DUMP_IBLK(&sblock, comment, i2blk, @@ -416,7 +417,8 @@ dump_whole_ufs1_inode(ino_t inode, int level) err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), - "Inode 0x%08x: indirect 1->%d", inode, ind2ctr); + "Inode 0x%08jx: indirect 1->%d", (uintmax_t)inode, + ind2ctr); DBG_DUMP_IBLK(&sblock, comment, i1blk, @@ -432,8 +434,8 @@ dump_whole_ufs1_inode(ino_t inode, int level) (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } - snprintf(comment, sizeof(comment), "Inode 0x%08x: indirect 2", - inode); + snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 2", + (uintmax_t)inode); #define SQUARE(a) ((a)*(a)) DBG_DUMP_IBLK(&sblock, comment, @@ -450,7 +452,8 @@ dump_whole_ufs1_inode(ino_t inode, int level) err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), - "Inode 0x%08x: indirect 2->%d", inode, ind3ctr); + "Inode 0x%08jx: indirect 2->%d", (uintmax_t)inode, + ind3ctr); DBG_DUMP_IBLK(&sblock, comment, i2blk, @@ -466,8 +469,8 @@ dump_whole_ufs1_inode(ino_t inode, int level) err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), - "Inode 0x%08x: indirect 2->%d->%d", inode, - ind3ctr, ind3ctr); + "Inode 0x%08jx: indirect 2->%d->%d", + (uintmax_t)inode, ind3ctr, ind3ctr); DBG_DUMP_IBLK(&sblock, comment, i1blk, @@ -513,7 +516,7 @@ dump_whole_ufs2_inode(ino_t inode, int level) /* * Dump the main inode structure. */ - snprintf(comment, sizeof(comment), "Inode 0x%08x", inode); + snprintf(comment, sizeof(comment), "Inode 0x%08jx", (uintmax_t)inode); if (level & 0x100) { DBG_DUMP_INO(&sblock, comment, ino); } @@ -535,7 +538,8 @@ dump_whole_ufs2_inode(ino_t inode, int level) (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } - snprintf(comment, sizeof(comment), "Inode 0x%08x: indirect 0", inode); + snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 0", + (uintmax_t)inode); DBG_DUMP_IBLK(&sblock, comment, i1blk, (size_t)rb); rb -= howmany(sblock.fs_bsize, sizeof(ufs2_daddr_t)); } @@ -547,7 +551,8 @@ dump_whole_ufs2_inode(ino_t inode, int level) (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } - snprintf(comment, sizeof(comment), "Inode 0x%08x: indirect 1", inode); + snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 1", + (uintmax_t)inode); DBG_DUMP_IBLK(&sblock, comment, i2blk, @@ -561,7 +566,8 @@ dump_whole_ufs2_inode(ino_t inode, int level) err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), - "Inode 0x%08x: indirect 1->%d", inode, ind2ctr); + "Inode 0x%08jx: indirect 1->%d", + (uintmax_t)inode, ind2ctr); DBG_DUMP_IBLK(&sblock, comment, i1blk, (size_t)rb); rb -= howmany(sblock.fs_bsize, sizeof(ufs2_daddr_t)); } @@ -574,7 +580,8 @@ dump_whole_ufs2_inode(ino_t inode, int level) (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } - snprintf(comment, sizeof(comment), "Inode 0x%08x: indirect 2", inode); + snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 2", + (uintmax_t)inode); #define SQUARE(a) ((a)*(a)) DBG_DUMP_IBLK(&sblock, comment, @@ -591,7 +598,8 @@ dump_whole_ufs2_inode(ino_t inode, int level) err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), - "Inode 0x%08x: indirect 2->%d", inode, ind3ctr); + "Inode 0x%08jx: indirect 2->%d", + (uintmax_t)inode, ind3ctr); DBG_DUMP_IBLK(&sblock, comment, i2blk, @@ -605,8 +613,8 @@ dump_whole_ufs2_inode(ino_t inode, int level) err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), - "Inode 0x%08x: indirect 2->%d->%d", inode, - ind3ctr, ind3ctr); + "Inode 0x%08jx: indirect 2->%d->%d", + (uintmax_t)inode, ind3ctr, ind3ctr); DBG_DUMP_IBLK(&sblock, comment, i1blk, (size_t)rb); rb -= howmany(sblock.fs_bsize, sizeof(ufs2_daddr_t)); } diff --git a/usr.bin/id/id.c b/usr.bin/id/id.c index a49fd756a74..345e2a677f5 100644 --- a/usr.bin/id/id.c +++ b/usr.bin/id/id.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -346,14 +347,14 @@ auditid(void) "mask.success=0x%08x\n" "mask.failure=0x%08x\n" "asid=%d\n" - "termid_addr.port=0x%08x\n" + "termid_addr.port=0x%08jx\n" "termid_addr.addr[0]=0x%08x\n" "termid_addr.addr[1]=0x%08x\n" "termid_addr.addr[2]=0x%08x\n" "termid_addr.addr[3]=0x%08x\n", ainfo_addr.ai_auid, ainfo_addr.ai_mask.am_success, ainfo_addr.ai_mask.am_failure, ainfo_addr.ai_asid, - ainfo_addr.ai_termid.at_port, + (uintmax_t)ainfo_addr.ai_termid.at_port, ainfo_addr.ai_termid.at_addr[0], ainfo_addr.ai_termid.at_addr[1], ainfo_addr.ai_termid.at_addr[2], @@ -363,11 +364,11 @@ auditid(void) "mask.success=0x%08x\n" "mask.failure=0x%08x\n" "asid=%d\n" - "termid.port=0x%08x\n" + "termid.port=0x%08jx\n" "termid.machine=0x%08x\n", auditinfo.ai_auid, auditinfo.ai_mask.am_success, auditinfo.ai_mask.am_failure, - auditinfo.ai_asid, auditinfo.ai_termid.port, + auditinfo.ai_asid, (uintmax_t)auditinfo.ai_termid.port, auditinfo.ai_termid.machine); } } diff --git a/usr.bin/killall/killall.c b/usr.bin/killall/killall.c index b171630d6b9..cdb62da6e4b 100644 --- a/usr.bin/killall/killall.c +++ b/usr.bin/killall/killall.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -262,7 +263,7 @@ main(int ac, char **av) errx(1, "%s: not a character device", buf); tdev = sb.st_rdev; if (dflag) - printf("ttydev:0x%x\n", tdev); + printf("ttydev:0x%jx\n", (uintmax_t)tdev); } if (user) { uid = strtol(user, &ep, 10); @@ -410,8 +411,9 @@ main(int ac, char **av) if (matched == 0) continue; if (dflag) - printf("sig:%d, cmd:%s, pid:%d, dev:0x%x uid:%d\n", sig, - thiscmd, thispid, thistdev, thisuid); + printf("sig:%d, cmd:%s, pid:%d, dev:0x%jx uid:%d\n", + sig, thiscmd, thispid, (uintmax_t)thistdev, + thisuid); if (vflag || sflag) printf("kill -%s %d\n", sys_signame[sig], thispid); diff --git a/usr.sbin/lpr/lpr/lpr.c b/usr.sbin/lpr/lpr/lpr.c index 394ccb06324..9a4382f12c5 100644 --- a/usr.sbin/lpr/lpr/lpr.c +++ b/usr.sbin/lpr/lpr/lpr.c @@ -387,8 +387,8 @@ main(int argc, char *argv[]) continue; /* file unreasonable */ if (sflag && (cp = linked(arg)) != NULL) { - (void)snprintf(buf, sizeof(buf), "%u %ju", - statb.st_dev, (uintmax_t)statb.st_ino); + (void)snprintf(buf, sizeof(buf), "%ju %ju", + (uintmax_t)statb.st_dev, (uintmax_t)statb.st_ino); card('S', buf); if (format == 'p') card('T', title ? title : arg); From dde58752dbf08343d9b74b48ffabedbf5ca2e7e8 Mon Sep 17 00:00:00 2001 From: Gleb Kurtsou Date: Wed, 17 Dec 2014 07:27:19 +0000 Subject: [PATCH 43/64] Adjust printf format specifiers for dev_t and ino_t in kernel. ino_t and dev_t are about to become uint64_t. Reviewed by: kib, mckusick --- sys/compat/linprocfs/linprocfs.c | 2 +- sys/compat/svr4/svr4_socket.c | 17 ++++++++++------- sys/dev/drm/drm_sysctl.c | 5 +++-- sys/dev/drm2/drm_sysctl.c | 3 ++- sys/fs/ext2fs/ext2_alloc.c | 8 ++++---- sys/fs/ext2fs/ext2_lookup.c | 10 ++++++---- sys/fs/ext2fs/ext2_vnops.c | 2 +- sys/kern/kern_conf.c | 3 ++- sys/security/mac_lomac/mac_lomac.c | 4 ++-- sys/ufs/ffs/ffs_alloc.c | 6 +++--- sys/ufs/ufs/ufs_lookup.c | 3 ++- 11 files changed, 36 insertions(+), 27 deletions(-) diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index 92ecb2f308a..8607646ded1 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -674,7 +674,7 @@ linprocfs_doprocstat(PFS_FILL_ARGS) PS_ADD("pgrp", "%d", p->p_pgid); PS_ADD("session", "%d", p->p_session->s_sid); PROC_UNLOCK(p); - PS_ADD("tty", "%d", kp.ki_tdev); + PS_ADD("tty", "%ju", (uintmax_t)kp.ki_tdev); PS_ADD("tpgid", "%d", kp.ki_tpgid); PS_ADD("flags", "%u", 0); /* XXX */ PS_ADD("minflt", "%lu", kp.ki_rusage.ru_minflt); diff --git a/sys/compat/svr4/svr4_socket.c b/sys/compat/svr4/svr4_socket.c index 038267ca221..f59241ce15f 100644 --- a/sys/compat/svr4/svr4_socket.c +++ b/sys/compat/svr4/svr4_socket.c @@ -93,7 +93,8 @@ svr4_find_socket(td, fp, dev, ino, saun) struct svr4_sockcache_entry *e; void *cookie = ((struct socket *)fp->f_data)->so_emuldata; - DPRINTF(("svr4_find_socket: [%p,%d,%d]: ", td, dev, ino)); + DPRINTF(("svr4_find_socket: [%p,%ju,%ju]: ", td, (uintmax_t)dev, + (uintmax_t)ino)); mtx_lock(&svr4_sockcache_lock); TAILQ_FOREACH(e, &svr4_head, entries) if (e->p == td->td_proc && e->dev == dev && e->ino == ino) { @@ -142,8 +143,8 @@ svr4_add_socket(td, path, st) mtx_lock(&svr4_sockcache_lock); TAILQ_INSERT_HEAD(&svr4_head, e, entries); mtx_unlock(&svr4_sockcache_lock); - DPRINTF(("svr4_add_socket: %s [%p,%d,%d]\n", e->sock.sun_path, - td->td_proc, e->dev, e->ino)); + DPRINTF(("svr4_add_socket: %s [%p,%ju,%ju]\n", e->sock.sun_path, + td->td_proc, (uintmax_t)e->dev, (uintmax_t)e->ino)); return 0; } @@ -160,8 +161,9 @@ svr4_delete_socket(p, fp) if (e->p == p && e->cookie == cookie) { TAILQ_REMOVE(&svr4_head, e, entries); mtx_unlock(&svr4_sockcache_lock); - DPRINTF(("svr4_delete_socket: %s [%p,%d,%d]\n", - e->sock.sun_path, p, (int)e->dev, e->ino)); + DPRINTF(("svr4_delete_socket: %s [%p,%ju,%ju]\n", + e->sock.sun_path, p, (uintmax_t)e->dev, + (uintmax_t)e->ino)); free(e, M_TEMP); return; } @@ -179,8 +181,9 @@ svr4_purge_sockcache(arg, p) TAILQ_FOREACH_SAFE(e, &svr4_head, entries, ne) { if (e->p == p) { TAILQ_REMOVE(&svr4_head, e, entries); - DPRINTF(("svr4_purge_sockcache: %s [%p,%d,%d]\n", - e->sock.sun_path, p, (int)e->dev, e->ino)); + DPRINTF(("svr4_purge_sockcache: %s [%p,%ju,%ju]\n", + e->sock.sun_path, p, (uintmax_t)e->dev, + (uintmax_t)e->ino)); free(e, M_TEMP); } } diff --git a/sys/dev/drm/drm_sysctl.c b/sys/dev/drm/drm_sysctl.c index 9e2c49a8e87..2a138e88a73 100644 --- a/sys/dev/drm/drm_sysctl.c +++ b/sys/dev/drm/drm_sysctl.c @@ -137,8 +137,9 @@ static int drm_name_info DRM_SYSCTL_HANDLER_ARGS int retcode; int hasunique = 0; - DRM_SYSCTL_PRINT("%s 0x%x", dev->driver->name, dev2udev(dev->devnode)); - + DRM_SYSCTL_PRINT("%s 0x%jx", dev->driver->name, + (uintmax_t)dev2udev(dev->devnode)); + DRM_LOCK(); if (dev->unique) { snprintf(buf, sizeof(buf), " %s", dev->unique); diff --git a/sys/dev/drm2/drm_sysctl.c b/sys/dev/drm2/drm_sysctl.c index aac21e6a486..9564e68df85 100644 --- a/sys/dev/drm2/drm_sysctl.c +++ b/sys/dev/drm2/drm_sysctl.c @@ -155,7 +155,8 @@ static int drm_name_info DRM_SYSCTL_HANDLER_ARGS int retcode; int hasunique = 0; - DRM_SYSCTL_PRINT("%s 0x%x", dev->driver->name, dev2udev(dev->devnode)); + DRM_SYSCTL_PRINT("%s 0x%jx", dev->driver->name, + (uintmax_t)dev2udev(dev->devnode)); DRM_LOCK(dev); if (dev->unique) { diff --git a/sys/fs/ext2fs/ext2_alloc.c b/sys/fs/ext2fs/ext2_alloc.c index 106a124a1dd..e2bb138793b 100644 --- a/sys/fs/ext2fs/ext2_alloc.c +++ b/sys/fs/ext2fs/ext2_alloc.c @@ -264,8 +264,8 @@ ext2_reallocblks(struct vop_reallocblks_args *ap) * with the file. */ #ifdef DEBUG - printf("realloc: ino %d, lbns %jd-%jd\n\told:", ip->i_number, - (intmax_t)start_lbn, (intmax_t)end_lbn); + printf("realloc: ino %ju, lbns %jd-%jd\n\told:", + (uintmax_t)ip->i_number, (intmax_t)start_lbn, (intmax_t)end_lbn); #endif /* DEBUG */ blkno = newblk; for (bap = &sbap[soff], i = 0; i < len; i++, blkno += fs->e2fs_fpb) { @@ -968,8 +968,8 @@ ext2_blkfree(struct inode *ip, e4fs_daddr_t bno, long size) ump = ip->i_ump; cg = dtog(fs, bno); if ((u_int)bno >= fs->e2fs->e2fs_bcount) { - printf("bad block %lld, ino %llu\n", (long long)bno, - (unsigned long long)ip->i_number); + printf("bad block %lld, ino %ju\n", (long long)bno, + (uintmax_t)ip->i_number); ext2_fserr(fs, ip->i_uid, "bad block"); return; } diff --git a/sys/fs/ext2fs/ext2_lookup.c b/sys/fs/ext2fs/ext2_lookup.c index ad1f41a5777..34f720a1401 100644 --- a/sys/fs/ext2fs/ext2_lookup.c +++ b/sys/fs/ext2fs/ext2_lookup.c @@ -801,11 +801,13 @@ ext2_dirbad(struct inode *ip, doff_t offset, char *how) mp = ITOV(ip)->v_mount; if ((mp->mnt_flag & MNT_RDONLY) == 0) - panic("ext2_dirbad: %s: bad dir ino %lu at offset %ld: %s\n", - mp->mnt_stat.f_mntonname, (u_long)ip->i_number,(long)offset, how); + panic("ext2_dirbad: %s: bad dir ino %ju at offset %ld: %s\n", + mp->mnt_stat.f_mntonname, (uintmax_t)ip->i_number, + (long)offset, how); else - (void)printf("%s: bad dir ino %lu at offset %ld: %s\n", - mp->mnt_stat.f_mntonname, (u_long)ip->i_number, (long)offset, how); + (void)printf("%s: bad dir ino %ju at offset %ld: %s\n", + mp->mnt_stat.f_mntonname, (uintmax_t)ip->i_number, + (long)offset, how); } diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c index 06173b1060e..899ae7970d6 100644 --- a/sys/fs/ext2fs/ext2_vnops.c +++ b/sys/fs/ext2fs/ext2_vnops.c @@ -1366,7 +1366,7 @@ ext2_print(struct vop_print_args *ap) struct vnode *vp = ap->a_vp; struct inode *ip = VTOI(vp); - vn_printf(ip->i_devvp, "\tino %lu", (u_long)ip->i_number); + vn_printf(ip->i_devvp, "\tino %ju", (uintmax_t)ip->i_number); if (vp->v_type == VFIFO) fifo_printinfo(vp); printf("\n"); diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index b1ae7a16cea..d15e5dabe6b 100644 --- a/sys/kern/kern_conf.c +++ b/sys/kern/kern_conf.c @@ -1292,7 +1292,8 @@ clone_cleanup(struct clonedevs **cdp) if (!(cp->cdp_flags & CDP_SCHED_DTR)) { cp->cdp_flags |= CDP_SCHED_DTR; KASSERT(dev->si_flags & SI_NAMED, - ("Driver has goofed in cloning underways udev %x unit %x", dev2udev(dev), dev2unit(dev))); + ("Driver has goofed in cloning underways udev %jx unit %x", + (uintmax_t)dev2udev(dev), dev2unit(dev))); destroy_devl(dev); } } diff --git a/sys/security/mac_lomac/mac_lomac.c b/sys/security/mac_lomac/mac_lomac.c index cf66423a91c..32ae2239a2d 100644 --- a/sys/security/mac_lomac/mac_lomac.c +++ b/sys/security/mac_lomac/mac_lomac.c @@ -559,11 +559,11 @@ maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel, pgid = p->p_pgrp->pg_id; /* XXX could be stale? */ if (vp != NULL && VOP_GETATTR(vp, &va, curthread->td_ucred) == 0) { log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" - " level %s after %s a level-%s %s (inode=%ld, " + " level %s after %s a level-%s %s (inode=%ju, " "mountpount=%s)\n", subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, p->p_comm, subjtext, actionname, objlabeltext, objname, - va.va_fileid, vp->v_mount->mnt_stat.f_mntonname); + (uintmax_t)va.va_fileid, vp->v_mount->mnt_stat.f_mntonname); } else { log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" " level %s after %s a level-%s %s\n", diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index 36db48f6352..c918cd74f65 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -845,7 +845,7 @@ ffs_reallocblks_ufs2(ap) */ #ifdef DEBUG if (prtrealloc) - printf("realloc: ino %d, lbns %jd-%jd\n\told:", ip->i_number, + printf("realloc: ino %ju, lbns %jd-%jd\n\told:", (uintmax_t)ip->i_number, (intmax_t)start_lbn, (intmax_t)end_lbn); #endif blkno = newblk; @@ -1029,8 +1029,8 @@ retry: ip = VTOI(*vpp); if (ip->i_mode) { dup_alloc: - printf("mode = 0%o, inum = %lu, fs = %s\n", - ip->i_mode, (u_long)ip->i_number, fs->fs_fsmnt); + printf("mode = 0%o, inum = %ju, fs = %s\n", + ip->i_mode, (uintmax_t)ip->i_number, fs->fs_fsmnt); panic("ffs_valloc: dup alloc"); } if (DIP(ip, i_blocks) && (fs->fs_flags & FS_UNCLEAN) == 0) { /* XXX */ diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index 87a030ea501..b34ed244914 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -1475,7 +1475,8 @@ ufs_checkpath(ino_t source_ino, ino_t parent_ino, struct inode *target, struct u } } KASSERT(dd_ino == VTOI(vp1)->i_number, - ("directory %d reparented\n", VTOI(vp1)->i_number)); + ("directory %ju reparented\n", + (uintmax_t)VTOI(vp1)->i_number)); if (vp != tvp) vput(vp); vp = vp1; From 2b8a4d803345d944f6184b1187e33f6db4f34cc0 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Wed, 17 Dec 2014 07:47:25 +0000 Subject: [PATCH 44/64] Initilize the msg_flags field consistently in all code paths. Reported by: Coverity CID: 1018726 --- lib/libc/net/sctp_sys_calls.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/libc/net/sctp_sys_calls.c b/lib/libc/net/sctp_sys_calls.c index ea66df9d886..6971c606dbc 100644 --- a/lib/libc/net/sctp_sys_calls.c +++ b/lib/libc/net/sctp_sys_calls.c @@ -597,6 +597,7 @@ sctp_sendmsg(int s, msg.msg_iovlen = 1; msg.msg_control = cmsgbuf; msg.msg_controllen = CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)); + msg.msg_flags = 0; cmsg = (struct cmsghdr *)cmsgbuf; cmsg->cmsg_level = IPPROTO_SCTP; cmsg->cmsg_type = SCTP_SNDRCV; @@ -663,6 +664,7 @@ sctp_send(int sd, const void *data, size_t len, msg.msg_iovlen = 1; msg.msg_control = cmsgbuf; msg.msg_controllen = CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)); + msg.msg_flags = 0; cmsg = (struct cmsghdr *)cmsgbuf; cmsg->cmsg_level = IPPROTO_SCTP; cmsg->cmsg_type = SCTP_SNDRCV; @@ -820,7 +822,6 @@ sctp_recvmsg(int s, errno = EINVAL; return (-1); } - msg.msg_flags = 0; iov.iov_base = dbuf; iov.iov_len = len; msg.msg_name = (caddr_t)from; @@ -832,6 +833,7 @@ sctp_recvmsg(int s, msg.msg_iovlen = 1; msg.msg_control = cmsgbuf; msg.msg_controllen = sizeof(cmsgbuf); + msg.msg_flags = 0; sz = recvmsg(s, &msg, *msg_flags); *msg_flags = msg.msg_flags; if (sz <= 0) { @@ -905,6 +907,7 @@ sctp_recvv(int sd, msg.msg_iovlen = iovlen; msg.msg_control = cmsgbuf; msg.msg_controllen = sizeof(cmsgbuf); + msg.msg_flags = 0; ret = recvmsg(sd, &msg, *flags); *flags = msg.msg_flags; if ((ret > 0) && From e2d5f675a0347ed9580b4381e4cb711624386fe9 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Wed, 17 Dec 2014 09:34:54 +0000 Subject: [PATCH 45/64] Use memory regions information provided in FDT. Reviewed by: brooks Sponsored by: DARPA, AFRL --- sys/mips/beri/beri_machdep.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sys/mips/beri/beri_machdep.c b/sys/mips/beri/beri_machdep.c index deda11968f7..714ee3d583e 100644 --- a/sys/mips/beri/beri_machdep.c +++ b/sys/mips/beri/beri_machdep.c @@ -88,6 +88,11 @@ static void mips_init(void) { int i; +#ifdef FDT + struct mem_region mr[FDT_MEM_REGIONS]; + int mr_cnt, val; + int j; +#endif for (i = 0; i < 10; i++) { phys_avail[i] = 0; @@ -102,6 +107,29 @@ mips_init(void) physmem = realmem; +#ifdef FDT + if (fdt_get_mem_regions(mr, &mr_cnt, &val) == 0) { + + physmem = btoc(val); + + KASSERT((phys_avail[0] >= mr[0].mr_start) && \ + (phys_avail[0] < (mr[0].mr_start + mr[0].mr_size)), + ("First region is not within FDT memory range")); + + /* Limit size of the first region */ + phys_avail[1] = MIN(mr[0].mr_size, ctob(realmem)); + dump_avail[1] = phys_avail[1]; + + /* Add the rest of regions */ + for (i = 1, j = 2; i < mr_cnt; i++, j+=2) { + phys_avail[j] = mr[i].mr_start; + phys_avail[j+1] = mr[i].mr_size; + dump_avail[j] = phys_avail[j]; + dump_avail[j+1] = phys_avail[j+1]; + } + } +#endif + init_param1(); init_param2(physmem); mips_cpu_init(); From 28dcb50c72931d95790cf6ff26f17532e3fd0c7d Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Wed, 17 Dec 2014 10:48:53 +0000 Subject: [PATCH 46/64] o Add PIO[2,3] devices information o Enable Virtio Block --- sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts | 22 +++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts b/sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts index 0ed81fcec26..c7dcde38263 100644 --- a/sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts +++ b/sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts @@ -106,20 +106,36 @@ status = "okay"; }; + pio2: pio@c0022000 { + compatible = "altr,pio"; + reg = <0xc0022000 0x1000>; /* recv */ + interrupts = < 77 >; + interrupt-parent = <&GIC>; + status = "okay"; + }; + + pio3: pio@c0023000 { + compatible = "altr,pio"; + reg = <0xc0023000 0x1000>; /* send */ + interrupts = < 83 >; /* not in use on arm side */ + interrupt-parent = <&GIC>; + status = "okay"; + }; + beri_vtblk: vtblk@00001000 { compatible = "sri-cambridge,beri-vtblk"; reg = <0x00001000 0x1000>; pio-recv = <&pio0>; pio-send = <&pio1>; beri-mem = <&beri_mem0>; - status = "disabled"; + status = "okay"; }; beri_vtnet: vtnet@00002000 { compatible = "sri-cambridge,beri-vtnet"; reg = <0x00002000 0x1000>; - pio-recv = <&pio0>; - pio-send = <&pio1>; + pio-recv = <&pio2>; + pio-send = <&pio3>; beri-mem = <&beri_mem0>; status = "okay"; }; From 628920c43bc46b9a477de665963c2aba1f1227d5 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Wed, 17 Dec 2014 11:05:44 +0000 Subject: [PATCH 47/64] Move memory node to the root, so fdt_get_mem_regions() can find it. --- sys/boot/fdt/dts/mips/beri-netfpga.dts | 10 +++++----- sys/boot/fdt/dts/mips/beri-sim.dts | 10 +++++----- sys/boot/fdt/dts/mips/beripad-de4.dts | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/sys/boot/fdt/dts/mips/beri-netfpga.dts b/sys/boot/fdt/dts/mips/beri-netfpga.dts index 605392192d1..f272f9cfa5d 100644 --- a/sys/boot/fdt/dts/mips/beri-netfpga.dts +++ b/sys/boot/fdt/dts/mips/beri-netfpga.dts @@ -82,6 +82,11 @@ */ }; + memory { + device_type = "memory"; + reg = <0x0 0x0FFFFFFF>; // ~256M at 0x0 + }; + soc { #address-cells = <1>; #size-cells = <1>; @@ -94,11 +99,6 @@ compatible = "simple-bus", "mips,mips4k"; ranges = <>; - memory { - device_type = "memory"; - reg = <0x0 0x0FFFFFFF>; // ~256M at 0x0 - }; - beripic: beripic@7f804000 { compatible = "sri-cambridge,beri-pic"; interrupt-controller; diff --git a/sys/boot/fdt/dts/mips/beri-sim.dts b/sys/boot/fdt/dts/mips/beri-sim.dts index 0704db86720..715445601d9 100644 --- a/sys/boot/fdt/dts/mips/beri-sim.dts +++ b/sys/boot/fdt/dts/mips/beri-sim.dts @@ -80,6 +80,11 @@ */ }; + memory { + device_type = "memory"; + reg = <0x0 0x4000000>; // 64M at 0x0 + }; + soc { #address-cells = <1>; #size-cells = <1>; @@ -92,11 +97,6 @@ compatible = "simple-bus", "mips,mips4k"; ranges = <>; - memory { - device_type = "memory"; - reg = <0x0 0x4000000>; // 64M at 0x0 - }; - beripic0: beripic@7f804000 { compatible = "sri-cambridge,beri-pic"; interrupt-controller; diff --git a/sys/boot/fdt/dts/mips/beripad-de4.dts b/sys/boot/fdt/dts/mips/beripad-de4.dts index 05ce0c2c8bc..287c2306d14 100644 --- a/sys/boot/fdt/dts/mips/beripad-de4.dts +++ b/sys/boot/fdt/dts/mips/beripad-de4.dts @@ -80,6 +80,11 @@ */ }; + memory { + device_type = "memory"; + reg = <0x0 0x40000000>; // 1G at 0x0 + }; + soc { #address-cells = <1>; #size-cells = <1>; @@ -92,11 +97,6 @@ compatible = "simple-bus", "mips,mips4k"; ranges = <>; - memory { - device_type = "memory"; - reg = <0x0 0x40000000>; // 1G at 0x0 - }; - beripic0: beripic@7f804000 { compatible = "sri-cambridge,beri-pic"; interrupt-controller; From 49506d68097da4c11188a567506efc73d6384d55 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Wed, 17 Dec 2014 11:36:31 +0000 Subject: [PATCH 48/64] Add configuration files for BERI soft-core synthesized on Terasic SoCKit board (Altera FPGA). Use virtio block as root filesystem device. Sponsored by: DARPA, AFRL --- sys/boot/fdt/dts/mips/beripad-sockit.dts | 219 +++++++++++++++++++++++ sys/mips/beri/files.beri | 1 + sys/mips/conf/BERI_SOCKIT | 26 +++ 3 files changed, 246 insertions(+) create mode 100644 sys/boot/fdt/dts/mips/beripad-sockit.dts create mode 100644 sys/mips/conf/BERI_SOCKIT diff --git a/sys/boot/fdt/dts/mips/beripad-sockit.dts b/sys/boot/fdt/dts/mips/beripad-sockit.dts new file mode 100644 index 00000000000..ad9e4acfbea --- /dev/null +++ b/sys/boot/fdt/dts/mips/beripad-sockit.dts @@ -0,0 +1,219 @@ +/*- + * Copyright (c) 2012-2013 Robert N. M. Watson + * Copyright (c) 2013-2014 SRI International + * Copyright (c) 2014 Ruslan Bukin + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/dts-v1/; + +/* + * Device names here have been largely made up on the spot, especially for the + * "compatible" strings, and might want to be revised. + */ + +/ { + model = "SRI/Cambridge BeriPad (SoCKit)"; + compatible = "sri-cambridge,beripad-sockit"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <1>; + + /* + * Secondary CPUs all start disabled and use the + * spin-table enable method. cpu-release-addr must be + * specified for each cpu other than cpu@0. Values of + * cpu-release-addr grow down from 0x100000 (kernel). + */ + status = "disabled"; + enable-method = "spin-table"; + + cpu@0 { + device-type = "cpu"; + compatible = "sri-cambridge,beri"; + + reg = <0 1>; + status = "okay"; + }; + +/* + cpu@1 { + device-type = "cpu"; + compatible = "sri-cambridge,beri"; + + reg = <1 1>; + // XXX: should we need cached prefix? + cpu-release-addr = <0xffffffff 0x800fffe0>; + }; +*/ + }; + + memory { + device_type = "memory"; + reg = <0x0 0x10000000>; /* 256MB at 0x0 */ + }; + + soc { + #address-cells = <2>; + #size-cells = <2>; + #interrupt-cells = <1>; + + /* + * Declare mips,mips4k since BERI doesn't (yet) have a PIC, so + * we use mips4k coprocessor 0 interrupt management directly. + */ + compatible = "simple-bus", "mips,mips4k"; + /* ranges = <>; */ + + beripic0: beripic@7f804000 { + compatible = "sri-cambridge,beri-pic"; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + reg = <0x0 0x7f804000 0x0 0x400 + 0x0 0x7f806000 0x0 0x10 + 0x0 0x7f806080 0x0 0x10 + 0x0 0x7f806100 0x0 0x10>; + interrupts = <0 1 2 3 4>; + hard-interrupt-sources = <64>; + soft-interrupt-sources = <64>; + }; + + pio0: pio@7f020000 { + compatible = "altr,pio"; + reg = <0x0 0x7f020000 0x0 0x1000>; /* send */ + interrupts = <4>; /* not used */ + interrupt-parent = <&beripic0>; + }; + + pio1: pio@7f021000 { + compatible = "altr,pio"; + reg = <0x0 0x7f021000 0x0 0x1000>; /* recv */ + interrupts = <10>; + interrupt-parent = <&beripic0>; + }; + + pio2: pio@7f022000 { + compatible = "altr,pio"; + reg = <0x0 0x7f022000 0x0 0x1000>; /* send */ + interrupts = <5>; /* not used */ + interrupt-parent = <&beripic0>; + }; + + pio3: pio@7f023000 { + compatible = "altr,pio"; + reg = <0x0 0x7f023000 0x0 0x1000>; /* recv */ + interrupts = <11>; + interrupt-parent = <&beripic0>; + }; + + virtio_mmio_platform0: virtio_mmio_platform@0 { + compatible = "beri,virtio_mmio_platform"; + pio-send = <&pio0>; + pio-recv = <&pio1>; + }; + + virtio_mmio_platform1: virtio_mmio_platform@1 { + compatible = "beri,virtio_mmio_platform"; + pio-send = <&pio2>; + pio-recv = <&pio3>; + }; + + virtio_block@200001000 { + compatible = "virtio,mmio"; + reg = <0x2 0x1000 0x0 0x1000>; + platform = <&virtio_mmio_platform0>; + status = "okay"; + }; + + virtio_net@200002000 { + compatible = "virtio,mmio"; + reg = <0x2 0x2000 0x0 0x1000>; + platform = <&virtio_mmio_platform1>; + status = "okay"; + }; + + serial@7f000000 { + compatible = "altera,jtag_uart-11_0"; + reg = <0x0 0x7f000000 0x0 0x40>; + interrupts = <0>; + interrupt-parent = <&beripic0>; + }; + +/* + serial@7f001000 { + compatible = "altera,jtag_uart-11_0"; + reg = <0x7f001000 0x40>; + }; + + serial@7f002000 { + compatible = "altera,jtag_uart-11_0"; + reg = <0x7f002000 0x40>; + }; +*/ + +/* + led@7f006000 { + compatible = "sri-cambridge,de4led"; + reg = <0x7f006000 0x1>; + }; +*/ + +/* + avgen@0x7f009000 { + compatible = "sri-cambridge,avgen"; + reg = <0x7f009000 0x2>; + sri-cambridge,width = <1>; + sri-cambridge,fileio = "r"; + sri-cambridge,devname = "de4bsw"; + }; +*/ + +/* + berirom@0x7f00a000 { + compatible = "sri-cambridge,berirom"; + reg = <0x7f00a000 0x1000>; + }; +*/ + +/* + avgen@0x7f00c000 { + compatible = "sri-cambridge,avgen"; + reg = <0x7f00c000 0x8>; + sri-cambridge,width = <4>; + sri-cambridge,fileio = "rw"; + sri-cambridge,devname = "de4tempfan"; + }; +*/ + }; +}; diff --git a/sys/mips/beri/files.beri b/sys/mips/beri/files.beri index 26c94ff651b..37e1839f4f1 100644 --- a/sys/mips/beri/files.beri +++ b/sys/mips/beri/files.beri @@ -6,6 +6,7 @@ dev/altera/jtag_uart/altera_jtag_uart_cons.c optional altera_jtag_uart dev/altera/jtag_uart/altera_jtag_uart_tty.c optional altera_jtag_uart dev/altera/jtag_uart/altera_jtag_uart_fdt.c optional altera_jtag_uart fdt dev/altera/jtag_uart/altera_jtag_uart_nexus.c optional altera_jtag_uart +dev/beri/virtio/virtio_mmio_platform.c optional virtio_mmio dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c optional netfpga10g_nf10bmac fdt dev/netfpga10g/nf10bmac/if_nf10bmac.c optional netfpga10g_nf10bmac dev/terasic/de4led/terasic_de4led.c optional terasic_de4led diff --git a/sys/mips/conf/BERI_SOCKIT b/sys/mips/conf/BERI_SOCKIT new file mode 100644 index 00000000000..ecc5bfe1edf --- /dev/null +++ b/sys/mips/conf/BERI_SOCKIT @@ -0,0 +1,26 @@ +# +# BERI_SOCKIT -- Kernel for the SRI/Cambridge "BERI" (Bluespec Extensible +# RISC Implementation) FPGA soft core, as configured in its Terasic SoCKit +# reference configuration. This kernel configration must be further +# specialized to to include a root filesystem specification. +# +# $FreeBSD$ +# + +include "BERI_TEMPLATE" + +ident BERI_SOCKIT + +options ROOTDEVNAME=\"ufs:vtbd0\" + +device altera_pio +device altera_jtag_uart + +device virtio +device virtio_blk +device vtnet +device virtio_mmio + +options FDT +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=beripad-sockit.dts From a356a1f51f57ec71f2ad40584b9ac856e9c074f4 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 17 Dec 2014 14:46:21 +0000 Subject: [PATCH 49/64] Do not strip all when stripping an explicit symbol When requested to strip specific symbols (-N flag) the default should be to strip nothing (other than the requested symbols). This is consistent with binutils strip(1). PR: 196038 Reviewed by: imp Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D1327 --- contrib/elftoolchain/elfcopy/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/elftoolchain/elfcopy/main.c b/contrib/elftoolchain/elfcopy/main.c index 3689f355fec..240ca5634cd 100644 --- a/contrib/elftoolchain/elfcopy/main.c +++ b/contrib/elftoolchain/elfcopy/main.c @@ -1109,7 +1109,8 @@ strip_main(struct elfcopy *ecp, int argc, char **argv) if (ecp->strip == 0 && ((ecp->flags & DISCARD_LOCAL) == 0) && - ((ecp->flags & DISCARD_LLABEL) == 0)) + ((ecp->flags & DISCARD_LLABEL) == 0) && + lookup_symop_list(ecp, NULL, SYMOP_STRIP) == NULL) ecp->strip = STRIP_ALL; if (optind == argc) strip_usage(); From 2124e3b07fe7bc1648596b971d9e58180b6fcbad Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 17 Dec 2014 15:13:21 +0000 Subject: [PATCH 50/64] Make sequence numbers checks more strict. While we don't support MCS, hole in received sequence numbers may mean only PDU loss. While we don't support lost PDU recovery, terminate the connection to avoid stuck commands. While there, improve handling of sequence numbers wrap after 2^32 PDUs. MFC after: 2 weeks --- sys/cam/ctl/ctl_frontend_iscsi.c | 48 ++++++++++++++++++++++++------- sys/cam/ctl/ctl_frontend_iscsi.h | 1 + sys/dev/iscsi/iscsi.c | 49 ++++++++++++++++++-------------- sys/dev/iscsi/iscsi_proto.h | 3 ++ usr.sbin/ctld/discovery.c | 12 ++++---- usr.sbin/ctld/login.c | 6 ++-- usr.sbin/iscsid/discovery.c | 4 +-- usr.sbin/iscsid/login.c | 2 +- 8 files changed, 81 insertions(+), 44 deletions(-) diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c index 8ec582586b7..0114b57b824 100644 --- a/sys/cam/ctl/ctl_frontend_iscsi.c +++ b/sys/cam/ctl/ctl_frontend_iscsi.c @@ -233,19 +233,34 @@ cfiscsi_pdu_update_cmdsn(const struct icl_pdu *request) } #endif - /* - * The target MUST silently ignore any non-immediate command outside - * of this range. - */ - if (cmdsn < cs->cs_cmdsn || cmdsn > cs->cs_cmdsn + maxcmdsn_delta) { - CFISCSI_SESSION_UNLOCK(cs); - CFISCSI_SESSION_WARN(cs, "received PDU with CmdSN %d, " - "while expected CmdSN was %d", cmdsn, cs->cs_cmdsn); - return (true); - } + if ((request->ip_bhs->bhs_opcode & ISCSI_BHS_OPCODE_IMMEDIATE) == 0) { + /* + * The target MUST silently ignore any non-immediate command + * outside of this range. + */ + if (ISCSI_SNLT(cmdsn, cs->cs_cmdsn) || + ISCSI_SNGT(cmdsn, cs->cs_cmdsn + maxcmdsn_delta)) { + CFISCSI_SESSION_UNLOCK(cs); + CFISCSI_SESSION_WARN(cs, "received PDU with CmdSN %u, " + "while expected %u", cmdsn, cs->cs_cmdsn); + return (true); + } - if ((request->ip_bhs->bhs_opcode & ISCSI_BHS_OPCODE_IMMEDIATE) == 0) + /* + * We don't support multiple connections now, so any + * discontinuity in CmdSN means lost PDUs. Since we don't + * support PDU retransmission -- terminate the connection. + */ + if (cmdsn != cs->cs_cmdsn) { + CFISCSI_SESSION_UNLOCK(cs); + CFISCSI_SESSION_WARN(cs, "received PDU with CmdSN %u, " + "while expected %u; dropping connection", + cmdsn, cs->cs_cmdsn); + cfiscsi_session_terminate(cs); + return (true); + } cs->cs_cmdsn++; + } CFISCSI_SESSION_UNLOCK(cs); @@ -892,6 +907,16 @@ cfiscsi_pdu_handle_data_out(struct icl_pdu *request) return; } + if (cdw->cdw_datasn != ntohl(bhsdo->bhsdo_datasn)) { + CFISCSI_SESSION_WARN(cs, "received Data-Out PDU with " + "DataSN %u, while expected %u; dropping connection", + ntohl(bhsdo->bhsdo_datasn), cdw->cdw_datasn); + icl_pdu_free(request); + cfiscsi_session_terminate(cs); + return; + } + cdw->cdw_datasn++; + io = cdw->cdw_ctl_io; KASSERT((io->io_hdr.flags & CTL_FLAG_DATA_MASK) != CTL_FLAG_DATA_IN, ("CTL_FLAG_DATA_IN")); @@ -2650,6 +2675,7 @@ cfiscsi_datamove_out(union ctl_io *io) cdw->cdw_target_transfer_tag = target_transfer_tag; cdw->cdw_initiator_task_tag = bhssc->bhssc_initiator_task_tag; cdw->cdw_r2t_end = io->scsiio.kern_data_len; + cdw->cdw_datasn = 0; /* Set initial data pointer for the CDW respecting ext_data_filled. */ if (io->scsiio.kern_sg_entries > 0) { diff --git a/sys/cam/ctl/ctl_frontend_iscsi.h b/sys/cam/ctl/ctl_frontend_iscsi.h index 336b69da323..5000f4c9c06 100644 --- a/sys/cam/ctl/ctl_frontend_iscsi.h +++ b/sys/cam/ctl/ctl_frontend_iscsi.h @@ -58,6 +58,7 @@ struct cfiscsi_data_wait { char *cdw_sg_addr; size_t cdw_sg_len; uint32_t cdw_r2t_end; + uint32_t cdw_datasn; }; #define CFISCSI_SESSION_STATE_INVALID 0 diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c index af7184684d3..f9edc8246c3 100644 --- a/sys/dev/iscsi/iscsi.c +++ b/sys/dev/iscsi/iscsi.c @@ -192,7 +192,7 @@ iscsi_pdu_prepare(struct icl_pdu *request) * Data-Out PDU does not contain CmdSN. */ if (bhssc->bhssc_opcode != ISCSI_BHS_OPCODE_SCSI_DATA_OUT) { - if (is->is_cmdsn > is->is_maxcmdsn && + if (ISCSI_SNGT(is->is_cmdsn, is->is_maxcmdsn) && (bhssc->bhssc_opcode & ISCSI_BHS_OPCODE_IMMEDIATE) == 0) { /* * Current MaxCmdSN prevents us from sending any more @@ -201,8 +201,10 @@ iscsi_pdu_prepare(struct icl_pdu *request) * or by maintenance thread. */ #if 0 - ISCSI_SESSION_DEBUG(is, "postponing send, CmdSN %d, ExpCmdSN %d, MaxCmdSN %d, opcode 0x%x", - is->is_cmdsn, is->is_expcmdsn, is->is_maxcmdsn, bhssc->bhssc_opcode); + ISCSI_SESSION_DEBUG(is, "postponing send, CmdSN %u, " + "ExpCmdSN %u, MaxCmdSN %u, opcode 0x%x", + is->is_cmdsn, is->is_expcmdsn, is->is_maxcmdsn, + bhssc->bhssc_opcode); #endif return (true); } @@ -611,7 +613,7 @@ iscsi_pdu_update_statsn(const struct icl_pdu *response) { const struct iscsi_bhs_data_in *bhsdi; struct iscsi_session *is; - uint32_t expcmdsn, maxcmdsn; + uint32_t expcmdsn, maxcmdsn, statsn; is = PDU_SESSION(response); @@ -630,26 +632,27 @@ iscsi_pdu_update_statsn(const struct icl_pdu *response) */ if (bhsdi->bhsdi_opcode != ISCSI_BHS_OPCODE_SCSI_DATA_IN || (bhsdi->bhsdi_flags & BHSDI_FLAGS_S) != 0) { - if (ntohl(bhsdi->bhsdi_statsn) < is->is_statsn) { - ISCSI_SESSION_WARN(is, - "PDU StatSN %d >= session StatSN %d, opcode 0x%x", - is->is_statsn, ntohl(bhsdi->bhsdi_statsn), - bhsdi->bhsdi_opcode); + statsn = ntohl(bhsdi->bhsdi_statsn); + if (statsn != is->is_statsn && statsn != (is->is_statsn + 1)) { + /* XXX: This is normal situation for MCS */ + ISCSI_SESSION_WARN(is, "PDU 0x%x StatSN %u != " + "session ExpStatSN %u (or + 1); reconnecting", + bhsdi->bhsdi_opcode, statsn, is->is_statsn); + iscsi_session_reconnect(is); } - is->is_statsn = ntohl(bhsdi->bhsdi_statsn); + if (ISCSI_SNGT(statsn, is->is_statsn)) + is->is_statsn = statsn; } expcmdsn = ntohl(bhsdi->bhsdi_expcmdsn); maxcmdsn = ntohl(bhsdi->bhsdi_maxcmdsn); - /* - * XXX: Compare using Serial Arithmetic Sense. - */ - if (maxcmdsn + 1 < expcmdsn) { - ISCSI_SESSION_DEBUG(is, "PDU MaxCmdSN %d + 1 < PDU ExpCmdSN %d; ignoring", + if (ISCSI_SNLT(maxcmdsn + 1, expcmdsn)) { + ISCSI_SESSION_DEBUG(is, + "PDU MaxCmdSN %u + 1 < PDU ExpCmdSN %u; ignoring", maxcmdsn, expcmdsn); } else { - if (maxcmdsn > is->is_maxcmdsn) { + if (ISCSI_SNGT(maxcmdsn, is->is_maxcmdsn)) { is->is_maxcmdsn = maxcmdsn; /* @@ -658,15 +661,19 @@ iscsi_pdu_update_statsn(const struct icl_pdu *response) */ if (!STAILQ_EMPTY(&is->is_postponed)) cv_signal(&is->is_maintenance_cv); - } else if (maxcmdsn < is->is_maxcmdsn) { - ISCSI_SESSION_DEBUG(is, "PDU MaxCmdSN %d < session MaxCmdSN %d; ignoring", + } else if (ISCSI_SNLT(maxcmdsn, is->is_maxcmdsn)) { + /* XXX: This is normal situation for MCS */ + ISCSI_SESSION_DEBUG(is, + "PDU MaxCmdSN %u < session MaxCmdSN %u; ignoring", maxcmdsn, is->is_maxcmdsn); } - if (expcmdsn > is->is_expcmdsn) { + if (ISCSI_SNGT(expcmdsn, is->is_expcmdsn)) { is->is_expcmdsn = expcmdsn; - } else if (expcmdsn < is->is_expcmdsn) { - ISCSI_SESSION_DEBUG(is, "PDU ExpCmdSN %d < session ExpCmdSN %d; ignoring", + } else if (ISCSI_SNLT(expcmdsn, is->is_expcmdsn)) { + /* XXX: This is normal situation for MCS */ + ISCSI_SESSION_DEBUG(is, + "PDU ExpCmdSN %u < session ExpCmdSN %u; ignoring", expcmdsn, is->is_expcmdsn); } } diff --git a/sys/dev/iscsi/iscsi_proto.h b/sys/dev/iscsi/iscsi_proto.h index 97d73a7a074..46572ce62d4 100644 --- a/sys/dev/iscsi/iscsi_proto.h +++ b/sys/dev/iscsi/iscsi_proto.h @@ -38,6 +38,9 @@ #define __CTASSERT(x, y) typedef char __assert_ ## y [(x) ? 1 : -1] #endif +#define ISCSI_SNGT(x, y) ((int32_t)(x) - (int32_t)(y) > 0) +#define ISCSI_SNLT(x, y) ((int32_t)(x) - (int32_t)(y) < 0) + #define ISCSI_BHS_SIZE 48 #define ISCSI_HEADER_DIGEST_SIZE 4 #define ISCSI_DATA_DIGEST_SIZE 4 diff --git a/usr.sbin/ctld/discovery.c b/usr.sbin/ctld/discovery.c index 01c9913051b..b370e0be586 100644 --- a/usr.sbin/ctld/discovery.c +++ b/usr.sbin/ctld/discovery.c @@ -65,13 +65,13 @@ text_receive(struct connection *conn) */ if ((bhstr->bhstr_flags & BHSTR_FLAGS_CONTINUE) != 0) log_errx(1, "received Text PDU with unsupported \"C\" flag"); - if (ntohl(bhstr->bhstr_cmdsn) < conn->conn_cmdsn) { + if (ISCSI_SNLT(ntohl(bhstr->bhstr_cmdsn), conn->conn_cmdsn)) { log_errx(1, "received Text PDU with decreasing CmdSN: " - "was %d, is %d", conn->conn_cmdsn, ntohl(bhstr->bhstr_cmdsn)); + "was %u, is %u", conn->conn_cmdsn, ntohl(bhstr->bhstr_cmdsn)); } if (ntohl(bhstr->bhstr_expstatsn) != conn->conn_statsn) { log_errx(1, "received Text PDU with wrong StatSN: " - "is %d, should be %d", ntohl(bhstr->bhstr_expstatsn), + "is %u, should be %u", ntohl(bhstr->bhstr_expstatsn), conn->conn_statsn); } conn->conn_cmdsn = ntohl(bhstr->bhstr_cmdsn); @@ -120,14 +120,14 @@ logout_receive(struct connection *conn) if ((bhslr->bhslr_reason & 0x7f) != BHSLR_REASON_CLOSE_SESSION) log_debugx("received Logout PDU with invalid reason 0x%x; " "continuing anyway", bhslr->bhslr_reason & 0x7f); - if (ntohl(bhslr->bhslr_cmdsn) < conn->conn_cmdsn) { + if (ISCSI_SNLT(ntohl(bhslr->bhslr_cmdsn), conn->conn_cmdsn)) { log_errx(1, "received Logout PDU with decreasing CmdSN: " - "was %d, is %d", conn->conn_cmdsn, + "was %u, is %u", conn->conn_cmdsn, ntohl(bhslr->bhslr_cmdsn)); } if (ntohl(bhslr->bhslr_expstatsn) != conn->conn_statsn) { log_errx(1, "received Logout PDU with wrong StatSN: " - "is %d, should be %d", ntohl(bhslr->bhslr_expstatsn), + "is %u, should be %u", ntohl(bhslr->bhslr_expstatsn), conn->conn_statsn); } conn->conn_cmdsn = ntohl(bhslr->bhslr_cmdsn); diff --git a/usr.sbin/ctld/login.c b/usr.sbin/ctld/login.c index fc41f5178d3..7add09b5d9b 100644 --- a/usr.sbin/ctld/login.c +++ b/usr.sbin/ctld/login.c @@ -127,17 +127,17 @@ login_receive(struct connection *conn, bool initial) log_errx(1, "received Login PDU with unsupported " "Version-min 0x%x", bhslr->bhslr_version_min); } - if (ntohl(bhslr->bhslr_cmdsn) < conn->conn_cmdsn) { + if (ISCSI_SNLT(ntohl(bhslr->bhslr_cmdsn), conn->conn_cmdsn)) { login_send_error(request, 0x02, 0x05); log_errx(1, "received Login PDU with decreasing CmdSN: " - "was %d, is %d", conn->conn_cmdsn, + "was %u, is %u", conn->conn_cmdsn, ntohl(bhslr->bhslr_cmdsn)); } if (initial == false && ntohl(bhslr->bhslr_expstatsn) != conn->conn_statsn) { login_send_error(request, 0x02, 0x05); log_errx(1, "received Login PDU with wrong ExpStatSN: " - "is %d, should be %d", ntohl(bhslr->bhslr_expstatsn), + "is %u, should be %u", ntohl(bhslr->bhslr_expstatsn), conn->conn_statsn); } conn->conn_cmdsn = ntohl(bhslr->bhslr_cmdsn); diff --git a/usr.sbin/iscsid/discovery.c b/usr.sbin/iscsid/discovery.c index c87d9fff735..a8975d73077 100644 --- a/usr.sbin/iscsid/discovery.c +++ b/usr.sbin/iscsid/discovery.c @@ -66,7 +66,7 @@ text_receive(struct connection *conn) log_errx(1, "received Text PDU with unsupported \"C\" flag"); if (ntohl(bhstr->bhstr_statsn) != conn->conn_statsn + 1) { log_errx(1, "received Text PDU with wrong StatSN: " - "is %d, should be %d", ntohl(bhstr->bhstr_statsn), + "is %u, should be %u", ntohl(bhstr->bhstr_statsn), conn->conn_statsn + 1); } conn->conn_statsn = ntohl(bhstr->bhstr_statsn); @@ -112,7 +112,7 @@ logout_receive(struct connection *conn) ntohs(bhslr->bhslr_response)); if (ntohl(bhslr->bhslr_statsn) != conn->conn_statsn + 1) { log_errx(1, "received Logout PDU with wrong StatSN: " - "is %d, should be %d", ntohl(bhslr->bhslr_statsn), + "is %u, should be %u", ntohl(bhslr->bhslr_statsn), conn->conn_statsn + 1); } conn->conn_statsn = ntohl(bhslr->bhslr_statsn); diff --git a/usr.sbin/iscsid/login.c b/usr.sbin/iscsid/login.c index afe7ebbc6bf..360b0ef186a 100644 --- a/usr.sbin/iscsid/login.c +++ b/usr.sbin/iscsid/login.c @@ -257,7 +257,7 @@ login_receive(struct connection *conn) * to be bug in NetBSD iSCSI target. */ log_warnx("received Login PDU with wrong StatSN: " - "is %d, should be %d", ntohl(bhslr->bhslr_statsn), + "is %u, should be %u", ntohl(bhslr->bhslr_statsn), conn->conn_statsn + 1); } conn->conn_tsih = ntohs(bhslr->bhslr_tsih); From 34961f407de5e59e219961c25c33db6bc0f39847 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 17 Dec 2014 17:30:54 +0000 Subject: [PATCH 51/64] Add configuration options to override physical and UNMAP blocks geometry. While in most cases CTL should correctly fetch those values from backing storages, there are some initiators (like MS SQL), that may not like large physical block sizes, even if they are true. For such cases allow override fetched values with supported ones (like 4K). MFC after: 1 week --- sys/cam/ctl/ctl.c | 8 ++-- sys/cam/ctl/ctl.h | 1 + sys/cam/ctl/ctl_backend.h | 2 + sys/cam/ctl/ctl_backend_block.c | 70 ++++++++++++++++++++++++++++++--- usr.sbin/ctladm/ctladm.8 | 9 ++++- 5 files changed, 79 insertions(+), 11 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 2a8aba908a2..8fccd02f47b 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -3900,7 +3900,7 @@ ctl_copy_io(union ctl_io *src, union ctl_io *dest) dest->io_hdr.flags |= CTL_FLAG_INT_COPY; } -static int +int ctl_expand_number(const char *buf, uint64_t *num) { char *endptr; @@ -10146,10 +10146,10 @@ ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len) if (lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) { scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_lba_cnt); scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_blk_cnt); - if (lun->be_lun->pblockexp != 0) { - scsi_ulto4b((1 << lun->be_lun->pblockexp), + if (lun->be_lun->ublockexp != 0) { + scsi_ulto4b((1 << lun->be_lun->ublockexp), bl_ptr->opt_unmap_grain); - scsi_ulto4b(0x80000000 | lun->be_lun->pblockoff, + scsi_ulto4b(0x80000000 | lun->be_lun->ublockoff, bl_ptr->unmap_grain_align); } } diff --git a/sys/cam/ctl/ctl.h b/sys/cam/ctl/ctl.h index 1ec0586da4e..ae6c5835f87 100644 --- a/sys/cam/ctl/ctl.h +++ b/sys/cam/ctl/ctl.h @@ -206,6 +206,7 @@ struct ctl_be_arg; void ctl_init_opts(ctl_options_t *opts, int num_args, struct ctl_be_arg *args); void ctl_free_opts(ctl_options_t *opts); char * ctl_get_opt(ctl_options_t *opts, const char *name); +int ctl_expand_number(const char *buf, uint64_t *num); #endif /* _KERNEL */ diff --git a/sys/cam/ctl/ctl_backend.h b/sys/cam/ctl/ctl_backend.h index 77975f9ffea..5e0af5cc302 100644 --- a/sys/cam/ctl/ctl_backend.h +++ b/sys/cam/ctl/ctl_backend.h @@ -194,6 +194,8 @@ struct ctl_be_lun { uint32_t blocksize; /* passed to CTL */ uint16_t pblockexp; /* passed to CTL */ uint16_t pblockoff; /* passed to CTL */ + uint16_t ublockexp; /* passed to CTL */ + uint16_t ublockoff; /* passed to CTL */ uint32_t atomicblock; /* passed to CTL */ uint32_t req_lun_id; /* passed to CTL */ uint32_t lun_id; /* returned from CTL */ diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c index 1eb5ed2e40b..9c3e8fd686d 100644 --- a/sys/cam/ctl/ctl_backend_block.c +++ b/sys/cam/ctl/ctl_backend_block.c @@ -173,6 +173,8 @@ struct ctl_be_block_lun { int blocksize_shift; uint16_t pblockexp; uint16_t pblockoff; + uint16_t ublockexp; + uint16_t ublockoff; struct ctl_be_block_softc *softc; struct devstat *disk_stats; ctl_be_block_lun_flags flags; @@ -1739,8 +1741,9 @@ ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) { struct ctl_be_block_filedata *file_data; struct ctl_lun_create_params *params; + char *value; struct vattr vattr; - off_t pss; + off_t ps, pss, po, pos, us, uss, uo, uos; int error; error = 0; @@ -1800,11 +1803,36 @@ ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) be_lun->blocksize = params->blocksize_bytes; else be_lun->blocksize = 512; - pss = vattr.va_blocksize / be_lun->blocksize; - if ((pss > 0) && (pss * be_lun->blocksize == vattr.va_blocksize) && - ((pss & (pss - 1)) == 0)) { + + us = ps = vattr.va_blocksize; + uo = po = 0; + + value = ctl_get_opt(&be_lun->ctl_be_lun.options, "pblocksize"); + if (value != NULL) + ctl_expand_number(value, &ps); + value = ctl_get_opt(&be_lun->ctl_be_lun.options, "pblockoffset"); + if (value != NULL) + ctl_expand_number(value, &po); + pss = ps / be_lun->blocksize; + pos = po / be_lun->blocksize; + if ((pss > 0) && (pss * be_lun->blocksize == ps) && (pss >= pos) && + ((pss & (pss - 1)) == 0) && (pos * be_lun->blocksize == po)) { be_lun->pblockexp = fls(pss) - 1; - be_lun->pblockoff = 0; + be_lun->pblockoff = (pss - pos) % pss; + } + + value = ctl_get_opt(&be_lun->ctl_be_lun.options, "ublocksize"); + if (value != NULL) + ctl_expand_number(value, &us); + value = ctl_get_opt(&be_lun->ctl_be_lun.options, "ublockoffset"); + if (value != NULL) + ctl_expand_number(value, &uo); + uss = us / be_lun->blocksize; + uos = uo / be_lun->blocksize; + if ((uss > 0) && (uss * be_lun->blocksize == us) && (uss >= uos) && + ((uss & (uss - 1)) == 0) && (uos * be_lun->blocksize == uo)) { + be_lun->ublockexp = fls(uss) - 1; + be_lun->ublockoff = (uss - uos) % uss; } /* @@ -1827,8 +1855,9 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) struct vattr vattr; struct cdev *dev; struct cdevsw *devsw; + char *value; int error; - off_t ps, pss, po, pos; + off_t ps, pss, po, pos, us, uss, uo, uos; params = &be_lun->params; @@ -1942,6 +1971,15 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) if (error) po = 0; } + us = ps; + uo = po; + + value = ctl_get_opt(&be_lun->ctl_be_lun.options, "pblocksize"); + if (value != NULL) + ctl_expand_number(value, &ps); + value = ctl_get_opt(&be_lun->ctl_be_lun.options, "pblockoffset"); + if (value != NULL) + ctl_expand_number(value, &po); pss = ps / be_lun->blocksize; pos = po / be_lun->blocksize; if ((pss > 0) && (pss * be_lun->blocksize == ps) && (pss >= pos) && @@ -1950,6 +1988,20 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) be_lun->pblockoff = (pss - pos) % pss; } + value = ctl_get_opt(&be_lun->ctl_be_lun.options, "ublocksize"); + if (value != NULL) + ctl_expand_number(value, &us); + value = ctl_get_opt(&be_lun->ctl_be_lun.options, "ublockoffset"); + if (value != NULL) + ctl_expand_number(value, &uo); + uss = us / be_lun->blocksize; + uos = uo / be_lun->blocksize; + if ((uss > 0) && (uss * be_lun->blocksize == us) && (uss >= uos) && + ((uss & (uss - 1)) == 0) && (uos * be_lun->blocksize == uo)) { + be_lun->ublockexp = fls(uss) - 1; + be_lun->ublockoff = (uss - uos) % uss; + } + return (0); } @@ -2162,6 +2214,8 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) be_lun->blocksize = 0; be_lun->pblockexp = 0; be_lun->pblockoff = 0; + be_lun->ublockexp = 0; + be_lun->ublockoff = 0; be_lun->size_blocks = 0; be_lun->size_bytes = 0; be_lun->ctl_be_lun.maxlba = 0; @@ -2212,6 +2266,8 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) be_lun->ctl_be_lun.blocksize = be_lun->blocksize; be_lun->ctl_be_lun.pblockexp = be_lun->pblockexp; be_lun->ctl_be_lun.pblockoff = be_lun->pblockoff; + be_lun->ctl_be_lun.ublockexp = be_lun->ublockexp; + be_lun->ctl_be_lun.ublockoff = be_lun->ublockoff; if (be_lun->dispatch == ctl_be_block_dispatch_zvol && be_lun->blocksize != 0) be_lun->ctl_be_lun.atomicblock = CTLBLK_MAX_IO_SIZE / @@ -2591,6 +2647,8 @@ ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) be_lun->ctl_be_lun.blocksize = be_lun->blocksize; be_lun->ctl_be_lun.pblockexp = be_lun->pblockexp; be_lun->ctl_be_lun.pblockoff = be_lun->pblockoff; + be_lun->ctl_be_lun.ublockexp = be_lun->ublockexp; + be_lun->ctl_be_lun.ublockoff = be_lun->ublockoff; if (be_lun->dispatch == ctl_be_block_dispatch_zvol && be_lun->blocksize != 0) be_lun->ctl_be_lun.atomicblock = CTLBLK_MAX_IO_SIZE / diff --git a/usr.sbin/ctladm/ctladm.8 b/usr.sbin/ctladm/ctladm.8 index 571a87a25b1..2a5123ab877 100644 --- a/usr.sbin/ctladm/ctladm.8 +++ b/usr.sbin/ctladm/ctladm.8 @@ -34,7 +34,7 @@ .\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $ .\" $FreeBSD$ .\" -.Dd December 6, 2014 +.Dd December 17, 2014 .Dt CTLADM 8 .Os .Sh NAME @@ -1002,6 +1002,13 @@ Set to "off" to allow them be issued in parallel. Parallel issue of consecutive operations may confuse logic of the backing file system, hurting performance; but it may improve performance of backing stores without prefetch/write-back. +.It Va psectorsize +.It Va psectoroffset +Specify physical block size and offset of the device. +.It Va usectorsize +.It Va usectoroffset +Specify UNMAP block size and offset of the device. +.It Va rpm .It Va rpm Specifies medium rotation rate of the device: 0 -- not reported, 1 -- non-rotating (SSD), >1024 -- value in revolutions per minute. From e92bda2e4b62fb3c190153f4375cbcfecae80216 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Wed, 17 Dec 2014 19:46:12 +0000 Subject: [PATCH 52/64] Parallelize building gnu/usr.bin/groff This speeds up building the directory from the bootstrap-tools stage in buildworld as well as building from the subdirectory Based on a patch submitted via -arch: https://lists.freebsd.org/pipermail/freebsd-arch/2014-December/016493.html MFC after: 1 week Submitted by: Jia-Shiun Li Sponsored by: EMC / Isilon Storage Division --- gnu/usr.bin/groff/Makefile | 4 ++++ gnu/usr.bin/groff/src/Makefile | 6 ++++++ gnu/usr.bin/groff/src/devices/Makefile | 2 ++ gnu/usr.bin/groff/src/libs/Makefile | 2 ++ gnu/usr.bin/groff/src/preproc/Makefile | 2 ++ gnu/usr.bin/groff/src/roff/Makefile | 2 ++ gnu/usr.bin/groff/src/utils/Makefile | 2 ++ 7 files changed, 20 insertions(+) diff --git a/gnu/usr.bin/groff/Makefile b/gnu/usr.bin/groff/Makefile index 7c61f71be94..2db554f6d40 100644 --- a/gnu/usr.bin/groff/Makefile +++ b/gnu/usr.bin/groff/Makefile @@ -2,4 +2,8 @@ SUBDIR= contrib doc font man src tmac +.for subdir in ${SUBDIR:Nsrc} +SUBDIR_DEPEND_${subdir}= src +.endfor + .include diff --git a/gnu/usr.bin/groff/src/Makefile b/gnu/usr.bin/groff/src/Makefile index 7d2ca90a225..291b27c9d56 100644 --- a/gnu/usr.bin/groff/src/Makefile +++ b/gnu/usr.bin/groff/src/Makefile @@ -2,4 +2,10 @@ SUBDIR= libs devices preproc roff utils +SUBDIR_PARALLEL= + +.for subdir in ${SUBDIR:Nlibs} +SUBDIR_DEPEND_${subdir}= libs +.endfor + .include diff --git a/gnu/usr.bin/groff/src/devices/Makefile b/gnu/usr.bin/groff/src/devices/Makefile index 8af4ff85b99..53dc4ed1581 100644 --- a/gnu/usr.bin/groff/src/devices/Makefile +++ b/gnu/usr.bin/groff/src/devices/Makefile @@ -2,4 +2,6 @@ SUBDIR= grodvi grohtml grolbp grolj4 grops grotty +SUBDIR_PARALLEL= + .include diff --git a/gnu/usr.bin/groff/src/libs/Makefile b/gnu/usr.bin/groff/src/libs/Makefile index 1461cda28ba..37383149264 100644 --- a/gnu/usr.bin/groff/src/libs/Makefile +++ b/gnu/usr.bin/groff/src/libs/Makefile @@ -2,4 +2,6 @@ SUBDIR= libgroff libdriver libbib +SUBDIR_PARALLEL= + .include diff --git a/gnu/usr.bin/groff/src/preproc/Makefile b/gnu/usr.bin/groff/src/preproc/Makefile index 70af839313d..f208bf2389b 100644 --- a/gnu/usr.bin/groff/src/preproc/Makefile +++ b/gnu/usr.bin/groff/src/preproc/Makefile @@ -2,4 +2,6 @@ SUBDIR= eqn grn html pic refer soelim tbl +SUBDIR_PARALLEL= + .include diff --git a/gnu/usr.bin/groff/src/roff/Makefile b/gnu/usr.bin/groff/src/roff/Makefile index 543a990c680..6f23c42c95a 100644 --- a/gnu/usr.bin/groff/src/roff/Makefile +++ b/gnu/usr.bin/groff/src/roff/Makefile @@ -2,4 +2,6 @@ SUBDIR= groff grog nroff psroff troff +SUBDIR_PARALLEL= + .include diff --git a/gnu/usr.bin/groff/src/utils/Makefile b/gnu/usr.bin/groff/src/utils/Makefile index 14953b92531..045030cb441 100644 --- a/gnu/usr.bin/groff/src/utils/Makefile +++ b/gnu/usr.bin/groff/src/utils/Makefile @@ -2,4 +2,6 @@ SUBDIR= addftinfo afmtodit hpftodit indxbib lkbib lookbib pfbtops tfmtodit +SUBDIR_PARALLEL= + .include From f9d93ea7755b52d57a5db4b74635260dbb853b70 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Wed, 17 Dec 2014 20:02:07 +0000 Subject: [PATCH 53/64] Fix sporadic build failures due to race when running make installworld when strip gets replaced at install time by adding it to ITOOLS for the default usr.bin/xinstall STRIP_CMD This will fix the failure noted in this Jenkins build step: https://jenkins.freebsd.org/job/Build-UFS-image/688/ This will also fix the issue reported by alfred@ dealing with installing on targets that differ from build hosts (e.g. installing on i386/i386 when built on amd64/amd64) MFC after: 1 week Sponsored by: EMC / Isilon Storage Division --- Makefile.inc1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index c7cb8ef0182..86294fef1b8 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -790,7 +790,7 @@ _zoneinfo= zic tzsetup ITOOLS= [ awk cap_mkdb cat chflags chmod chown \ date echo egrep find grep id install ${_install-info} \ ln lockf make mkdir mtree mv pwd_mkdb \ - rm sed services_mkdb sh sysctl test true uname wc ${_zoneinfo} \ + rm sed services_mkdb sh strip sysctl test true uname wc ${_zoneinfo} \ ${LOCAL_ITOOLS} # Needed for share/man From caeae63f97ec54833d17a36032db1590796913a8 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Wed, 17 Dec 2014 20:19:57 +0000 Subject: [PATCH 54/64] Plug a memory leak in an error code path. Reported by: Coverity CID: 1018936 MFC after: 3 days --- sys/netinet6/sctp6_usrreq.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c index 93253f2a3f2..08b1bb708cc 100644 --- a/sys/netinet6/sctp6_usrreq.c +++ b/sys/netinet6/sctp6_usrreq.c @@ -1125,8 +1125,11 @@ sctp6_peeraddr(struct socket *so, struct sockaddr **addr) SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT); return (ENOENT); } - if ((error = sa6_recoverscope(sin6)) != 0) + if ((error = sa6_recoverscope(sin6)) != 0) { + SCTP_FREE_SONAME(sin6); + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, error); return (error); + } *addr = (struct sockaddr *)sin6; return (0); } From 142a4d9e866574ca1a19e7badcdabeb8b8d8aa2f Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Wed, 17 Dec 2014 20:34:38 +0000 Subject: [PATCH 55/64] Add a missing break. Reported by: Coverity CID: 1232014 MFC after: 3 days --- sys/netinet/sctp_pcb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index f986375e563..fc39495f2f0 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -6462,6 +6462,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, switch (pr_supported->chunk_types[i]) { case SCTP_ASCONF: peer_supports_asconf = 1; + break; case SCTP_ASCONF_ACK: peer_supports_asconf_ack = 1; break; From e03905177a3e5a18429e8c99c8b524d8d2adc83a Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Wed, 17 Dec 2014 21:26:25 +0000 Subject: [PATCH 56/64] Use the correct macro for listing the maximum bus space size. Without this, it fails to compile on i386 PAE builds. --- sys/dev/mwl/if_mwl_pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/mwl/if_mwl_pci.c b/sys/dev/mwl/if_mwl_pci.c index 8527cd67e38..ef7009c785d 100644 --- a/sys/dev/mwl/if_mwl_pci.c +++ b/sys/dev/mwl/if_mwl_pci.c @@ -178,9 +178,9 @@ mwl_pci_attach(device_t dev) BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ - BUS_SPACE_MAXADDR, /* maxsize */ + BUS_SPACE_MAXSIZE, /* maxsize */ MWL_TXDESC, /* nsegments */ - BUS_SPACE_MAXADDR, /* maxsegsize */ + BUS_SPACE_MAXSIZE, /* maxsegsize */ 0, /* flags */ NULL, /* lockfunc */ NULL, /* lockarg */ From d13ccc6ac291297456d96f27d528f749c0762746 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Wed, 17 Dec 2014 21:27:27 +0000 Subject: [PATCH 57/64] Update the use of bus space macros to be more correct. This was a problem on i386 PAE builds. --- sys/dev/malo/if_malo_pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/malo/if_malo_pci.c b/sys/dev/malo/if_malo_pci.c index c9e6b207038..26324c09f09 100644 --- a/sys/dev/malo/if_malo_pci.c +++ b/sys/dev/malo/if_malo_pci.c @@ -225,9 +225,9 @@ malo_pci_attach(device_t dev) BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ - BUS_SPACE_MAXADDR, /* maxsize */ + BUS_SPACE_MAXSIZE, /* maxsize */ 0, /* nsegments */ - BUS_SPACE_MAXADDR, /* maxsegsize */ + BUS_SPACE_MAXSIZE, /* maxsegsize */ 0, /* flags */ NULL, /* lockfunc */ NULL, /* lockarg */ From e5701220a84fa45e3d8606fcbb3701156a4c2eb3 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Thu, 18 Dec 2014 03:12:46 +0000 Subject: [PATCH 58/64] Make gas parse '__tls_get_addr(foo@tlsgd)'. Corresponds to 727fc41e077139570ea8b8ddfd6c546b2a55627c. This allows us to use -no-integrated-as with clang, if we prefer. Obtained from: binutils-gdb (Relicensed from Alan Modra as GPLv2) MFC after: 2 weeks X-MFC-with: r275718 --- contrib/binutils/gas/config/tc-ppc.c | 236 ++++++++++++++++----------- 1 file changed, 143 insertions(+), 93 deletions(-) diff --git a/contrib/binutils/gas/config/tc-ppc.c b/contrib/binutils/gas/config/tc-ppc.c index 1ecd99faea5..940633b6a3f 100644 --- a/contrib/binutils/gas/config/tc-ppc.c +++ b/contrib/binutils/gas/config/tc-ppc.c @@ -2509,108 +2509,156 @@ md_assemble (char *str) (char *) NULL, 0); } #ifdef OBJ_ELF - else if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED) + else { - /* Some TLS tweaks. */ - switch (reloc) + if (ex.X_op == O_symbol && str[0] == '(') { - default: - break; - case BFD_RELOC_PPC_TLS: - insn = ppc_insert_operand (insn, operand, ppc_obj64 ? 13 : 2, - (char *) NULL, 0); - break; - /* We'll only use the 32 (or 64) bit form of these relocations - in constants. Instructions get the 16 bit form. */ - case BFD_RELOC_PPC_DTPREL: - reloc = BFD_RELOC_PPC_DTPREL16; - break; - case BFD_RELOC_PPC_TPREL: - reloc = BFD_RELOC_PPC_TPREL16; - break; - } + const char *sym_name = S_GET_NAME (ex.X_add_symbol); + if (sym_name[0] == '.') + ++sym_name; - /* For the absolute forms of branches, convert the PC - relative form back into the absolute. */ - if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0) - { - switch (reloc) + if (strcasecmp (sym_name, "__tls_get_addr") == 0) { - case BFD_RELOC_PPC_B26: - reloc = BFD_RELOC_PPC_BA26; - break; - case BFD_RELOC_PPC_B16: - reloc = BFD_RELOC_PPC_BA16; - break; - case BFD_RELOC_PPC_B16_BRTAKEN: - reloc = BFD_RELOC_PPC_BA16_BRTAKEN; - break; - case BFD_RELOC_PPC_B16_BRNTAKEN: - reloc = BFD_RELOC_PPC_BA16_BRNTAKEN; - break; - default: - break; + expressionS tls_exp; + + hold = input_line_pointer; + input_line_pointer = str + 1; + expression (&tls_exp); + if (tls_exp.X_op == O_symbol) + { + reloc = BFD_RELOC_UNUSED; + if (strncasecmp (input_line_pointer, "@tlsgd)", 7) == 0) + { + reloc = BFD_RELOC_PPC_TLSGD; + input_line_pointer += 7; + } + else if (strncasecmp (input_line_pointer, "@tlsld)", 7) == 0) + { + reloc = BFD_RELOC_PPC_TLSLD; + input_line_pointer += 7; + } + if (reloc != BFD_RELOC_UNUSED) + { + SKIP_WHITESPACE (); + str = input_line_pointer; + + if (fc >= MAX_INSN_FIXUPS) + as_fatal (_("too many fixups")); + fixups[fc].exp = tls_exp; + fixups[fc].opindex = *opindex_ptr; + fixups[fc].reloc = reloc; + ++fc; + } + } + input_line_pointer = hold; } } - if (ppc_obj64 - && (operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0) + if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED) { + /* Some TLS tweaks. */ switch (reloc) { - case BFD_RELOC_16: - reloc = BFD_RELOC_PPC64_ADDR16_DS; - break; - case BFD_RELOC_LO16: - reloc = BFD_RELOC_PPC64_ADDR16_LO_DS; - break; - case BFD_RELOC_16_GOTOFF: - reloc = BFD_RELOC_PPC64_GOT16_DS; - break; - case BFD_RELOC_LO16_GOTOFF: - reloc = BFD_RELOC_PPC64_GOT16_LO_DS; - break; - case BFD_RELOC_LO16_PLTOFF: - reloc = BFD_RELOC_PPC64_PLT16_LO_DS; - break; - case BFD_RELOC_16_BASEREL: - reloc = BFD_RELOC_PPC64_SECTOFF_DS; - break; - case BFD_RELOC_LO16_BASEREL: - reloc = BFD_RELOC_PPC64_SECTOFF_LO_DS; - break; - case BFD_RELOC_PPC_TOC16: - reloc = BFD_RELOC_PPC64_TOC16_DS; - break; - case BFD_RELOC_PPC64_TOC16_LO: - reloc = BFD_RELOC_PPC64_TOC16_LO_DS; - break; - case BFD_RELOC_PPC64_PLTGOT16: - reloc = BFD_RELOC_PPC64_PLTGOT16_DS; - break; - case BFD_RELOC_PPC64_PLTGOT16_LO: - reloc = BFD_RELOC_PPC64_PLTGOT16_LO_DS; - break; - case BFD_RELOC_PPC_DTPREL16: - reloc = BFD_RELOC_PPC64_DTPREL16_DS; - break; - case BFD_RELOC_PPC_DTPREL16_LO: - reloc = BFD_RELOC_PPC64_DTPREL16_LO_DS; - break; - case BFD_RELOC_PPC_TPREL16: - reloc = BFD_RELOC_PPC64_TPREL16_DS; - break; - case BFD_RELOC_PPC_TPREL16_LO: - reloc = BFD_RELOC_PPC64_TPREL16_LO_DS; - break; - case BFD_RELOC_PPC_GOT_DTPREL16: - case BFD_RELOC_PPC_GOT_DTPREL16_LO: - case BFD_RELOC_PPC_GOT_TPREL16: - case BFD_RELOC_PPC_GOT_TPREL16_LO: - break; default: - as_bad (_("unsupported relocation for DS offset field")); break; + + case BFD_RELOC_PPC_TLS: + insn = ppc_insert_operand (insn, operand, ppc_obj64 ? 13 : 2, + (char *) NULL, 0); + break; + + /* We'll only use the 32 (or 64) bit form of these relocations + in constants. Instructions get the 16 bit form. */ + case BFD_RELOC_PPC_DTPREL: + reloc = BFD_RELOC_PPC_DTPREL16; + break; + case BFD_RELOC_PPC_TPREL: + reloc = BFD_RELOC_PPC_TPREL16; + break; + } + + /* For the absolute forms of branches, convert the PC + relative form back into the absolute. */ + if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0) + { + switch (reloc) + { + case BFD_RELOC_PPC_B26: + reloc = BFD_RELOC_PPC_BA26; + break; + case BFD_RELOC_PPC_B16: + reloc = BFD_RELOC_PPC_BA16; + break; + case BFD_RELOC_PPC_B16_BRTAKEN: + reloc = BFD_RELOC_PPC_BA16_BRTAKEN; + break; + case BFD_RELOC_PPC_B16_BRNTAKEN: + reloc = BFD_RELOC_PPC_BA16_BRNTAKEN; + break; + default: + break; + } + } + + if (ppc_obj64 + && (operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0) + { + switch (reloc) + { + case BFD_RELOC_16: + reloc = BFD_RELOC_PPC64_ADDR16_DS; + break; + case BFD_RELOC_LO16: + reloc = BFD_RELOC_PPC64_ADDR16_LO_DS; + break; + case BFD_RELOC_16_GOTOFF: + reloc = BFD_RELOC_PPC64_GOT16_DS; + break; + case BFD_RELOC_LO16_GOTOFF: + reloc = BFD_RELOC_PPC64_GOT16_LO_DS; + break; + case BFD_RELOC_LO16_PLTOFF: + reloc = BFD_RELOC_PPC64_PLT16_LO_DS; + break; + case BFD_RELOC_16_BASEREL: + reloc = BFD_RELOC_PPC64_SECTOFF_DS; + break; + case BFD_RELOC_LO16_BASEREL: + reloc = BFD_RELOC_PPC64_SECTOFF_LO_DS; + break; + case BFD_RELOC_PPC_TOC16: + reloc = BFD_RELOC_PPC64_TOC16_DS; + break; + case BFD_RELOC_PPC64_TOC16_LO: + reloc = BFD_RELOC_PPC64_TOC16_LO_DS; + break; + case BFD_RELOC_PPC64_PLTGOT16: + reloc = BFD_RELOC_PPC64_PLTGOT16_DS; + break; + case BFD_RELOC_PPC64_PLTGOT16_LO: + reloc = BFD_RELOC_PPC64_PLTGOT16_LO_DS; + break; + case BFD_RELOC_PPC_DTPREL16: + reloc = BFD_RELOC_PPC64_DTPREL16_DS; + break; + case BFD_RELOC_PPC_DTPREL16_LO: + reloc = BFD_RELOC_PPC64_DTPREL16_LO_DS; + break; + case BFD_RELOC_PPC_TPREL16: + reloc = BFD_RELOC_PPC64_TPREL16_DS; + break; + case BFD_RELOC_PPC_TPREL16_LO: + reloc = BFD_RELOC_PPC64_TPREL16_LO_DS; + break; + case BFD_RELOC_PPC_GOT_DTPREL16: + case BFD_RELOC_PPC_GOT_DTPREL16_LO: + case BFD_RELOC_PPC_GOT_TPREL16: + case BFD_RELOC_PPC_GOT_TPREL16_LO: + break; + default: + as_bad (_("unsupported relocation for DS offset field")); + break; + } } } @@ -2618,12 +2666,11 @@ md_assemble (char *str) if (fc >= MAX_INSN_FIXUPS) as_fatal (_("too many fixups")); fixups[fc].exp = ex; - fixups[fc].opindex = 0; + fixups[fc].opindex = *opindex_ptr; fixups[fc].reloc = reloc; ++fc; } -#endif /* OBJ_ELF */ - +#else /* OBJ_ELF */ else { /* We need to generate a fixup for this expression. */ @@ -2634,6 +2681,7 @@ md_assemble (char *str) fixups[fc].reloc = BFD_RELOC_UNUSED; ++fc; } +#endif /* OBJ_ELF */ if (need_paren) { @@ -5908,6 +5956,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) break; case BFD_RELOC_PPC_TLS: + case BFD_RELOC_PPC_TLSLD: + case BFD_RELOC_PPC_TLSGD: break; case BFD_RELOC_PPC_DTPMOD: From 4ff1fc3b17053f19a7bf1aced7f929bd5888a4f4 Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Thu, 18 Dec 2014 03:51:09 +0000 Subject: [PATCH 59/64] In bsdinstall's distextract, replace mixed_gauge() of dialog(3) with new dpv(3) wrapper to dialog(3) dialog_gauge(). The dpv(3) library provides a more flexible and refined interface similar to dialog_mixedgauge() however is implemented atop the more generalized dialog_gauge() for portability. Noticeable improvements in bsdinstall's distextract will be a status line showing data rate information (with support for localeconv(3) to format numbers according to $LANG or $LC_ALL conversion information), i18n support, improved auto-sizing of gauge widget, a ``wheel barrow'' to keep the user informed that things are moving (even if status/progress has not changed), improved color support (mini-progress bars use the same color, if enabled, as the main gauge bar), and several other improvements (some not visible). dpv stands for "dialog progress view" (dpv was introduced in SVN r274116). Differential Revision: https://reviews.freebsd.org/D714 Discussed on: -current Reviewed by: julian MFC after: 3 days X-MFC-to: stable/10 Relnotes: Improved installer feedback from bsdinstall distextract --- usr.sbin/bsdinstall/distextract/Makefile | 2 +- usr.sbin/bsdinstall/distextract/distextract.c | 183 +++++++++--------- 2 files changed, 88 insertions(+), 97 deletions(-) diff --git a/usr.sbin/bsdinstall/distextract/Makefile b/usr.sbin/bsdinstall/distextract/Makefile index 464ef6bf346..313ec00902f 100644 --- a/usr.sbin/bsdinstall/distextract/Makefile +++ b/usr.sbin/bsdinstall/distextract/Makefile @@ -2,7 +2,7 @@ BINDIR= /usr/libexec/bsdinstall PROG= distextract -LIBADD= archive ncursesw dialog m +LIBADD= archive dpv figpar ncursesw dialog m WARNS?= 6 MAN= diff --git a/usr.sbin/bsdinstall/distextract/distextract.c b/usr.sbin/bsdinstall/distextract/distextract.c index 54e0171cfe9..94536bc8063 100644 --- a/usr.sbin/bsdinstall/distextract/distextract.c +++ b/usr.sbin/bsdinstall/distextract/distextract.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -42,17 +43,13 @@ __FBSDID("$FreeBSD$"); /* Data to process */ static char *distdir = NULL; -struct file_node { - char *path; - char *name; - int length; - struct file_node *next; -}; -static struct file_node *dists = NULL; +static struct archive *archive = NULL; +static struct dpv_file_node *dists = NULL; /* Function prototypes */ +static void sig_int(int sig); static int count_files(const char *file); -static int extract_files(int nfiles, struct file_node *files); +static int extract_files(struct dpv_file_node *file, int out); #if __FreeBSD_version <= 1000008 /* r232154: bump for libarchive update */ #define archive_read_support_filter_all(x) \ @@ -66,11 +63,17 @@ main(void) { char *chrootdir; char *distributions; - int ndists = 0; int retval; - size_t file_node_size = sizeof(struct file_node); + size_t config_size = sizeof(struct dpv_config); + size_t file_node_size = sizeof(struct dpv_file_node); size_t span; - struct file_node *dist = dists; + struct dpv_config *config; + struct dpv_file_node *dist = dists; + static char backtitle[] = "FreeBSD Installer"; + static char title[] = "Archive Extraction"; + static char aprompt[] = "\n Overall Progress:"; + static char pprompt[] = "Extracting distribution files...\n"; + struct sigaction act; char error[PATH_MAX + 512]; if ((distributions = getenv("DISTRIBUTIONS")) == NULL) @@ -80,14 +83,14 @@ main(void) /* Initialize dialog(3) */ init_dialog(stdin, stdout); - dialog_vars.backtitle = __DECONST(char *, "FreeBSD Installer"); + dialog_vars.backtitle = backtitle; dlg_put_backtitle(); dialog_msgbox("", "Checking distribution archives.\nPlease wait...", 4, 35, FALSE); /* - * Parse $DISTRIBUTIONS into linked-list + * Parse $DISTRIBUTIONS into dpv(3) linked-list */ while (*distributions != '\0') { span = strcspn(distributions, "\t\n\v\f\r "); @@ -95,7 +98,6 @@ main(void) distributions++; continue; } - ndists++; /* Allocate a new struct for the distribution */ if (dist == NULL) { @@ -141,10 +143,30 @@ main(void) return (EXIT_FAILURE); } - retval = extract_files(ndists, dists); + /* Set cleanup routine for Ctrl-C action */ + act.sa_handler = sig_int; + sigaction(SIGINT, &act, 0); + /* + * Hand off to dpv(3) + */ + if ((config = calloc(1, config_size)) == NULL) + _errx(EXIT_FAILURE, "Out of memory!"); + config->backtitle = backtitle; + config->title = title; + config->pprompt = pprompt; + config->aprompt = aprompt; + config->options |= DPV_WIDE_MODE; + config->label_size = -1; + config->action = extract_files; + config->status_solo = + "%10lli files read @ %'9.1f files/sec."; + config->status_many = + "%10lli files read @ %'9.1f files/sec. [%i/%i busy/wait]"; end_dialog(); + retval = dpv(config, dists); + dpv_free(); while ((dist = dists) != NULL) { dists = dist->next; if (dist->path != NULL) @@ -155,6 +177,12 @@ main(void) return (retval); } +static void +sig_int(int sig __unused) +{ + dpv_interrupt = TRUE; +} + /* * Returns number of files in archive file. Parses $BSDINSTALL_DISTDIR/MANIFEST * if it exists, otherwise uses archive(3) to read the archive file. @@ -167,7 +195,6 @@ count_files(const char *file) int file_count; int retval; size_t span; - struct archive *archive; struct archive_entry *entry; char line[512]; char path[PATH_MAX]; @@ -220,6 +247,7 @@ count_files(const char *file) "Error while extracting %s: %s\n", file, archive_error_string(archive)); dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + archive = NULL; return (-1); } @@ -227,49 +255,27 @@ count_files(const char *file) while (archive_read_next_header(archive, &entry) == ARCHIVE_OK) file_count++; archive_read_free(archive); + archive = NULL; return (file_count); } static int -extract_files(int nfiles, struct file_node *files) +extract_files(struct dpv_file_node *file, int out __unused) { - int archive_file; - int archive_files[nfiles]; - int current_files = 0; - int i; - int last_progress; - int progress = 0; int retval; - int total_files = 0; - struct archive *archive; struct archive_entry *entry; - struct file_node *file; - char status[8]; - static char title[] = "Archive Extraction"; - static char pprompt[] = "Extracting distribution files...\n"; char path[PATH_MAX]; char errormsg[PATH_MAX + 512]; - const char *items[nfiles*2]; - /* Make the transfer list for dialog */ - i = 0; - for (file = files; file != NULL; file = file->next) { - items[i*2] = file->name; - items[i*2 + 1] = "Pending"; - archive_files[i] = file->length; - - total_files += file->length; - i++; - } - - i = 0; - for (file = files; file != NULL; file = file->next) { + /* Open the archive if necessary */ + if (archive == NULL) { if ((archive = archive_read_new()) == NULL) { snprintf(errormsg, sizeof(errormsg), "Error: %s\n", archive_error_string(NULL)); dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); - return (EXIT_FAILURE); + dpv_abort = 1; + return (-1); } archive_read_support_format_all(archive); archive_read_support_filter_all(archive); @@ -280,59 +286,44 @@ extract_files(int nfiles, struct file_node *files) "Error opening %s: %s\n", file->name, archive_error_string(archive)); dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); - return (EXIT_FAILURE); + file->status = DPV_STATUS_FAILED; + dpv_abort = 1; + return (-1); } - - items[i*2 + 1] = "In Progress"; - archive_file = 0; - - dialog_mixedgauge(title, pprompt, 0, 0, progress, nfiles, - __DECONST(char **, items)); - - while ((retval = archive_read_next_header(archive, &entry)) == - ARCHIVE_OK) { - last_progress = progress; - progress = (current_files*100)/total_files; - - snprintf(status, sizeof(status), "-%d", - (archive_file*100)/archive_files[i]); - items[i*2 + 1] = status; - - if (progress > last_progress) - dialog_mixedgauge(title, pprompt, 0, 0, - progress, nfiles, - __DECONST(char **, items)); - - retval = archive_read_extract(archive, entry, - ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_OWNER | - ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | - ARCHIVE_EXTRACT_XATTR | ARCHIVE_EXTRACT_FFLAGS); - - if (retval != ARCHIVE_OK) - break; - - archive_file++; - current_files++; - } - - items[i*2 + 1] = "Done"; - - if (retval != ARCHIVE_EOF) { - snprintf(errormsg, sizeof(errormsg), - "Error while extracting %s: %s\n", items[i*2], - archive_error_string(archive)); - items[i*2 + 1] = "Failed"; - dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); - return (retval); - } - - progress = (current_files*100)/total_files; - dialog_mixedgauge(title, pprompt, 0, 0, progress, nfiles, - __DECONST(char **, items)); - - archive_read_free(archive); - i++; } - return (EXIT_SUCCESS); + /* Read the next archive header */ + retval = archive_read_next_header(archive, &entry); + + /* If that went well, perform the extraction */ + if (retval == ARCHIVE_OK) + retval = archive_read_extract(archive, entry, + ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_OWNER | + ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | + ARCHIVE_EXTRACT_XATTR | ARCHIVE_EXTRACT_FFLAGS); + + /* Test for either EOF or error */ + if (retval == ARCHIVE_EOF) { + archive_read_free(archive); + archive = NULL; + file->status = DPV_STATUS_DONE; + return (100); + } else if (retval != ARCHIVE_OK) { + snprintf(errormsg, sizeof(errormsg), + "Error while extracting %s: %s\n", file->name, + archive_error_string(archive)); + dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + file->status = DPV_STATUS_FAILED; + dpv_abort = 1; + return (-1); + } + + dpv_overall_read++; + file->read++; + + /* Calculate [overall] percentage of completion (if possible) */ + if (file->length >= 0) + return (file->read * 100 / file->length); + else + return (-1); } From 9c75c3d4ba7c4e45507dbf57712b4aba8251735c Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 18 Dec 2014 05:17:18 +0000 Subject: [PATCH 60/64] Fix the scan handling for 11b->11g upgrades in a world where, well, it's not just 11b/11g. The following was happening, and it's quite .. annoyingly grr-y. * create vap, setup wpa_supplicant with no bgscanning, etc - there's no call to ieee80211_media_change, so vap->iv_des_mode is IEEE80211_MODE_AUTO; * do ifconfig wlan0 scan - same thing, media_change doesn't get called, iv_des_mode stays as auto. * But then, run wpa_cli and do 'scan' - it'll do a media change. * if you're on 11ng, vap->iv_des_mode gets changed to IEEE80211_MODE_11NG * Then makescanlist() is called. There's a block of code that gets called if iv_des_mode != IEEE80211_MODE_AUTO, and it does this: if (vap->iv_des_mode != IEEE80211_MODE_11G || mode != IEEE80211_MODE_11B) continue; mode = IEEE80211_MODE_11G; /* upgrade */ * .. now, iv_des_mode is not IEEE80211_MODE_11G, so it always runs 'continue' * .. and thus the scan list stays empty and no further channel scans occur. Ever.(1) If you then disassociate and try associating to something, your scan table has likely been purged / aged out and you'll never see anything in the scan list. (1) You need to do 'ifconfig wlan0 mode auto' or just destroy/re-create the VAP to get working wireless again. Tested: * iwn(4) - intel 5300 wifi; STA mode; using wpa_supplicant; bgscan enabled -and- wpa_supplicant scanning. Thanks to: * Everyone who kept poking me about this and wondering why the hell their wifi would eventually stop seeing scan lists. Grr. I eventually snapped this evening and dug back into this code. --- sys/net80211/ieee80211_scan_sta.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sys/net80211/ieee80211_scan_sta.c b/sys/net80211/ieee80211_scan_sta.c index 6da06fd1c4d..1e87e35245e 100644 --- a/sys/net80211/ieee80211_scan_sta.c +++ b/sys/net80211/ieee80211_scan_sta.c @@ -600,10 +600,12 @@ makescanlist(struct ieee80211_scan_state *ss, struct ieee80211vap *vap, * so if the desired mode is 11g, then use * the 11b channel list but upgrade the mode. */ - if (vap->iv_des_mode != IEEE80211_MODE_11G || - mode != IEEE80211_MODE_11B) - continue; - mode = IEEE80211_MODE_11G; /* upgrade */ + if (vap->iv_des_mode == IEEE80211_MODE_11G) { + if (mode == IEEE80211_MODE_11G) /* Skip the G check */ + continue; + else if (mode == IEEE80211_MODE_11B) + mode = IEEE80211_MODE_11G; /* upgrade */ + } } } else { /* From 6c21f6edb8adc1083e0f3204068b84147a7e0982 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 18 Dec 2014 10:01:12 +0000 Subject: [PATCH 61/64] The VOP_LOOKUP() implementations for CREATE op do not put the name into namecache, to avoid cache trashing when doing large operations. E.g., tar archive extraction is not usually followed by access to many of the files created. Right now, each VOP_LOOKUP() implementation explicitely knowns about this quirk and tests for both MAKEENTRY flag presence and op != CREATE to make the call to cache_enter(). Centralize the handling of the quirk into VFS, by deciding to cache only by MAKEENTRY flag in VOP. VFS now sets NOCACHE flag for CREATE namei() calls. Note that the change in semantic is backward-compatible and could be merged to the stable branch, and is compatible with non-changed third-party filesystems which correctly handle MAKEENTRY. Suggested by: Chris Torek Reviewed by: mckusick Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 2 +- sys/fs/ext2fs/ext2_lookup.c | 2 +- sys/fs/fuse/fuse_vnops.c | 2 +- sys/fs/msdosfs/msdosfs_lookup.c | 2 +- sys/fs/nandfs/nandfs_vnops.c | 2 +- sys/fs/nfsclient/nfs_clvnops.c | 3 +-- sys/fs/nfsserver/nfs_nfsdserv.c | 12 ++++----- sys/fs/tmpfs/tmpfs_vnops.c | 2 +- sys/fs/unionfs/union_subr.c | 2 ++ sys/fs/unionfs/union_vnops.c | 5 ++-- sys/kern/uipc_usrreq.c | 2 +- sys/kern/vfs_syscalls.c | 25 +++++++++++-------- sys/kern/vfs_vnops.c | 6 ++++- sys/nfsclient/nfs_vnops.c | 3 +-- sys/nfsserver/nfs_serv.c | 10 ++++---- sys/ufs/ffs/ffs_snapshot.c | 3 ++- sys/ufs/ufs/ufs_lookup.c | 2 +- 17 files changed, 47 insertions(+), 38 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 7763d44acaa..5d7fa70544e 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -1548,7 +1548,7 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp, /* * Insert name into cache (as non-existent) if appropriate. */ - if (error == ENOENT && (cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) + if (error == ENOENT && (cnp->cn_flags & MAKEENTRY) != 0) cache_enter(dvp, *vpp, cnp); /* * Insert name into cache if appropriate. diff --git a/sys/fs/ext2fs/ext2_lookup.c b/sys/fs/ext2fs/ext2_lookup.c index 34f720a1401..e59b60614c4 100644 --- a/sys/fs/ext2fs/ext2_lookup.c +++ b/sys/fs/ext2fs/ext2_lookup.c @@ -514,7 +514,7 @@ notfound: /* * Insert name into cache (as non-existent) if appropriate. */ - if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) + if ((cnp->cn_flags & MAKEENTRY) != 0) cache_enter(vdp, NULL, cnp); return (ENOENT); diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c index 54f659fe70c..085edbaf141 100644 --- a/sys/fs/fuse/fuse_vnops.c +++ b/sys/fs/fuse/fuse_vnops.c @@ -795,7 +795,7 @@ calldaemon: * caching...) */ #if 0 - if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) { + if ((cnp->cn_flags & MAKEENTRY) != 0) { FS_DEBUG("inserting NULL into cache\n"); cache_enter(dvp, NULL, cnp); } diff --git a/sys/fs/msdosfs/msdosfs_lookup.c b/sys/fs/msdosfs/msdosfs_lookup.c index 3704915b714..b5b8e316933 100644 --- a/sys/fs/msdosfs/msdosfs_lookup.c +++ b/sys/fs/msdosfs/msdosfs_lookup.c @@ -416,7 +416,7 @@ notfound: * and 8.3 filenames. Hence, it may not invalidate all negative * entries if a file with this name is later created. */ - if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) + if ((cnp->cn_flags & MAKEENTRY) != 0) cache_enter(vdp, *vpp, cnp); #endif return (ENOENT); diff --git a/sys/fs/nandfs/nandfs_vnops.c b/sys/fs/nandfs/nandfs_vnops.c index 2c92f8b02dc..65dcf6416e0 100644 --- a/sys/fs/nandfs/nandfs_vnops.c +++ b/sys/fs/nandfs/nandfs_vnops.c @@ -478,7 +478,7 @@ out: * the file might not be found and thus putting it into the namecache * might be seen as negative caching. */ - if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) + if ((cnp->cn_flags & MAKEENTRY) != 0) cache_enter(dvp, *vpp, cnp); return (error); diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 9570b70092a..818551fa3b6 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -1184,8 +1184,7 @@ nfs_lookup(struct vop_lookup_args *ap) return (EJUSTRETURN); } - if ((cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE && - dattrflag) { + if ((cnp->cn_flags & MAKEENTRY) != 0 && dattrflag) { /* * Cache the modification time of the parent * directory from the post-op attributes in diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 9bf43c37b10..e6e02d7ea9d 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -994,7 +994,7 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int isdgram, goto out; } NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, - LOCKPARENT | LOCKLEAF | SAVESTART); + LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE); nfsvno_setpathbuf(&named, &bufp, &hashp); error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); if (error) @@ -1205,7 +1205,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram, goto out; } } - NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, cnflags); + NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, cnflags | NOCACHE); nfsvno_setpathbuf(&named, &bufp, &hashp); error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); if (error) @@ -1658,7 +1658,7 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram, } } NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, - LOCKPARENT | SAVENAME); + LOCKPARENT | SAVENAME | NOCACHE); if (!nd->nd_repstat) { nfsvno_setpathbuf(&named, &bufp, &hashp); error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); @@ -1735,7 +1735,7 @@ nfsrvd_symlink(struct nfsrv_descript *nd, __unused int isdgram, *vpp = NULL; NFSVNO_ATTRINIT(&nva); NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, - LOCKPARENT | SAVESTART); + LOCKPARENT | SAVESTART | NOCACHE); nfsvno_setpathbuf(&named, &bufp, &hashp); error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); if (!error && !nd->nd_repstat) @@ -1853,7 +1853,7 @@ nfsrvd_mkdir(struct nfsrv_descript *nd, __unused int isdgram, goto out; } NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, - LOCKPARENT | SAVENAME); + LOCKPARENT | SAVENAME | NOCACHE); nfsvno_setpathbuf(&named, &bufp, &hashp); error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); if (error) @@ -2782,7 +2782,7 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, } if (create == NFSV4OPEN_CREATE) NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, - LOCKPARENT | LOCKLEAF | SAVESTART); + LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE); else NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, LOOKUP, LOCKLEAF | SAVESTART); diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index 5ffab5013e5..29ee38915ab 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -195,7 +195,7 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) /* Store the result of this lookup in the cache. Avoid this if the * request was for creation, as it does not improve timings on * emprical tests. */ - if ((cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE) + if ((cnp->cn_flags & MAKEENTRY) != 0) cache_enter(dvp, *vpp, cnp); out: diff --git a/sys/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c index e3391a7f769..74192dcfbb3 100644 --- a/sys/fs/unionfs/union_subr.c +++ b/sys/fs/unionfs/union_subr.c @@ -536,6 +536,8 @@ unionfs_relookup(struct vnode *dvp, struct vnode **vpp, cn->cn_flags |= (cnp->cn_flags & (DOWHITEOUT | SAVESTART)); else if (RENAME == nameiop) cn->cn_flags |= (cnp->cn_flags & SAVESTART); + else if (nameiop == CREATE) + cn->cn_flags |= NOCACHE; vref(dvp); VOP_UNLOCK(dvp, LK_RELEASE); diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c index 5076f161e24..6b60dbd47fb 100644 --- a/sys/fs/unionfs/union_vnops.c +++ b/sys/fs/unionfs/union_vnops.c @@ -160,8 +160,7 @@ unionfs_lookup(struct vop_cachedlookup_args *ap) LK_RETRY); vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); - } else if (error == ENOENT && (cnflags & MAKEENTRY) && - nameiop != CREATE) + } else if (error == ENOENT && (cnflags & MAKEENTRY) != 0) cache_enter(dvp, NULLVP, cnp); UNIONFS_INTERNAL_DEBUG("unionfs_lookup: leave (%d)\n", error); @@ -337,7 +336,7 @@ unionfs_lookup_out: if (lvp != NULLVP) vrele(lvp); - if (error == ENOENT && (cnflags & MAKEENTRY) && nameiop != CREATE) + if (error == ENOENT && (cnflags & MAKEENTRY) != 0) cache_enter(dvp, NULLVP, cnp); UNIONFS_INTERNAL_DEBUG("unionfs_lookup: leave (%d)\n", error); diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index a540cc0dfa8..ef0b83c9b53 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -505,7 +505,7 @@ uipc_bindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td) buf[namelen] = 0; restart: - NDINIT_ATRIGHTS(&nd, CREATE, NOFOLLOW | LOCKPARENT | SAVENAME, + NDINIT_ATRIGHTS(&nd, CREATE, NOFOLLOW | LOCKPARENT | SAVENAME | NOCACHE, UIO_SYSSPACE, buf, fd, cap_rights_init(&rights, CAP_BINDAT), td); /* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */ error = namei(&nd); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 2bcf85d352c..3105c2f4bcd 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1269,8 +1269,9 @@ kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, return (error); restart: bwillwrite(); - NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1, - pathseg, path, fd, cap_rights_init(&rights, CAP_MKNODAT), td); + NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 | + NOCACHE, pathseg, path, fd, cap_rights_init(&rights, CAP_MKNODAT), + td); if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; @@ -1384,8 +1385,9 @@ kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg, AUDIT_ARG_MODE(mode); restart: bwillwrite(); - NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1, - pathseg, path, fd, cap_rights_init(&rights, CAP_MKFIFOAT), td); + NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 | + NOCACHE, pathseg, path, fd, cap_rights_init(&rights, CAP_MKFIFOAT), + td); if ((error = namei(&nd)) != 0) return (error); if (nd.ni_vp != NULL) { @@ -1530,8 +1532,9 @@ again: vrele(vp); return (EPERM); /* POSIX */ } - NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE2, - segflg, path2, fd2, cap_rights_init(&rights, CAP_LINKAT), td); + NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE2 | + NOCACHE, segflg, path2, fd2, cap_rights_init(&rights, CAP_LINKAT), + td); if ((error = namei(&nd)) == 0) { if (nd.ni_vp != NULL) { NDFREE(&nd, NDF_ONLY_PNBUF); @@ -1650,8 +1653,9 @@ kern_symlinkat(struct thread *td, char *path1, int fd, char *path2, AUDIT_ARG_TEXT(syspath); restart: bwillwrite(); - NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1, - segflg, path2, fd, cap_rights_init(&rights, CAP_SYMLINKAT), td); + NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 | + NOCACHE, segflg, path2, fd, cap_rights_init(&rights, CAP_SYMLINKAT), + td); if ((error = namei(&nd)) != 0) goto out; if (nd.ni_vp) { @@ -3581,8 +3585,9 @@ kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, AUDIT_ARG_MODE(mode); restart: bwillwrite(); - NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1, - segflg, path, fd, cap_rights_init(&rights, CAP_MKDIRAT), td); + NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 | + NOCACHE, segflg, path, fd, cap_rights_init(&rights, CAP_MKDIRAT), + td); nd.ni_cnd.cn_flags |= WILLBEDIR; if ((error = namei(&nd)) != 0) return (error); diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 687269dd35a..40a69bbf27e 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -189,7 +189,11 @@ restart: fmode = *flagp; if (fmode & O_CREAT) { ndp->ni_cnd.cn_nameiop = CREATE; - ndp->ni_cnd.cn_flags = ISOPEN | LOCKPARENT | LOCKLEAF; + /* + * Set NOCACHE to avoid flushing the cache when + * rolling in many files at once. + */ + ndp->ni_cnd.cn_flags = ISOPEN | LOCKPARENT | LOCKLEAF | NOCACHE; if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0) ndp->ni_cnd.cn_flags |= FOLLOW; if (!(vn_open_flags & VN_OPEN_NOAUDIT)) diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index a841f65dc96..2516d7db94c 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -1184,8 +1184,7 @@ nfsmout: return (EJUSTRETURN); } - if ((cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE && - dattrflag) { + if ((cnp->cn_flags & MAKEENTRY) != 0 && dattrflag) { /* * Cache the modification time of the parent * directory from the post-op attributes in diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c index 1010da66d10..32fd3f59029 100644 --- a/sys/nfsserver/nfs_serv.c +++ b/sys/nfsserver/nfs_serv.c @@ -1217,7 +1217,7 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nd.ni_cnd.cn_cred = cred; nd.ni_cnd.cn_nameiop = CREATE; - nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART; + nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE; /* * Call namei and do initial cleanup to get a few things @@ -1501,7 +1501,7 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nd.ni_cnd.cn_cred = cred; nd.ni_cnd.cn_nameiop = CREATE; - nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART; + nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE; /* * Handle nfs_namei() call. If an error occurs, the nd structure @@ -2030,7 +2030,7 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, VOP_UNLOCK(vp, 0); nd.ni_cnd.cn_cred = cred; nd.ni_cnd.cn_nameiop = CREATE; - nd.ni_cnd.cn_flags = LOCKPARENT; + nd.ni_cnd.cn_flags = LOCKPARENT | NOCACHE; error = nfs_namei(&nd, nfsd, dfhp, len, slp, nam, &md, &dpos, &dirp, v3, &dirfor, &dirfor_ret, FALSE); if (dirp && !v3) { @@ -2153,7 +2153,7 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsm_srvnamesiz(len); nd.ni_cnd.cn_cred = cred; nd.ni_cnd.cn_nameiop = CREATE; - nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART; + nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART | NOCACHE; error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos, &dirp, v3, &dirfor, &dirfor_ret, FALSE); if (error == 0) { @@ -2325,7 +2325,7 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsm_srvnamesiz(len); nd.ni_cnd.cn_cred = cred; nd.ni_cnd.cn_nameiop = CREATE; - nd.ni_cnd.cn_flags = LOCKPARENT; + nd.ni_cnd.cn_flags = LOCKPARENT | NOCACHE; error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos, &dirp, v3, &dirfor, &dirfor_ret, FALSE); diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index 3df89326118..099faeb77f1 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -256,7 +256,8 @@ ffs_snapshot(mp, snapfile) * Create the snapshot file. */ restart: - NDINIT(&nd, CREATE, LOCKPARENT | LOCKLEAF, UIO_SYSSPACE, snapfile, td); + NDINIT(&nd, CREATE, LOCKPARENT | LOCKLEAF | NOCACHE, UIO_SYSSPACE, + snapfile, td); if ((error = namei(&nd)) != 0) return (error); if (nd.ni_vp != NULL) { diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index b34ed244914..408349e28e6 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -550,7 +550,7 @@ notfound: /* * Insert name into cache (as non-existent) if appropriate. */ - if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) + if ((cnp->cn_flags & MAKEENTRY) != 0) cache_enter(vdp, NULL, cnp); return (ENOENT); From 7f5a9777e73449eee42d20f503a1bce7a5982f5b Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Thu, 18 Dec 2014 14:31:30 +0000 Subject: [PATCH 62/64] Add AArch64 64-bit relocation values. These will be needed by rtld when we import it along with utilities in elftoolchain. Differential Revision: https://reviews.freebsd.org/D1330 Reviewed by: emaste Sponsored by: The FreeBSD Foundation --- sys/sys/elf_common.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h index 2a29dd42df0..805238463a1 100644 --- a/sys/sys/elf_common.h +++ b/sys/sys/elf_common.h @@ -641,6 +641,18 @@ typedef struct { #define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ #define R_386_IRELATIVE 42 /* PLT entry resolved indirectly at runtime */ +#define R_AARCH64_ABS64 257 /* Absolute offset */ +#define R_AARCH64_ABS32 258 /* Absolute, 32-bit overflow check */ +#define R_AARCH64_ABS16 259 /* Absolute, 16-bit overflow check */ +#define R_AARCH64_PREL64 260 /* PC relative */ +#define R_AARCH64_PREL32 261 /* PC relative, 32-bit overflow check */ +#define R_AARCH64_PREL16 262 /* PC relative, 16-bit overflow check */ +#define R_AARCH64_COPY 1024 /* Copy data from shared object */ +#define R_AARCH64_GLOB_DAT 1025 /* Set GOT entry to data address */ +#define R_AARCH64_JUMP_SLOT 1026 /* Set GOT entry to code address */ +#define R_AARCH64_RELATIVE 1027 /* Add load address of shared object */ +#define R_AARCH64_TLSDESC 1031 /* Identify the TLS descriptor */ + #define R_ARM_NONE 0 /* No relocation. */ #define R_ARM_PC24 1 #define R_ARM_ABS32 2 From 8bc65725c766c52ebc282c317051f7616e6899c0 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 18 Dec 2014 16:57:19 +0000 Subject: [PATCH 63/64] Remove -fno-strict-alias, as it is no longer needed. --- usr.sbin/kldxref/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/usr.sbin/kldxref/Makefile b/usr.sbin/kldxref/Makefile index 767cc23cea2..75e74efc65d 100644 --- a/usr.sbin/kldxref/Makefile +++ b/usr.sbin/kldxref/Makefile @@ -5,7 +5,6 @@ MAN= kldxref.8 SRCS= kldxref.c ef.c ef_obj.c WARNS?= 2 -CFLAGS+=-fno-strict-aliasing .if exists(ef_${MACHINE_CPUARCH}.c) && ${MACHINE_ARCH} != "powerpc64" SRCS+= ef_${MACHINE_CPUARCH}.c From b9a2a3f1cf7320a3fb2df655be2060c234be0e9c Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 18 Dec 2014 16:57:22 +0000 Subject: [PATCH 64/64] Don't deselect the card too soon. To set the block size or switch the function parameters, the card has to be in transfer state. If it is in the idle state, the commands are ignored. This caused us not to set the proper parameters that we later assume to be present, leading to downstream failures of the card / interface as our state machine mismatches the card's. Submitted by: Svatopluk Kraus , Michal Meloun --- sys/dev/mmc/mmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/mmc/mmc.c b/sys/dev/mmc/mmc.c index a7762badec4..a3b9744b99b 100644 --- a/sys/dev/mmc/mmc.c +++ b/sys/dev/mmc/mmc.c @@ -1357,7 +1357,6 @@ mmc_discover_cards(struct mmc_softc *sc) ivar->erase_sector = 16 << ivar->sd_status.au_size; } - mmc_select_card(sc, 0); /* Find max supported bus width. */ if ((mmcbr_get_caps(sc->dev) & MMC_CAP_4_BIT_DATA) && (ivar->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) @@ -1385,6 +1384,7 @@ mmc_discover_cards(struct mmc_softc *sc) child = device_add_child(sc->dev, NULL, -1); device_set_ivars(child, ivar); } + mmc_select_card(sc, 0); return; } mmc_decode_cid_mmc(ivar->raw_cid, &ivar->cid); @@ -1443,7 +1443,6 @@ mmc_discover_cards(struct mmc_softc *sc) ivar->hs_tran_speed = ivar->tran_speed; /* Find max supported bus width. */ ivar->bus_width = mmc_test_bus_width(sc); - mmc_select_card(sc, 0); /* Handle HC erase sector size. */ if (ivar->raw_ext_csd[EXT_CSD_ERASE_GRP_SIZE] != 0) { ivar->erase_sector = 1024 * @@ -1451,6 +1450,7 @@ mmc_discover_cards(struct mmc_softc *sc) mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_ERASE_GRP_DEF, 1); } + mmc_select_card(sc, 0); } else { ivar->bus_width = bus_width_1; ivar->timing = bus_timing_normal;