diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2018-09-24 11:40:02 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2018-09-24 11:40:02 +0000 |
commit | eae4e4f053cd08905af071b7fa6b8392026b68cb (patch) | |
tree | 4471b669b51ada0e4be168b3001d84f4ab3e6310 | |
parent | 198b273b500c16488856bc36cabe112849dd6d3b (diff) | |
parent | 48d370f1e98a10b1bdf160dd83a49e0f49f6c1b7 (diff) | |
download | illumos-joyent-eae4e4f053cd08905af071b7fa6b8392026b68cb.tar.gz |
[illumos-gate merge]
commit fd6d41c5025e9fb45a115fc82d86e9983d1e9fd6
9815 Want basic AHCI enclosure services
commit b346eedd4542677e9fcb483b961bfeda95289212
commit 921f410897840ae3150db7a9e99cb22126a52ad1
9799 libstand: tftp.c cstyle cleanup
commit 4667a9b13a267e53bf6c785cb5745b689f413f1d
9802 libstand: memory leak in tftp_open()
commit 1bb0ebc19aa99ecdb4a9bff9d5972a8320407a25
9795 libstand: re-send ACK for older data packets
commit 2017dcb08b21dd2f977954ddb50394ba3010137c
9789 loader: tftp should not read past file end
commit 63e2133b60ad42fc1b90a89825378dc1cdc82f85
9788 loader: validate tftp_makereq() after we did reset the read
commit 75383e32bbd38e24115eefe5dee272d42a5c723e
9627 No longer need 32-bit boot_archive
9628 UFS boot archives are too large
9721 cmd/boot: support cpio boot archive
commit c057d312c6f715bb3aeadb653466e7046f26c4af
9845 make clobber in uts/intel does attempt to remove debug64/
Conflicts:
usr/src/uts/common/io/sata/adapters/ahci/ahci.c
-rw-r--r-- | manifest | 89 | ||||
-rw-r--r-- | usr/src/boot/lib/libstand/tftp.c | 282 | ||||
-rw-r--r-- | usr/src/cmd/boot/bootadm/Makefile | 3 | ||||
-rw-r--r-- | usr/src/cmd/boot/bootadm/bootadm.c | 589 | ||||
-rw-r--r-- | usr/src/cmd/boot/scripts/boot-archive-update.ksh | 9 | ||||
-rw-r--r-- | usr/src/cmd/boot/scripts/create_ramdisk.ksh | 487 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/usr.sbin/ipqosconf/ipqosconf.c | 4 | ||||
-rw-r--r-- | usr/src/cmd/halt/halt.c | 15 | ||||
-rw-r--r-- | usr/src/cmd/svc/milestone/boot-archive.xml | 8 | ||||
-rw-r--r-- | usr/src/man/man1m/bootadm.1m | 102 | ||||
-rw-r--r-- | usr/src/man/man3head/Makefile | 182 | ||||
-rw-r--r-- | usr/src/man/man3head/queue.h.3head | 1315 | ||||
-rw-r--r-- | usr/src/pkg/manifests/driver-storage-ahci.mf | 3 | ||||
-rw-r--r-- | usr/src/pkg/manifests/system-header.mf | 107 | ||||
-rw-r--r-- | usr/src/uts/common/io/sata/adapters/ahci/ahci.c | 1 | ||||
-rw-r--r-- | usr/src/uts/common/sys/queue.h | 859 | ||||
-rw-r--r-- | usr/src/uts/intel/Makefile | 4 |
17 files changed, 1081 insertions, 2978 deletions
@@ -15608,26 +15608,6 @@ s usr/share/man/man3head/libintl.3head=libintl.h.3head f usr/share/man/man3head/libintl.h.3head 0444 root bin s usr/share/man/man3head/limits.3head=limits.h.3head f usr/share/man/man3head/limits.h.3head 0444 root bin -s usr/share/man/man3head/LIST_CLASS_ENTRY.3head=queue.h.3head -s usr/share/man/man3head/LIST_CLASS_HEAD.3head=queue.h.3head -s usr/share/man/man3head/LIST_CONCAT.3head=queue.h.3head -s usr/share/man/man3head/LIST_EMPTY.3head=queue.h.3head -s usr/share/man/man3head/LIST_ENTRY.3head=queue.h.3head -s usr/share/man/man3head/LIST_FIRST.3head=queue.h.3head -s usr/share/man/man3head/LIST_FOREACH.3head=queue.h.3head -s usr/share/man/man3head/LIST_FOREACH_FROM.3head=queue.h.3head -s usr/share/man/man3head/LIST_FOREACH_FROM_SAFE.3head=queue.h.3head -s usr/share/man/man3head/LIST_FOREACH_SAFE.3head=queue.h.3head -s usr/share/man/man3head/LIST_HEAD.3head=queue.h.3head -s usr/share/man/man3head/LIST_HEAD_INITIALIZER.3head=queue.h.3head -s usr/share/man/man3head/LIST_INIT.3head=queue.h.3head -s usr/share/man/man3head/LIST_INSERT_AFTER.3head=queue.h.3head -s usr/share/man/man3head/LIST_INSERT_BEFORE.3head=queue.h.3head -s usr/share/man/man3head/LIST_INSERT_HEAD.3head=queue.h.3head -s usr/share/man/man3head/LIST_NEXT.3head=queue.h.3head -s usr/share/man/man3head/LIST_PREV.3head=queue.h.3head -s usr/share/man/man3head/LIST_REMOVE.3head=queue.h.3head -s usr/share/man/man3head/LIST_SWAP.3head=queue.h.3head s usr/share/man/man3head/locale.3head=locale.h.3head f usr/share/man/man3head/locale.h.3head 0444 root bin s usr/share/man/man3head/math.3head=math.h.3head @@ -15652,7 +15632,6 @@ s usr/share/man/man3head/pthread.3head=pthread.h.3head f usr/share/man/man3head/pthread.h.3head 0444 root bin s usr/share/man/man3head/pwd.3head=pwd.h.3head f usr/share/man/man3head/pwd.h.3head 0444 root bin -f usr/share/man/man3head/queue.h.3head 0444 root bin s usr/share/man/man3head/regex.3head=regex.h.3head f usr/share/man/man3head/regex.h.3head 0444 root bin s usr/share/man/man3head/resource.3head=resource.h.3head @@ -15675,52 +15654,10 @@ s usr/share/man/man3head/siginfo.3head=siginfo.h.3head f usr/share/man/man3head/siginfo.h.3head 0444 root bin s usr/share/man/man3head/signal.3head=signal.h.3head f usr/share/man/man3head/signal.h.3head 0444 root bin -s usr/share/man/man3head/SLIST_CLASS_ENTRY.3head=queue.h.3head -s usr/share/man/man3head/SLIST_CLASS_HEAD.3head=queue.h.3head -s usr/share/man/man3head/SLIST_CONCAT.3head=queue.h.3head -s usr/share/man/man3head/SLIST_EMPTY.3head=queue.h.3head -s usr/share/man/man3head/SLIST_ENTRY.3head=queue.h.3head -s usr/share/man/man3head/SLIST_FIRST.3head=queue.h.3head -s usr/share/man/man3head/SLIST_FOREACH.3head=queue.h.3head -s usr/share/man/man3head/SLIST_FOREACH_FROM.3head=queue.h.3head -s usr/share/man/man3head/SLIST_FOREACH_FROM_SAFE.3head=queue.h.3head -s usr/share/man/man3head/SLIST_FOREACH_SAFE.3head=queue.h.3head -s usr/share/man/man3head/SLIST_HEAD.3head=queue.h.3head -s usr/share/man/man3head/SLIST_HEAD_INITIALIZER.3head=queue.h.3head -s usr/share/man/man3head/SLIST_INIT.3head=queue.h.3head -s usr/share/man/man3head/SLIST_INSERT_AFTER.3head=queue.h.3head -s usr/share/man/man3head/SLIST_INSERT_HEAD.3head=queue.h.3head -s usr/share/man/man3head/SLIST_NEXT.3head=queue.h.3head -s usr/share/man/man3head/SLIST_REMOVE.3head=queue.h.3head -s usr/share/man/man3head/SLIST_REMOVE_AFTER.3head=queue.h.3head -s usr/share/man/man3head/SLIST_REMOVE_HEAD.3head=queue.h.3head -s usr/share/man/man3head/SLIST_SWAP.3head=queue.h.3head s usr/share/man/man3head/socket.3head=socket.h.3head f usr/share/man/man3head/socket.h.3head 0444 root bin s usr/share/man/man3head/spawn.3head=spawn.h.3head f usr/share/man/man3head/spawn.h.3head 0444 root bin -s usr/share/man/man3head/STAILQ_CLASS_ENTRY.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_CLASS_HEAD.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_CONCAT.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_EMPTY.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_ENTRY.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_FIRST.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_FOREACH.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_FOREACH_FROM.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_FOREACH_FROM_SAFE.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_FOREACH_SAFE.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_HEAD.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_HEAD_INITIALIZER.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_INIT.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_INSERT_AFTER.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_INSERT_HEAD.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_INSERT_TAIL.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_LAST.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_NEXT.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_REMOVE.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_REMOVE_AFTER.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_REMOVE_HEAD.3head=queue.h.3head -s usr/share/man/man3head/STAILQ_SWAP.3head=queue.h.3head s usr/share/man/man3head/stat.3head=stat.h.3head f usr/share/man/man3head/stat.h.3head 0444 root bin s usr/share/man/man3head/statvfs.3head=statvfs.h.3head @@ -15743,32 +15680,6 @@ s usr/share/man/man3head/stropts.3head=stropts.h.3head f usr/share/man/man3head/stropts.h.3head 0444 root bin s usr/share/man/man3head/syslog.3head=syslog.h.3head f usr/share/man/man3head/syslog.h.3head 0444 root bin -s usr/share/man/man3head/TAILQ_CLASS_ENTRY.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_CLASS_HEAD.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_CONCAT.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_EMPTY.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_ENTRY.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_FIRST.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_FOREACH.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_FOREACH_FROM.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_FOREACH_FROM_SAFE.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_FOREACH_REVERSE.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_FOREACH_REVERSE_FROM.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_FOREACH_REVERSE_FROM_SAFE.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_FOREACH_REVERSE_SAFE.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_FOREACH_SAFE.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_HEAD.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_HEAD_INITIALIZER.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_INIT.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_INSERT_AFTER.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_INSERT_BEFORE.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_INSERT_HEAD.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_INSERT_TAIL.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_LAST.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_NEXT.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_PREV.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_REMOVE.3head=queue.h.3head -s usr/share/man/man3head/TAILQ_SWAP.3head=queue.h.3head s usr/share/man/man3head/tar.3head=tar.h.3head f usr/share/man/man3head/tar.h.3head 0444 root bin s usr/share/man/man3head/tcp.3head=tcp.h.3head diff --git a/usr/src/boot/lib/libstand/tftp.c b/usr/src/boot/lib/libstand/tftp.c index e235f8a537..503626d89b 100644 --- a/usr/src/boot/lib/libstand/tftp.c +++ b/usr/src/boot/lib/libstand/tftp.c @@ -62,30 +62,29 @@ struct tftp_handle; struct tftprecv_extra; -static ssize_t recvtftp(struct iodesc *d, void **pkt, void **payload, - time_t tleft, void *recv_extra); -static int tftp_open(const char *path, struct open_file *f); -static int tftp_close(struct open_file *f); -static int tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len); -static int tftp_read(struct open_file *f, void *buf, size_t size, size_t *resid); -static off_t tftp_seek(struct open_file *f, off_t offset, int where); -static int tftp_set_blksize(struct tftp_handle *h, const char *str); -static int tftp_stat(struct open_file *f, struct stat *sb); +static ssize_t recvtftp(struct iodesc *, void **, void **, time_t, void *); +static int tftp_open(const char *, struct open_file *); +static int tftp_close(struct open_file *); +static int tftp_parse_oack(struct tftp_handle *, char *, size_t); +static int tftp_read(struct open_file *, void *, size_t, size_t *); +static off_t tftp_seek(struct open_file *, off_t, int); +static int tftp_set_blksize(struct tftp_handle *, const char *); +static int tftp_stat(struct open_file *, struct stat *); struct fs_ops tftp_fsops = { - "tftp", - tftp_open, - tftp_close, - tftp_read, - null_write, - tftp_seek, - tftp_stat, - null_readdir + .fs_name = "tftp", + .fo_open = tftp_open, + .fo_close = tftp_close, + .fo_read = tftp_read, + .fo_write = null_write, + .fo_seek = tftp_seek, + .fo_stat = tftp_stat, + .fo_readdir = null_readdir }; extern struct in_addr servip; -static int tftpport = 2000; +static int tftpport = 2000; static int is_open = 0; /* @@ -93,21 +92,21 @@ static int is_open = 0; * TFTP_REQUESTED_BLKSIZE of 1428 is (Ethernet MTU, less the TFTP, UDP and * IP header lengths). */ -#define TFTP_REQUESTED_BLKSIZE 1428 +#define TFTP_REQUESTED_BLKSIZE 1428 /* * Choose a blksize big enough so we can test with Ethernet * Jumbo frames in the future. */ -#define TFTP_MAX_BLKSIZE 9008 +#define TFTP_MAX_BLKSIZE 9008 struct tftp_handle { struct iodesc *iodesc; - int currblock; /* contents of lastdata */ - int islastblock; /* flag */ - int validsize; - int off; - char *path; /* saved for re-requests */ + int currblock; /* contents of lastdata */ + int islastblock; /* flag */ + int validsize; + int off; + char *path; /* saved for re-requests */ unsigned int tftp_blksize; unsigned long tftp_tsize; void *pkt; @@ -136,46 +135,46 @@ static int tftp_getnextblock(struct tftp_handle *h); /* send error message back. */ static void -tftp_senderr(struct tftp_handle *h, u_short errcode, const char *msg) +tftp_senderr(struct tftp_handle *h, ushort_t errcode, const char *msg) { struct { - u_char header[HEADER_SIZE]; - struct tftphdr t; - u_char space[63]; /* +1 from t */ + uchar_t header[HEADER_SIZE]; + struct tftphdr t; + uchar_t space[63]; /* +1 from t */ } __packed __aligned(4) wbuf; - char *wtail; - int len; + char *wtail; + int len; len = strlen(msg); - if (len > sizeof(wbuf.space)) - len = sizeof(wbuf.space); + if (len > sizeof (wbuf.space)) + len = sizeof (wbuf.space); - wbuf.t.th_opcode = htons((u_short) ERROR); - wbuf.t.th_code = htons(errcode); + wbuf.t.th_opcode = htons((ushort_t)ERROR); + wbuf.t.th_code = htons(errcode); wtail = wbuf.t.th_msg; bcopy(msg, wtail, len); wtail[len] = '\0'; wtail += len + 1; - sendudp(h->iodesc, &wbuf.t, wtail - (char *) &wbuf.t); + sendudp(h->iodesc, &wbuf.t, wtail - (char *)&wbuf.t); } static void -tftp_sendack(struct tftp_handle *h) +tftp_sendack(struct tftp_handle *h, ushort_t block) { struct { - u_char header[HEADER_SIZE]; + uchar_t header[HEADER_SIZE]; struct tftphdr t; } __packed __aligned(4) wbuf; - char *wtail; + char *wtail; - wbuf.t.th_opcode = htons((u_short) ACK); - wtail = (char *) &wbuf.t.th_block; - wbuf.t.th_block = htons((u_short) h->currblock); + wbuf.t.th_opcode = htons((ushort_t)ACK); + wtail = (char *)&wbuf.t.th_block; + wbuf.t.th_block = htons(block); wtail += 2; - sendudp(h->iodesc, &wbuf.t, wtail - (char *) &wbuf.t); + sendudp(h->iodesc, &wbuf.t, wtail - (char *)&wbuf.t); } static ssize_t @@ -189,7 +188,7 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft, ssize_t len; errno = 0; - extra = (struct tftprecv_extra *)recv_extra; + extra = recv_extra; h = extra->tftp_handle; len = readudp(d, &ptr, (void **)&t, tleft); @@ -204,9 +203,17 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft, case DATA: { int got; - if (htons(t->th_block) != (u_short) d->xid) { + if (htons(t->th_block) < (ushort_t)d->xid) { /* - * Expected block? + * Apparently our ACK was missed, re-send. + */ + tftp_sendack(h, htons(t->th_block)); + free(ptr); + return (-1); + } + if (htons(t->th_block) != (ushort_t)d->xid) { + /* + * Packet from the future, drop this. */ free(ptr); return (-1); @@ -216,16 +223,16 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft, * First data packet from new port. */ struct udphdr *uh; - uh = (struct udphdr *) t - 1; + uh = (struct udphdr *)t - 1; d->destport = uh->uh_sport; - } /* else check uh_sport has not changed??? */ + } got = len - (t->th_data - (char *)t); *pkt = ptr; *payload = t; return (got); } case ERROR: - if ((unsigned) ntohs(t->th_code) > TFTP_MAX_ERRCODE) { + if ((unsigned)ntohs(t->th_code) > TFTP_MAX_ERRCODE) { printf("illegal tftp error %d\n", ntohs(t->th_code)); errno = EIO; } else { @@ -240,8 +247,8 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft, struct udphdr *uh; int tftp_oack_len; - /* - * Unexpected OACK. TFTP transfer already in progress. + /* + * Unexpected OACK. TFTP transfer already in progress. * Drop the pkt. */ if (d->xid != 1) { @@ -253,11 +260,11 @@ recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft, * Remember which port this OACK came from, because we need * to send the ACK or errors back to it. */ - uh = (struct udphdr *) t - 1; + uh = (struct udphdr *)t - 1; d->destport = uh->uh_sport; - + /* Parse options ACK-ed by the server. */ - tftp_oack_len = len - sizeof(t->th_opcode); + tftp_oack_len = len - sizeof (t->th_opcode); if (tftp_parse_oack(h, t->th_u.tu_stuff, tftp_oack_len) != 0) { tftp_senderr(h, EOPTNEG, "Malformed OACK"); errno = EIO; @@ -282,14 +289,14 @@ static int tftp_makereq(struct tftp_handle *h) { struct { - u_char header[HEADER_SIZE]; + uchar_t header[HEADER_SIZE]; struct tftphdr t; - u_char space[FNAME_SIZE + 6]; + uchar_t space[FNAME_SIZE + 6]; } __packed __aligned(4) wbuf; struct tftprecv_extra recv_extra; - char *wtail; - int l; - ssize_t res; + char *wtail; + int l; + ssize_t res; void *pkt; struct tftphdr *t; char *tftp_blksize = NULL; @@ -303,14 +310,14 @@ tftp_makereq(struct tftp_handle *h) tftp_set_blksize(h, tftp_blksize); } - wbuf.t.th_opcode = htons((u_short) RRQ); + wbuf.t.th_opcode = htons((ushort_t)RRQ); wtail = wbuf.t.th_stuff; l = strlen(h->path); #ifdef TFTP_PREPEND_PATH - if (l > FNAME_SIZE - (sizeof(TFTP_PREPEND_PATH) - 1)) + if (l > FNAME_SIZE - (sizeof (TFTP_PREPEND_PATH) - 1)) return (ENAMETOOLONG); - bcopy(TFTP_PREPEND_PATH, wtail, sizeof(TFTP_PREPEND_PATH) - 1); - wtail += sizeof(TFTP_PREPEND_PATH) - 1; + bcopy(TFTP_PREPEND_PATH, wtail, sizeof (TFTP_PREPEND_PATH) - 1); + wtail += sizeof (TFTP_PREPEND_PATH) - 1; #else if (l > FNAME_SIZE) return (ENAMETOOLONG); @@ -328,7 +335,6 @@ tftp_makereq(struct tftp_handle *h) bcopy("0", wtail, 2); wtail += 2; - /* h->iodesc->myport = htons(--tftpport); */ h->iodesc->myport = htons(tftpport + (getsecs() & 0x3ff)); h->iodesc->destport = htons(IPPORT_TFTP); h->iodesc->xid = 1; /* expected block */ @@ -339,8 +345,8 @@ tftp_makereq(struct tftp_handle *h) pkt = NULL; recv_extra.tftp_handle = h; - res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t, - &recvtftp, &pkt, (void **)&t, &recv_extra); + res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *)&wbuf.t, + &recvtftp, &pkt, (void **)&t, &recv_extra); if (res == -1) { free(pkt); return (errno); @@ -363,7 +369,7 @@ tftp_makereq(struct tftp_handle *h) h->islastblock = 0; if (res < h->tftp_blksize) { h->islastblock = 1; /* very short file */ - tftp_sendack(h); + tftp_sendack(h, h->currblock); } return (0); } @@ -375,29 +381,30 @@ tftp_makereq(struct tftp_handle *h) } /* ack block, expect next */ -static int +static int tftp_getnextblock(struct tftp_handle *h) { struct { - u_char header[HEADER_SIZE]; + uchar_t header[HEADER_SIZE]; struct tftphdr t; } __packed __aligned(4) wbuf; struct tftprecv_extra recv_extra; - char *wtail; - int res; + char *wtail; + int res; void *pkt; struct tftphdr *t; - wbuf.t.th_opcode = htons((u_short) ACK); - wtail = (char *) &wbuf.t.th_block; - wbuf.t.th_block = htons((u_short) h->currblock); + + wbuf.t.th_opcode = htons((ushort_t)ACK); + wtail = (char *)&wbuf.t.th_block; + wbuf.t.th_block = htons((ushort_t)h->currblock); wtail += 2; h->iodesc->xid = h->currblock + 1; /* expected block */ pkt = NULL; recv_extra.tftp_handle = h; - res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t, - &recvtftp, &pkt, (void **)&t, &recv_extra); + res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *)&wbuf.t, + &recvtftp, &pkt, (void **)&t, &recv_extra); if (res == -1) { /* 0 is OK! */ free(pkt); @@ -413,8 +420,8 @@ tftp_getnextblock(struct tftp_handle *h) h->islastblock = 1; /* EOF */ if (h->islastblock == 1) { - /* Send an ACK for the last block */ - wbuf.t.th_block = htons((u_short) h->currblock); + /* Send an ACK for the last block */ + wbuf.t.th_block = htons((ushort_t)h->currblock); sendudp(h->iodesc, &wbuf.t, wtail - (char *)&wbuf.t); } @@ -425,10 +432,10 @@ static int tftp_open(const char *path, struct open_file *f) { struct tftp_handle *tftpfile; - struct iodesc *io; - int res; - size_t pathsize; - const char *extraslash; + struct iodesc *io; + int res; + size_t pathsize; + const char *extraslash; if (netproto != NET_TFTP) return (EINVAL); @@ -439,23 +446,24 @@ tftp_open(const char *path, struct open_file *f) if (is_open) return (EBUSY); - tftpfile = (struct tftp_handle *) malloc(sizeof(*tftpfile)); + tftpfile = calloc(1, sizeof (*tftpfile)); if (!tftpfile) return (ENOMEM); - memset(tftpfile, 0, sizeof(*tftpfile)); tftpfile->tftp_blksize = TFTP_REQUESTED_BLKSIZE; - tftpfile->iodesc = io = socktodesc(*(int *) (f->f_devdata)); - if (io == NULL) + tftpfile->iodesc = io = socktodesc(*(int *)(f->f_devdata)); + if (io == NULL) { + free(tftpfile); return (EINVAL); + } io->destip = servip; tftpfile->off = 0; - pathsize = (strlen(rootpath) + 1 + strlen(path) + 1) * sizeof(char); + pathsize = (strlen(rootpath) + 1 + strlen(path) + 1) * sizeof (char); tftpfile->path = malloc(pathsize); if (tftpfile->path == NULL) { free(tftpfile); - return(ENOMEM); + return (ENOMEM); } if (rootpath[strlen(rootpath) - 1] == '/' || path[0] == '/') extraslash = ""; @@ -466,7 +474,7 @@ tftp_open(const char *path, struct open_file *f) if (res < 0 || res > pathsize) { free(tftpfile->path); free(tftpfile); - return(ENOMEM); + return (ENOMEM); } res = tftp_makereq(tftpfile); @@ -477,7 +485,7 @@ tftp_open(const char *path, struct open_file *f) free(tftpfile); return (res); } - f->f_fsdata = (void *) tftpfile; + f->f_fsdata = tftpfile; is_open = 1; return (0); } @@ -487,7 +495,18 @@ tftp_read(struct open_file *f, void *addr, size_t size, size_t *resid /* out */) { struct tftp_handle *tftpfile; - tftpfile = (struct tftp_handle *) f->f_fsdata; + size_t res; + int rc; + + rc = 0; + res = size; + tftpfile = f->f_fsdata; + + /* Make sure we will not read past file end */ + if (tftpfile->tftp_tsize > 0 && + tftpfile->off + size > tftpfile->tftp_tsize) { + size = tftpfile->tftp_tsize - tftpfile->off; + } while (size > 0) { int needblock, count; @@ -498,19 +517,19 @@ tftp_read(struct open_file *f, void *addr, size_t size, if (tftpfile->currblock > needblock) { /* seek backwards */ tftp_senderr(tftpfile, 0, "No error: read aborted"); - tftp_makereq(tftpfile); /* no error check, it worked - * for open */ + rc = tftp_makereq(tftpfile); + if (rc != 0) + break; } while (tftpfile->currblock < needblock) { - int res; - res = tftp_getnextblock(tftpfile); - if (res) { /* no answer */ + rc = tftp_getnextblock(tftpfile); + if (rc) { /* no answer */ #ifdef TFTP_DEBUG printf("tftp: read error\n"); #endif - return (res); + return (rc); } if (tftpfile->islastblock) break; @@ -536,6 +555,7 @@ tftp_read(struct open_file *f, void *addr, size_t size, addr = (char *)addr + count; tftpfile->off += count; size -= count; + res -= count; if ((tftpfile->islastblock) && (count == inbuffer)) break; /* EOF */ @@ -548,16 +568,16 @@ tftp_read(struct open_file *f, void *addr, size_t size, } - if (resid) - *resid = size; - return (0); + if (resid != NULL) + *resid = res; + return (rc); } -static int +static int tftp_close(struct open_file *f) { struct tftp_handle *tftpfile; - tftpfile = (struct tftp_handle *) f->f_fsdata; + tftpfile = f->f_fsdata; /* let it time out ... */ @@ -570,17 +590,17 @@ tftp_close(struct open_file *f) return (0); } -static int +static int tftp_stat(struct open_file *f, struct stat *sb) { struct tftp_handle *tftpfile; - tftpfile = (struct tftp_handle *) f->f_fsdata; + tftpfile = f->f_fsdata; sb->st_mode = 0444 | S_IFREG; sb->st_nlink = 1; sb->st_uid = 0; sb->st_gid = 0; - sb->st_size = (off_t) tftpfile->tftp_tsize; + sb->st_size = tftpfile->tftp_tsize; return (0); } @@ -588,7 +608,7 @@ static off_t tftp_seek(struct open_file *f, off_t offset, int where) { struct tftp_handle *tftpfile; - tftpfile = (struct tftp_handle *) f->f_fsdata; + tftpfile = f->f_fsdata; switch (where) { case SEEK_SET: @@ -607,7 +627,7 @@ tftp_seek(struct open_file *f, off_t offset, int where) static int tftp_set_blksize(struct tftp_handle *h, const char *str) { - char *endptr; + char *endptr; int new_blksize; int ret = 0; @@ -622,8 +642,8 @@ tftp_set_blksize(struct tftp_handle *h, const char *str) * RFC2348 specifies that acceptable values are 8-65464. * Let's choose a limit less than MAXRSPACE. */ - if (*endptr == '\0' && new_blksize >= 8 - && new_blksize <= TFTP_MAX_BLKSIZE) { + if (*endptr == '\0' && new_blksize >= 8 && + new_blksize <= TFTP_MAX_BLKSIZE) { h->tftp_blksize = new_blksize; ret = 1; } @@ -654,10 +674,10 @@ tftp_set_blksize(struct tftp_handle *h, const char *str) * optN, valueN * The final option/value acknowledgment pair. */ -static int +static int tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len) { - /* + /* * We parse the OACK strings into an array * of name-value pairs. */ @@ -667,7 +687,7 @@ tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len) int option_idx = 0; int blksize_is_set = 0; int tsize = 0; - + unsigned int orig_blksize; while (option_idx < 128 && i < len) { @@ -684,26 +704,30 @@ tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len) /* Save the block size we requested for sanity check later. */ orig_blksize = h->tftp_blksize; - /* + /* * Parse individual TFTP options. * * "blksize" is specified in RFC2348. * * "tsize" is specified in RFC2349. - */ + */ for (i = 0; i < option_idx; i += 2) { - if (strcasecmp(tftp_options[i], "blksize") == 0) { - if (i + 1 < option_idx) - blksize_is_set = - tftp_set_blksize(h, tftp_options[i + 1]); - } else if (strcasecmp(tftp_options[i], "tsize") == 0) { - if (i + 1 < option_idx) - tsize = strtol(tftp_options[i + 1], (char **)NULL, 10); - if (tsize != 0) - h->tftp_tsize = tsize; - } else { - /* Do not allow any options we did not expect to be ACKed. */ - printf("unexpected tftp option '%s'\n", tftp_options[i]); - return (-1); - } + if (strcasecmp(tftp_options[i], "blksize") == 0) { + if (i + 1 < option_idx) + blksize_is_set = + tftp_set_blksize(h, tftp_options[i + 1]); + } else if (strcasecmp(tftp_options[i], "tsize") == 0) { + if (i + 1 < option_idx) + tsize = strtol(tftp_options[i + 1], NULL, 10); + if (tsize != 0) + h->tftp_tsize = tsize; + } else { + /* + * Do not allow any options we did not expect to be + * ACKed. + */ + printf("unexpected tftp option '%s'\n", + tftp_options[i]); + return (-1); + } } if (!blksize_is_set) { @@ -725,5 +749,5 @@ tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len) printf("tftp_blksize: %u\n", h->tftp_blksize); printf("tftp_tsize: %lu\n", h->tftp_tsize); #endif - return 0; + return (0); } diff --git a/usr/src/cmd/boot/bootadm/Makefile b/usr/src/cmd/boot/bootadm/Makefile index b25c45ce04..da5dbf5332 100644 --- a/usr/src/cmd/boot/bootadm/Makefile +++ b/usr/src/cmd/boot/bootadm/Makefile @@ -24,6 +24,7 @@ # # Copyright 2016 Toomas Soome <tsoome@me.com> # Copyright 2016 Nexenta Systems, Inc. +# Copyright 2018 OmniOS Community Edition (OmniOSce) Association. # PROG= bootadm @@ -43,7 +44,7 @@ POFILE= bootadm_cmd.po LDLIBS_i386= -lfdisk LDLIBS += -lficl-sys -lmd -lcryptoutil -lnvpair -lgen -ladm -lefi -LDLIBS += -lz -lbe -lzfs -lofmt $(LDLIBS_$(MACH)) +LDLIBS += -lscf -lz -lbe -lzfs -lofmt $(LDLIBS_$(MACH)) # Writing into string literals is incorrect. We need to match gcc's # behavior, which causes us to take SIGSEGV on such a write. diff --git a/usr/src/cmd/boot/bootadm/bootadm.c b/usr/src/cmd/boot/bootadm/bootadm.c index 0444c5cda7..bedca2a6b5 100644 --- a/usr/src/cmd/boot/bootadm/bootadm.c +++ b/usr/src/cmd/boot/bootadm/bootadm.c @@ -31,7 +31,7 @@ /* * bootadm(1M) is a new utility for managing bootability of * Solaris *Newboot* environments. It has two primary tasks: - * - Allow end users to manage bootability of Newboot Solaris instances + * - Allow end users to manage bootability of Newboot Solaris instances * - Provide services to other subsystems in Solaris (primarily Install) */ @@ -125,6 +125,11 @@ typedef enum { #define UFS_SIGNATURE_LIST "/var/run/grub_ufs_signatures" #define ZFS_LEGACY_MNTPT "/tmp/bootadm_mnt_zfs_legacy" +/* SMF */ +#define BOOT_ARCHIVE_FMRI "system/boot-archive:default" +#define SCF_PG_CONFIG "config" +#define SCF_PROPERTY_FORMAT "format" + /* BE defaults */ #define BE_DEFAULTS "/etc/default/be" #define BE_DFLT_BE_HAS_GRUB "BE_HAS_GRUB=" @@ -184,6 +189,17 @@ char *menu_cmds[] = { NULL }; +char *bam_formats[] = { + "hsfs", + "ufs", + "cpio", + "ufs-nocompress", + NULL +}; +#define BAM_FORMAT_UNSET -1 +#define BAM_FORMAT_HSFS 0 +short bam_format = BAM_FORMAT_UNSET; + #define OPT_ENTRY_NUM "entry" /* @@ -208,6 +224,7 @@ typedef struct { int bam_verbose; int bam_force; int bam_debug; +int bam_skip_lock; static char *prog; static subcmd_t bam_cmd; char *bam_root; @@ -309,29 +326,27 @@ static subcmd_defn_t inst_subcmds[] = { NULL, 0, NULL, 0 /* must be last */ }; -enum dircache_copy_opt { - FILE32 = 0, - FILE64, - CACHEDIR_NUM -}; +#define build_path(buf, len, root, prefix, suffix) \ + snprintf((buf), (len), "%s%s%s%s%s", (root), (prefix), get_machine(), \ + is_flag_on(IS_SPARC_TARGET) ? "" : "/amd64", (suffix)) /* * Directory specific flags: * NEED_UPDATE : the specified archive needs to be updated - * NO_MULTI : don't extend the specified archive, but recreate it + * NO_EXTEND : don't extend the specified archive, but recreate it */ #define NEED_UPDATE 0x00000001 -#define NO_MULTI 0x00000002 +#define NO_EXTEND 0x00000002 -#define set_dir_flag(id, f) (walk_arg.dirinfo[id].flags |= f) -#define unset_dir_flag(id, f) (walk_arg.dirinfo[id].flags &= ~f) -#define is_dir_flag_on(id, f) (walk_arg.dirinfo[id].flags & f ? 1 : 0) +#define set_dir_flag(f) (walk_arg.dirinfo.flags |= (f)) +#define unset_dir_flag(f) (walk_arg.dirinfo.flags &= ~(f)) +#define is_dir_flag_on(f) (walk_arg.dirinfo.flags & (f) ? 1 : 0) -#define get_cachedir(id) (walk_arg.dirinfo[id].cdir_path) -#define get_updatedir(id) (walk_arg.dirinfo[id].update_path) -#define get_count(id) (walk_arg.dirinfo[id].count) -#define has_cachedir(id) (walk_arg.dirinfo[id].has_dir) -#define set_dir_present(id) (walk_arg.dirinfo[id].has_dir = 1) +#define get_cachedir() (walk_arg.dirinfo.cdir_path) +#define get_updatedir() (walk_arg.dirinfo.update_path) +#define get_count() (walk_arg.dirinfo.count) +#define has_cachedir() (walk_arg.dirinfo.has_dir) +#define set_dir_present() (walk_arg.dirinfo.has_dir = 1) /* * dirinfo_t (specific cache directory information): @@ -375,11 +390,11 @@ typedef struct _dirinfo { * sparcfile: list of file paths for mkisofs -path-list (SPARC only) */ static struct { - int update_flags; - nvlist_t *new_nvlp; - nvlist_t *old_nvlp; - FILE *sparcfile; - dirinfo_t dirinfo[CACHEDIR_NUM]; + int update_flags; + nvlist_t *new_nvlp; + nvlist_t *old_nvlp; + FILE *sparcfile; + dirinfo_t dirinfo; } walk_arg; struct safefile { @@ -418,7 +433,7 @@ struct iso_pdesc { /* * COUNT_MAX: maximum number of changed files to justify a multisession update * BA_SIZE_MAX: maximum size of the boot_archive to justify a multisession - * update + * update */ #define COUNT_MAX 50 #define BA_SIZE_MAX (50 * 1024 * 1024) @@ -434,7 +449,8 @@ usage(void) /* archive usage */ (void) fprintf(stderr, - "\t%s update-archive [-vn] [-R altroot [-p platform]]\n", prog); + "\t%s update-archive [-vnf] [-R altroot [-p platform]] " + "[-F format]\n", prog); (void) fprintf(stderr, "\t%s list-archive [-R altroot [-p platform]]\n", prog); #if defined(_OBP) @@ -619,7 +635,7 @@ parse_args(int argc, char *argv[]) * The internal syntax and the corresponding functionality are: * -a update -- update-archive * -a list -- list-archive - * -a update-all -- (reboot to sync all mnted OS archive) + * -a update_all -- (reboot to sync all mnted OS archive) * -i install_bootloader -- install-bootloader * -m update_entry -- update-menu * -m list_entry -- list-menu @@ -630,20 +646,21 @@ parse_args(int argc, char *argv[]) * -m list_setting [entry] [value] -- list_setting * * A set of private flags is there too: - * -F -- purge the cache directories and rebuild them + * -Q -- purge the cache directories and rebuild them * -e -- use the (faster) archive update approach (used by * reboot) + * -L -- skip locking */ static void parse_args_internal(int argc, char *argv[]) { - int c, error; + int c, i, error; extern char *optarg; extern int optind, opterr; #if defined(_OBP) - const char *optstring = "a:d:fi:m:no:veFCR:p:P:XZ"; + const char *optstring = "a:d:fF:i:m:no:veQCLR:p:P:XZ"; #else - const char *optstring = "a:d:fi:m:no:veFCMR:p:P:XZ"; + const char *optstring = "a:d:fF:i:m:no:veQCMLR:p:P:XZ"; #endif /* Suppress error message from getopt */ @@ -673,8 +690,30 @@ parse_args_internal(int argc, char *argv[]) bam_force = 1; break; case 'F': + if (bam_format != BAM_FORMAT_UNSET) { + error = 1; + bam_error( + _("multiple formats specified: -%c\n"), c); + } + for (i = 0; bam_formats[i] != NULL; i++) { + if (strcmp(bam_formats[i], optarg) == 0) { + bam_format = i; + break; + } + } + if (bam_format == BAM_FORMAT_UNSET) { + error = 1; + bam_error( + _("unknown format specified: -%c %s\n"), + c, optarg); + } + break; + case 'Q': bam_purge = 1; break; + case 'L': + bam_skip_lock = 1; + break; case 'i': if (bam_cmd) { error = 1; @@ -1648,6 +1687,9 @@ bam_lock(void) struct flock lock; pid_t pid; + if (bam_skip_lock) + return; + bam_lock_fd = open(BAM_LOCK_FILE, O_CREAT|O_RDWR, LOCK_FILE_PERMS); if (bam_lock_fd < 0) { /* @@ -1707,6 +1749,9 @@ bam_unlock(void) { struct flock unlock; + if (bam_skip_lock) + return; + /* * NOP if we don't hold the lock */ @@ -1910,7 +1955,7 @@ list2file(char *root, char *tmp, char *final, line_t *start) static int setup_path(char *path) { - char *p; + char *p; int ret; struct stat sb; @@ -2047,19 +2092,19 @@ cache_close(cachefile cf) } static int -dircache_updatefile(const char *path, int what) +dircache_updatefile(const char *path) { - int ret, exitcode; - char buf[4096 * 4]; - FILE *infile; - cachefile outfile, outupdt; + int ret, exitcode; + char buf[4096 * 4]; + FILE *infile; + cachefile outfile, outupdt; if (bam_nowrite()) { - set_dir_flag(what, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); return (BAM_SUCCESS); } - if (!has_cachedir(what)) + if (!has_cachedir()) return (BAM_SUCCESS); if ((infile = fopen(path, "rb")) == NULL) { @@ -2068,15 +2113,15 @@ dircache_updatefile(const char *path, int what) return (BAM_ERROR); } - ret = setup_file(get_cachedir(what), path, &outfile); + ret = setup_file(get_cachedir(), path, &outfile); if (ret == BAM_ERROR) { exitcode = BAM_ERROR; goto out; } - if (!is_dir_flag_on(what, NO_MULTI)) { - ret = setup_file(get_updatedir(what), path, &outupdt); + if (!is_dir_flag_on(NO_EXTEND)) { + ret = setup_file(get_updatedir(), path, &outupdt); if (ret == BAM_ERROR) - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); } while ((ret = fread(buf, 1, sizeof (buf), infile)) > 0) { @@ -2084,21 +2129,21 @@ dircache_updatefile(const char *path, int what) exitcode = BAM_ERROR; goto out; } - if (!is_dir_flag_on(what, NO_MULTI)) + if (!is_dir_flag_on(NO_EXTEND)) if (cache_write(outupdt, buf, ret) == BAM_ERROR) - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); } - set_dir_flag(what, NEED_UPDATE); - get_count(what)++; - if (get_count(what) > COUNT_MAX) - set_dir_flag(what, NO_MULTI); + set_dir_flag(NEED_UPDATE); + get_count()++; + if (get_count() > COUNT_MAX) + set_dir_flag(NO_EXTEND); exitcode = BAM_SUCCESS; out: (void) fclose(infile); if (cache_close(outfile) == BAM_ERROR) exitcode = BAM_ERROR; - if (!is_dir_flag_on(what, NO_MULTI) && + if (!is_dir_flag_on(NO_EXTEND) && cache_close(outupdt) == BAM_ERROR) exitcode = BAM_ERROR; if (exitcode == BAM_ERROR) @@ -2107,7 +2152,7 @@ out: } static int -dircache_updatedir(const char *path, int what, int updt) +dircache_updatedir(const char *path, int updt) { int ret; char dpath[PATH_MAX]; @@ -2117,7 +2162,7 @@ dircache_updatedir(const char *path, int what, int updt) strip = (char *)path + strlen(rootbuf); ret = snprintf(dpath, sizeof (dpath), "%s/%s", updt ? - get_updatedir(what) : get_cachedir(what), strip); + get_updatedir() : get_cachedir(), strip); if (ret >= sizeof (dpath)) { bam_error(_("unable to create path on mountpoint %s, " @@ -2130,9 +2175,9 @@ dircache_updatedir(const char *path, int what, int updt) return (BAM_SUCCESS); if (updt) { - if (!is_dir_flag_on(what, NO_MULTI)) + if (!is_dir_flag_on(NO_EXTEND)) if (!bam_nowrite() && mkdirp(dpath, DIR_PERMS) == -1) - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); } else { if (!bam_nowrite() && mkdirp(dpath, DIR_PERMS) == -1) { set_flag(UPDATE_ERROR); @@ -2140,7 +2185,7 @@ dircache_updatedir(const char *path, int what, int updt) } } - set_dir_flag(what, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); return (BAM_SUCCESS); } @@ -2190,51 +2235,33 @@ update_dircache(const char *path, int flags) } (void) close(fd); - /* - * If the file is not an executable and is not inside an amd64 - * directory, we copy it in both the cache directories, - * otherwise, we only copy it inside the 64-bit one. - */ if (memcmp(elf.e_ident, ELFMAG, 4) != 0) { - if (strstr(path, "/amd64")) { - rc = dircache_updatefile(path, FILE64); - } else { - rc = dircache_updatefile(path, FILE32); - if (rc == BAM_SUCCESS) - rc = dircache_updatefile(path, FILE64); - } + /* Not an ELF file, include in archive */ + rc = dircache_updatefile(path); } else { - /* - * Based on the ELF class we copy the file in the 32-bit - * or the 64-bit cache directory. - */ - if (elf.e_ident[EI_CLASS] == ELFCLASS32) { - rc = dircache_updatefile(path, FILE32); - } else if (elf.e_ident[EI_CLASS] == ELFCLASS64) { - rc = dircache_updatefile(path, FILE64); - } else { - bam_print(_("WARNING: file %s is neither a " - "32-bit nor a 64-bit ELF\n"), path); - /* paranoid */ - rc = dircache_updatefile(path, FILE32); - if (rc == BAM_SUCCESS) - rc = dircache_updatefile(path, FILE64); + /* Include 64-bit ELF files only */ + switch (elf.e_ident[EI_CLASS]) { + case ELFCLASS32: + bam_print(_("WARNING: ELF file %s is 32-bit " + "and will be excluded\n"), path); + break; + case ELFCLASS64: + rc = dircache_updatefile(path); + break; + default: + bam_print(_("WARNING: ELF file %s is neither " + "32-bit nor 64-bit\n"), path); + break; } } break; } case FTW_D: - if (strstr(path, "/amd64") == NULL) { - rc = dircache_updatedir(path, FILE32, DO_UPDATE_DIR); - if (rc == BAM_SUCCESS) - rc = dircache_updatedir(path, FILE32, - DO_CACHE_DIR); - } else { - if (has_cachedir(FILE64)) { - rc = dircache_updatedir(path, FILE64, - DO_UPDATE_DIR); + if (strstr(path, "/amd64") != NULL) { + if (has_cachedir()) { + rc = dircache_updatedir(path, DO_UPDATE_DIR); if (rc == BAM_SUCCESS) - rc = dircache_updatedir(path, FILE64, + rc = dircache_updatedir(path, DO_CACHE_DIR); } } @@ -2255,13 +2282,13 @@ cmpstat( int flags, struct FTW *ftw) { - uint_t sz; - uint64_t *value; - uint64_t filestat[2]; - int error, ret, status; + uint_t sz; + uint64_t *value; + uint64_t filestat[2]; + int error, ret, status; struct safefile *safefilep; - FILE *fp; + FILE *fp; struct stat sb; regex_t re; @@ -2347,7 +2374,7 @@ cmpstat( bam_print(_(" new %s\n"), file); if (is_flag_on(IS_SPARC_TARGET)) { - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); return (0); } @@ -2371,7 +2398,7 @@ cmpstat( return (0); if (is_flag_on(IS_SPARC_TARGET)) { - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); } else { ret = update_dircache(file, flags); if (ret == BAM_ERROR) { @@ -2391,7 +2418,7 @@ cmpstat( * iso image. We just need to know if we are going to rebuild it or not */ if (is_flag_on(IS_SPARC_TARGET) && - is_dir_flag_on(FILE64, NEED_UPDATE) && !bam_nowrite()) + is_dir_flag_on(NEED_UPDATE) && !bam_nowrite()) return (0); /* * File exists in old archive. Check if file has changed @@ -2422,7 +2449,7 @@ cmpstat( } if (is_flag_on(IS_SPARC_TARGET)) { - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); } else { ret = update_dircache(file, flags); if (ret == BAM_ERROR) { @@ -2449,10 +2476,10 @@ cmpstat( static int rmdir_r(char *path) { - struct dirent *d = NULL; - DIR *dir = NULL; - char tpath[PATH_MAX]; - struct stat sb; + struct dirent *d = NULL; + DIR *dir = NULL; + char tpath[PATH_MAX]; + struct stat sb; if ((dir = opendir(path)) == NULL) return (-1); @@ -2480,105 +2507,93 @@ rmdir_r(char *path) * If the user requested a 'purge', always recreate the directory from scratch. */ static int -set_cache_dir(char *root, int what) +set_cache_dir(char *root) { struct stat sb; int ret = 0; - ret = snprintf(get_cachedir(what), sizeof (get_cachedir(what)), - "%s%s%s%s%s", root, ARCHIVE_PREFIX, get_machine(), what == FILE64 ? - "/amd64" : "", CACHEDIR_SUFFIX); + ret = build_path(get_cachedir(), sizeof (get_cachedir()), + root, ARCHIVE_PREFIX, CACHEDIR_SUFFIX); - if (ret >= sizeof (get_cachedir(what))) { + if (ret >= sizeof (get_cachedir())) { bam_error(_("unable to create path on mountpoint %s, " "path too long\n"), rootbuf); return (BAM_ERROR); } if (bam_purge || is_flag_on(INVALIDATE_CACHE)) - (void) rmdir_r(get_cachedir(what)); + (void) rmdir_r(get_cachedir()); - if (stat(get_cachedir(what), &sb) != 0 || !(S_ISDIR(sb.st_mode))) { + if (stat(get_cachedir(), &sb) != 0 || !(S_ISDIR(sb.st_mode))) { /* best effort unlink attempt, mkdir will catch errors */ - (void) unlink(get_cachedir(what)); + (void) unlink(get_cachedir()); if (bam_verbose) bam_print(_("archive cache directory not found: %s\n"), - get_cachedir(what)); - ret = mkdir(get_cachedir(what), DIR_PERMS); + get_cachedir()); + ret = mkdir(get_cachedir(), DIR_PERMS); if (ret < 0) { bam_error(_("mkdir of %s failed: %s\n"), - get_cachedir(what), strerror(errno)); - get_cachedir(what)[0] = '\0'; + get_cachedir(), strerror(errno)); + get_cachedir()[0] = '\0'; return (ret); } set_flag(NEED_CACHE_DIR); - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); } return (BAM_SUCCESS); } static int -set_update_dir(char *root, int what) +set_update_dir(char *root) { struct stat sb; int ret; - if (is_dir_flag_on(what, NO_MULTI)) + if (is_dir_flag_on(NO_EXTEND)) return (BAM_SUCCESS); if (!bam_extend) { - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); return (BAM_SUCCESS); } - if (what == FILE64 && !is_flag_on(IS_SPARC_TARGET)) - ret = snprintf(get_updatedir(what), - sizeof (get_updatedir(what)), "%s%s%s/amd64%s", root, - ARCHIVE_PREFIX, get_machine(), UPDATEDIR_SUFFIX); - else - ret = snprintf(get_updatedir(what), - sizeof (get_updatedir(what)), "%s%s%s%s", root, - ARCHIVE_PREFIX, get_machine(), UPDATEDIR_SUFFIX); + ret = build_path(get_updatedir(), sizeof (get_updatedir()), + root, ARCHIVE_PREFIX, UPDATEDIR_SUFFIX); - if (ret >= sizeof (get_updatedir(what))) { + if (ret >= sizeof (get_updatedir())) { bam_error(_("unable to create path on mountpoint %s, " "path too long\n"), rootbuf); return (BAM_ERROR); } - if (stat(get_updatedir(what), &sb) == 0) { + if (stat(get_updatedir(), &sb) == 0) { if (S_ISDIR(sb.st_mode)) - ret = rmdir_r(get_updatedir(what)); + ret = rmdir_r(get_updatedir()); else - ret = unlink(get_updatedir(what)); + ret = unlink(get_updatedir()); if (ret != 0) - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); } - if (mkdir(get_updatedir(what), DIR_PERMS) < 0) - set_dir_flag(what, NO_MULTI); + if (mkdir(get_updatedir(), DIR_PERMS) < 0) + set_dir_flag(NO_EXTEND); return (BAM_SUCCESS); } static int -is_valid_archive(char *root, int what) +is_valid_archive(char *root) { - char archive_path[PATH_MAX]; + char archive_path[PATH_MAX]; char timestamp_path[PATH_MAX]; - struct stat sb, timestamp; - int ret; + struct stat sb, timestamp; + int ret; - if (what == FILE64 && !is_flag_on(IS_SPARC_TARGET)) - ret = snprintf(archive_path, sizeof (archive_path), - "%s%s%s/amd64%s", root, ARCHIVE_PREFIX, get_machine(), - ARCHIVE_SUFFIX); - else - ret = snprintf(archive_path, sizeof (archive_path), "%s%s%s%s", - root, ARCHIVE_PREFIX, get_machine(), ARCHIVE_SUFFIX); + ret = build_path(archive_path, sizeof (archive_path), + root, ARCHIVE_PREFIX, ARCHIVE_SUFFIX); if (ret >= sizeof (archive_path)) { bam_error(_("unable to create path on mountpoint %s, " @@ -2589,8 +2604,7 @@ is_valid_archive(char *root, int what) if (stat(archive_path, &sb) != 0) { if (bam_verbose && !bam_check) bam_print(_("archive not found: %s\n"), archive_path); - set_dir_flag(what, NEED_UPDATE); - set_dir_flag(what, NO_MULTI); + set_dir_flag(NEED_UPDATE | NO_EXTEND); return (BAM_SUCCESS); } @@ -2630,8 +2644,7 @@ is_valid_archive(char *root, int what) } set_flag(INVALIDATE_CACHE); - set_dir_flag(what, NEED_UPDATE); - set_dir_flag(what, NO_MULTI); + set_dir_flag(NEED_UPDATE | NO_EXTEND); return (BAM_SUCCESS); } @@ -2642,7 +2655,7 @@ is_valid_archive(char *root, int what) if (bam_verbose && !bam_check) bam_print(_("archive %s is bigger than %d bytes and " "will be rebuilt\n"), archive_path, BA_SIZE_MAX); - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); } return (BAM_SUCCESS); @@ -2659,80 +2672,62 @@ static int check_flags_and_files(char *root) { - struct stat sb; - int ret; + struct stat sb; + int ret; /* * If archive is missing, create archive */ - if (is_flag_on(IS_SPARC_TARGET)) { - ret = is_valid_archive(root, FILE64); - if (ret == BAM_ERROR) - return (BAM_ERROR); - } else { - int what = FILE32; - do { - ret = is_valid_archive(root, what); - if (ret == BAM_ERROR) - return (BAM_ERROR); - what++; - } while (bam_direct == BAM_DIRECT_DBOOT && what < CACHEDIR_NUM); - } + ret = is_valid_archive(root); + if (ret == BAM_ERROR) + return (BAM_ERROR); if (bam_nowrite()) return (BAM_SUCCESS); - /* * check if cache directories exist on x86. * check (and always open) the cache file on SPARC. */ if (is_sparc()) { - ret = snprintf(get_cachedir(FILE64), - sizeof (get_cachedir(FILE64)), "%s%s%s/%s", root, + ret = snprintf(get_cachedir(), + sizeof (get_cachedir()), "%s%s%s/%s", root, ARCHIVE_PREFIX, get_machine(), CACHEDIR_SUFFIX); - if (ret >= sizeof (get_cachedir(FILE64))) { + if (ret >= sizeof (get_cachedir())) { bam_error(_("unable to create path on mountpoint %s, " "path too long\n"), rootbuf); return (BAM_ERROR); } - if (stat(get_cachedir(FILE64), &sb) != 0) { + if (stat(get_cachedir(), &sb) != 0) { set_flag(NEED_CACHE_DIR); - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); } - walk_arg.sparcfile = fopen(get_cachedir(FILE64), "w"); + walk_arg.sparcfile = fopen(get_cachedir(), "w"); if (walk_arg.sparcfile == NULL) { bam_error(_("failed to open file: %s: %s\n"), - get_cachedir(FILE64), strerror(errno)); + get_cachedir(), strerror(errno)); return (BAM_ERROR); } - set_dir_present(FILE64); + set_dir_present(); } else { - int what = FILE32; - - do { - if (set_cache_dir(root, what) != 0) - return (BAM_ERROR); + if (set_cache_dir(root) != 0) + return (BAM_ERROR); - set_dir_present(what); + set_dir_present(); - if (set_update_dir(root, what) != 0) - return (BAM_ERROR); - what++; - } while (bam_direct == BAM_DIRECT_DBOOT && what < CACHEDIR_NUM); + if (set_update_dir(root) != 0) + return (BAM_ERROR); } /* * if force, create archive unconditionally */ if (bam_force) { - if (!is_sparc()) - set_dir_flag(FILE32, NEED_UPDATE); - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); if (bam_verbose) bam_print(_("forced update of archive requested\n")); return (BAM_SUCCESS); @@ -2744,10 +2739,10 @@ check_flags_and_files(char *root) static error_t read_one_list(char *root, filelist_t *flistp, char *filelist) { - char path[PATH_MAX]; - FILE *fp; - char buf[BAM_MAXLINE]; - const char *fcn = "read_one_list()"; + char path[PATH_MAX]; + FILE *fp; + char buf[BAM_MAXLINE]; + const char *fcn = "read_one_list()"; (void) snprintf(path, sizeof (path), "%s%s", root, filelist); @@ -2774,11 +2769,11 @@ read_one_list(char *root, filelist_t *flistp, char *filelist) static error_t read_list(char *root, filelist_t *flistp) { - char path[PATH_MAX]; - char cmd[PATH_MAX]; - struct stat sb; - int n, rval; - const char *fcn = "read_list()"; + char path[PATH_MAX]; + char cmd[PATH_MAX]; + struct stat sb; + int n, rval; + const char *fcn = "read_list()"; flistp->head = flistp->tail = NULL; @@ -2855,10 +2850,10 @@ read_list(char *root, filelist_t *flistp) static void getoldstat(char *root) { - char path[PATH_MAX]; - int fd, error; - struct stat sb; - char *ostat; + char path[PATH_MAX]; + int fd, error; + struct stat sb; + char *ostat; (void) snprintf(path, sizeof (path), "%s%s", root, FILE_STAT); fd = open(path, O_RDONLY); @@ -2904,26 +2899,24 @@ getoldstat(char *root) out_err: if (fd != -1) (void) close(fd); - if (!is_flag_on(IS_SPARC_TARGET)) - set_dir_flag(FILE32, NEED_UPDATE); - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); } /* Best effort stale entry removal */ static void -delete_stale(char *file, int what) +delete_stale(char *file) { char path[PATH_MAX]; struct stat sb; - (void) snprintf(path, sizeof (path), "%s/%s", get_cachedir(what), file); + (void) snprintf(path, sizeof (path), "%s/%s", get_cachedir(), file); if (!bam_check && stat(path, &sb) == 0) { if (sb.st_mode & S_IFDIR) (void) rmdir_r(path); else (void) unlink(path); - set_dir_flag(what, (NEED_UPDATE | NO_MULTI)); + set_dir_flag(NEED_UPDATE | NO_EXTEND); } } @@ -2938,7 +2931,7 @@ check4stale(char *root) { nvpair_t *nvp; nvlist_t *nvlp; - char *file; + char *file; char path[PATH_MAX]; /* @@ -2966,17 +2959,14 @@ check4stale(char *root) (void) snprintf(path, sizeof (path), "%s/%s", root, file); if (access(path, F_OK) < 0) { - int what; - if (bam_verbose) bam_print(_(" stale %s\n"), path); if (is_flag_on(IS_SPARC_TARGET)) { - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); } else { - for (what = FILE32; what < CACHEDIR_NUM; what++) - if (has_cachedir(what)) - delete_stale(file, what); + if (has_cachedir()) + delete_stale(file); } } } @@ -3058,11 +3048,11 @@ update_timestamp(char *root) static void savenew(char *root) { - char path[PATH_MAX]; - char path2[PATH_MAX]; - size_t sz; - char *nstat; - int fd, wrote, error; + char path[PATH_MAX]; + char path2[PATH_MAX]; + size_t sz; + char *nstat; + int fd, wrote, error; nstat = NULL; sz = 0; @@ -3131,11 +3121,11 @@ clear_walk_args(void) static int update_required(char *root) { - struct stat sb; - char path[PATH_MAX]; - filelist_t flist; - filelist_t *flistp = &flist; - int ret; + struct stat sb; + char path[PATH_MAX]; + filelist_t flist; + filelist_t *flistp = &flist; + int ret; flistp->head = flistp->tail = NULL; @@ -3189,7 +3179,7 @@ update_required(char *root) create_newstat(); /* * This walk does 2 things: - * - gets new stat data for every file + * - gets new stat data for every file * - (optional) compare old and new stat data */ ret = walk_list(root, &flist); @@ -3213,8 +3203,7 @@ update_required(char *root) /* If nothing was updated, discard newstat. */ - if (!is_dir_flag_on(FILE32, NEED_UPDATE) && - !is_dir_flag_on(FILE64, NEED_UPDATE)) { + if (!is_dir_flag_on(NEED_UPDATE)) { clear_walk_args(); return (0); } @@ -3346,14 +3335,61 @@ is_be(char *root) } /* - * Returns 1 if mkiso is in the expected PATH, 0 otherwise + * Returns B_TRUE if mkiso is in the expected PATH and should be used, + * B_FALSE otherwise */ -static int -is_mkisofs() +static boolean_t +use_mkisofs() { - if (access(MKISOFS_PATH, X_OK) == 0) - return (1); - return (0); + scf_simple_prop_t *prop; + char *format = NULL; + boolean_t ret; + + /* Check whether the mkisofs binary is in the expected location */ + if (access(MKISOFS_PATH, X_OK) != 0) { + if (bam_verbose) + bam_print("mkisofs not found\n"); + return (B_FALSE); + } + + if (bam_format == BAM_FORMAT_HSFS) { + if (bam_verbose) + bam_print("-F specified HSFS"); + return (B_TRUE); + } + + /* If working on an alt-root, do not use HSFS unless asked via -F */ + if (bam_alt_root) + return (B_FALSE); + + /* + * Then check that the system/boot-archive config/format property + * is "hsfs" or empty. + */ + if ((prop = scf_simple_prop_get(NULL, BOOT_ARCHIVE_FMRI, SCF_PG_CONFIG, + SCF_PROPERTY_FORMAT)) == NULL) { + /* Could not find property, use mkisofs */ + if (bam_verbose) { + bam_print( + "%s does not have %s/%s property, using mkisofs\n", + BOOT_ARCHIVE_FMRI, SCF_PG_CONFIG, + SCF_PROPERTY_FORMAT); + } + return (B_TRUE); + } + if (scf_simple_prop_numvalues(prop) < 0 || + (format = scf_simple_prop_next_astring(prop)) == NULL) + ret = B_TRUE; + else + ret = strcmp(format, "hsfs") == 0 ? B_TRUE : B_FALSE; + if (bam_verbose) { + if (ret) + bam_print("Creating hsfs boot archive\n"); + else + bam_print("Creating %s boot archive\n", format); + } + scf_simple_prop_free(prop); + return (ret); } #define MKISO_PARAMS " -quiet -graft-points -dlrDJN -relaxed-filenames " @@ -3668,37 +3704,31 @@ create_x86_archive(char *archive, char *tempname, char *update_dir) } static int -mkisofs_archive(char *root, int what) +mkisofs_archive(char *root) { int ret; + char suffix[20]; char temp[PATH_MAX]; - char bootblk[PATH_MAX]; + char bootblk[PATH_MAX]; char boot_archive[PATH_MAX]; - if (what == FILE64 && !is_flag_on(IS_SPARC_TARGET)) - ret = snprintf(temp, sizeof (temp), - "%s%s%s/amd64/archive-new-%d", root, ARCHIVE_PREFIX, - get_machine(), getpid()); - else - ret = snprintf(temp, sizeof (temp), "%s%s%s/archive-new-%d", - root, ARCHIVE_PREFIX, get_machine(), getpid()); + ret = snprintf(suffix, sizeof (suffix), "/archive-new-%d", getpid()); + if (ret >= sizeof (suffix)) + goto out_path_err; + + ret = build_path(temp, sizeof (temp), root, ARCHIVE_PREFIX, suffix); if (ret >= sizeof (temp)) goto out_path_err; - if (what == FILE64 && !is_flag_on(IS_SPARC_TARGET)) - ret = snprintf(boot_archive, sizeof (boot_archive), - "%s%s%s/amd64%s", root, ARCHIVE_PREFIX, get_machine(), - ARCHIVE_SUFFIX); - else - ret = snprintf(boot_archive, sizeof (boot_archive), - "%s%s%s%s", root, ARCHIVE_PREFIX, get_machine(), - ARCHIVE_SUFFIX); + ret = build_path(boot_archive, sizeof (boot_archive), root, + ARCHIVE_PREFIX, ARCHIVE_SUFFIX); if (ret >= sizeof (boot_archive)) goto out_path_err; - bam_print("updating %s\n", boot_archive); + bam_print("updating %s (HSFS)\n", + boot_archive[1] == '/' ? boot_archive + 1 : boot_archive); if (is_flag_on(IS_SPARC_TARGET)) { ret = snprintf(bootblk, sizeof (bootblk), @@ -3707,21 +3737,21 @@ mkisofs_archive(char *root, int what) goto out_path_err; ret = create_sparc_archive(boot_archive, temp, bootblk, - get_cachedir(what)); + get_cachedir()); } else { - if (!is_dir_flag_on(what, NO_MULTI)) { + if (!is_dir_flag_on(NO_EXTEND)) { if (bam_verbose) bam_print("Attempting to extend x86 archive: " "%s\n", boot_archive); ret = extend_iso_archive(boot_archive, temp, - get_updatedir(what)); + get_updatedir()); if (ret == BAM_SUCCESS) { if (bam_verbose) bam_print("Successfully extended %s\n", boot_archive); - (void) rmdir_r(get_updatedir(what)); + (void) rmdir_r(get_updatedir()); return (BAM_SUCCESS); } } @@ -3739,12 +3769,12 @@ mkisofs_archive(char *root, int what) bam_print("Unable to extend %s... rebuilding archive\n", boot_archive); - if (get_updatedir(what)[0] != '\0') - (void) rmdir_r(get_updatedir(what)); + if (get_updatedir()[0] != '\0') + (void) rmdir_r(get_updatedir()); ret = create_x86_archive(boot_archive, temp, - get_cachedir(what)); + get_cachedir()); } if (digest_archive(boot_archive) == BAM_ERROR && bam_verbose) @@ -3767,27 +3797,25 @@ create_ramdisk(char *root) char *cmdline, path[PATH_MAX]; size_t len; struct stat sb; - int ret, what, status = BAM_SUCCESS; - - /* If there is mkisofs, use it to create the required archives */ - if (is_mkisofs()) { - for (what = FILE32; what < CACHEDIR_NUM; what++) { - if (has_cachedir(what) && is_dir_flag_on(what, - NEED_UPDATE)) { - ret = mkisofs_archive(root, what); - if (ret != 0) - status = BAM_ERROR; - } + int ret, status = BAM_SUCCESS; + + /* If mkisofs should be used, use it to create the required archives */ + if (use_mkisofs()) { + if (has_cachedir() && is_dir_flag_on(NEED_UPDATE)) { + ret = mkisofs_archive(root); + if (ret != 0) + status = BAM_ERROR; } return (status); + } else if (bam_format == BAM_FORMAT_HSFS) { + bam_error(_("cannot create hsfs archive\n")); + return (BAM_ERROR); } /* - * Else setup command args for create_ramdisk.ksh for the UFS archives + * Else setup command args for create_ramdisk.ksh for the archive * Note: we will not create hash here, CREATE_RAMDISK should create it. */ - if (bam_verbose) - bam_print("mkisofs not found, creating UFS archive\n"); (void) snprintf(path, sizeof (path), "%s/%s", root, CREATE_RAMDISK); if (stat(path, &sb) != 0) { @@ -3801,7 +3829,9 @@ create_ramdisk(char *root) len = strlen(path) + strlen(root) + 10; /* room for space + -R */ if (bam_alt_platform) - len += strlen(bam_platform) + strlen("-p "); + len += strlen(bam_platform) + strlen(" -p "); + if (bam_format != BAM_FORMAT_UNSET) + len += strlen(bam_formats[bam_format]) + strlen(" -f "); cmdline = s_calloc(1, len); if (bam_alt_platform) { @@ -3817,6 +3847,15 @@ create_ramdisk(char *root) } else (void) snprintf(cmdline, len, "%s", path); + if (bam_format != BAM_FORMAT_UNSET) { + if (strlcat(cmdline, " -f ", len) >= len || + strlcat(cmdline, bam_formats[bam_format], len) >= len) { + bam_error(_("boot-archive command line too long\n")); + free(cmdline); + return (BAM_ERROR); + } + } + if (exec_cmd(cmdline, NULL) != 0) { bam_error(_("boot-archive creation FAILED, command: '%s'\n"), cmdline); @@ -5812,7 +5851,7 @@ get_mountpoint(char *special, char *fstype) /* * Mounts a "legacy" top dataset (if needed) * Returns: The mountpoint of the legacy top dataset or NULL on error - * mnted returns one of the above values defined for zfs_mnted_t + * mnted returns one of the above values defined for zfs_mnted_t */ static char * mount_legacy_dataset(char *pool, zfs_mnted_t *mnted) @@ -5906,7 +5945,7 @@ mount_legacy_dataset(char *pool, zfs_mnted_t *mnted) /* * Mounts the top dataset (if needed) * Returns: The mountpoint of the top dataset or NULL on error - * mnted returns one of the above values defined for zfs_mnted_t + * mnted returns one of the above values defined for zfs_mnted_t */ char * mount_top_dataset(char *pool, zfs_mnted_t *mnted) @@ -6349,7 +6388,7 @@ search_hash(mhash_t *mhp, char *special, char **mntpt) { int idx; mcache_t *mcp; - const char *fcn = "search_hash()"; + const char *fcn = "search_hash()"; assert(mntpt); @@ -7754,7 +7793,7 @@ get_special(char *mountp) struct mnttab mpref = {0}; int error; int ret; - const char *fcn = "get_special()"; + const char *fcn = "get_special()"; INJECT_ERROR1("GET_SPECIAL_MNTPT", mountp = NULL); if (mountp == NULL) { diff --git a/usr/src/cmd/boot/scripts/boot-archive-update.ksh b/usr/src/cmd/boot/scripts/boot-archive-update.ksh index 693c715c73..deae20e814 100644 --- a/usr/src/cmd/boot/scripts/boot-archive-update.ksh +++ b/usr/src/cmd/boot/scripts/boot-archive-update.ksh @@ -22,6 +22,7 @@ # # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2018 OmniOS Community Edition (OmniOSce) Association. # . /lib/svc/share/smf_include.sh @@ -31,14 +32,18 @@ UPDATEFILE=/etc/svc/volatile/boot_archive_safefile_update smf_is_globalzone || exit $SMF_EXIT_OK -# on x86 get rid of transient reboot entry in the GRUB menu -# if [ `uname -p` = "i386" ]; then + # on x86 get rid of transient reboot entry in the GRUB menu if [ -f /stubboot/boot/grub/menu.lst ]; then /sbin/bootadm -m update_temp -R /stubboot else /sbin/bootadm -m update_temp fi + # Remove old 32-bit archives if present. + plat=/platform/`uname -i` + [ -f $plat/boot_archive ] && rm -f $plat/boot_archive + [ -f $plat/boot_archive.hash ] && rm -f $plat/boot_archive.hash + [ -d $plat/archive_cache ] && rm -rf $plat/archive_cache fi if [ -f $UPDATEFILE ] || [ -f /reconfigure ]; then diff --git a/usr/src/cmd/boot/scripts/create_ramdisk.ksh b/usr/src/cmd/boot/scripts/create_ramdisk.ksh index 6ccd546bfd..1f6f4a4dfd 100644 --- a/usr/src/cmd/boot/scripts/create_ramdisk.ksh +++ b/usr/src/cmd/boot/scripts/create_ramdisk.ksh @@ -27,23 +27,25 @@ # # Copyright (c) 2014 by Delphix. All rights reserved. +# Copyright 2018 OmniOS Community Edition (OmniOSce) Association. # ALT_ROOT= EXTRACT_ARGS= +FORMAT= +format_set=0 compress=yes -SPLIT=unknown -ERROR=0 -dirsize32=0 -dirsize64=0 +dirsize=0 usage() { - echo "This utility is a component of the bootadm(1M) implementation" - echo "and it is not recommended for stand-alone use." - echo "Please use bootadm(1M) instead." - echo "" - echo "Usage: ${0##*/}: [-R \<root\>] [-p \<platform\>] [--nocompress]" - echo "where \<platform\> is one of i86pc, sun4u or sun4v" + cat <<- EOM +This utility is a component of the bootadm(1M) implementation and it is not +recommended for stand-alone use. Please use bootadm(1M) instead. + +Usage: ${0##*/}: [-R <root>] [-p <platform>] [ -f <format> ] [--nocompress] +where <platform> is one of i86pc, sun4u or sun4v + and <format> is one of ufs, ufs-nocompress or cpio + EOM exit } @@ -52,15 +54,25 @@ PLATFORM=`uname -m` export PATH=/usr/sbin:/usr/bin:/sbin export GZIP_CMD=/usr/bin/gzip +export CPIO_CMD=/usr/bin/cpio EXTRACT_FILELIST="/boot/solaris/bin/extract_boot_filelist" # # Parse options # -while [ "$1" != "" ] -do +while [ -n "$1" ]; do case $1 in + -f) shift + FORMAT="$1" + format_set=1 + ;; + -n|--nocompress) compress=no + ;; + -p) shift + PLATFORM="$1" + EXTRACT_ARGS="${EXTRACT_ARGS} -p ${PLATFORM}" + ;; -R) shift ALT_ROOT="$1" if [ "$ALT_ROOT" != "/" ]; then @@ -69,12 +81,6 @@ do EXTRACT_FILELIST="${ALT_ROOT}${EXTRACT_FILELIST}" fi ;; - -n|--nocompress) compress=no - ;; - -p) shift - PLATFORM="$1" - EXTRACT_ARGS="${EXTRACT_ARGS} -p ${PLATFORM}" - ;; *) usage ;; esac @@ -88,73 +94,56 @@ if [ $# -eq 1 ]; then echo "Creating boot_archive for $ALT_ROOT" fi -case $PLATFORM in -i386) PLATFORM=i86pc - ISA=i386 - ARCH64=amd64 - ;; -i86pc) ISA=i386 - ARCH64=amd64 - ;; -sun4u) ISA=sparc - ARCH64=sparcv9 - ;; -sun4v) ISA=sparc - ARCH64=sparcv9 - ;; -*) usage - ;; -esac - -BOOT_ARCHIVE=platform/$PLATFORM/boot_archive -BOOT_ARCHIVE_64=platform/$PLATFORM/$ARCH64/boot_archive +if [ -z "$FORMAT" ]; then + if [ -n "$ALT_ROOT" ]; then + SVCCFG_DTD=/$ALT_ROOT/usr/share/lib/xml/dtd/service_bundle.dtd.1 + SVCCFG_REPOSITORY=/$ALT_ROOT/etc/svc/repository.db + export SVCCFG_DTD SVCCFG_REPOSITORY + fi + FORMAT=`svccfg -s system/boot-archive listprop config/format \ + | awk '{print $3}'` +fi -if [ $PLATFORM = i86pc ] ; then - SPLIT=yes -else # must be sparc - SPLIT=no # there's only 64-bit (sparcv9), so don't split - compress=no +if [ $format_set -eq 0 -a "$FORMAT" = hsfs ]; then + if /sbin/bootadm update-archive -R ${ALT_ROOT:-/} -f -L -F hsfs; then + exit 0 + else + echo "Failed to create HSFS archive, falling back." + fi fi -[ -x $GZIP_CMD ] || compress=no +[[ "$FORMAT" =~ ^(cpio|ufs|ufs-nocompress)$ ]] || FORMAT=ufs + +case $PLATFORM in +i386|i86pc) PLATFORM=i86pc + ISA=i386 + ARCH64=amd64 + BOOT_ARCHIVE_SUFFIX=$ARCH64/boot_archive + ;; +sun4u|sun4v) ISA=sparc + ARCH64=sparcv9 + BOOT_ARCHIVE_SUFFIX=boot_archive + compress=no + ;; +*) usage + ;; +esac + +BOOT_ARCHIVE=platform/$PLATFORM/$BOOT_ARCHIVE_SUFFIX -function cleanup +function fatal_error { - umount -f "$rdmnt32" 2>/dev/null - umount -f "$rdmnt64" 2>/dev/null - lofiadm -d "$rdfile32" 2>/dev/null - lofiadm -d "$rdfile64" 2>/dev/null - [ -n "$rddir" ] && rm -fr "$rddir" 2> /dev/null - [ -n "$new_rddir" ] && rm -fr "$new_rddir" 2>/dev/null + print -u2 $* + exit 1 } -function getsize -{ - # Estimate image size and add 10% overhead for ufs stuff. - # Note, we can't use du here in case we're on a filesystem, e.g. zfs, - # in which the disk usage is less than the sum of the file sizes. - # The nawk code - # - # {t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5} - # - # below rounds up the size of a file/directory, in bytes, to the - # next multiple of 1024. This mimics the behavior of ufs especially - # with directories. This results in a total size that's slightly - # bigger than if du was called on a ufs directory. - size32=$(cat "$list32" | xargs -I {} ls -lLd "{}" 2> /dev/null | - nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5} - END {print int(t * 1.10 / 1024)}') - (( size32 += dirsize32 )) - size64=$(cat "$list64" | xargs -I {} ls -lLd "{}" 2> /dev/null | - nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5} - END {print int(t * 1.10 / 1024)}') - (( size64 += dirsize64 )) - (( total_size = size32 + size64 )) +[ -x $GZIP_CMD ] || compress=no - if [ $compress = yes ] ; then - total_size=`echo $total_size | nawk '{print int($1 / 2)}'` - fi -} +case $FORMAT in +cpio) [ -x $CPIO_CMD ] || FORMAT=ufs ;; +ufs-nocompress) FORMAT=ufs; compress=no ;; +ufs) ;; +esac # # Copies all desired files to a target directory. One argument should be @@ -167,7 +156,7 @@ function getsize # function copy_files { - list="$1" + typeset listfile="$1" # # If compress is set, the files are gzip'd and put in the correct @@ -177,8 +166,7 @@ function copy_files # If compress is not set, the file names are printed, which causes # the cpio at the end to do the copy. # - while read path - do + while read path; do if [ $compress = yes ]; then dir="${path%/*}" [ -d "$rdmnt/$dir" ] || mkdir -p "$rdmnt/$dir" @@ -186,7 +174,7 @@ function copy_files else print "$path" fi - done <"$list" | cpio -pdum "$rdmnt" 2>/dev/null + done <"$listfile" | cpio -pdum "$rdmnt" 2>/dev/null if [ $ISA = sparc ] ; then # copy links @@ -201,39 +189,112 @@ function copy_files } -# -# The first argument can be: -# -# "both" - create an archive with both 32-bit and 64-bit binaries -# "32-bit" - create an archive with only 32-bit binaries -# "64-bit" - create an archive with only 64-bit binaries -# -function create_ufs +function ufs_cleanup { - which=$1 - archive=$2 - lofidev=$3 - - # should we exclude amd64 binaries? - if [ "$which" = "32-bit" ]; then - rdfile="$rdfile32" - rdmnt="$rdmnt32" - list="$list32" - elif [ "$which" = "64-bit" ]; then - rdfile="$rdfile64" - rdmnt="$rdmnt64" - list="$list64" - else - rdfile="$rdfile32" - rdmnt="$rdmnt32" - list="$list32" + umount -f "$rdmnt" 2>/dev/null + lofiadm -d "$rdfile" 2>/dev/null + [ -n "$rddir" ] && rm -fr "$rddir" 2> /dev/null + [ -n "$new_rddir" ] && rm -fr "$new_rddir" 2>/dev/null +} + +function ufs_getsize +{ + # Estimate image size and add 10% overhead for ufs stuff. + # Note, we can't use du here in case we're on a filesystem, e.g. zfs, + # in which the disk usage is less than the sum of the file sizes. + # The nawk code + # + # {t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5} + # + # below rounds up the size of a file/directory, in bytes, to the + # next multiple of 1024. This mimics the behavior of ufs especially + # with directories. This results in a total size that's slightly + # bigger than if du was called on a ufs directory. + size=$(cat "$list" | xargs -I {} ls -lLd "{}" 2> /dev/null | + nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5} + END {print int(t * 1.10 / 1024)}') + (( size += dirsize )) + (( total_size = size )) + # If compression is enabled, then each file within the archive will + # be individually compressed. The compression ratio is around 60% + # across the archive so make the image smaller. + [ $compress = yes ] && (( total_size = total_size / 2 )) +} + +function create_ufs_archive +{ + typeset archive="$ALT_ROOT/$BOOT_ARCHIVE" + + [ "$compress" = yes ] && \ + echo "updating $archive (UFS)" || \ + echo "updating $archive (UFS-nocompress)" + + # + # We use /tmp/ for scratch space now. This will be changed later to + # $ALT_ROOT/var/tmp if there is insufficient space in /tmp/. + # + rddir="/tmp/create_ramdisk.$$.tmp" + new_rddir= + rm -rf "$rddir" + mkdir "$rddir" || fatal_error "Could not create directory $rddir" + + # Clean up upon exit. + trap 'ufs_cleanup' EXIT + + list="$rddir/filelist" + + cd "/$ALT_ROOT" || fatal_error "Cannot chdir to $ALT_ROOT" + find $filelist -print 2>/dev/null | while read path; do + if [ -d "$path" ]; then + size=`ls -lLd "$path" | nawk ' + {print ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}'` + (( dirsize += size / 1024 )) + else + print "$path" + fi + done >"$list" + + # calculate image size + ufs_getsize + + # check to see if there is sufficient space in tmpfs + # + tmp_free=`df -b /tmp | tail -1 | awk '{ print $2 }'` + (( tmp_free = tmp_free / 3 )) + + if [ $total_size -gt $tmp_free ] ; then + echo "Insufficient space in /tmp, using $ALT_ROOT/var/tmp" + # assumes we have enough scratch space on $ALT_ROOT + new_rddir="/$ALT_ROOT/var/tmp/create_ramdisk.$$.tmp" + rm -rf "$new_rddir" + mkdir "$new_rddir" || fatal_error \ + "Could not create temporary directory $new_rddir" + + # Save the file lists + mv "$list" "$new_rddir"/ + list="/$new_rddir/filelist" + + # Remove the old $rddir and set the new value of rddir + rm -rf "$rddir" + rddir="$new_rddir" + new_rddir= fi - NOINUSE_CHECK=1 newfs $lofidev < /dev/null 2> /dev/null + rdfile="$rddir/rd.file" + rdmnt="$rddir/rd.mount" + errlog="$rddir/rd.errlog" + lofidev="" + + mkfile ${total_size}k "$rdfile" || \ + fatal_error "Could not create backing file" + lofidev=`lofiadm -a "$rdfile"` || \ + fatal_error "Could not create lofi device" + + NOINUSE_CHECK=1 newfs -m 0 $lofidev < /dev/null 2> /dev/null mkdir "$rdmnt" mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1 mount -F ufs -o nologging $lofidev "$rdmnt" - files= + rm -rf "$rdmnt/lost+found" # do the actual copy copy_files "$list" @@ -241,12 +302,14 @@ function create_ufs rmdir "$rdmnt" if [ $ISA = sparc ] ; then - rlofidev=`echo "$lofidev" | sed -e "s/dev\/lofi/dev\/rlofi/"` - bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/ufs/bootblk" + rlofidev="${lofidev/lofi/rlofi}" + bb="/$ALT_ROOT/platform/$PLATFORM/lib/fs/ufs/bootblk" # installboot is not available on all platforms dd if=$bb of=$rlofidev bs=1b oseek=1 count=15 conv=sync 2>&1 fi + lofiadm -d "$rdfile" + # # Check if gzip exists in /usr/bin, so we only try to run gzip # on systems that have gzip. Then run gzip out of the patch to @@ -256,27 +319,15 @@ function create_ufs # compressed, and the final compression will accomplish very # little. To save time, we skip the gzip in this case. # - if [ $ISA = i386 ] && [ $compress = no ] && \ - [ -x $GZIP_CMD ] ; then - gzip -c "$rdfile" > "${archive}-new" + if [ $ISA = i386 ] && [ $compress = no ] && [ -x $GZIP_CMD ] ; then + $GZIP_CMD -c "$rdfile" > "${archive}-new" else cat "$rdfile" > "${archive}-new" fi - + if [ $? -ne 0 ] ; then rm -f "${archive}-new" fi -} - -function create_archive -{ - which=$1 - archive=$2 - lofidev=$3 - - echo "updating $archive" - - create_ufs "$which" "$archive" "$lofidev" # sanity check the archive before moving it into place # @@ -298,27 +349,59 @@ function create_archive if [ $? = 1 ] && [ -x $GZIP_CMD ] || [ "$ARCHIVE_SIZE" -lt 10000 ] then - # - # Two of these functions may be run in parallel. We - # need to allow the other to clean up, so we can't - # exit immediately. Instead, we set a flag. - # - echo "update of $archive failed" - ERROR=1 + fatal_error "update of $archive failed" else lockfs -f "/$ALT_ROOT" 2>/dev/null - mv "${archive}-new" "$archive" rm -f "$archive.hash" - digest -a sha1 "$archive" > "$archive.hash" + mv "${archive}-new" "$archive" + digest -a sha1 "$rdfile" > "$archive.hash" lockfs -f "/$ALT_ROOT" 2>/dev/null fi + [ -n "$rddir" ] && rm -rf "$rddir" +} +function cpio_cleanup +{ + [ -f "/$ALT_ROOT/$tarchive" ] && rm -f "/$ALT_ROOT/$tarchive" + [ -f "/$ALT_ROOT/$tarchive.cpio" ] && rm -f "/$ALT_ROOT/$tarchive.cpio" + [ -f "/$ALT_ROOT/$tarchive.hash" ] && rm -f "/$ALT_ROOT/$tarchive.hash" } -function fatal_error +function create_cpio_archive { - print -u2 $* - exit 1 + typeset archive="$ALT_ROOT/$BOOT_ARCHIVE" + + echo "updating $archive (CPIO)" + + tarchive="$archive.$$.new" + + # Clean up upon exit. + trap 'cpio_cleanup' EXIT + + cd "/$ALT_ROOT" || fatal_error "Cannot chdir to $ALT_ROOT" + + touch "$tarchive" \ + || fatal_error "Cannot create temporary archive $tarchive" + + find $filelist 2>/dev/null | cpio -qo -H odc > "$tarchive.cpio" \ + || fatal_error "Problem creating archive" + + [ -x /usr/bin/digest ] \ + && /usr/bin/digest -a sha1 "$tarchive.cpio" \ + > "$tarchive.hash" + + if [ -x "$GZIP_CMD" ]; then + $GZIP_CMD -c "$tarchive.cpio" > "$tarchive" + rm -f "$tarchive.cpio" + else + mv "$tarchive.cpio" "$tarchive" + fi + + # Move new archive into place + [ -f "$archive.hash" ] && rm -f "$archive.hash" + mv "$tarchive" "$archive" + [ $? -eq 0 -a -f "$tarchive.hash" ] \ + && mv "$tarchive.hash" "$archive.hash" } # @@ -335,119 +418,15 @@ filelist=$($EXTRACT_FILELIST $EXTRACT_ARGS \ /etc/boot/solaris/filelist.ramdisk \ 2>/dev/null | sort -u) -# -# We use /tmp/ for scratch space now. This may be changed later if there -# is insufficient space in /tmp/. -# -rddir="/tmp/create_ramdisk.$$.tmp" -new_rddir= -rm -rf "$rddir" -mkdir "$rddir" || fatal_error "Could not create temporary directory $rddir" - -# Clean up upon exit. -trap 'cleanup' EXIT - -list32="$rddir/filelist.32" -list64="$rddir/filelist.64" - -touch $list32 $list64 - -# -# This loop creates the 32-bit and 64-bit lists of files. The 32-bit list -# is written to stdout, which is redirected at the end of the loop. The -# 64-bit list is appended with each write. -# -cd "/$ALT_ROOT" -find $filelist -print 2>/dev/null | while read path -do - if [ $SPLIT = no ]; then - print "$path" - elif [ -d "$path" ]; then - size=`ls -lLd "$path" | nawk ' - {print ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}'` - if [ `basename "$path"` != "amd64" ]; then - (( dirsize32 += size )) - fi - (( dirsize64 += size )) - else - case `LC_MESSAGES=C /usr/bin/file -m /dev/null "$path" 2>/dev/null` in - *ELF\ 64-bit*) - print "$path" >> "$list64" - ;; - *ELF\ 32-bit*) - print "$path" - ;; - *) - # put in both lists - print "$path" - print "$path" >> "$list64" - esac - fi -done >"$list32" - -# calculate image size -getsize - -# check to see if there is sufficient space in tmpfs -# -tmp_free=`df -b /tmp | tail -1 | awk '{ printf ($2) }'` -(( tmp_free = tmp_free / 3 )) -if [ $SPLIT = yes ]; then - (( tmp_free = tmp_free / 2 )) -fi - -if [ $total_size -gt $tmp_free ] ; then - # assumes we have enough scratch space on $ALT_ROOT - new_rddir="/$ALT_ROOT/var/tmp/create_ramdisk.$$.tmp" - rm -rf "$new_rddir" - mkdir "$new_rddir" || fatal_error \ - "Could not create temporary directory $new_rddir" - - # Save the file lists - mv "$list32" "$new_rddir"/ - mv "$list64" "$new_rddir"/ - list32="/$new_rddir/filelist.32" - list64="/$new_rddir/filelist.64" - - # Remove the old $rddir and set the new value of rddir - rm -rf "$rddir" - rddir="$new_rddir" - new_rddir= -fi +# Now that we have the list of files, we can create the archive. -rdfile32="$rddir/rd.file.32" -rdfile64="$rddir/rd.file.64" -rdmnt32="$rddir/rd.mount.32" -rdmnt64="$rddir/rd.mount.64" -errlog32="$rddir/rd.errlog.32" -errlog64="$rddir/rd.errlog.64" -lofidev32="" -lofidev64="" - -if [ $SPLIT = yes ]; then - # - # We can't run lofiadm commands in parallel, so we have to do - # them here. - # - mkfile ${size32}k "$rdfile32" - lofidev32=`lofiadm -a "$rdfile32"` - mkfile ${size64}k "$rdfile64" - lofidev64=`lofiadm -a "$rdfile64"` - create_archive "32-bit" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32 & - create_archive "64-bit" "$ALT_ROOT/$BOOT_ARCHIVE_64" $lofidev64 - wait - lofiadm -d "$rdfile32" - lofiadm -d "$rdfile64" -else - mkfile ${total_size}k "$rdfile32" - lofidev32=`lofiadm -a "$rdfile32"` - create_archive "both" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32 - lofiadm -d "$rdfile32" -fi -if [ $ERROR = 1 ]; then - cleanup - exit 1 -fi +case "$FORMAT" in + cpio) create_cpio_archive ;; + ufs) create_ufs_archive ;; + *) print -u2 "Unknown boot archive format, $FORMAT" + exit 1 + ;; +esac # # For the diskless case, hardlink archive to /boot to make it @@ -456,11 +435,7 @@ fi # grep "[ ]/[ ]*nfs[ ]" "$ALT_ROOT/etc/vfstab" > /dev/null if [ $? = 0 ]; then - rm -f "$ALT_ROOT/boot/boot_archive" "$ALT_ROOT/boot/amd64/boot_archive" - ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/boot_archive" - if [ $SPLIT = yes ]; then - ln "$ALT_ROOT/$BOOT_ARCHIVE_64" \ - "$ALT_ROOT/boot/amd64/boot_archive" - fi + rm -f "$ALT_ROOT/boot/$BOOT_ARCHIVE_SUFFIX" + mkdir -p "$ALT_ROOT/boot/`dirname $BOOT_ARCHIVE_SUFFIX`" + ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/$BOOT_ARCHIVE_SUFFIX" fi -[ -n "$rddir" ] && rm -rf "$rddir" diff --git a/usr/src/cmd/cmd-inet/usr.sbin/ipqosconf/ipqosconf.c b/usr/src/cmd/cmd-inet/usr.sbin/ipqosconf/ipqosconf.c index 914c6f05db..dc7327158a 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/ipqosconf/ipqosconf.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/ipqosconf/ipqosconf.c @@ -249,7 +249,7 @@ static int readuser(char *str, uid_t *uid); * macros to call list functions with the more complex list element type * cast to the skeletal type iqpos_list_el_t. */ -#define GET_LIST_END(list, end)\ +#define LIST_END(list, end)\ list_end((ipqos_list_el_t **)list, (ipqos_list_el_t ***)end) #define ADD_TO_LIST(list, el)\ add_to_list((ipqos_list_el_t **)list, (ipqos_list_el_t *)el) @@ -9247,7 +9247,7 @@ ipqos_conf_action_t *actions) for (act = actions; act != NULL; act = act->next) { /* store start of new resolved filters */ - GET_LIST_END(&act->filters, &new_filters); + LIST_END(&act->filters, &new_filters); /* * do name resolution on retry list adding resolved filters diff --git a/usr/src/cmd/halt/halt.c b/usr/src/cmd/halt/halt.c index 0293c5e788..84d3a723f5 100644 --- a/usr/src/cmd/halt/halt.c +++ b/usr/src/cmd/halt/halt.c @@ -19,7 +19,6 @@ * CDDL HEADER END */ /* - * Copyright 2016 Toomas Soome <tsoome@me.com> * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * Copyright 2011 Joyent, Inc. All rights reserved. @@ -27,6 +26,8 @@ /* * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2015 by Delphix. All rights reserved. + * Copyright 2016 Toomas Soome <tsoome@me.com> + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -1595,18 +1596,10 @@ main(int argc, char *argv[]) * handle a SIGTERM and clean up properly. */ if (cmd != A_DUMP) { - int start, end, delta; - - (void) kill(-1, SIGTERM); - start = time(NULL); - if (zoneid == GLOBAL_ZONEID && !nosync) do_archives_update(fast_reboot); - - end = time(NULL); - delta = end - start; - if (delta < 5) - (void) sleep(5 - delta); + (void) kill(-1, SIGTERM); + (void) sleep(5); } (void) signal(SIGINT, SIG_IGN); diff --git a/usr/src/cmd/svc/milestone/boot-archive.xml b/usr/src/cmd/svc/milestone/boot-archive.xml index ca8f947321..a342834cab 100644 --- a/usr/src/cmd/svc/milestone/boot-archive.xml +++ b/usr/src/cmd/svc/milestone/boot-archive.xml @@ -24,12 +24,12 @@ CDDL HEADER END - ident "%Z%%M% %I% %E% SMI" - NOTE: This service manifest is not editable; its contents will be overwritten by package or patch operations, including operating system upgrade. Make customizations in a different file. + + Copyright 2018 OmniOS Community Edition (OmniOSce) Association. --> <service_bundle type='manifest' name='SUNWcsr:boot-archive'> @@ -71,6 +71,10 @@ <propval name='duration' type='astring' value='transient' /> </property_group> + <property_group name='config' type='application'> + <propval name='format' type='astring' value='cpio' /> + </property_group> + <stability value='Unstable' /> <template> diff --git a/usr/src/man/man1m/bootadm.1m b/usr/src/man/man1m/bootadm.1m index 5276786d82..608807a7fe 100644 --- a/usr/src/man/man1m/bootadm.1m +++ b/usr/src/man/man1m/bootadm.1m @@ -4,13 +4,15 @@ .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] .\" Copyright 2016 Toomas Soome <tsoome@me.com> -.TH BOOTADM 1M "Aug 18, 2016" +.\" Copyright 2018 OmniOS Community Edition (OmniOSce) Association. +.TH BOOTADM 1M "Jul 05, 2018" .SH NAME bootadm \- manage bootability of the operating system .SH SYNOPSIS .LP .nf -\fB/sbin/bootadm\fR update-archive [\fB-vn\fR] [\fB-R\fR \fIaltroot\fR [\fB-p\fR \fIplatform\fR]] +\fB/sbin/bootadm\fR update-archive [\fB-vnf\fR] [\fB-R\fR \fIaltroot\fR [\fB-p\fR \fIplatform\fR]] + [\fB-F \fIformat\fR] .fi .LP @@ -87,7 +89,68 @@ The \fBbootadm\fR command has the following subcommands: .sp .6 .RS 4n Updates current boot archive if required. Applies to both SPARC and x86 -platforms. +platforms. The boot archive can be created in a number of different formats; +the default format is an IEEE/P1003 Data Interchange Standard cpio archive. +The format is configured through the following service management facility +(\fBsmf\fR(5)) property: +.sp +.in +2 +.nf +svc:/system/boot-archive:default/config/format +.fi +.in -2 + +.sp +.LP +This property takes one of the following values: +.RS 8n + +.sp +.ne 2 +.na +\fBcpio\fR +.ad +.sp .6 +.RS 4n +IEEE/P1003 Data Interchange Standard cpio archive (default). +.RE + +.sp +.ne 2 +.na +\fBhsfs\fR +.ad +.sp .6 +.RS 4n +ISO 9660 filesystem image (only supported if \fI/usr/bin/mkisofs\fR is +available). +.RE + +.sp +.ne 2 +.na +\fBufs\fR +.ad +.sp .6 +.RS 4n +UFS filesystem in which the files within are compressed using gzip if +\fI/usr/bin/gzip\fR is available. +.RE + +.sp +.ne 2 +.na +\fBufs-nocompress\fR +.ad +.sp .6 +.RS 4n +UFS filesystem. The files within are not compressed but the resulting overall +boot archive will still be compressed if \fI/usr/bin/gzip\fR is available. +.RE +.RE + +See \fBEXAMPLES\fR for how to change this value. + .RE .sp @@ -163,6 +226,7 @@ title of each entry. Applies to x86 platforms only. .SH OPTIONS .LP The \fBbootadm\fR command has the following options: + .sp .ne 2 .na @@ -170,6 +234,9 @@ The \fBbootadm\fR command has the following options: .ad .sp .6 .RS 4n +In an \fBupdate-archive\fR operation, force re-generation of the boot-archive +even if no files have changed. + In an \fBinstall-bootloader\fR operation, override the boot loader versioning constraints. .RE @@ -177,6 +244,18 @@ constraints. .sp .ne 2 .na +\fB-F \fIformat\fR\fR +.ad +.sp .6 +.RS 4n +In an \fBupdate-archive\fR operation, select the desired archive format. The +format can be any of the values shown above for the +svc:/system/boot-archive:default/config/format property. +.RE + +.sp +.ne 2 +.na \fB\fB-n\fR\fR .ad .sp .6 @@ -367,7 +446,22 @@ user selects test-183 (item 1). .in -2 .LP -\fBExample 5 \fRDetailed information about menu entry. +\fBExample 5 \fRChanging archive format +.sp +.LP +The following command changes the boot archive format to \fIufs\fR + +.sp +.in +2 +.nf +# svccfg -s system/boot-archive:default setprop config/format = ufs +# svcadm refresh system/boot-archive:default +# bootadm update-archive -f +.fi +.in -2 + +.LP +\fBExample 6 \fRDetailed information about menu entry. .sp .LP The following command lists more detailed information about a boot menu entry: diff --git a/usr/src/man/man3head/Makefile b/usr/src/man/man3head/Makefile index e212c67457..0e1c2efb17 100644 --- a/usr/src/man/man3head/Makefile +++ b/usr/src/man/man3head/Makefile @@ -61,7 +61,6 @@ MANFILES= acct.h.3head \ poll.h.3head \ pthread.h.3head \ pwd.h.3head \ - queue.h.3head \ regex.h.3head \ resource.h.3head \ sched.h.3head \ @@ -110,97 +109,7 @@ MANFILES= acct.h.3head \ wordexp.h.3head \ xlocale.h.3head -MANLINKS= \ - LIST_CLASS_ENTRY.3head \ - LIST_CLASS_HEAD.3head \ - LIST_CONCAT.3head \ - LIST_EMPTY.3head \ - LIST_ENTRY.3head \ - LIST_FIRST.3head \ - LIST_FOREACH.3head \ - LIST_FOREACH_FROM.3head \ - LIST_FOREACH_FROM_SAFE.3head \ - LIST_FOREACH_SAFE.3head \ - LIST_HEAD.3head \ - LIST_HEAD_INITIALIZER.3head \ - LIST_INIT.3head \ - LIST_INSERT_AFTER.3head \ - LIST_INSERT_BEFORE.3head \ - LIST_INSERT_HEAD.3head \ - LIST_NEXT.3head \ - LIST_PREV.3head \ - LIST_REMOVE.3head \ - LIST_SWAP.3head \ - SLIST_CLASS_ENTRY.3head \ - SLIST_CLASS_HEAD.3head \ - SLIST_CONCAT.3head \ - SLIST_EMPTY.3head \ - SLIST_ENTRY.3head \ - SLIST_FIRST.3head \ - SLIST_FOREACH.3head \ - SLIST_FOREACH_FROM.3head \ - SLIST_FOREACH_FROM_SAFE.3head \ - SLIST_FOREACH_SAFE.3head \ - SLIST_HEAD.3head \ - SLIST_HEAD_INITIALIZER.3head \ - SLIST_INIT.3head \ - SLIST_INSERT_AFTER.3head \ - SLIST_INSERT_HEAD.3head \ - SLIST_NEXT.3head \ - SLIST_REMOVE.3head \ - SLIST_REMOVE_AFTER.3head \ - SLIST_REMOVE_HEAD.3head \ - SLIST_SWAP.3head \ - STAILQ_CLASS_ENTRY.3head \ - STAILQ_CLASS_HEAD.3head \ - STAILQ_CONCAT.3head \ - STAILQ_EMPTY.3head \ - STAILQ_ENTRY.3head \ - STAILQ_FIRST.3head \ - STAILQ_FOREACH.3head \ - STAILQ_FOREACH_FROM.3head \ - STAILQ_FOREACH_FROM_SAFE.3head \ - STAILQ_FOREACH_SAFE.3head \ - STAILQ_HEAD.3head \ - STAILQ_HEAD_INITIALIZER.3head \ - STAILQ_INIT.3head \ - STAILQ_INSERT_AFTER.3head \ - STAILQ_INSERT_HEAD.3head \ - STAILQ_INSERT_TAIL.3head \ - STAILQ_LAST.3head \ - STAILQ_NEXT.3head \ - STAILQ_REMOVE.3head \ - STAILQ_REMOVE_AFTER.3head \ - STAILQ_REMOVE_HEAD.3head \ - STAILQ_SWAP.3head \ - TAILQ_CLASS_ENTRY.3head \ - TAILQ_CLASS_HEAD.3head \ - TAILQ_CONCAT.3head \ - TAILQ_EMPTY.3head \ - TAILQ_ENTRY.3head \ - TAILQ_FIRST.3head \ - TAILQ_FOREACH.3head \ - TAILQ_FOREACH_FROM.3head \ - TAILQ_FOREACH_FROM_SAFE.3head \ - TAILQ_FOREACH_REVERSE.3head \ - TAILQ_FOREACH_REVERSE_FROM.3head \ - TAILQ_FOREACH_REVERSE_FROM_SAFE.3head \ - TAILQ_FOREACH_REVERSE_SAFE.3head \ - TAILQ_FOREACH_SAFE.3head \ - TAILQ_HEAD.3head \ - TAILQ_HEAD_INITIALIZER.3head \ - TAILQ_INIT.3head \ - TAILQ_INSERT_AFTER.3head \ - TAILQ_INSERT_BEFORE.3head \ - TAILQ_INSERT_HEAD.3head \ - TAILQ_INSERT_TAIL.3head \ - TAILQ_LAST.3head \ - TAILQ_NEXT.3head \ - TAILQ_PREV.3head \ - TAILQ_REMOVE.3head \ - TAILQ_SWAP.3head - -MANLINKS += acct.3head \ +MANLINKS= acct.3head \ aio.3head \ ar.3head \ archives.3head \ @@ -289,95 +198,6 @@ MANLINKS += acct.3head \ wordexp.3head \ xlocale.3head -LIST_CLASS_ENTRY.3head := LINKSRC = queue.h.3head -LIST_CLASS_HEAD.3head := LINKSRC = queue.h.3head -LIST_CONCAT.3head := LINKSRC = queue.h.3head -LIST_EMPTY.3head := LINKSRC = queue.h.3head -LIST_ENTRY.3head := LINKSRC = queue.h.3head -LIST_FIRST.3head := LINKSRC = queue.h.3head -LIST_FOREACH.3head := LINKSRC = queue.h.3head -LIST_FOREACH_FROM.3head := LINKSRC = queue.h.3head -LIST_FOREACH_FROM_SAFE.3head := LINKSRC = queue.h.3head -LIST_FOREACH_SAFE.3head := LINKSRC = queue.h.3head -LIST_HEAD.3head := LINKSRC = queue.h.3head -LIST_HEAD_INITIALIZER.3head := LINKSRC = queue.h.3head -LIST_INIT.3head := LINKSRC = queue.h.3head -LIST_INSERT_AFTER.3head := LINKSRC = queue.h.3head -LIST_INSERT_BEFORE.3head := LINKSRC = queue.h.3head -LIST_INSERT_HEAD.3head := LINKSRC = queue.h.3head -LIST_NEXT.3head := LINKSRC = queue.h.3head -LIST_PREV.3head := LINKSRC = queue.h.3head -LIST_REMOVE.3head := LINKSRC = queue.h.3head -LIST_SWAP.3head := LINKSRC = queue.h.3head -SLIST_CLASS_ENTRY.3head := LINKSRC = queue.h.3head -SLIST_CLASS_HEAD.3head := LINKSRC = queue.h.3head -SLIST_CONCAT.3head := LINKSRC = queue.h.3head -SLIST_EMPTY.3head := LINKSRC = queue.h.3head -SLIST_ENTRY.3head := LINKSRC = queue.h.3head -SLIST_FIRST.3head := LINKSRC = queue.h.3head -SLIST_FOREACH.3head := LINKSRC = queue.h.3head -SLIST_FOREACH_FROM.3head := LINKSRC = queue.h.3head -SLIST_FOREACH_FROM_SAFE.3head := LINKSRC = queue.h.3head -SLIST_FOREACH_SAFE.3head := LINKSRC = queue.h.3head -SLIST_HEAD.3head := LINKSRC = queue.h.3head -SLIST_HEAD_INITIALIZER.3head := LINKSRC = queue.h.3head -SLIST_INIT.3head := LINKSRC = queue.h.3head -SLIST_INSERT_AFTER.3head := LINKSRC = queue.h.3head -SLIST_INSERT_HEAD.3head := LINKSRC = queue.h.3head -SLIST_NEXT.3head := LINKSRC = queue.h.3head -SLIST_REMOVE.3head := LINKSRC = queue.h.3head -SLIST_REMOVE_AFTER.3head := LINKSRC = queue.h.3head -SLIST_REMOVE_HEAD.3head := LINKSRC = queue.h.3head -SLIST_SWAP.3head := LINKSRC = queue.h.3head -STAILQ_CLASS_ENTRY.3head := LINKSRC = queue.h.3head -STAILQ_CLASS_HEAD.3head := LINKSRC = queue.h.3head -STAILQ_CONCAT.3head := LINKSRC = queue.h.3head -STAILQ_EMPTY.3head := LINKSRC = queue.h.3head -STAILQ_ENTRY.3head := LINKSRC = queue.h.3head -STAILQ_FIRST.3head := LINKSRC = queue.h.3head -STAILQ_FOREACH.3head := LINKSRC = queue.h.3head -STAILQ_FOREACH_FROM.3head := LINKSRC = queue.h.3head -STAILQ_FOREACH_FROM_SAFE.3head := LINKSRC = queue.h.3head -STAILQ_FOREACH_SAFE.3head := LINKSRC = queue.h.3head -STAILQ_HEAD.3head := LINKSRC = queue.h.3head -STAILQ_HEAD_INITIALIZER.3head := LINKSRC = queue.h.3head -STAILQ_INIT.3head := LINKSRC = queue.h.3head -STAILQ_INSERT_AFTER.3head := LINKSRC = queue.h.3head -STAILQ_INSERT_HEAD.3head := LINKSRC = queue.h.3head -STAILQ_INSERT_TAIL.3head := LINKSRC = queue.h.3head -STAILQ_LAST.3head := LINKSRC = queue.h.3head -STAILQ_NEXT.3head := LINKSRC = queue.h.3head -STAILQ_REMOVE.3head := LINKSRC = queue.h.3head -STAILQ_REMOVE_AFTER.3head := LINKSRC = queue.h.3head -STAILQ_REMOVE_HEAD.3head := LINKSRC = queue.h.3head -STAILQ_SWAP.3head := LINKSRC = queue.h.3head -TAILQ_CLASS_ENTRY.3head := LINKSRC = queue.h.3head -TAILQ_CLASS_HEAD.3head := LINKSRC = queue.h.3head -TAILQ_CONCAT.3head := LINKSRC = queue.h.3head -TAILQ_EMPTY.3head := LINKSRC = queue.h.3head -TAILQ_ENTRY.3head := LINKSRC = queue.h.3head -TAILQ_FIRST.3head := LINKSRC = queue.h.3head -TAILQ_FOREACH.3head := LINKSRC = queue.h.3head -TAILQ_FOREACH_FROM.3head := LINKSRC = queue.h.3head -TAILQ_FOREACH_FROM_SAFE.3head := LINKSRC = queue.h.3head -TAILQ_FOREACH_REVERSE.3head := LINKSRC = queue.h.3head -TAILQ_FOREACH_REVERSE_FROM.3head := LINKSRC = queue.h.3head -TAILQ_FOREACH_REVERSE_FROM_SAFE.3head := LINKSRC = queue.h.3head -TAILQ_FOREACH_REVERSE_SAFE.3head := LINKSRC = queue.h.3head -TAILQ_FOREACH_SAFE.3head := LINKSRC = queue.h.3head -TAILQ_HEAD.3head := LINKSRC = queue.h.3head -TAILQ_HEAD_INITIALIZER.3head := LINKSRC = queue.h.3head -TAILQ_INIT.3head := LINKSRC = queue.h.3head -TAILQ_INSERT_AFTER.3head := LINKSRC = queue.h.3head -TAILQ_INSERT_BEFORE.3head := LINKSRC = queue.h.3head -TAILQ_INSERT_HEAD.3head := LINKSRC = queue.h.3head -TAILQ_INSERT_TAIL.3head := LINKSRC = queue.h.3head -TAILQ_LAST.3head := LINKSRC = queue.h.3head -TAILQ_NEXT.3head := LINKSRC = queue.h.3head -TAILQ_PREV.3head := LINKSRC = queue.h.3head -TAILQ_REMOVE.3head := LINKSRC = queue.h.3head -TAILQ_SWAP.3head := LINKSRC = queue.h.3head - acct.3head := LINKSRC = acct.h.3head aio.3head := LINKSRC = aio.h.3head ar.3head := LINKSRC = ar.h.3head diff --git a/usr/src/man/man3head/queue.h.3head b/usr/src/man/man3head/queue.h.3head deleted file mode 100644 index b55170ea5b..0000000000 --- a/usr/src/man/man3head/queue.h.3head +++ /dev/null @@ -1,1315 +0,0 @@ -.\" Copyright (c) 1993 -.\" The Regents of the University of California. 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. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. -.\" -.\" @(#)queue.3 8.2 (Berkeley) 1/24/94 -.\" -.Dd August 6, 2018 -.Dt QUEUE.H 3HEAD -.Os -.Sh NAME -.Nm SLIST_CLASS_ENTRY , -.Nm SLIST_CLASS_HEAD , -.Nm SLIST_CONCAT , -.Nm SLIST_EMPTY , -.Nm SLIST_ENTRY , -.Nm SLIST_FIRST , -.Nm SLIST_FOREACH , -.Nm SLIST_FOREACH_FROM , -.Nm SLIST_FOREACH_FROM_SAFE , -.Nm SLIST_FOREACH_SAFE , -.Nm SLIST_HEAD , -.Nm SLIST_HEAD_INITIALIZER , -.Nm SLIST_INIT , -.Nm SLIST_INSERT_AFTER , -.Nm SLIST_INSERT_HEAD , -.Nm SLIST_NEXT , -.Nm SLIST_REMOVE , -.Nm SLIST_REMOVE_AFTER , -.Nm SLIST_REMOVE_HEAD , -.Nm SLIST_SWAP , -.Nm STAILQ_CLASS_ENTRY , -.Nm STAILQ_CLASS_HEAD , -.Nm STAILQ_CONCAT , -.Nm STAILQ_EMPTY , -.Nm STAILQ_ENTRY , -.Nm STAILQ_FIRST , -.Nm STAILQ_FOREACH , -.Nm STAILQ_FOREACH_FROM , -.Nm STAILQ_FOREACH_FROM_SAFE , -.Nm STAILQ_FOREACH_SAFE , -.Nm STAILQ_HEAD , -.Nm STAILQ_HEAD_INITIALIZER , -.Nm STAILQ_INIT , -.Nm STAILQ_INSERT_AFTER , -.Nm STAILQ_INSERT_HEAD , -.Nm STAILQ_INSERT_TAIL , -.Nm STAILQ_LAST , -.Nm STAILQ_NEXT , -.Nm STAILQ_REMOVE , -.Nm STAILQ_REMOVE_AFTER , -.Nm STAILQ_REMOVE_HEAD , -.Nm STAILQ_SWAP , -.Nm LIST_CLASS_ENTRY , -.Nm LIST_CLASS_HEAD , -.Nm LIST_CONCAT , -.Nm LIST_EMPTY , -.Nm LIST_ENTRY , -.Nm LIST_FIRST , -.Nm LIST_FOREACH , -.Nm LIST_FOREACH_FROM , -.Nm LIST_FOREACH_FROM_SAFE , -.Nm LIST_FOREACH_SAFE , -.Nm LIST_HEAD , -.Nm LIST_HEAD_INITIALIZER , -.Nm LIST_INIT , -.Nm LIST_INSERT_AFTER , -.Nm LIST_INSERT_BEFORE , -.Nm LIST_INSERT_HEAD , -.Nm LIST_NEXT , -.Nm LIST_PREV , -.Nm LIST_REMOVE , -.Nm LIST_SWAP , -.Nm TAILQ_CLASS_ENTRY , -.Nm TAILQ_CLASS_HEAD , -.Nm TAILQ_CONCAT , -.Nm TAILQ_EMPTY , -.Nm TAILQ_ENTRY , -.Nm TAILQ_FIRST , -.Nm TAILQ_FOREACH , -.Nm TAILQ_FOREACH_FROM , -.Nm TAILQ_FOREACH_FROM_SAFE , -.Nm TAILQ_FOREACH_REVERSE , -.Nm TAILQ_FOREACH_REVERSE_FROM , -.Nm TAILQ_FOREACH_REVERSE_FROM_SAFE , -.Nm TAILQ_FOREACH_REVERSE_SAFE , -.Nm TAILQ_FOREACH_SAFE , -.Nm TAILQ_HEAD , -.Nm TAILQ_HEAD_INITIALIZER , -.Nm TAILQ_INIT , -.Nm TAILQ_INSERT_AFTER , -.Nm TAILQ_INSERT_BEFORE , -.Nm TAILQ_INSERT_HEAD , -.Nm TAILQ_INSERT_TAIL , -.Nm TAILQ_LAST , -.Nm TAILQ_NEXT , -.Nm TAILQ_PREV , -.Nm TAILQ_REMOVE , -.Nm TAILQ_SWAP -.Nd implementations of singly-linked lists, singly-linked tail queues, -lists and tail queues -.Sh SYNOPSIS -.In sys/queue.h -.\" -.Fn SLIST_CLASS_ENTRY "CLASSTYPE" -.Fn SLIST_CLASS_HEAD "HEADNAME" "CLASSTYPE" -.Fn SLIST_CONCAT "SLIST_HEAD *head1" "SLIST_HEAD *head2" "TYPE" "SLIST_ENTRY NAME" -.Fn SLIST_EMPTY "SLIST_HEAD *head" -.Fn SLIST_ENTRY "TYPE" -.Fn SLIST_FIRST "SLIST_HEAD *head" -.Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" -.Fn SLIST_FOREACH_FROM "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" -.Fn SLIST_FOREACH_FROM_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var" -.Fn SLIST_FOREACH_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var" -.Fn SLIST_HEAD "HEADNAME" "TYPE" -.Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head" -.Fn SLIST_INIT "SLIST_HEAD *head" -.Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME" -.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME" -.Fn SLIST_NEXT "TYPE *elm" "SLIST_ENTRY NAME" -.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME" -.Fn SLIST_REMOVE_AFTER "TYPE *elm" "SLIST_ENTRY NAME" -.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME" -.Fn SLIST_SWAP "SLIST_HEAD *head1" "SLIST_HEAD *head2" "TYPE" -.\" -.Fn STAILQ_CLASS_ENTRY "CLASSTYPE" -.Fn STAILQ_CLASS_HEAD "HEADNAME" "CLASSTYPE" -.Fn STAILQ_CONCAT "STAILQ_HEAD *head1" "STAILQ_HEAD *head2" -.Fn STAILQ_EMPTY "STAILQ_HEAD *head" -.Fn STAILQ_ENTRY "TYPE" -.Fn STAILQ_FIRST "STAILQ_HEAD *head" -.Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" -.Fn STAILQ_FOREACH_FROM "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" -.Fn STAILQ_FOREACH_FROM_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var" -.Fn STAILQ_FOREACH_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var" -.Fn STAILQ_HEAD "HEADNAME" "TYPE" -.Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head" -.Fn STAILQ_INIT "STAILQ_HEAD *head" -.Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME" -.Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" -.Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" -.Fn STAILQ_LAST "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" -.Fn STAILQ_NEXT "TYPE *elm" "STAILQ_ENTRY NAME" -.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME" -.Fn STAILQ_REMOVE_AFTER "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" -.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" -.Fn STAILQ_SWAP "STAILQ_HEAD *head1" "STAILQ_HEAD *head2" "TYPE" -.\" -.Fn LIST_CLASS_ENTRY "CLASSTYPE" -.Fn LIST_CLASS_HEAD "HEADNAME" "CLASSTYPE" -.Fn LIST_CONCAT "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME" -.Fn LIST_EMPTY "LIST_HEAD *head" -.Fn LIST_ENTRY "TYPE" -.Fn LIST_FIRST "LIST_HEAD *head" -.Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" -.Fn LIST_FOREACH_FROM "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" -.Fn LIST_FOREACH_FROM_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var" -.Fn LIST_FOREACH_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var" -.Fn LIST_HEAD "HEADNAME" "TYPE" -.Fn LIST_HEAD_INITIALIZER "LIST_HEAD head" -.Fn LIST_INIT "LIST_HEAD *head" -.Fn LIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME" -.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME" -.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME" -.Fn LIST_NEXT "TYPE *elm" "LIST_ENTRY NAME" -.Fn LIST_PREV "TYPE *elm" "LIST_HEAD *head" "TYPE" "LIST_ENTRY NAME" -.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME" -.Fn LIST_SWAP "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME" -.\" -.Fn TAILQ_CLASS_ENTRY "CLASSTYPE" -.Fn TAILQ_CLASS_HEAD "HEADNAME" "CLASSTYPE" -.Fn TAILQ_CONCAT "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TAILQ_ENTRY NAME" -.Fn TAILQ_EMPTY "TAILQ_HEAD *head" -.Fn TAILQ_ENTRY "TYPE" -.Fn TAILQ_FIRST "TAILQ_HEAD *head" -.Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" -.Fn TAILQ_FOREACH_FROM "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" -.Fn TAILQ_FOREACH_FROM_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var" -.Fn TAILQ_FOREACH_REVERSE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" -.Fn TAILQ_FOREACH_REVERSE_FROM "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" -.Fn TAILQ_FOREACH_REVERSE_FROM_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var" -.Fn TAILQ_FOREACH_REVERSE_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var" -.Fn TAILQ_FOREACH_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var" -.Fn TAILQ_HEAD "HEADNAME" "TYPE" -.Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head" -.Fn TAILQ_INIT "TAILQ_HEAD *head" -.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME" -.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME" -.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" -.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" -.Fn TAILQ_LAST "TAILQ_HEAD *head" "HEADNAME" -.Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME" -.Fn TAILQ_PREV "TYPE *elm" "HEADNAME" "TAILQ_ENTRY NAME" -.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" -.Fn TAILQ_SWAP "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TYPE" "TAILQ_ENTRY NAME" -.\" -.Sh DESCRIPTION -These macros define and operate on four types of data structures which -can be used in both C and C++ source code: -.Bl -enum -compact -offset indent -.It -Lists -.It -Singly-linked lists -.It -Singly-linked tail queues -.It -Tail queues -.El -All four structures support the following functionality: -.Bl -enum -compact -offset indent -.It -Insertion of a new entry at the head of the list. -.It -Insertion of a new entry after any element in the list. -.It -O(1) removal of an entry from the head of the list. -.It -Forward traversal through the list. -.It -Swapping the contents of two lists. -.El -.Pp -Singly-linked lists are the simplest of the four data structures -and support only the above functionality. -Singly-linked lists are ideal for applications with large datasets -and few or no removals, -or for implementing a LIFO queue. -Singly-linked lists add the following functionality: -.Bl -enum -compact -offset indent -.It -O(n) removal of any entry in the list. -.It -O(n) concatenation of two lists. -.El -.Pp -Singly-linked tail queues add the following functionality: -.Bl -enum -compact -offset indent -.It -Entries can be added at the end of a list. -.It -O(n) removal of any entry in the list. -.It -They may be concatenated. -.El -However: -.Bl -enum -compact -offset indent -.It -All list insertions must specify the head of the list. -.It -Each head entry requires two pointers rather than one. -.It -Code size is about 15% greater and operations run about 20% slower -than singly-linked lists. -.El -.Pp -Singly-linked tail queues are ideal for applications with large datasets and -few or no removals, -or for implementing a FIFO queue. -.Pp -All doubly linked types of data structures (lists and tail queues) -additionally allow: -.Bl -enum -compact -offset indent -.It -Insertion of a new entry before any element in the list. -.It -O(1) removal of any entry in the list. -.El -However: -.Bl -enum -compact -offset indent -.It -Each element requires two pointers rather than one. -.It -Code size and execution time of operations (except for removal) is about -twice that of the singly-linked data-structures. -.El -.Pp -Linked lists are the simplest of the doubly linked data structures. -They add the following functionality over the above: -.Bl -enum -compact -offset indent -.It -O(n) concatenation of two lists. -.It -They may be traversed backwards. -.El -However: -.Bl -enum -compact -offset indent -.It -To traverse backwards, an entry to begin the traversal and the list in -which it is contained must be specified. -.El -.Pp -Tail queues add the following functionality: -.Bl -enum -compact -offset indent -.It -Entries can be added at the end of a list. -.It -They may be traversed backwards, from tail to head. -.It -They may be concatenated. -.El -However: -.Bl -enum -compact -offset indent -.It -All list insertions and removals must specify the head of the list. -.It -Each head entry requires two pointers rather than one. -.It -Code size is about 15% greater and operations run about 20% slower -than singly-linked lists. -.El -.Pp -In the macro definitions, -.Fa TYPE -is the name of a user defined structure. -The structure must contain a field called -.Fa NAME -which is of type -.Li SLIST_ENTRY , -.Li STAILQ_ENTRY , -.Li LIST_ENTRY , -or -.Li TAILQ_ENTRY . -In the macro definitions, -.Fa CLASSTYPE -is the name of a user defined class. -The class must contain a field called -.Fa NAME -which is of type -.Li SLIST_CLASS_ENTRY , -.Li STAILQ_CLASS_ENTRY , -.Li LIST_CLASS_ENTRY , -or -.Li TAILQ_CLASS_ENTRY . -The argument -.Fa HEADNAME -is the name of a user defined structure that must be declared -using the macros -.Li SLIST_HEAD , -.Li SLIST_CLASS_HEAD , -.Li STAILQ_HEAD , -.Li STAILQ_CLASS_HEAD , -.Li LIST_HEAD , -.Li LIST_CLASS_HEAD , -.Li TAILQ_HEAD , -or -.Li TAILQ_CLASS_HEAD . -See the examples below for further explanation of how these -macros are used. -.Sh SINGLY-LINKED LISTS -A singly-linked list is headed by a structure defined by the -.Nm SLIST_HEAD -macro. -This structure contains a single pointer to the first element -on the list. -The elements are singly linked for minimum space and pointer manipulation -overhead at the expense of O(n) removal for arbitrary elements. -New elements can be added to the list after an existing element or -at the head of the list. -An -.Fa SLIST_HEAD -structure is declared as follows: -.Bd -literal -offset indent -SLIST_HEAD(HEADNAME, TYPE) head; -.Ed -.Pp -where -.Fa HEADNAME -is the name of the structure to be defined, and -.Fa TYPE -is the type of the elements to be linked into the list. -A pointer to the head of the list can later be declared as: -.Bd -literal -offset indent -struct HEADNAME *headp; -.Ed -.Pp -(The names -.Li head -and -.Li headp -are user selectable.) -.Pp -The macro -.Nm SLIST_HEAD_INITIALIZER -evaluates to an initializer for the list -.Fa head . -.Pp -The macro -.Nm SLIST_CONCAT -concatenates the list headed by -.Fa head2 -onto the end of the one headed by -.Fa head1 -removing all entries from the former. -Use of this macro should be avoided as it traverses the entirety of the -.Fa head1 -list. -A singly-linked tail queue should be used if this macro is needed in -high-usage code paths or to operate on long lists. -.Pp -The macro -.Nm SLIST_EMPTY -evaluates to true if there are no elements in the list. -.Pp -The macro -.Nm SLIST_ENTRY -declares a structure that connects the elements in -the list. -.Pp -The macro -.Nm SLIST_FIRST -returns the first element in the list or NULL if the list is empty. -.Pp -The macro -.Nm SLIST_FOREACH -traverses the list referenced by -.Fa head -in the forward direction, assigning each element in -turn to -.Fa var . -.Pp -The macro -.Nm SLIST_FOREACH_FROM -behaves identically to -.Nm SLIST_FOREACH -when -.Fa var -is NULL, else it treats -.Fa var -as a previously found SLIST element and begins the loop at -.Fa var -instead of the first element in the SLIST referenced by -.Fa head . -.Pp -The macro -.Nm SLIST_FOREACH_SAFE -traverses the list referenced by -.Fa head -in the forward direction, assigning each element in -turn to -.Fa var . -However, unlike -.Fn SLIST_FOREACH -here it is permitted to both remove -.Fa var -as well as free it from within the loop safely without interfering with the -traversal. -.Pp -The macro -.Nm SLIST_FOREACH_FROM_SAFE -behaves identically to -.Nm SLIST_FOREACH_SAFE -when -.Fa var -is NULL, else it treats -.Fa var -as a previously found SLIST element and begins the loop at -.Fa var -instead of the first element in the SLIST referenced by -.Fa head . -.Pp -The macro -.Nm SLIST_INIT -initializes the list referenced by -.Fa head . -.Pp -The macro -.Nm SLIST_INSERT_HEAD -inserts the new element -.Fa elm -at the head of the list. -.Pp -The macro -.Nm SLIST_INSERT_AFTER -inserts the new element -.Fa elm -after the element -.Fa listelm . -.Pp -The macro -.Nm SLIST_NEXT -returns the next element in the list. -.Pp -The macro -.Nm SLIST_REMOVE_AFTER -removes the element after -.Fa elm -from the list. -Unlike -.Fa SLIST_REMOVE , -this macro does not traverse the entire list. -.Pp -The macro -.Nm SLIST_REMOVE_HEAD -removes the element -.Fa elm -from the head of the list. -For optimum efficiency, -elements being removed from the head of the list should explicitly use -this macro instead of the generic -.Fa SLIST_REMOVE -macro. -.Pp -The macro -.Nm SLIST_REMOVE -removes the element -.Fa elm -from the list. -Use of this macro should be avoided as it traverses the entire list. -A doubly-linked list should be used if this macro is needed in -high-usage code paths or to operate on long lists. -.Pp -The macro -.Nm SLIST_SWAP -swaps the contents of -.Fa head1 -and -.Fa head2 . -.Sh SINGLY-LINKED TAIL QUEUES -A singly-linked tail queue is headed by a structure defined by the -.Nm STAILQ_HEAD -macro. -This structure contains a pair of pointers, -one to the first element in the tail queue and the other to -the last element in the tail queue. -The elements are singly linked for minimum space and pointer -manipulation overhead at the expense of O(n) removal for arbitrary -elements. -New elements can be added to the tail queue after an existing element, -at the head of the tail queue, or at the end of the tail queue. -A -.Fa STAILQ_HEAD -structure is declared as follows: -.Bd -literal -offset indent -STAILQ_HEAD(HEADNAME, TYPE) head; -.Ed -.Pp -where -.Li HEADNAME -is the name of the structure to be defined, and -.Li TYPE -is the type of the elements to be linked into the tail queue. -A pointer to the head of the tail queue can later be declared as: -.Bd -literal -offset indent -struct HEADNAME *headp; -.Ed -.Pp -(The names -.Li head -and -.Li headp -are user selectable.) -.Pp -The macro -.Nm STAILQ_HEAD_INITIALIZER -evaluates to an initializer for the tail queue -.Fa head . -.Pp -The macro -.Nm STAILQ_CONCAT -concatenates the tail queue headed by -.Fa head2 -onto the end of the one headed by -.Fa head1 -removing all entries from the former. -.Pp -The macro -.Nm STAILQ_EMPTY -evaluates to true if there are no items on the tail queue. -.Pp -The macro -.Nm STAILQ_ENTRY -declares a structure that connects the elements in -the tail queue. -.Pp -The macro -.Nm STAILQ_FIRST -returns the first item on the tail queue or NULL if the tail queue -is empty. -.Pp -The macro -.Nm STAILQ_FOREACH -traverses the tail queue referenced by -.Fa head -in the forward direction, assigning each element -in turn to -.Fa var . -.Pp -The macro -.Nm STAILQ_FOREACH_FROM -behaves identically to -.Nm STAILQ_FOREACH -when -.Fa var -is NULL, else it treats -.Fa var -as a previously found STAILQ element and begins the loop at -.Fa var -instead of the first element in the STAILQ referenced by -.Fa head . -.Pp -The macro -.Nm STAILQ_FOREACH_SAFE -traverses the tail queue referenced by -.Fa head -in the forward direction, assigning each element -in turn to -.Fa var . -However, unlike -.Fn STAILQ_FOREACH -here it is permitted to both remove -.Fa var -as well as free it from within the loop safely without interfering with the -traversal. -.Pp -The macro -.Nm STAILQ_FOREACH_FROM_SAFE -behaves identically to -.Nm STAILQ_FOREACH_SAFE -when -.Fa var -is NULL, else it treats -.Fa var -as a previously found STAILQ element and begins the loop at -.Fa var -instead of the first element in the STAILQ referenced by -.Fa head . -.Pp -The macro -.Nm STAILQ_INIT -initializes the tail queue referenced by -.Fa head . -.Pp -The macro -.Nm STAILQ_INSERT_HEAD -inserts the new element -.Fa elm -at the head of the tail queue. -.Pp -The macro -.Nm STAILQ_INSERT_TAIL -inserts the new element -.Fa elm -at the end of the tail queue. -.Pp -The macro -.Nm STAILQ_INSERT_AFTER -inserts the new element -.Fa elm -after the element -.Fa listelm . -.Pp -The macro -.Nm STAILQ_LAST -returns the last item on the tail queue. -If the tail queue is empty the return value is -.Dv NULL . -.Pp -The macro -.Nm STAILQ_NEXT -returns the next item on the tail queue, or NULL this item is the last. -.Pp -The macro -.Nm STAILQ_REMOVE_AFTER -removes the element after -.Fa elm -from the tail queue. -Unlike -.Fa STAILQ_REMOVE , -this macro does not traverse the entire tail queue. -.Pp -The macro -.Nm STAILQ_REMOVE_HEAD -removes the element at the head of the tail queue. -For optimum efficiency, -elements being removed from the head of the tail queue should -use this macro explicitly rather than the generic -.Fa STAILQ_REMOVE -macro. -.Pp -The macro -.Nm STAILQ_REMOVE -removes the element -.Fa elm -from the tail queue. -Use of this macro should be avoided as it traverses the entire list. -A doubly-linked tail queue should be used if this macro is needed in -high-usage code paths or to operate on long tail queues. -.Pp -The macro -.Nm STAILQ_SWAP -swaps the contents of -.Fa head1 -and -.Fa head2 . -.Sh LISTS -A list is headed by a structure defined by the -.Nm LIST_HEAD -macro. -This structure contains a single pointer to the first element -on the list. -The elements are doubly linked so that an arbitrary element can be -removed without traversing the list. -New elements can be added to the list after an existing element, -before an existing element, or at the head of the list. -A -.Fa LIST_HEAD -structure is declared as follows: -.Bd -literal -offset indent -LIST_HEAD(HEADNAME, TYPE) head; -.Ed -.Pp -where -.Fa HEADNAME -is the name of the structure to be defined, and -.Fa TYPE -is the type of the elements to be linked into the list. -A pointer to the head of the list can later be declared as: -.Bd -literal -offset indent -struct HEADNAME *headp; -.Ed -.Pp -(The names -.Li head -and -.Li headp -are user selectable.) -.Pp -The macro -.Nm LIST_HEAD_INITIALIZER -evaluates to an initializer for the list -.Fa head . -.Pp -The macro -.Nm LIST_CONCAT -concatenates the list headed by -.Fa head2 -onto the end of the one headed by -.Fa head1 -removing all entries from the former. -Use of this macro should be avoided as it traverses the entirety of the -.Fa head1 -list. -A tail queue should be used if this macro is needed in -high-usage code paths or to operate on long lists. -.Pp -The macro -.Nm LIST_EMPTY -evaluates to true if there are no elements in the list. -.Pp -The macro -.Nm LIST_ENTRY -declares a structure that connects the elements in -the list. -.Pp -The macro -.Nm LIST_FIRST -returns the first element in the list or NULL if the list -is empty. -.Pp -The macro -.Nm LIST_FOREACH -traverses the list referenced by -.Fa head -in the forward direction, assigning each element in turn to -.Fa var . -.Pp -The macro -.Nm LIST_FOREACH_FROM -behaves identically to -.Nm LIST_FOREACH -when -.Fa var -is NULL, else it treats -.Fa var -as a previously found LIST element and begins the loop at -.Fa var -instead of the first element in the LIST referenced by -.Fa head . -.Pp -The macro -.Nm LIST_FOREACH_SAFE -traverses the list referenced by -.Fa head -in the forward direction, assigning each element in turn to -.Fa var . -However, unlike -.Fn LIST_FOREACH -here it is permitted to both remove -.Fa var -as well as free it from within the loop safely without interfering with the -traversal. -.Pp -The macro -.Nm LIST_FOREACH_FROM_SAFE -behaves identically to -.Nm LIST_FOREACH_SAFE -when -.Fa var -is NULL, else it treats -.Fa var -as a previously found LIST element and begins the loop at -.Fa var -instead of the first element in the LIST referenced by -.Fa head . -.Pp -The macro -.Nm LIST_INIT -initializes the list referenced by -.Fa head . -.Pp -The macro -.Nm LIST_INSERT_HEAD -inserts the new element -.Fa elm -at the head of the list. -.Pp -The macro -.Nm LIST_INSERT_AFTER -inserts the new element -.Fa elm -after the element -.Fa listelm . -.Pp -The macro -.Nm LIST_INSERT_BEFORE -inserts the new element -.Fa elm -before the element -.Fa listelm . -.Pp -The macro -.Nm LIST_NEXT -returns the next element in the list, or NULL if this is the last. -.Pp -The macro -.Nm LIST_PREV -returns the previous element in the list, or NULL if this is the first. -List -.Fa head -must contain element -.Fa elm . -.Pp -The macro -.Nm LIST_REMOVE -removes the element -.Fa elm -from the list. -.Pp -The macro -.Nm LIST_SWAP -swaps the contents of -.Fa head1 -and -.Fa head2 . -.Sh TAIL QUEUES -A tail queue is headed by a structure defined by the -.Nm TAILQ_HEAD -macro. -This structure contains a pair of pointers, -one to the first element in the tail queue and the other to -the last element in the tail queue. -The elements are doubly linked so that an arbitrary element can be -removed without traversing the tail queue. -New elements can be added to the tail queue after an existing element, -before an existing element, at the head of the tail queue, -or at the end of the tail queue. -A -.Fa TAILQ_HEAD -structure is declared as follows: -.Bd -literal -offset indent -TAILQ_HEAD(HEADNAME, TYPE) head; -.Ed -.Pp -where -.Li HEADNAME -is the name of the structure to be defined, and -.Li TYPE -is the type of the elements to be linked into the tail queue. -A pointer to the head of the tail queue can later be declared as: -.Bd -literal -offset indent -struct HEADNAME *headp; -.Ed -.Pp -(The names -.Li head -and -.Li headp -are user selectable.) -.Pp -The macro -.Nm TAILQ_HEAD_INITIALIZER -evaluates to an initializer for the tail queue -.Fa head . -.Pp -The macro -.Nm TAILQ_CONCAT -concatenates the tail queue headed by -.Fa head2 -onto the end of the one headed by -.Fa head1 -removing all entries from the former. -.Pp -The macro -.Nm TAILQ_EMPTY -evaluates to true if there are no items on the tail queue. -.Pp -The macro -.Nm TAILQ_ENTRY -declares a structure that connects the elements in -the tail queue. -.Pp -The macro -.Nm TAILQ_FIRST -returns the first item on the tail queue or NULL if the tail queue -is empty. -.Pp -The macro -.Nm TAILQ_FOREACH -traverses the tail queue referenced by -.Fa head -in the forward direction, assigning each element in turn to -.Fa var . -.Fa var -is set to -.Dv NULL -if the loop completes normally, or if there were no elements. -.Pp -The macro -.Nm TAILQ_FOREACH_FROM -behaves identically to -.Nm TAILQ_FOREACH -when -.Fa var -is NULL, else it treats -.Fa var -as a previously found TAILQ element and begins the loop at -.Fa var -instead of the first element in the TAILQ referenced by -.Fa head . -.Pp -The macro -.Nm TAILQ_FOREACH_REVERSE -traverses the tail queue referenced by -.Fa head -in the reverse direction, assigning each element in turn to -.Fa var . -.Pp -The macro -.Nm TAILQ_FOREACH_REVERSE_FROM -behaves identically to -.Nm TAILQ_FOREACH_REVERSE -when -.Fa var -is NULL, else it treats -.Fa var -as a previously found TAILQ element and begins the reverse loop at -.Fa var -instead of the last element in the TAILQ referenced by -.Fa head . -.Pp -The macros -.Nm TAILQ_FOREACH_SAFE -and -.Nm TAILQ_FOREACH_REVERSE_SAFE -traverse the list referenced by -.Fa head -in the forward or reverse direction respectively, -assigning each element in turn to -.Fa var . -However, unlike their unsafe counterparts, -.Nm TAILQ_FOREACH -and -.Nm TAILQ_FOREACH_REVERSE -permit to both remove -.Fa var -as well as free it from within the loop safely without interfering with the -traversal. -.Pp -The macro -.Nm TAILQ_FOREACH_FROM_SAFE -behaves identically to -.Nm TAILQ_FOREACH_SAFE -when -.Fa var -is NULL, else it treats -.Fa var -as a previously found TAILQ element and begins the loop at -.Fa var -instead of the first element in the TAILQ referenced by -.Fa head . -.Pp -The macro -.Nm TAILQ_FOREACH_REVERSE_FROM_SAFE -behaves identically to -.Nm TAILQ_FOREACH_REVERSE_SAFE -when -.Fa var -is NULL, else it treats -.Fa var -as a previously found TAILQ element and begins the reverse loop at -.Fa var -instead of the last element in the TAILQ referenced by -.Fa head . -.Pp -The macro -.Nm TAILQ_INIT -initializes the tail queue referenced by -.Fa head . -.Pp -The macro -.Nm TAILQ_INSERT_HEAD -inserts the new element -.Fa elm -at the head of the tail queue. -.Pp -The macro -.Nm TAILQ_INSERT_TAIL -inserts the new element -.Fa elm -at the end of the tail queue. -.Pp -The macro -.Nm TAILQ_INSERT_AFTER -inserts the new element -.Fa elm -after the element -.Fa listelm . -.Pp -The macro -.Nm TAILQ_INSERT_BEFORE -inserts the new element -.Fa elm -before the element -.Fa listelm . -.Pp -The macro -.Nm TAILQ_LAST -returns the last item on the tail queue. -If the tail queue is empty the return value is -.Dv NULL . -.Pp -The macro -.Nm TAILQ_NEXT -returns the next item on the tail queue, or NULL if this item is the last. -.Pp -The macro -.Nm TAILQ_PREV -returns the previous item on the tail queue, or NULL if this item -is the first. -.Pp -The macro -.Nm TAILQ_REMOVE -removes the element -.Fa elm -from the tail queue. -.Pp -The macro -.Nm TAILQ_SWAP -swaps the contents of -.Fa head1 -and -.Fa head2 . -.Sh EXAMPLES -.Ss SINGLY-LINKED LIST EXAMPLE -.Bd -literal -SLIST_HEAD(slisthead, entry) head = - SLIST_HEAD_INITIALIZER(head); -struct slisthead *headp; /* Singly-linked List head. */ -struct entry { - ... - SLIST_ENTRY(entry) entries; /* Singly-linked List. */ - ... -} *n1, *n2, *n3, *np; - -SLIST_INIT(&head); /* Initialize the list. */ - -n1 = malloc(sizeof(struct entry)); /* Insert at the head. */ -SLIST_INSERT_HEAD(&head, n1, entries); - -n2 = malloc(sizeof(struct entry)); /* Insert after. */ -SLIST_INSERT_AFTER(n1, n2, entries); - -SLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */ -free(n2); - -n3 = SLIST_FIRST(&head); -SLIST_REMOVE_HEAD(&head, entries); /* Deletion from the head. */ -free(n3); - /* Forward traversal. */ -SLIST_FOREACH(np, &head, entries) - np-> ... - /* Safe forward traversal. */ -SLIST_FOREACH_SAFE(np, &head, entries, np_temp) { - np->do_stuff(); - ... - SLIST_REMOVE(&head, np, entry, entries); - free(np); -} - -while (!SLIST_EMPTY(&head)) { /* List Deletion. */ - n1 = SLIST_FIRST(&head); - SLIST_REMOVE_HEAD(&head, entries); - free(n1); -} -.Ed -.Ss SINGLY-LINKED TAIL QUEUE EXAMPLE -.Bd -literal -STAILQ_HEAD(stailhead, entry) head = - STAILQ_HEAD_INITIALIZER(head); -struct stailhead *headp; /* Singly-linked tail queue head. */ -struct entry { - ... - STAILQ_ENTRY(entry) entries; /* Tail queue. */ - ... -} *n1, *n2, *n3, *np; - -STAILQ_INIT(&head); /* Initialize the queue. */ - -n1 = malloc(sizeof(struct entry)); /* Insert at the head. */ -STAILQ_INSERT_HEAD(&head, n1, entries); - -n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ -STAILQ_INSERT_TAIL(&head, n1, entries); - -n2 = malloc(sizeof(struct entry)); /* Insert after. */ -STAILQ_INSERT_AFTER(&head, n1, n2, entries); - /* Deletion. */ -STAILQ_REMOVE(&head, n2, entry, entries); -free(n2); - /* Deletion from the head. */ -n3 = STAILQ_FIRST(&head); -STAILQ_REMOVE_HEAD(&head, entries); -free(n3); - /* Forward traversal. */ -STAILQ_FOREACH(np, &head, entries) - np-> ... - /* Safe forward traversal. */ -STAILQ_FOREACH_SAFE(np, &head, entries, np_temp) { - np->do_stuff(); - ... - STAILQ_REMOVE(&head, np, entry, entries); - free(np); -} - /* TailQ Deletion. */ -while (!STAILQ_EMPTY(&head)) { - n1 = STAILQ_FIRST(&head); - STAILQ_REMOVE_HEAD(&head, entries); - free(n1); -} - /* Faster TailQ Deletion. */ -n1 = STAILQ_FIRST(&head); -while (n1 != NULL) { - n2 = STAILQ_NEXT(n1, entries); - free(n1); - n1 = n2; -} -STAILQ_INIT(&head); -.Ed -.Ss LIST EXAMPLE -.Bd -literal -LIST_HEAD(listhead, entry) head = - LIST_HEAD_INITIALIZER(head); -struct listhead *headp; /* List head. */ -struct entry { - ... - LIST_ENTRY(entry) entries; /* List. */ - ... -} *n1, *n2, *n3, *np, *np_temp; - -LIST_INIT(&head); /* Initialize the list. */ - -n1 = malloc(sizeof(struct entry)); /* Insert at the head. */ -LIST_INSERT_HEAD(&head, n1, entries); - -n2 = malloc(sizeof(struct entry)); /* Insert after. */ -LIST_INSERT_AFTER(n1, n2, entries); - -n3 = malloc(sizeof(struct entry)); /* Insert before. */ -LIST_INSERT_BEFORE(n2, n3, entries); - -LIST_REMOVE(n2, entries); /* Deletion. */ -free(n2); - /* Forward traversal. */ -LIST_FOREACH(np, &head, entries) - np-> ... - - /* Safe forward traversal. */ -LIST_FOREACH_SAFE(np, &head, entries, np_temp) { - np->do_stuff(); - ... - LIST_REMOVE(np, entries); - free(np); -} - -while (!LIST_EMPTY(&head)) { /* List Deletion. */ - n1 = LIST_FIRST(&head); - LIST_REMOVE(n1, entries); - free(n1); -} - -n1 = LIST_FIRST(&head); /* Faster List Deletion. */ -while (n1 != NULL) { - n2 = LIST_NEXT(n1, entries); - free(n1); - n1 = n2; -} -LIST_INIT(&head); -.Ed -.Ss TAIL QUEUE EXAMPLE -.Bd -literal -TAILQ_HEAD(tailhead, entry) head = - TAILQ_HEAD_INITIALIZER(head); -struct tailhead *headp; /* Tail queue head. */ -struct entry { - ... - TAILQ_ENTRY(entry) entries; /* Tail queue. */ - ... -} *n1, *n2, *n3, *np; - -TAILQ_INIT(&head); /* Initialize the queue. */ - -n1 = malloc(sizeof(struct entry)); /* Insert at the head. */ -TAILQ_INSERT_HEAD(&head, n1, entries); - -n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ -TAILQ_INSERT_TAIL(&head, n1, entries); - -n2 = malloc(sizeof(struct entry)); /* Insert after. */ -TAILQ_INSERT_AFTER(&head, n1, n2, entries); - -n3 = malloc(sizeof(struct entry)); /* Insert before. */ -TAILQ_INSERT_BEFORE(n2, n3, entries); - -TAILQ_REMOVE(&head, n2, entries); /* Deletion. */ -free(n2); - /* Forward traversal. */ -TAILQ_FOREACH(np, &head, entries) - np-> ... - /* Safe forward traversal. */ -TAILQ_FOREACH_SAFE(np, &head, entries, np_temp) { - np->do_stuff(); - ... - TAILQ_REMOVE(&head, np, entries); - free(np); -} - /* Reverse traversal. */ -TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries) - np-> ... - /* TailQ Deletion. */ -while (!TAILQ_EMPTY(&head)) { - n1 = TAILQ_FIRST(&head); - TAILQ_REMOVE(&head, n1, entries); - free(n1); -} - /* Faster TailQ Deletion. */ -n1 = TAILQ_FIRST(&head); -while (n1 != NULL) { - n2 = TAILQ_NEXT(n1, entries); - free(n1); - n1 = n2; -} -TAILQ_INIT(&head); -.Ed -.Sh DIAGNOSTICS -When debugging -.Nm queue.h(3head) , -it can be useful to trace queue changes. -To enable tracing, define the macro -.Va QUEUE_MACRO_DEBUG_TRACE -at compile time. -.Pp -It can also be useful to trash pointers that have been unlinked from a queue, -to detect use after removal. -To enable pointer trashing, define the macro -.Va QUEUE_MACRO_DEBUG_TRASH -at compile time. -The macro -.Fn QMD_IS_TRASHED "void *ptr" -returns true if -.Fa ptr -has been trashed by the -.Va QUEUE_MACRO_DEBUG_TRASH -option. -.Sh INTERFACE STABILITY -Committed -.Sh MT-LEVEL -Unsafe -.Sh HISTORY -The -.Nm queue -functions first appeared in -.Bx 4.4 . diff --git a/usr/src/pkg/manifests/driver-storage-ahci.mf b/usr/src/pkg/manifests/driver-storage-ahci.mf index 031baffd31..e01b367360 100644 --- a/usr/src/pkg/manifests/driver-storage-ahci.mf +++ b/usr/src/pkg/manifests/driver-storage-ahci.mf @@ -21,6 +21,7 @@ # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, Joyent, Inc. # # @@ -39,11 +40,13 @@ set name=variant.arch value=i386 dir path=kernel group=sys dir path=kernel/drv group=sys dir path=kernel/drv/$(ARCH64) group=sys +dir path=usr/lib/ahci dir path=usr/share/man dir path=usr/share/man/man7d driver name=ahci alias=pciclass,010601 class=scsi-self-identifying \ perms="* 0644 root sys" file path=kernel/drv/$(ARCH64)/ahci group=sys +file path=usr/lib/ahci/ahciem mode=0555 file path=usr/share/man/man7d/ahci.7d legacy pkg=SUNWahci \ desc="Advanced Host Controller Interface (AHCI) SATA HBA Driver" \ diff --git a/usr/src/pkg/manifests/system-header.mf b/usr/src/pkg/manifests/system-header.mf index 396ec52488..a65dbd02b9 100644 --- a/usr/src/pkg/manifests/system-header.mf +++ b/usr/src/pkg/manifests/system-header.mf @@ -178,7 +178,6 @@ $(sparc_ONLY)dir path=usr/platform/sun4v/include/sys $(sparc_ONLY)dir path=usr/platform/sun4v/include/vm dir path=usr/share dir path=usr/share/man -dir path=usr/share/man/man3 dir path=usr/share/man/man3head dir path=usr/share/man/man4 dir path=usr/share/man/man5 @@ -1877,7 +1876,6 @@ file path=usr/share/man/man3head/nl_types.h.3head file path=usr/share/man/man3head/poll.h.3head file path=usr/share/man/man3head/pthread.h.3head file path=usr/share/man/man3head/pwd.h.3head -file path=usr/share/man/man3head/queue.h.3head file path=usr/share/man/man3head/regex.h.3head file path=usr/share/man/man3head/resource.h.3head file path=usr/share/man/man3head/sched.h.3head @@ -2019,111 +2017,6 @@ $(sparc_ONLY)link path=usr/platform/SUNW,UltraSPARC-IIe-NetraCT-60/include \ target=../sun4u/include $(sparc_ONLY)link path=usr/platform/SUNW,UltraSPARC-IIi-Netract/include \ target=../sun4u/include -link path=usr/share/man/man3head/LIST_CLASS_ENTRY.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_CLASS_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_CONCAT.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_EMPTY.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_ENTRY.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_FIRST.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_FOREACH.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_FOREACH_FROM.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_FOREACH_FROM_SAFE.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/LIST_FOREACH_SAFE.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_HEAD_INITIALIZER.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/LIST_INIT.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_INSERT_AFTER.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_INSERT_BEFORE.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_INSERT_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_NEXT.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_PREV.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_REMOVE.3head target=queue.h.3head -link path=usr/share/man/man3head/LIST_SWAP.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_CLASS_ENTRY.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_CLASS_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_CONCAT.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_EMPTY.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_ENTRY.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_FIRST.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_FOREACH.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_FOREACH_FROM.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_FOREACH_FROM_SAFE.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/SLIST_FOREACH_SAFE.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_HEAD_INITIALIZER.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/SLIST_INIT.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_INSERT_AFTER.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_INSERT_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_NEXT.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_REMOVE.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_REMOVE_AFTER.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_REMOVE_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/SLIST_SWAP.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_CLASS_ENTRY.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_CLASS_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_CONCAT.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_EMPTY.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_ENTRY.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_FIRST.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_FOREACH.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_FOREACH_FROM.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_FOREACH_FROM_SAFE.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_FOREACH_SAFE.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_HEAD_INITIALIZER.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_INIT.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_INSERT_AFTER.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_INSERT_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_INSERT_TAIL.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_LAST.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_NEXT.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_REMOVE.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_REMOVE_AFTER.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_REMOVE_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/STAILQ_SWAP.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_CLASS_ENTRY.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_CLASS_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_CONCAT.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_EMPTY.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_ENTRY.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_FIRST.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_FOREACH.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_FOREACH_FROM.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_FOREACH_FROM_SAFE.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_FOREACH_REVERSE.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_FOREACH_REVERSE_FROM.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_FOREACH_REVERSE_FROM_SAFE.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_FOREACH_REVERSE_SAFE.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_FOREACH_SAFE.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_HEAD_INITIALIZER.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_INIT.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_INSERT_AFTER.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_INSERT_BEFORE.3head \ - target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_INSERT_HEAD.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_INSERT_TAIL.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_LAST.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_NEXT.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_PREV.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_REMOVE.3head target=queue.h.3head -link path=usr/share/man/man3head/TAILQ_SWAP.3head target=queue.h.3head link path=usr/share/man/man3head/acct.3head target=acct.h.3head link path=usr/share/man/man3head/aio.3head target=aio.h.3head link path=usr/share/man/man3head/ar.3head target=ar.h.3head diff --git a/usr/src/uts/common/io/sata/adapters/ahci/ahci.c b/usr/src/uts/common/io/sata/adapters/ahci/ahci.c index 8a7b1be281..f29da7631a 100644 --- a/usr/src/uts/common/io/sata/adapters/ahci/ahci.c +++ b/usr/src/uts/common/io/sata/adapters/ahci/ahci.c @@ -10771,6 +10771,7 @@ ahci_em_ioctl_set(ahci_ctl_t *ahci_ctlp, intptr_t arg) task->aelta_ctl = ahci_ctlp; task->aelta_port = set.aiems_port; + task->aelta_port = (uint8_t)set.aiems_port; task->aelta_op = set.aiems_op; task->aelta_state = set.aiems_leds; diff --git a/usr/src/uts/common/sys/queue.h b/usr/src/uts/common/sys/queue.h index 8a22f6663c..39a476450f 100644 --- a/usr/src/uts/common/sys/queue.h +++ b/usr/src/uts/common/sys/queue.h @@ -1,3 +1,5 @@ +/* $NetBSD: queue.h,v 1.42 2005/07/13 15:08:24 wiz Exp $ */ + /* * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. @@ -37,9 +39,8 @@ #define _SYS_QUEUE_H #include <sys/note.h> -#include <sys/stddef.h> -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -89,69 +90,102 @@ extern "C" { * For details on the use of these macros, see the queue(3) manual page. */ -#ifdef QUEUE_MACRO_DEBUG -#warn Use QUEUE_MACRO_DEBUG_TRACE and/or QUEUE_MACRO_DEBUG_TRASH -#define QUEUE_MACRO_DEBUG_TRACE -#define QUEUE_MACRO_DEBUG_TRASH +/* + * List definitions. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ +#if defined(_KERNEL) && defined(QUEUEDEBUG) +#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field) \ + if ((head)->lh_first && \ + (head)->lh_first->field.le_prev != &(head)->lh_first) \ + panic("LIST_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__); +#define QUEUEDEBUG_LIST_OP(elm, field) \ + if ((elm)->field.le_next && \ + (elm)->field.le_next->field.le_prev != \ + &(elm)->field.le_next) \ + panic("LIST_* forw %p %s:%d", (elm), __FILE__, __LINE__);\ + if (*(elm)->field.le_prev != (elm)) \ + panic("LIST_* back %p %s:%d", (elm), __FILE__, __LINE__); +#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field) \ + (elm)->field.le_next = (void *)1L; \ + (elm)->field.le_prev = (void *)1L; +#else +#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field) +#define QUEUEDEBUG_LIST_OP(elm, field) +#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field) #endif -#ifdef QUEUE_MACRO_DEBUG_TRACE -/* Store the last 2 places the queue element or head was altered */ -struct qm_trace { - unsigned long lastline; - unsigned long prevline; - const char *lastfile; - const char *prevfile; -}; - -#define TRACEBUF struct qm_trace trace; -#define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL }, - -#define QMD_TRACE_HEAD(head) do { \ - (head)->trace.prevline = (head)->trace.lastline; \ - (head)->trace.prevfile = (head)->trace.lastfile; \ - (head)->trace.lastline = __LINE__; \ - (head)->trace.lastfile = __FILE__; \ +#define LIST_INIT(head) do { \ + (head)->lh_first = NULL; \ + _NOTE(CONSTCOND) \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + QUEUEDEBUG_LIST_OP((listelm), field) \ + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ + (listelm)->field.le_next->field.le_prev = \ + &(elm)->field.le_next; \ + (listelm)->field.le_next = (elm); \ + (elm)->field.le_prev = &(listelm)->field.le_next; \ _NOTE(CONSTCOND) \ } while (0) -#define QMD_TRACE_ELEM(elem) do { \ - (elem)->trace.prevline = (elem)->trace.lastline; \ - (elem)->trace.prevfile = (elem)->trace.lastfile; \ - (elem)->trace.lastline = __LINE__; \ - (elem)->trace.lastfile = __FILE__; \ +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + QUEUEDEBUG_LIST_OP((listelm), field) \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + (elm)->field.le_next = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &(elm)->field.le_next; \ + _NOTE(CONSTCOND) \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field) \ + if (((elm)->field.le_next = (head)->lh_first) != NULL) \ + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ + (head)->lh_first = (elm); \ + (elm)->field.le_prev = &(head)->lh_first; \ + _NOTE(CONSTCOND) \ +} while (0) + +#define LIST_REMOVE(elm, field) do { \ + QUEUEDEBUG_LIST_OP((elm), field) \ + if ((elm)->field.le_next != NULL) \ + (elm)->field.le_next->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = (elm)->field.le_next; \ + QUEUEDEBUG_LIST_POSTREMOVE((elm), field) \ _NOTE(CONSTCOND) \ } while (0) -#else /* !QUEUE_MACRO_DEBUG_TRACE */ -#define QMD_TRACE_ELEM(elem) -#define QMD_TRACE_HEAD(head) -#define TRACEBUF -#define TRACEBUF_INITIALIZER -#endif /* QUEUE_MACRO_DEBUG_TRACE */ - -#ifdef QUEUE_MACRO_DEBUG_TRASH -#define TRASHIT(x) do {(x) = (void *)-1; } while (0) -#define QMD_IS_TRASHED(x) ((x) == (void *)(intptr_t)-1) -#else /* !QUEUE_MACRO_DEBUG_TRASH */ -#define TRASHIT(x) -#define QMD_IS_TRASHED(x) 0 -#endif /* QUEUE_MACRO_DEBUG_TRASH */ - -#if defined(QUEUE_MACRO_DEBUG_TRACE) || defined(QUEUE_MACRO_DEBUG_TRASH) -#define QMD_SAVELINK(name, link) void **name = (void *)&(link) -#else /* !QUEUE_MACRO_DEBUG_TRACE && !QUEUE_MACRO_DEBUG_TRASH */ -#define QMD_SAVELINK(name, link) -#endif /* QUEUE_MACRO_DEBUG_TRACE || QUEUE_MACRO_DEBUG_TRASH */ - -#ifdef __cplusplus +#define LIST_FOREACH(var, head, field) \ + for ((var) = ((head)->lh_first); \ + (var); \ + (var) = ((var)->field.le_next)) + /* - * In C++ there can be structure lists and class lists: + * List access methods. */ -#define QUEUE_TYPEOF(type) type -#else -#define QUEUE_TYPEOF(type) struct type -#endif +#define LIST_EMPTY(head) ((head)->lh_first == NULL) +#define LIST_FIRST(head) ((head)->lh_first) +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + /* * Singly-linked List definitions. @@ -161,11 +195,6 @@ struct name { \ struct type *slh_first; /* first element */ \ } -#define SLIST_CLASS_HEAD(name, type) \ -struct name { \ - class type *slh_first; /* first element */ \ -} - #define SLIST_HEAD_INITIALIZER(head) \ { NULL } @@ -174,107 +203,55 @@ struct { \ struct type *sle_next; /* next element */ \ } -#define SLIST_CLASS_ENTRY(type) \ -struct { \ - class type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List access methods. - */ -#define SLIST_FIRST(head) ((head)->slh_first) -#define SLIST_END(head) NULL -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) -#define SLIST_EMPTY(head) ((head)->slh_first == SLIST_END(head)) - -#define SLIST_FOREACH(var, head, field) \ - for ((var) = SLIST_FIRST((head)); \ - (var) != SLIST_END(head); \ - (var) = SLIST_NEXT((var), field)) - -#define SLIST_FOREACH_FROM(var, head, field) \ - for ((var) = ((var) != SLIST_END(head) ? (var) : SLIST_FIRST((head))); \ - (var) != SLIST_END(head); \ - (var) = SLIST_NEXT((var), field)) - -#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = SLIST_FIRST((head)); \ - (var) != SLIST_END(head) && \ - ((tvar) = SLIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ - for ((var) = ((var) != SLIST_END(head) ? (var) : SLIST_FIRST((head))); \ - (var) != SLIST_END(head) && \ - ((tvar) = SLIST_NEXT((var), field), 1); \ - (var) = (tvar)) - /* * Singly-linked List functions. */ #define SLIST_INIT(head) do { \ - (head)->slh_first = SLIST_END(head); \ - _NOTE(CONSTCOND) \ -} while (0) - -#define SLIST_CONCAT(head1, head2, type, field) do { \ - QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \ - if (curelm == SLIST_END(head1)) { \ - if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != \ - SLIST_END(head1)) \ - SLIST_INIT(head2); \ - } else if (SLIST_FIRST(head2) != SLIST_END(head2)) { \ - while (SLIST_NEXT(curelm, field) != SLIST_END(head1)) \ - curelm = SLIST_NEXT(curelm, field); \ - SLIST_NEXT(curelm, field) = SLIST_FIRST(head2); \ - SLIST_INIT(head2); \ - } \ + (head)->slh_first = NULL; \ _NOTE(CONSTCOND) \ } while (0) #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ - SLIST_NEXT((slistelm), field) = (elm); \ + (elm)->field.sle_next = (slistelm)->field.sle_next; \ + (slistelm)->field.sle_next = (elm); \ _NOTE(CONSTCOND) \ } while (0) #define SLIST_INSERT_HEAD(head, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ - SLIST_FIRST((head)) = (elm); \ + (elm)->field.sle_next = (head)->slh_first; \ + (head)->slh_first = (elm); \ _NOTE(CONSTCOND) \ } while (0) #define SLIST_REMOVE_HEAD(head, field) do { \ - SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ - _NOTE(CONSTCOND) \ -} while (0) - -#define SLIST_REMOVE_AFTER(slistelm, field) do { \ - SLIST_NEXT((slistelm), field) = \ - SLIST_NEXT(SLIST_NEXT((slistelm), field), field); \ + (head)->slh_first = (head)->slh_first->field.sle_next; \ _NOTE(CONSTCOND) \ } while (0) #define SLIST_REMOVE(head, elm, type, field) do { \ - QMD_SAVELINK(oldnext, SLIST_NEXT((elm), field)); \ - if (SLIST_FIRST((head)) == (elm)) { \ + if ((head)->slh_first == (elm)) { \ SLIST_REMOVE_HEAD((head), field); \ } \ else { \ - QUEUE_TYPEOF(type) *curelm = SLIST_FIRST((head)); \ - while (SLIST_NEXT(curelm, field) != (elm)) \ - curelm = SLIST_NEXT(curelm, field); \ - SLIST_REMOVE_AFTER(curelm, field); \ + struct type *curelm = (head)->slh_first; \ + while (curelm->field.sle_next != (elm)) \ + curelm = curelm->field.sle_next; \ + curelm->field.sle_next = \ + curelm->field.sle_next->field.sle_next; \ } \ - TRASHIT(*oldnext); \ _NOTE(CONSTCOND) \ } while (0) -#define SLIST_SWAP(head1, head2, type) do { \ - QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \ - SLIST_FIRST(head1) = SLIST_FIRST(head2); \ - SLIST_FIRST(head2) = swap_first; \ -} while (0) +#define SLIST_FOREACH(var, head, field) \ + for ((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) + +/* + * Singly-linked List access methods. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) +#define SLIST_FIRST(head) ((head)->slh_first) +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + /* * Singly-linked Tail queue declarations. @@ -285,281 +262,78 @@ struct name { \ struct type **stqh_last; /* addr of last next element */ \ } -#define STAILQ_CLASS_HEAD(name, type) \ -struct name { \ - class type *stqh_first; /* first element */ \ - class type **stqh_last; /* addr of last next element */ \ -} - #define STAILQ_HEAD_INITIALIZER(head) \ { NULL, &(head).stqh_first } #define STAILQ_ENTRY(type) \ struct { \ - struct type *stqe_next; /* next element */ \ + struct type *stqe_next; /* next element */ \ } -#define STAILQ_CLASS_ENTRY(type) \ -struct { \ - class type *stqe_next; /* next element */ \ -} - -/* - * Singly-linked Tail queue access methods. - */ -#define STAILQ_FIRST(head) ((head)->stqh_first) -#define STAILQ_END(head) NULL -#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) -#define STAILQ_EMPTY(head) ((head)->stqh_first == STAILQ_END(head)) - -#define STAILQ_FOREACH(var, head, field) \ - for ((var) = STAILQ_FIRST(head); \ - (var) != STAILQ_END(head); \ - (var) = STAILQ_NEXT((var), field)) - -#define STAILQ_FOREACH_FROM(var, head, field) \ - for ((var) = \ - ((var) != STAILQ_END(head) ? (var) : STAILQ_FIRST((head))); \ - (var) != STAILQ_END(head); \ - (var) = STAILQ_NEXT((var), field)) - -#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = STAILQ_FIRST(head); \ - (var) != STAILQ_END(head) && \ - ((tvar) = STAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ - for ((var) = \ - ((var) != STAILQ_END(head) ? (var) : STAILQ_FIRST((head))); \ - (var) != STAILQ_END(head) && \ - ((tvar) = STAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - /* * Singly-linked Tail queue functions. */ #define STAILQ_INIT(head) do { \ - STAILQ_FIRST(head) = STAILQ_END(head); \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ - _NOTE(CONSTCOND) \ -} while (0) - -#define STAILQ_CONCAT(head1, head2) do { \ - if (!STAILQ_EMPTY((head2))) { \ - *(head1)->stqh_last = STAILQ_FIRST((head2)); \ - (head1)->stqh_last = (head2)->stqh_last; \ - STAILQ_INIT((head2)); \ - } \ - _NOTE(CONSTCOND) \ -} while (0) - -#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_NEXT((tqelm), field) = (elm); \ + (head)->stqh_first = NULL; \ + (head)->stqh_last = &(head)->stqh_first; \ _NOTE(CONSTCOND) \ } while (0) #define STAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_FIRST((head)) = (elm); \ + if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \ + (head)->stqh_last = &(elm)->field.stqe_next; \ + (head)->stqh_first = (elm); \ _NOTE(CONSTCOND) \ } while (0) #define STAILQ_INSERT_TAIL(head, elm, field) do { \ - STAILQ_NEXT((elm), field) = NULL; \ + (elm)->field.stqe_next = NULL; \ *(head)->stqh_last = (elm); \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + (head)->stqh_last = &(elm)->field.stqe_next; \ _NOTE(CONSTCOND) \ } while (0) -#define STAILQ_LAST(head, type, field) \ - (STAILQ_EMPTY((head)) ? NULL : \ - container_of((head)->stqh_last, \ - QUEUE_TYPEOF(type), field.stqe_next)) - -#define STAILQ_REMOVE_HEAD(head, field) do { \ - if ((STAILQ_FIRST((head)) = \ - STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ +#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.stqe_next = (listelm)->field.stqe_next) \ + == NULL) \ + (head)->stqh_last = &(elm)->field.stqe_next; \ + (listelm)->field.stqe_next = (elm); \ _NOTE(CONSTCOND) \ } while (0) -#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ - if ((STAILQ_NEXT(elm, field) = \ - STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) \ + == NULL) \ + (head)->stqh_last = &(head)->stqh_first; \ _NOTE(CONSTCOND) \ } while (0) #define STAILQ_REMOVE(head, elm, type, field) do { \ - QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \ - if (STAILQ_FIRST((head)) == (elm)) { \ + if ((head)->stqh_first == (elm)) { \ STAILQ_REMOVE_HEAD((head), field); \ } else { \ - QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head); \ - while (STAILQ_NEXT(curelm, field) != (elm)) \ - curelm = STAILQ_NEXT(curelm, field); \ - STAILQ_REMOVE_AFTER(head, curelm, field); \ + struct type *curelm = (head)->stqh_first; \ + while (curelm->field.stqe_next != (elm)) \ + curelm = curelm->field.stqe_next; \ + if ((curelm->field.stqe_next = \ + curelm->field.stqe_next->field.stqe_next) == NULL) \ + (head)->stqh_last = &(curelm)->field.stqe_next; \ } \ - TRASHIT(*oldnext); \ - _NOTE(CONSTCOND) \ -} while (0) - -#define STAILQ_SWAP(head1, head2, type) do { \ - QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1); \ - QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last; \ - STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ - (head1)->stqh_last = (head2)->stqh_last; \ - STAILQ_FIRST(head2) = swap_first; \ - (head2)->stqh_last = swap_last; \ - if (STAILQ_EMPTY(head1)) \ - (head1)->stqh_last = &STAILQ_FIRST(head1); \ - if (STAILQ_EMPTY(head2)) \ - (head2)->stqh_last = &STAILQ_FIRST(head2); \ _NOTE(CONSTCOND) \ } while (0) -/* - * List definitions. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_CLASS_HEAD(name, type) \ -struct name { \ - class type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -#define LIST_CLASS_ENTRY(type) \ -struct { \ - class type *le_next; /* next element */ \ - class type **le_prev; /* address of previous next element */ \ -} - -/* - * List access methods. - */ -#define LIST_FIRST(head) ((head)->lh_first) -#define LIST_END(head) NULL -#define LIST_EMPTY(head) ((head)->lh_first == LIST_END(head)) -#define LIST_NEXT(elm, field) ((elm)->field.le_next) -#define LIST_PREV(elm, head, type, field) \ - ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \ - container_of((elm)->field.le_prev, type, field.le_next)) - -#define LIST_FOREACH(var, head, field) \ - for ((var) = LIST_FIRST((head)); \ - (var) != LIST_END(head); \ - (var) = LIST_NEXT((var), field)) - -#define LIST_FOREACH_FROM(var, head, field) \ - for ((var) = ((var) != LIST_END(head) ? (var) : LIST_FIRST((head));\ - (var) != LIST_END(head); \ - (var) = LIST_NEXT((var), field)) - -#define LIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = LIST_FIRST((head)); \ - (var) != LIST_END(head) && \ - ((tvar) = LIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ - for ((var) = ((var) != LIST_END(head) ? (var) : LIST_FIRST((head));\ - (var) != LIST_END(head) && \ - ((tvar) = LIST_NEXT((var), field), 1); \ - (var) = (tvar)) +#define STAILQ_FOREACH(var, head, field) \ + for ((var) = ((head)->stqh_first); \ + (var); \ + (var) = ((var)->field.stqe_next)) /* - * List functions. + * Singly-linked Tail queue access methods. */ -#if defined(_KERNEL) && defined(QUEUEDEBUG) -#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field) \ - if ((head)->lh_first && \ - (head)->lh_first->field.le_prev != &(head)->lh_first) \ - panic("LIST_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__); -#define QUEUEDEBUG_LIST_OP(elm, field) \ - if ((elm)->field.le_next && \ - (elm)->field.le_next->field.le_prev != \ - &(elm)->field.le_next) \ - panic("LIST_* forw %p %s:%d", (elm), __FILE__, __LINE__);\ - if (*(elm)->field.le_prev != (elm)) \ - panic("LIST_* back %p %s:%d", (elm), __FILE__, __LINE__); -#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field) \ - (elm)->field.le_next = (void *)1L; \ - (elm)->field.le_prev = (void *)1L; -#else -#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field) -#define QUEUEDEBUG_LIST_OP(elm, field) -#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field) -#endif - -#define LIST_INIT(head) do { \ - LIST_FIRST((head)) = LIST_END(head); \ - _NOTE(CONSTCOND) \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - QUEUEDEBUG_LIST_OP((listelm), field) \ - if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ - LIST_NEXT((listelm), field)->field.le_prev = \ - &LIST_NEXT((elm), field); \ - LIST_NEXT((listelm), field) = (elm); \ - (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ - _NOTE(CONSTCOND) \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - QUEUEDEBUG_LIST_OP((listelm), field) \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - LIST_NEXT((elm), field) = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ - _NOTE(CONSTCOND) \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field) \ - if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ - LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ - LIST_FIRST((head)) = (elm); \ - (elm)->field.le_prev = &LIST_FIRST((head)); \ - _NOTE(CONSTCOND) \ -} while (0) - -#define LIST_REMOVE(elm, field) do { \ - QUEUEDEBUG_LIST_OP((elm), field) \ - if (LIST_NEXT((elm), field) != NULL) \ - LIST_NEXT((elm), field)->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = LIST_NEXT((elm), field); \ - QUEUEDEBUG_LIST_POSTREMOVE((elm), field) \ - _NOTE(CONSTCOND) \ -} while (0) +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) +#define STAILQ_FIRST(head) ((head)->stqh_first) +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) -#define LIST_SWAP(head1, head2, type, field) do { \ - QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \ - LIST_FIRST((head1)) = LIST_FIRST((head2)); \ - LIST_FIRST((head2)) = swap_tmp; \ - if ((swap_tmp = LIST_FIRST((head1))) != NULL) \ - swap_tmp->field.le_prev = &LIST_FIRST((head1)); \ - if ((swap_tmp = LIST_FIRST((head2))) != NULL) \ - swap_tmp->field.le_prev = &LIST_FIRST((head2)); \ - _NOTE(CONSTCOND) \ -} while (0) /* * Simple queue definitions. @@ -570,12 +344,6 @@ struct name { \ struct type **sqh_last; /* addr of last next element */ \ } -#define SIMPLEQ_CLASS_HEAD(name, type) \ -struct name { \ - class type *sqh_first; /* first element */ \ - class type **sqh_last; /* addr of last next element */ \ -} - #define SIMPLEQ_HEAD_INITIALIZER(head) \ { NULL, &(head).sqh_first } @@ -584,209 +352,88 @@ struct { \ struct type *sqe_next; /* next element */ \ } -#define SIMPLEQ_CLASS_ENTRY(type) \ -struct { \ - class type *sqe_next; /* next element */ \ -} - -/* - * Simple queue access methods. - */ -#define SIMPLEQ_FIRST(head) ((head)->sqh_first) -#define SIMPLEQ_END(head) NULL -#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == SIMPLEQ_END(head)) -#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) - -#define SIMPLEQ_FOREACH(var, head, field) \ - for ((var) = SIMPLEQ_FIRST((head)); \ - (var) != SIMPLEQ_END(head); \ - (var) = SIMPLEQ_NEXT((var), field)) - -#define SIMPLEQ_FOREACH_FROM(var, head, field) \ - for ((var) = \ - ((var) != SIMPLEQ_END(head) ? (var) : SIMPLEQ_FIRST((head)));\ - (var) != SIMPLEQ_END(head); \ - (var) = SIMPLEQ_NEXT((var), field)) - -#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = SIMPLEQ_FIRST((head)); \ - (var) != SIMPLEQ_END(head) && \ - ((tvar) = SIMPLEQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define SIMPLEQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ - for ((var) = \ - ((var) != SIMPLEQ_END(head) ? (var) : SIMPLEQ_FIRST((head)));\ - (var) != SIMPLEQ_END(head) && \ - ((tvar) = SIMPLEQ_NEXT((var), field), 1); \ - (var) = (tvar)) - /* * Simple queue functions. */ #define SIMPLEQ_INIT(head) do { \ - SIMPLEQ_FIRST((head)) = NULL; \ - (head)->sqh_last = &SIMPLEQ_FIRST((head)); \ + (head)->sqh_first = NULL; \ + (head)->sqh_last = &(head)->sqh_first; \ _NOTE(CONSTCOND) \ } while (0) #define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ - if ((SIMPLEQ_NEXT((elm), field) = SIMPLEQ_FIRST((head))) == NULL)\ - (head)->sqh_last = &SIMPLEQ_NEXT((elm), field); \ - SIMPLEQ_FIRST((head)) = (elm); \ + if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (head)->sqh_first = (elm); \ _NOTE(CONSTCOND) \ } while (0) #define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ - SIMPLEQ_NEXT((elm), field) = NULL; \ + (elm)->field.sqe_next = NULL; \ *(head)->sqh_last = (elm); \ - (head)->sqh_last = &SIMPLEQ_NEXT((elm), field); \ + (head)->sqh_last = &(elm)->field.sqe_next; \ _NOTE(CONSTCOND) \ } while (0) #define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if ((SIMPLEQ_NEXT((elm), field) = SIMPLEQ_NEXT((listelm), field)) == \ - NULL) \ - (head)->sqh_last = &SIMPLEQ_NEXT((elm), field); \ - SIMPLEQ_NEXT((listelm), field) = (elm); \ + if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (listelm)->field.sqe_next = (elm); \ _NOTE(CONSTCOND) \ } while (0) #define SIMPLEQ_REMOVE_HEAD(head, field) do { \ - if ((SIMPLEQ_FIRST((head)) = \ - SIMPLEQ_NEXT(SIMPLEQ_FIRST((head)), field)) == NULL) \ - (head)->sqh_last = &SIMPLEQ_FIRST((head)); \ - _NOTE(CONSTCOND) \ -} while (0) - -#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ - if ((SIMPLEQ_NEXT((elm)) = \ - SIMPLEQ_NEXT(SIMPLEQ_NEXT((elm), field), field)) == NULL) \ - (head)->sqh_last = &SIMPLEQ_NEXT((elm), field); \ + if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ + (head)->sqh_last = &(head)->sqh_first; \ _NOTE(CONSTCOND) \ } while (0) #define SIMPLEQ_REMOVE(head, elm, type, field) do { \ - if (SIMPLEQ_FIRST((head)) == (elm)) { \ + if ((head)->sqh_first == (elm)) { \ SIMPLEQ_REMOVE_HEAD((head), field); \ } else { \ - QUEUE_TYPEOF(type) *curelm = SIMPLEQ_FIRST((head)); \ - while (SIMPLEQ_NEXT(curelm, field) != (elm)) \ - curelm = SIMPLEQ_NEXT(curelm, field); \ - SIMPLEQ_REMOVE_AFTER((head), curelm, field); \ + struct type *curelm = (head)->sqh_first; \ + while (curelm->field.sqe_next != (elm)) \ + curelm = curelm->field.sqe_next; \ + if ((curelm->field.sqe_next = \ + curelm->field.sqe_next->field.sqe_next) == NULL) \ + (head)->sqh_last = &(curelm)->field.sqe_next; \ } \ _NOTE(CONSTCOND) \ } while (0) -#define SIMPLEQ_CONCAT(head1, head2) do { \ - if (!SIMPLEQ_EMPTY((head2))) { \ - *(head1)->sqh_last = (head2)->sqh_first; \ - (head1)->sqh_last = (head2)->sqh_last; \ - SIMPLEQ_INIT((head2)); \ - } \ - _NOTE(CONSTCOND) \ -} while (0) +#define SIMPLEQ_FOREACH(var, head, field) \ + for ((var) = ((head)->sqh_first); \ + (var); \ + (var) = ((var)->field.sqe_next)) + +/* + * Simple queue access methods. + */ +#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL) +#define SIMPLEQ_FIRST(head) ((head)->sqh_first) +#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) -#define SIMPLEQ_LAST(head, type, field) \ - (SIMPLEQ_EMPTY((head)) ? \ - NULL : \ - ((QUEUE_TYPEOF(type) *)(void *) \ - ((char *)((head)->sqh_last) - offsetof(QUEUE_TYPEOF(type), field)))) /* * Tail queue definitions. */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ - TRACEBUF \ -} - -#define TAILQ_CLASS_HEAD(name, type) \ +#define _TAILQ_HEAD(name, type) \ struct name { \ - class type *tqh_first; /* first element */ \ - class type **tqh_last; /* addr of last next element */ \ - TRACEBUF \ + type *tqh_first; /* first element */ \ + type **tqh_last; /* addr of last next element */ \ } +#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type) #define TAILQ_HEAD_INITIALIZER(head) \ { NULL, &(head).tqh_first } -#define TAILQ_ENTRY(type) \ +#define _TAILQ_ENTRY(type) \ struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ - TRACEBUF \ -} - -#define TAILQ_CLASS_ENTRY(type) \ -struct { \ - class type *tqe_next; /* next element */ \ - class type **tqe_prev; /* address of previous next element */ \ - TRACEBUF \ + type *tqe_next; /* next element */ \ + type **tqe_prev; /* address of previous next element */\ } - -/* - * Tail queue access methods. - */ -#define TAILQ_FIRST(head) ((head)->tqh_first) -#define TAILQ_END(head) NULL -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) -#define TAILQ_EMPTY(head) ((head)->tqh_first == TAILQ_END(head)) - - -#define TAILQ_FOREACH(var, head, field) \ - for ((var) = TAILQ_FIRST((head)); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_NEXT((var), field)) - -#define TAILQ_FOREACH_FROM(var, head, field) \ - for ((var) = ((var) != TAILQ_END((head)) ? \ - (var) : TAILQ_FIRST((head))); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_NEXT((var), field)) - -#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = TAILQ_FIRST((head)); \ - (var) != TAILQ_END(head) && \ - ((tvar) = TAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ - for ((var) = ((var) != TAILQ_END((head)) ? \ - (var) : TAILQ_FIRST((head))); \ - (var) != TAILQ_END(head) && \ - ((tvar) = TAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for ((var) = TAILQ_LAST((head), headname); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_PREV((var), headname, field)) - -#define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \ - for ((var) = ((var) != TAILQ_END((head)) ? \ - (var) : TAILQ_LAST((head), headname)); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_PREV((var), headname, field)) - -#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ - for ((var) = TAILQ_LAST((head), headname); \ - (var) != TAILQ_END(head) && \ - ((tvar) = TAILQ_PREV((var), headname, field), 1); \ - (var) = (tvar)) - -#define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar)\ - for ((var) = ((var) != TAILQ_END((head)) ? \ - (var) : TAILQ_LAST((head), headname)); \ - (var) != TAILQ_END(head) && \ - ((tvar) = TAILQ_PREV((var), headname, field), 1); \ - (var) = (tvar)) +#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type) /* * Tail queue functions. @@ -827,88 +474,92 @@ struct { \ #endif #define TAILQ_INIT(head) do { \ - TAILQ_FIRST((head)) = TAILQ_END((head)); \ - (head)->tqh_last = &TAILQ_FIRST((head)); \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ _NOTE(CONSTCOND) \ } while (0) #define TAILQ_INSERT_HEAD(head, elm, field) do { \ QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field) \ - if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ - TAILQ_FIRST((head))->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (head)->tqh_first->field.tqe_prev = \ + &(elm)->field.tqe_next; \ else \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - TAILQ_FIRST((head)) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ _NOTE(CONSTCOND) \ } while (0) #define TAILQ_INSERT_TAIL(head, elm, field) do { \ QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field) \ - TAILQ_NEXT((elm), field) = NULL; \ + (elm)->field.tqe_next = NULL; \ (elm)->field.tqe_prev = (head)->tqh_last; \ *(head)->tqh_last = (elm); \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ _NOTE(CONSTCOND) \ } while (0) #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ QUEUEDEBUG_TAILQ_OP((listelm), field) \ - if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ else \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - TAILQ_NEXT((listelm), field) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ _NOTE(CONSTCOND) \ } while (0) #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ QUEUEDEBUG_TAILQ_OP((listelm), field) \ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - TAILQ_NEXT((elm), field) = (listelm); \ + (elm)->field.tqe_next = (listelm); \ *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ _NOTE(CONSTCOND) \ } while (0) #define TAILQ_REMOVE(head, elm, field) do { \ QUEUEDEBUG_TAILQ_PREREMOVE((head), (elm), field) \ QUEUEDEBUG_TAILQ_OP((elm), field) \ - if ((TAILQ_NEXT((elm), field)) != NULL) \ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ (elm)->field.tqe_prev; \ else \ (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field); \ _NOTE(CONSTCOND) \ } while (0) -#define TAILQ_SWAP(head1, head2, type, field) do { \ - QUEUE_TYPEOF(type) *swap_first = TAILQ_FIRST((head1)); \ - QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \ - TAILQ_FIRST((head1)) = TAILQ_FIRST((head2)); \ - (head1)->tqh_last = (head2)->tqh_last; \ - TAILQ_FIRST((head2)) = swap_first; \ - (head2)->tqh_last = swap_last; \ - if ((swap_first = TAILQ_FIRST((head1))) != NULL) \ - swap_first->field.tqe_prev = &TAILQ_FIRST((head1)); \ - else \ - (head1)->tqh_last = &TAILQ_FIRST((head1)); \ - if ((swap_first = TAILQ_FIRST((head2))) != NULL) \ - swap_first->field.tqe_prev = &TAILQ_FIRST((head2)); \ - else \ - (head2)->tqh_last = &TAILQ_FIRST((head2)); \ - _NOTE(CONSTCOND) \ -} while (0) +#define TAILQ_FOREACH(var, head, field) \ + for ((var) = ((head)->tqh_first); \ + (var); \ + (var) = ((var)->field.tqe_next)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));\ + (var); \ + (var) = \ + (*(((struct headname *)((var)->field.tqe_prev))->tqh_last))) /* - * Circular queue definitions. Do not use. We still keep the macros - * for compatibility but because of pointer aliasing issues their use - * is discouraged! + * Tail queue access methods. + */ +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) +#define TAILQ_FIRST(head) ((head)->tqh_first) +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + + +/* + * Circular queue definitions. */ #define CIRCLEQ_HEAD(name, type) \ struct name { \ @@ -926,34 +577,6 @@ struct { \ } /* - * Circular queue access methods. - */ -#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) -#define CIRCLEQ_FIRST(head) ((head)->cqh_first) -#define CIRCLEQ_LAST(head) ((head)->cqh_last) -#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) -#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) - -#define CIRCLEQ_LOOP_NEXT(head, elm, field) \ - (((elm)->field.cqe_next == (void *)(head)) \ - ? ((head)->cqh_first) \ - : (elm->field.cqe_next)) -#define CIRCLEQ_LOOP_PREV(head, elm, field) \ - (((elm)->field.cqe_prev == (void *)(head)) \ - ? ((head)->cqh_last) \ - : (elm->field.cqe_prev)) - -#define CIRCLEQ_FOREACH(var, head, field) \ - for ((var) = CIRCLEQ_FIRST((head)); \ - (var) != (void *)(head); \ - (var) = CIRCLEQ_NEXT((var), field)) - -#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ - for ((var) = CIRCLEQ_LAST((head)); \ - (var) != (void *)(head); \ - (var) = CIRCLEQ_PREV((var), field)) - -/* * Circular queue functions. */ #define CIRCLEQ_INIT(head) do { \ @@ -1020,7 +643,35 @@ struct { \ _NOTE(CONSTCOND) \ } while (0) -#ifdef __cplusplus +#define CIRCLEQ_FOREACH(var, head, field) \ + for ((var) = ((head)->cqh_first); \ + (var) != (void *)(head); \ + (var) = ((var)->field.cqe_next)) + +#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ + for ((var) = ((head)->cqh_last); \ + (var) != (void *)(head); \ + (var) = ((var)->field.cqe_prev)) + +/* + * Circular queue access methods. + */ +#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) +#define CIRCLEQ_FIRST(head) ((head)->cqh_first) +#define CIRCLEQ_LAST(head) ((head)->cqh_last) +#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) +#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) + +#define CIRCLEQ_LOOP_NEXT(head, elm, field) \ + (((elm)->field.cqe_next == (void *)(head)) \ + ? ((head)->cqh_first) \ + : (elm->field.cqe_next)) +#define CIRCLEQ_LOOP_PREV(head, elm, field) \ + (((elm)->field.cqe_prev == (void *)(head)) \ + ? ((head)->cqh_last) \ + : (elm->field.cqe_prev)) + +#ifdef __cplusplus } #endif diff --git a/usr/src/uts/intel/Makefile b/usr/src/uts/intel/Makefile index 1f873651ec..9a1f819983 100644 --- a/usr/src/uts/intel/Makefile +++ b/usr/src/uts/intel/Makefile @@ -30,6 +30,10 @@ UTSBASE = .. include Makefile.intel +# Unset BINARY for clobber.targ because otherwise it will try to remove +# a directory under uts/intel. +BINARY= + LINT_KMODS_X1 = $(LINT_KMODS:nsmb=) LINT_KMODS_X2 = $(LINT_KMODS_X1:smbfs=) LINT_KMODS_X3 = $(LINT_KMODS_X2:e1000g=) |