https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=287741

            Bug ID: 287741
           Summary: ctld deletes ports if they already exist
           Product: Base System
           Version: CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: bin
          Assignee: [email protected]
          Reporter: [email protected]
                CC: [email protected], [email protected], [email protected]

I've been helping a client track down an issue introduced by commit
15b3e3bb7efcbf7c29ab76e9ea7990c17df790e6 to ctld.  Here is the change, with a
little extra context:

        /*
         * Now add new ports or modify existing ones.
         */
-       TAILQ_FOREACH(newport, &newconf->conf_ports, p_next) {
+       TAILQ_FOREACH_SAFE(newport, &newconf->conf_ports, p_next, tmpport) {
                if (port_is_dummy(newport))
                        continue;
                oldport = port_find(oldconf, newport->p_name);

                if (oldport == NULL || port_is_dummy(oldport)) {
                        log_debugx("adding port \"%s\"", newport->p_name);
 (1)                    error = kernel_port_add(newport);
                } else {
                        log_debugx("updating port \"%s\"", newport->p_name);
                        newport->p_ctl_port = oldport->p_ctl_port;
 (2)                    error = kernel_port_update(newport, oldport);
                }
                if (error != 0) {
                        log_warnx("failed to %s port %s",
 (3)                        (oldport == NULL) ? "add" : "update",
                            newport->p_name);
+                       if (oldport == NULL || port_is_dummy(oldport))
+(4)                            port_delete(newport);
                        /*
                         * XXX: Uncomment after fixing the root cause.
                         *
                         * cumulated_error++;
                         */
                }
        }


Some observations:

(1) If kernel_port_add() fails because the port being added already exists, it
returns non-zero, with no way for the caller to determine that the error can
safely be ignored.
(2) kernel_port_update() always returns zero, regardless of outcome.
(3) The log_warnx() call in the error case should print "add" when
port_is_dummy(newport) is true, not only when oldport is NULL.  In fact, this
log_warnx() call is only reached in the add case since kernel_port_update()
never returns non-zero.
(4) If kernel_port_add() failed because the port already existed, we now react
by deleting it.

I'm still working on determining why ctld thinks the port is new when it in
fact already exists, but we should handle this gracefully regardless.

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to